Salome HOME
Old development made for salome Hydro:
[modules/geom.git] / src / CurveCreator / CurveCreator_TreeView.cxx
1 // Copyright (C) 2013-2020  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, or (at your option) any later version.
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 #include "CurveCreator_Curve.hxx"
23 #include "CurveCreator_Utils.hxx"
24
25 #include <SUIT_Session.h>
26 #include <SUIT_ResourceMgr.h>
27
28 #include <QHeaderView>
29 #include <QtAlgorithms>
30
31 #define ID_SECTION -1
32
33 CurveCreator_TreeViewModel::CurveCreator_TreeViewModel( CurveCreator_ICurve* theCurve, QObject* parent, bool toDrawColorIcon ) :
34   QAbstractItemModel(parent), myCurve(theCurve), myDrawColorIcon(toDrawColorIcon)
35 {
36   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
37   QPixmap aSplineIcon(aResMgr->loadPixmap("GEOM", tr("ICON_CC_SPLINE")));
38   QPixmap aPolylineIcon(aResMgr->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
39   QPixmap aClosedSplineIcon(aResMgr->loadPixmap("GEOM", tr("ICON_CC_CLOSED_SPLINE")));
40   QPixmap aClosedPolylineIcon(aResMgr->loadPixmap("GEOM", tr("ICON_CC_CLOSED_POLYLINE")));
41   QPixmap aPointIcon(aResMgr->loadPixmap("GEOM", tr("ICON_CC_POINT")));
42
43 /*  QPixmap aSplineIcon(tr(":images/ICON_SPLINE"));
44   QPixmap aPolylineIcon(tr(":images/ICON_POLYLINE"));
45   QPixmap aClosedPolylineIcon(tr(":images/ICON_CLOSED_POLYLINE"));
46   QPixmap aClosedSplineIcon(tr(":images/ICON_CLOSED_SPLINE"));
47   QPixmap aPointIcon(tr(":images/ICON_POINT")); */
48
49   if( !aSplineIcon.isNull() )
50     myCachedIcons[ICON_SPLINE] = aSplineIcon;
51
52   if( !aPolylineIcon.isNull() )
53     myCachedIcons[ICON_POLYLINE] = aPolylineIcon;
54
55   if( !aPolylineIcon.isNull() )
56     myCachedIcons[ICON_CLOSED_POLYLINE] = aClosedPolylineIcon;
57
58   if( !aPolylineIcon.isNull() )
59     myCachedIcons[ICON_CLOSED_SPLINE] = aClosedSplineIcon;
60
61   if( !aPointIcon.isNull() )
62     myCachedIcons[ICON_POINT] = aPointIcon;
63
64   setHeaderData(1, Qt::Horizontal, QVariant("Name"), Qt::DisplayRole);
65   setHeaderData(2, Qt::Horizontal, QVariant("Nb points"), Qt::DisplayRole);
66 }
67
68 int     CurveCreator_TreeViewModel::columnCount(const QModelIndex & parent ) const
69 {
70   if( myDrawColorIcon )
71     return 3;
72   else
73     return 2;
74 }
75
76 QVariant        CurveCreator_TreeViewModel::data(const QModelIndex & index, int role ) const
77 {
78   int aRow = index.row();
79   int aColumn = index.column();
80   if( myCurve ){
81     if( index.internalId() == (quintptr)ID_SECTION ){
82       if( role == Qt::DisplayRole ){
83         if( aColumn == 0 )
84           return QString::fromStdString(myCurve->getSectionName(aRow));
85         else if( aColumn == 1 )
86           return QString::number(myCurve->getNbPoints(aRow));
87         return QVariant();
88       }
89       else if( role == Qt::DecorationRole ){
90         if( aColumn == 0 ){
91           CurveCreator::SectionType aSectionType = myCurve->getSectionType(aRow);
92           if( aSectionType == CurveCreator::Polyline ){
93             if( myCurve->isClosed(aRow) ){
94               return myCachedIcons[ICON_CLOSED_POLYLINE];
95             }
96             else{
97               return myCachedIcons[ICON_POLYLINE];
98             }
99           }
100           else{
101             if( myCurve->isClosed(aRow) ){
102               return myCachedIcons[ICON_CLOSED_SPLINE];
103             }
104             else{
105               return myCachedIcons[ICON_SPLINE];
106             }
107           }
108         }
109         else if (myDrawColorIcon && aColumn == 2)
110         {
111           Quantity_Color color = ((CurveCreator_Curve*)myCurve)->getColorSection(aRow);
112           QPixmap pixmap(16,16);
113           pixmap.fill( CurveCreator_Utils::colorConv(color));
114           return pixmap;
115         }
116       }
117     }
118 /*    else{
119       if( role == Qt::DisplayRole ){
120         if( aColumn == 1 )
121           return QVariant();
122         //                    return "Point";
123         else if( aColumn == 0 ){
124           CurveCreator::Coordinates aCoords = myCurve->getCoordinates(index.internalId(),index.row() );
125           QString anOut;
126           if( myCurve->getDimension() == CurveCreator::Dim2d ){
127             anOut = QString(tr("X=%1, Y=%2")).arg(aCoords[0]).arg(aCoords[1]);
128           }
129           else{
130             anOut = QString(tr("X=%1, Y=%2, Z=%3")).arg(aCoords[0]).arg(aCoords[1]).arg(aCoords[2]);
131           }
132           return anOut;
133         }
134       }
135       else if( role == Qt::DecorationRole ){
136         if( aColumn == 0 ){
137           return myCachedIcons[ICON_POINT];
138         }
139       }
140     }*/
141   }
142   return QVariant();
143 }
144
145 QModelIndex     CurveCreator_TreeViewModel::index(int row, int column, const QModelIndex & parent ) const
146 {
147   if( parent.isValid() ){
148     return createIndex(row, column, parent.row() );
149   }
150   else{
151     QModelIndex aParent = createIndex(row, column, ID_SECTION );
152     return aParent;
153   }
154   return QModelIndex();
155 }
156
157 QModelIndex     CurveCreator_TreeViewModel::parent(const QModelIndex & theIndex) const
158 {
159   if( !theIndex.isValid() )
160     return QModelIndex();
161
162   if( theIndex.internalId() == (quintptr)ID_SECTION ){
163     return QModelIndex();
164   }
165   return createIndex( theIndex.internalId(), 0, ID_SECTION  );
166 }
167
168 int     CurveCreator_TreeViewModel::rowCount(const QModelIndex & parent ) const
169 {
170   int aRowCnt = 0;
171   if( myCurve != NULL ){
172     if( !parent.isValid() ){
173       //Section level
174       aRowCnt =  myCurve->getNbSections();
175     }
176     else{
177       if( parent.internalId() == (quintptr)ID_SECTION ){
178         //Points level
179         aRowCnt = myCurve->getNbPoints(parent.row());
180       }
181     }
182   }
183   return aRowCnt;
184 }
185
186 QModelIndex CurveCreator_TreeViewModel::sectionIndex( int theSection ) const
187 {
188   return createIndex( theSection, 0, ID_SECTION );
189 }
190
191 QModelIndex CurveCreator_TreeViewModel::nbPointsIndex( int theSection ) const
192 {
193   return createIndex( theSection, 1, ID_SECTION );
194 }
195
196 QModelIndex CurveCreator_TreeViewModel::pointIndex( int theSection, int thePoint ) const
197 {
198   return createIndex( thePoint, 0, theSection );
199 }
200
201 bool CurveCreator_TreeViewModel::isSection( const QModelIndex& theIndx ) const
202 {
203   if( theIndx.internalId() == (quintptr)ID_SECTION )
204     return true;
205   return false;
206 }
207
208 int CurveCreator_TreeViewModel::getSection( const QModelIndex& theIndx ) const
209 {
210   if( theIndx.internalId() == (quintptr)ID_SECTION )
211     return theIndx.row();
212   return theIndx.internalId();
213 }
214
215 int CurveCreator_TreeViewModel::getPoint( const QModelIndex& theIndx ) const
216 {
217   if( theIndx.internalId() == (quintptr)ID_SECTION )
218     return -1;
219   return theIndx.row();
220 }
221
222 void CurveCreator_TreeViewModel::setCurve( CurveCreator_ICurve* theCurve )
223 {
224   beginResetModel();
225   myCurve = theCurve;
226   endResetModel();
227 }
228
229 /*****************************************************************************************/
230 CurveCreator_TreeView::CurveCreator_TreeView( CurveCreator_ICurve* theCurve, QWidget *parent, bool toDrawColorIcon) :
231   QTreeView(parent)
232 {
233   header()->hide();
234   header()->setSectionResizeMode(QHeaderView::ResizeToContents);
235   setUniformRowHeights(true);
236   setContextMenuPolicy( Qt::CustomContextMenu );
237   CurveCreator_TreeViewModel* aModel = new CurveCreator_TreeViewModel(theCurve, this, toDrawColorIcon);
238   setModel(aModel);
239   setSelectionBehavior(SelectRows);
240   setSelectionMode(SingleSelection);
241   setRootIsDecorated(false);
242   setItemsExpandable(false);
243   setAllColumnsShowFocus(true);
244   connect( selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
245            this, SIGNAL(selectionChanged()) );
246   connect( this, SIGNAL(activated(QModelIndex)), this, SLOT(onActivated(QModelIndex)));
247 }
248
249 QList<int> CurveCreator_TreeView::getSelectedSections() const
250 {
251   QList<int> aSect;
252   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
253   if( !aModel )
254     return aSect;
255 //  QModelIndexList anIndxs = selectionModel()->selectedIndexes();
256   QModelIndexList anIndxs = selectionModel()->selectedRows();
257   for( int i = 0 ; i < anIndxs.size() ; i++ ){
258     if( aModel->isSection(anIndxs[i]) ){
259       aSect << aModel->getSection( anIndxs[i] );
260     }
261   }
262   return aSect;
263 }
264
265 void CurveCreator_TreeView::pointsAdded( int theSection, int thePoint, int thePointsCnt )
266 {
267   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
268   if( aModel ){
269     QModelIndex aSectIndx = aModel->sectionIndex( theSection );
270     rowsInserted(aSectIndx, thePoint, thePoint + thePointsCnt - 1 );
271 //    expand( aSectIndx );
272     update( aModel->nbPointsIndex( theSection ) );
273   }
274 }
275
276 void CurveCreator_TreeView::pointDataChanged( int theSection, int thePoint )
277 {
278   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
279   if( aModel ){
280     QModelIndex aPointIndx = aModel->pointIndex( theSection, thePoint );
281     dataChanged( aPointIndx, aPointIndx );
282   }
283 }
284
285 void CurveCreator_TreeView::pointsRemoved( int theSection, int thePoint, int thePointsCnt )
286 {
287   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
288   if( aModel ){
289     for( int i = 0 ; i < thePointsCnt ; i++ ){
290       QModelIndex aSectIndx = aModel->pointIndex(theSection, thePoint + i);
291       selectionModel()->select(aSectIndx,QItemSelectionModel::Deselect);
292     }
293     QModelIndex aSectIndx = aModel->sectionIndex( theSection );
294     rowsRemoved(aSectIndx, thePoint, thePoint + thePointsCnt - 1 );
295   }
296 }
297
298 void CurveCreator_TreeView::sectionAdded( int theSection )
299 {
300   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
301   if( aModel ){
302     int nbRows = aModel->rowCount();
303     int aSection = (theSection == -1 ? (nbRows==0 ? 0 : nbRows-1) : theSection);
304     rowsInserted(QModelIndex(), aSection, aSection );
305     QModelIndex aSectIndx = aModel->sectionIndex(aSection);
306     selectionModel()->select(aSectIndx, QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect);
307   }
308 }
309
310 void CurveCreator_TreeView::sectionChanged( int theSection, int aSectCnt )
311 {
312   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
313   if( aModel ){
314     QModelIndex aFirstSectIndx = aModel->sectionIndex( theSection );
315     QModelIndex aLastSectIndx = aModel->sectionIndex( theSection + aSectCnt - 1);
316     dataChanged( aFirstSectIndx, aLastSectIndx );
317   }
318 }
319
320 void CurveCreator_TreeView::sectionsRemoved( int theSection, int theSectionCnt )
321 {
322   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
323   if( aModel ){
324     for( int i = 0 ; i < theSectionCnt ; i++ ){
325       QModelIndex aSectIndx = aModel->sectionIndex(theSection + i);
326       this->selectionModel()->select(aSectIndx,QItemSelectionModel::Deselect);
327     }
328     rowsRemoved( QModelIndex(), theSection, theSection+theSectionCnt-1 );
329   }
330 }
331
332 void CurveCreator_TreeView::setIndexState( const QModelIndex& theIndx, bool& isExpanded, bool& isSelected, bool& /*isCurrent*/ ) // todo: isCurrent is not set!
333 {
334   setExpanded( theIndx, isExpanded );
335   QItemSelectionModel::SelectionFlags aFlag = QItemSelectionModel::Select;
336   if( !isSelected ){
337     aFlag = QItemSelectionModel::Deselect;
338   }
339   selectionModel()->select( theIndx, aFlag );
340 }
341
342 void CurveCreator_TreeView::getIndexInfo( const QModelIndex& theIndx, bool& isExpand, bool& isSelected, bool& isCurrent )
343 {
344   isExpand = isExpanded(theIndx);
345   isSelected = selectionModel()->isSelected(theIndx);
346   isCurrent = (theIndx == selectionModel()->currentIndex());
347 }
348
349 void CurveCreator_TreeView::swapIndexes( const QModelIndex& theFirst, const QModelIndex& theSecond )
350 {
351   bool isFirstSelected;
352   bool isFirstExpanded;
353   bool isFirstCurrent;
354   getIndexInfo( theFirst, isFirstExpanded, isFirstSelected, isFirstCurrent );
355
356   bool isSecondSelected;
357   bool isSecondExpanded;
358   bool isSecondCurrent;
359   getIndexInfo( theSecond, isSecondExpanded, isSecondSelected, isSecondCurrent );
360
361   setIndexState( theFirst, isSecondExpanded, isSecondSelected, isSecondCurrent );
362   setIndexState( theSecond, isFirstExpanded, isFirstSelected, isFirstCurrent );
363   dataChanged(theFirst,theFirst);
364   dataChanged(theSecond,theSecond);
365 }
366
367 void CurveCreator_TreeView::sectionsSwapped( int theSection, int theOffset )
368 {
369   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
370   if( aModel ){
371     QModelIndex aFirstIndex = aModel->sectionIndex( theSection );
372     QModelIndex aSecondIndex = aModel->sectionIndex( theSection + theOffset );
373     swapIndexes( aFirstIndex, aSecondIndex );
374   }
375 }
376
377 void CurveCreator_TreeView::setSelectedSections( const QList<int>& theList )
378 {
379   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
380   if( aModel ){
381     selectionModel()->clearSelection();
382     for( int i = 0 ; i < theList.size() ; i++ ){
383       QModelIndex aSectIndx = aModel->sectionIndex(theList[i]);
384       selectionModel()->select(aSectIndx, QItemSelectionModel::Select | QItemSelectionModel::Rows );
385     }
386   }
387 }
388
389 bool pointLessThan(const QPair<int,int> &s1, const QPair<int,int> &s2)
390 {
391   if( s1.first < s2.first )
392     return true;
393   if( s1.first > s2.first )
394     return false;
395   return s1.second < s2.second;
396 }
397
398 CurveCreator_TreeView::SelectionType CurveCreator_TreeView::getSelectionType() const
399 {
400   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
401   if( !aModel )
402     return ST_NOSEL;
403   bool isPointSel = false;
404   bool isSectSel = false;
405   bool isOneSection = true;
406   int aSectNum = -1;
407   QModelIndexList aLst = selectionModel()->selectedIndexes();
408   for( int i = 0 ; i < aLst.size() ; i++ ){
409     if( aModel->isSection( aLst[i] ) ){
410       isSectSel = true;
411     }
412     else{
413       isPointSel = true;
414       if( aSectNum == -1 ){
415         aSectNum = aModel->getSection(aLst[i]);
416       }
417       else{
418         if( aSectNum != aModel->getSection( aLst[i] ) ){
419           isOneSection = false;
420         }
421       }
422     }
423   }
424   if( isSectSel && !isPointSel )
425     return ST_SECTIONS;
426   if( isPointSel && !isSectSel ){
427     if( isOneSection ){
428       return ST_POINTS_ONE_SECTION;
429     }
430     return ST_POINTS;
431   }
432   if( isPointSel && isSectSel )
433     return ST_MIXED;
434   return ST_NOSEL;
435 }
436
437 void CurveCreator_TreeView::onActivated( QModelIndex theIndx )
438 {
439   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
440   if( !aModel )
441     return;
442   int aSect = aModel->getSection(theIndx);
443   if( aModel->isSection(theIndx) ){
444     emit sectionEntered( aSect );
445   }
446 }
447
448 void CurveCreator_TreeView::setCurve( CurveCreator_ICurve* theCurve )
449 {
450   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
451   if( aModel )
452     aModel->setCurve(theCurve);
453   reset();
454 }
455
456 void CurveCreator_TreeView::reset()
457 {
458   QList<int> aSelSections = getSelectedSections();
459   QTreeView::reset();
460   setSelectedSections(aSelSections);
461 }