Salome HOME
Profile object realization. OCC Viewer embeded into the profile dialog box.
[modules/hydro.git] / src / HYDROCurveCreator / CurveCreator_TreeView.cxx
1 // Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "CurveCreator_TreeView.h"
21 #include "CurveCreator_ICurve.hxx"
22
23 #include <SUIT_Session.h>
24 #include <SUIT_ResourceMgr.h>
25
26 #include <QHeaderView>
27 #include <QtAlgorithms>
28
29 #define ID_SECTION -1
30
31 CurveCreator_TreeViewModel::CurveCreator_TreeViewModel( CurveCreator_ICurve* theCurve, QObject* parent ) :
32   QAbstractItemModel(parent), myCurve(theCurve)
33 {
34   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
35   QPixmap aSplineIcon(aResMgr->loadPixmap("GEOM", tr("ICON_CC_SPLINE")));
36   QPixmap aPolylineIcon(aResMgr->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
37   QPixmap aClosedSplineIcon(aResMgr->loadPixmap("GEOM", tr("ICON_CC_CLOSED_SPLINE")));
38   QPixmap aClosedPolylineIcon(aResMgr->loadPixmap("GEOM", tr("ICON_CC_CLOSED_POLYLINE")));
39   QPixmap aPointIcon(aResMgr->loadPixmap("GEOM", tr("ICON_CC_POINT")));
40
41 /*  QPixmap aSplineIcon(tr(":images/ICON_SPLINE"));
42   QPixmap aPolylineIcon(tr(":images/ICON_POLYLINE"));
43   QPixmap aClosedPolylineIcon(tr(":images/ICON_CLOSED_POLYLINE"));
44   QPixmap aClosedSplineIcon(tr(":images/ICON_CLOSED_SPLINE"));
45   QPixmap aPointIcon(tr(":images/ICON_POINT")); */
46
47   if( !aSplineIcon.isNull() )
48     myCachedIcons[ICON_SPLINE] = aSplineIcon;
49
50   if( !aPolylineIcon.isNull() )
51     myCachedIcons[ICON_POLYLINE] = aPolylineIcon;
52
53   if( !aPolylineIcon.isNull() )
54     myCachedIcons[ICON_CLOSED_POLYLINE] = aClosedPolylineIcon;
55
56   if( !aPolylineIcon.isNull() )
57     myCachedIcons[ICON_CLOSED_SPLINE] = aClosedSplineIcon;
58
59   if( !aPointIcon.isNull() )
60     myCachedIcons[ICON_POINT] = aPointIcon;
61
62   setHeaderData(1, Qt::Horizontal, QVariant("Name"), Qt::DisplayRole);
63   setHeaderData(2, Qt::Horizontal, QVariant("Nb points"), Qt::DisplayRole);
64 }
65
66 int     CurveCreator_TreeViewModel::columnCount(const QModelIndex & parent ) const
67 {
68   if( parent.internalId() == ID_SECTION )
69     return 2;
70   else
71     return 2;
72 }
73
74 QVariant        CurveCreator_TreeViewModel::data(const QModelIndex & index, int role ) const
75 {
76   int aRow = index.row();
77   int aColumn = index.column();
78   if( myCurve ){
79     if( index.internalId() == ID_SECTION ){
80       if( role == Qt::DisplayRole ){
81         if( aColumn == 0 )
82           return QString::fromStdString(myCurve->getSectionName(aRow));
83         else if( aColumn == 1 )
84           return QString::number(myCurve->getNbPoints(aRow));
85         return QVariant();
86       }
87       else if( role == Qt::DecorationRole ){
88         if( aColumn == 0 ){
89           CurveCreator::SectionType aSectionType = myCurve->getSectionType(aRow);
90           if( aSectionType == CurveCreator::Polyline ){
91             if( myCurve->isClosed(aRow) ){
92               return myCachedIcons[ICON_CLOSED_POLYLINE];
93             }
94             else{
95               return myCachedIcons[ICON_POLYLINE];
96             }
97           }
98           else{
99             if( myCurve->isClosed(aRow) ){
100               return myCachedIcons[ICON_CLOSED_SPLINE];
101             }
102             else{
103               return myCachedIcons[ICON_SPLINE];
104             }
105           }
106         }
107       }
108     }
109 /*    else{
110       if( role == Qt::DisplayRole ){
111         if( aColumn == 1 )
112           return QVariant();
113         //                    return "Point";
114         else if( aColumn == 0 ){
115           CurveCreator::Coordinates aCoords = myCurve->getCoordinates(index.internalId(),index.row() );
116           QString anOut;
117           if( myCurve->getDimension() == CurveCreator::Dim2d ){
118             anOut = QString(tr("X=%1, Y=%2")).arg(aCoords[0]).arg(aCoords[1]);
119           }
120           else{
121             anOut = QString(tr("X=%1, Y=%2, Z=%3")).arg(aCoords[0]).arg(aCoords[1]).arg(aCoords[2]);
122           }
123           return anOut;
124         }
125       }
126       else if( role == Qt::DecorationRole ){
127         if( aColumn == 0 ){
128           return myCachedIcons[ICON_POINT];
129         }
130       }
131     }*/
132   }
133   return QVariant();
134 }
135
136 QModelIndex     CurveCreator_TreeViewModel::index(int row, int column, const QModelIndex & parent ) const
137 {
138   if( parent.isValid() ){
139     return createIndex(row, column, parent.row() );
140   }
141   else{
142     QModelIndex aParent = createIndex(row, column, ID_SECTION );
143     return aParent;
144   }
145   return QModelIndex();
146 }
147
148 QModelIndex     CurveCreator_TreeViewModel::parent(const QModelIndex & theIndex) const
149 {
150   if( !theIndex.isValid() )
151     return QModelIndex();
152
153   if( theIndex.internalId() == ID_SECTION ){
154     return QModelIndex();
155   }
156   return createIndex( theIndex.internalId(), 0, ID_SECTION  );
157 }
158
159 int     CurveCreator_TreeViewModel::rowCount(const QModelIndex & parent ) const
160 {
161   int aRowCnt = 0;
162   if( myCurve != NULL ){
163     if( !parent.isValid() ){
164       //Section level
165       aRowCnt =  myCurve->getNbSections();
166     }
167     else{
168       if( parent.internalId() == ID_SECTION ){
169         //Points level
170         aRowCnt = myCurve->getNbPoints(parent.row());
171       }
172     }
173   }
174   return aRowCnt;
175 }
176
177 QModelIndex CurveCreator_TreeViewModel::sectionIndex( int theSection ) const
178 {
179   return createIndex( theSection, 0, ID_SECTION );
180 }
181
182 QModelIndex CurveCreator_TreeViewModel::nbPointsIndex( int theSection ) const
183 {
184   return createIndex( theSection, 1, ID_SECTION );
185 }
186
187 QModelIndex CurveCreator_TreeViewModel::pointIndex( int theSection, int thePoint ) const
188 {
189   return createIndex( thePoint, 0, theSection );
190 }
191
192 bool CurveCreator_TreeViewModel::isSection( const QModelIndex& theIndx ) const
193 {
194   if( theIndx.internalId() == ID_SECTION )
195     return true;
196   return false;
197 }
198
199 int CurveCreator_TreeViewModel::getSection( const QModelIndex& theIndx ) const
200 {
201   if( theIndx.internalId() == ID_SECTION )
202     return theIndx.row();
203   return theIndx.internalId();
204 }
205
206 int CurveCreator_TreeViewModel::getPoint( const QModelIndex& theIndx ) const
207 {
208   if( theIndx.internalId() == ID_SECTION )
209     return -1;
210   return theIndx.row();
211 }
212
213 void CurveCreator_TreeViewModel::setCurve( CurveCreator_ICurve* theCurve )
214 {
215   myCurve = theCurve;
216   reset();
217 }
218
219 /*****************************************************************************************/
220 CurveCreator_TreeView::CurveCreator_TreeView( CurveCreator_ICurve* theCurve, QWidget *parent) :
221   QTreeView(parent)
222 {
223   header()->hide();
224   header()->setResizeMode(QHeaderView::ResizeToContents);
225   setUniformRowHeights(true);
226   setContextMenuPolicy( Qt::CustomContextMenu );
227   CurveCreator_TreeViewModel* aModel = new CurveCreator_TreeViewModel(theCurve, this);
228   setModel(aModel);
229   setSelectionBehavior(SelectRows);
230   setSelectionMode(SingleSelection);
231   setRootIsDecorated(false);
232   setItemsExpandable(false);
233   setAllColumnsShowFocus(true);
234   connect( selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
235            this, SIGNAL(selectionChanged()) );
236   connect( this, SIGNAL(activated(QModelIndex)), this, SLOT(onActivated(QModelIndex)));
237 }
238
239 QList<int> CurveCreator_TreeView::getSelectedSections() const
240 {
241   QList<int> aSect;
242   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
243   if( !aModel )
244     return aSect;
245 //  QModelIndexList anIndxs = selectionModel()->selectedIndexes();
246   QModelIndexList anIndxs = selectionModel()->selectedRows();
247   for( int i = 0 ; i < anIndxs.size() ; i++ ){
248     if( aModel->isSection(anIndxs[i]) ){
249       aSect << aModel->getSection( anIndxs[i] );
250     }
251   }
252   qSort(aSect.begin(), aSect.end());
253   return aSect;
254 }
255
256 void CurveCreator_TreeView::pointsAdded( int theSection, int thePoint, int thePointsCnt )
257 {
258   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
259   if( aModel ){
260     QModelIndex aSectIndx = aModel->sectionIndex( theSection );
261     rowsInserted(aSectIndx, thePoint, thePoint + thePointsCnt - 1 );
262 //    expand( aSectIndx );
263     update( aModel->nbPointsIndex( theSection ) );
264   }
265 }
266
267 void CurveCreator_TreeView::pointDataChanged( int theSection, int thePoint )
268 {
269   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
270   if( aModel ){
271     QModelIndex aPointIndx = aModel->pointIndex( theSection, thePoint );
272     dataChanged( aPointIndx, aPointIndx );
273   }
274 }
275
276 void CurveCreator_TreeView::pointsRemoved( int theSection, int thePoint, int thePointsCnt )
277 {
278   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
279   if( aModel ){
280     for( int i = 0 ; i < thePointsCnt ; i++ ){
281       QModelIndex aSectIndx = aModel->pointIndex(theSection, thePoint + i);
282       selectionModel()->select(aSectIndx,QItemSelectionModel::Deselect);
283     }
284     QModelIndex aSectIndx = aModel->sectionIndex( theSection );
285     rowsRemoved(aSectIndx, thePoint, thePoint + thePointsCnt - 1 );
286   }
287 }
288
289 void CurveCreator_TreeView::sectionAdded( int theSection )
290 {
291   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
292   if( aModel ){
293     int nbRows = aModel->rowCount();
294     int aSection = (theSection == -1 ? (nbRows==0 ? 0 : nbRows-1) : theSection);
295     rowsInserted(QModelIndex(), aSection, aSection );
296     QModelIndex aSectIndx = aModel->sectionIndex(aSection);
297     selectionModel()->select(aSectIndx, QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect);
298   }
299 }
300
301 void CurveCreator_TreeView::sectionChanged( int theSection, int aSectCnt )
302 {
303   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
304   if( aModel ){
305     QModelIndex aFirstSectIndx = aModel->sectionIndex( theSection );
306     QModelIndex aLastSectIndx = aModel->sectionIndex( theSection + aSectCnt - 1);
307     dataChanged( aFirstSectIndx, aLastSectIndx );
308   }
309 }
310
311 void CurveCreator_TreeView::sectionsRemoved( int theSection, int theSectionCnt )
312 {
313   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
314   if( aModel ){
315     for( int i = 0 ; i < theSectionCnt ; i++ ){
316       QModelIndex aSectIndx = aModel->sectionIndex(theSection + i);
317       this->selectionModel()->select(aSectIndx,QItemSelectionModel::Deselect);
318     }
319     rowsRemoved( QModelIndex(), theSection, theSection+theSectionCnt-1 );
320   }
321 }
322
323 void CurveCreator_TreeView::setIndexState( const QModelIndex& theIndx, bool& isExpanded, bool& isSelected, bool& isCurrent )
324 {
325   setExpanded( theIndx, isExpanded );
326   QItemSelectionModel::SelectionFlags aFlag = QItemSelectionModel::Select;
327   if( !isSelected ){
328     aFlag = QItemSelectionModel::Deselect;
329   }
330   selectionModel()->select( theIndx, aFlag );
331 }
332
333 void CurveCreator_TreeView::getIndexInfo( const QModelIndex& theIndx, bool& isExpand, bool& isSelected, bool& isCurrent )
334 {
335   isExpand = isExpanded(theIndx);
336   isSelected = selectionModel()->isSelected(theIndx);
337   isCurrent = (theIndx == selectionModel()->currentIndex());
338 }
339
340 void CurveCreator_TreeView::swapIndexes( const QModelIndex& theFirst, const QModelIndex& theSecond )
341 {
342   bool isFirstSelected;
343   bool isFirstExpanded;
344   bool isFirstCurrent;
345   getIndexInfo( theFirst, isFirstExpanded, isFirstSelected, isFirstCurrent );
346
347   bool isSecondSelected;
348   bool isSecondExpanded;
349   bool isSecondCurrent;
350   getIndexInfo( theSecond, isSecondExpanded, isSecondSelected, isSecondCurrent );
351
352   setIndexState( theFirst, isSecondExpanded, isSecondSelected, isSecondCurrent );
353   setIndexState( theSecond, isFirstExpanded, isFirstSelected, isFirstCurrent );
354   dataChanged(theFirst,theFirst);
355   dataChanged(theSecond,theSecond);
356 }
357
358 void CurveCreator_TreeView::sectionsSwapped( int theSection, int theOffset )
359 {
360   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
361   if( aModel ){
362     QModelIndex aFirstIndex = aModel->sectionIndex( theSection );
363     QModelIndex aSecondIndex = aModel->sectionIndex( theSection + theOffset );
364     swapIndexes( aFirstIndex, aSecondIndex );
365   }
366 }
367
368 void CurveCreator_TreeView::pointsSwapped( int theSection, int thePointNum, int theOffset )
369 {
370   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
371   if( aModel ){
372     QModelIndex aFirstIndex = aModel->pointIndex( theSection, thePointNum );
373     QModelIndex aSecondIndex = aModel->pointIndex( theSection, thePointNum + theOffset );
374     swapIndexes( aFirstIndex, aSecondIndex );
375   }
376 }
377
378 void CurveCreator_TreeView::setSelectedSections( const QList<int>& theList )
379 {
380   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
381   if( aModel ){
382     selectionModel()->clearSelection();
383     for( int i = 0 ; i < theList.size() ; i++ ){
384       QModelIndex aSectIndx = aModel->sectionIndex(theList[i]);
385       selectionModel()->select(aSectIndx, QItemSelectionModel::Select | QItemSelectionModel::Rows );
386     }
387   }
388 }
389
390 void CurveCreator_TreeView::setSelectedPoints( const QList< QPair<int, int> >& thePointsList )
391 {
392   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
393   if( aModel ){
394     selectionModel()->clearSelection();
395     for( int i = 0 ; i < thePointsList.size() ; i++ ){
396       QModelIndex aSectIndx = aModel->pointIndex( thePointsList[i].first, thePointsList[i].second );
397       selectionModel()->select(aSectIndx, QItemSelectionModel::Select );
398     }
399   }
400 }
401
402 bool pointLessThan(const QPair<int,int> &s1, const QPair<int,int> &s2)
403 {
404   if( s1.first < s2.first )
405     return true;
406   if( s1.first > s2.first )
407     return false;
408   return s1.second < s2.second;
409 }
410
411 QList< QPair< int, int > > CurveCreator_TreeView::getSelectedPoints() const
412 {
413   QList< QPair< int, int > > aPoints;
414   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
415   if( !aModel )
416     return aPoints;
417   QModelIndexList anIndxs = selectionModel()->selectedIndexes();
418   for( int i = 0 ; i < anIndxs.size() ; i++ ){
419     if( !aModel->isSection( anIndxs[i] ) ){
420       int aSect = aModel->getSection(anIndxs[i]);
421       int aPointNum = aModel->getPoint(anIndxs[i]);
422       QPair< int, int > aPoint = QPair<int,int>( aSect, aPointNum );
423       aPoints.push_back( aPoint );
424     }
425   }
426   qSort( aPoints.begin(), aPoints.end(), pointLessThan );
427   return aPoints;
428 }
429
430 CurveCreator_TreeView::SelectionType CurveCreator_TreeView::getSelectionType() const
431 {
432   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
433   if( !aModel )
434     return ST_NOSEL;
435   bool isPointSel = false;
436   bool isSectSel = false;
437   bool isOneSection = true;
438   int aSectNum = -1;
439   QModelIndexList aLst = selectionModel()->selectedIndexes();
440   for( int i = 0 ; i < aLst.size() ; i++ ){
441     if( aModel->isSection( aLst[i] ) ){
442       isSectSel = true;
443     }
444     else{
445       isPointSel = true;
446       if( aSectNum == -1 ){
447         aSectNum = aModel->getSection(aLst[i]);
448       }
449       else{
450         if( aSectNum != aModel->getSection( aLst[i] ) ){
451           isOneSection = false;
452         }
453       }
454     }
455   }
456   if( isSectSel && !isPointSel )
457     return ST_SECTIONS;
458   if( isPointSel && !isSectSel ){
459     if( isOneSection ){
460       return ST_POINTS_ONE_SECTION;
461     }
462     return ST_POINTS;
463   }
464   if( isPointSel && isSectSel )
465     return ST_MIXED;
466   return ST_NOSEL;
467 }
468
469 void CurveCreator_TreeView::onActivated( QModelIndex theIndx )
470 {
471   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
472   if( !aModel )
473     return;
474   int aSect = aModel->getSection(theIndx);
475   if( aModel->isSection(theIndx) ){
476     emit sectionEntered( aSect );
477     return;
478   }
479   int aPointNum = aModel->getPoint( theIndx );
480   emit pointEntered( aSect, aPointNum );
481 }
482
483 void CurveCreator_TreeView::setCurve( CurveCreator_ICurve* theCurve )
484 {
485   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
486   if( aModel )
487     aModel->setCurve(theCurve);
488   reset();
489 }
490
491 void CurveCreator_TreeView::reset()
492 {
493   QList<int> aSelSections = getSelectedSections();
494   QTreeView::reset();
495   setSelectedSections(aSelSections);
496 }