Salome HOME
Corrections of examples path after install with scbi
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_OrderedListWidget.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROGUI_OrderedListWidget.h"
20
21 #include "HYDROGUI_ListModel.h"
22
23 #include <SUIT_Session.h>
24 #include <SUIT_ResourceMgr.h>
25
26 #include <QLayout>
27 #include <QListView>
28 #include <QPushButton>
29 #include <QSignalMapper>
30 #include <QSortFilterProxyModel>
31
32
33 /**
34   Constructor.
35   @param theParent the parent widget
36   @param theIconSize the icon size for arrow buttons
37 */
38 HYDROGUI_OrderedListWidget::HYDROGUI_OrderedListWidget( QWidget* theParent, int theArrowIconSize )
39 : QWidget( theParent )
40 {
41   // Main layout
42   QHBoxLayout* aMainLayout = new QHBoxLayout( this );
43   aMainLayout->setMargin( 0 );
44   aMainLayout->setSpacing( 5 );
45
46   // List view
47   myList = new QListView( this );
48   myList->setSelectionMode( QAbstractItemView::ExtendedSelection );
49   // enable drag and drop
50   myList->setDragEnabled( true );
51   myList->setAcceptDrops( true );
52   // configure drag and drop
53   myList->setDropIndicatorShown( true );
54   myList->setDragDropMode( QAbstractItemView::InternalMove );
55
56   // Set the custom model
57   HYDROGUI_ListModel* aModel = new HYDROGUI_ListModel();
58   QSortFilterProxyModel* aFilteredModel = new QSortFilterProxyModel();
59   aFilteredModel->setSourceModel( aModel );
60   aFilteredModel->setFilterKeyColumn( 0 );
61   aFilteredModel->setFilterRole( HYDROGUI_VisibleRole );
62
63   myList->setModel( aFilteredModel );
64
65   // Add list to the main layout
66   aMainLayout->addWidget( myList );
67
68   // Buttons top, up, down, bottom
69   if ( theArrowIconSize > 0 ) {
70     SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
71     myTop = new QPushButton( this );
72     myTop->setIcon( aResMgr->loadPixmap( "HYDRO", tr( "ARROW_TOP_ICO" ) ) );
73     myTop->setIconSize( QSize( theArrowIconSize, theArrowIconSize ) );
74     myTop->setToolTip( tr( "TOP_TLT" ) );
75     myUp = new QPushButton( this );
76     myUp->setIcon( aResMgr->loadPixmap( "HYDRO", tr( "ARROW_UP_ICO" ) ) );
77     myUp->setIconSize( myTop->iconSize() );
78     myUp->setToolTip( tr( "UP_TLT" ) );
79     myDown = new QPushButton( this );
80     myDown->setIcon( aResMgr->loadPixmap( "HYDRO", tr( "ARROW_DOWN_ICO" ) ) );
81     myDown->setIconSize( myTop->iconSize() );
82     myDown->setToolTip( tr( "DOWN_TLT" ) );
83     myBottom = new QPushButton( this );
84     myBottom->setIcon( aResMgr->loadPixmap( "HYDRO", tr( "ARROW_BOTTOM_ICO" ) ) );
85     myBottom->setIconSize( myTop->iconSize() );
86     myBottom->setToolTip( tr( "BOTTOM_TLT" ) );
87
88     // Add buttons to the main layout
89     QVBoxLayout* aListButtonsLayout = new QVBoxLayout();
90     aListButtonsLayout->addWidget( myTop );
91     aListButtonsLayout->addWidget( myUp );
92     aListButtonsLayout->addWidget( myDown );
93     aListButtonsLayout->addWidget( myBottom );
94     aListButtonsLayout->addStretch();
95     
96     aMainLayout->addLayout( aListButtonsLayout );
97
98     // Buttons connections
99     QSignalMapper* aSignalMapper = new QSignalMapper( this );
100     aSignalMapper->setMapping( myTop, HYDROGUI_ListModel::Top );
101     aSignalMapper->setMapping( myUp, HYDROGUI_ListModel::Up );
102     aSignalMapper->setMapping( myDown, HYDROGUI_ListModel::Down );
103     aSignalMapper->setMapping( myBottom, HYDROGUI_ListModel::Bottom );
104     connect( myTop, SIGNAL( clicked() ), aSignalMapper, SLOT( map() ) );
105     connect( myUp, SIGNAL( clicked() ), aSignalMapper, SLOT( map() ) );
106     connect( myDown, SIGNAL( clicked() ), aSignalMapper, SLOT( map() ) );
107     connect( myBottom, SIGNAL( clicked() ), aSignalMapper, SLOT( map() ) );
108     connect( aSignalMapper, SIGNAL( mapped( int ) ), this, SLOT( onMove( int ) ) );
109   } else {
110     myTop = myUp = myDown = myBottom = 0;
111   }
112
113   connect ( myList->selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), 
114             this, SIGNAL( selectionChanged() ) );
115   
116   connect ( myList->selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), 
117             this, SLOT( onSelectionChanged() ) );
118
119   // Initialize
120   setHiddenObjectsShown( true );
121   setVisibilityIconShown( true );
122 }
123
124 void HYDROGUI_OrderedListWidget::onSelectionChanged()
125 {
126   QStringList selectedEntries = getSelectedEntries();
127
128 }
129
130 /**
131   Destructor.
132 */
133 HYDROGUI_OrderedListWidget::~HYDROGUI_OrderedListWidget()
134 {
135 }
136
137 /**
138   Set the list of objects (which supposed to be ordered by the widget).
139   @param theObjects the list of pairs (object; visibility)
140 */
141 void HYDROGUI_OrderedListWidget::setObjects( const HYDROGUI_ListModel::Object2VisibleList& theObjects )
142 {
143   HYDROGUI_ListModel* aModel = getSourceModel();
144   if( aModel ) {
145     aModel->setObjects( theObjects );
146   }
147 }
148
149 void HYDROGUI_OrderedListWidget::setBackgroundColor (int theInd, QColor theColor)
150 {
151   HYDROGUI_ListModel* aModel = getSourceModel();
152   if( aModel ) {
153     aModel->setBackgroundColor( theInd, theColor );
154   }
155 }
156
157 void HYDROGUI_OrderedListWidget::setBackgroundColor (QString theName, QColor theColor)
158 {
159   HYDROGUI_ListModel* aModel = getSourceModel();
160   if (aModel)
161   {
162     QList<Handle(HYDROData_Entity)> anObjects = aModel->getObjects();
163     int ind = -1;
164     int cur_ind = 0;
165     foreach (Handle(HYDROData_Entity) ent, anObjects)
166     {
167       if (ent->GetName() == theName)
168       {
169         ind = cur_ind;
170         break;
171       }
172       cur_ind++;
173     }
174     if (ind != -1)
175       aModel->setBackgroundColor( ind, theColor );
176   }
177 }
178
179 void HYDROGUI_OrderedListWidget::clearAllBackgroundColors ()
180 {
181   HYDROGUI_ListModel* aModel = getSourceModel();
182   if( aModel ) {
183     aModel->clearAllBackgroundColors( );
184   }
185 }
186
187
188  QColor HYDROGUI_OrderedListWidget::getBackgroundColor (int theInd) const
189  {
190    HYDROGUI_ListModel* aModel = getSourceModel();
191    if( aModel ) {
192      return aModel->getBackgroundColor( theInd );
193    }
194  }
195
196 /**
197   Returns the ordered list of objects.
198   @return the list of objects
199 */
200 QList<Handle(HYDROData_Entity)> HYDROGUI_OrderedListWidget::getObjects() const
201 {
202   QList<Handle(HYDROData_Entity)> anObjects;
203
204   HYDROGUI_ListModel* aModel = getSourceModel();
205   if( aModel ) {
206     anObjects = aModel->getObjects();
207   }
208
209   return anObjects;
210 }
211
212 /**
213   Add the object to the end of the list.
214   @param theObjects the pair (object; visibility)
215 */
216 void HYDROGUI_OrderedListWidget::addObject( const HYDROGUI_ListModel::Object2Visible& theObject )
217 {
218   HYDROGUI_ListModel* aModel = getSourceModel();
219   if( aModel ) {
220     aModel->addObject(theObject);
221   }
222 }
223
224 /**
225   Remove the object from the list.
226   @param theObjectName the name of the object to remove
227 */
228 void HYDROGUI_OrderedListWidget::removeObjectByName( const QString& theObjectName )
229 {
230   HYDROGUI_ListModel* aModel = getSourceModel();
231   if( aModel ) {
232     aModel->removeObjectByName(theObjectName);
233   }
234 }
235
236 /**
237   Set whether the hidden objects are presented in the list.
238   @param theIsToShow if true - the hidden objects will be shown in the list
239 */
240 void HYDROGUI_OrderedListWidget::setHiddenObjectsShown( const bool theIsToShow )
241 {
242   myIsHiddenObjectsShown = theIsToShow; 
243
244   QSortFilterProxyModel* aFilterModel = dynamic_cast<QSortFilterProxyModel*>( myList->model() );
245   QString anExpr = theIsToShow ? "true|false" : "true";
246   aFilterModel->setFilterRegExp( anExpr );
247 }
248
249 /**
250   Set whether the visibility icon (eye icon) are presented in the list.
251   @param theIsToShow if true - the eye icon will be shown in the list
252 */
253 void HYDROGUI_OrderedListWidget::setVisibilityIconShown( const bool theIsToShow )
254 {
255   HYDROGUI_ListModel* aModel = getSourceModel();
256   if( aModel ) {
257     aModel->setDecorationEnabled( theIsToShow );
258   }
259 }
260
261 /**
262   Get entries of the selected objects.
263   @return the list of entries
264 */
265 QStringList HYDROGUI_OrderedListWidget::getSelectedEntries() const
266
267   QStringList anEntries;
268
269   QSortFilterProxyModel* aFilterModel = 
270     dynamic_cast<QSortFilterProxyModel*>( myList->model() );
271   if( aFilterModel ) {
272     HYDROGUI_ListModel* aSourceModel = 
273       dynamic_cast<HYDROGUI_ListModel*>( aFilterModel->sourceModel() );
274     if ( aSourceModel ) {
275       QModelIndexList aSelectedIndexes = myList->selectionModel()->selectedIndexes();
276       foreach ( const QModelIndex& anIndex, aSelectedIndexes ) {
277         QModelIndex aSourceIndex = aFilterModel->mapToSource( anIndex );
278         QString anEntry = aSourceModel->data( aSourceIndex, HYDROGUI_EntryRole ).toString();
279         anEntries << anEntry;
280       }
281     }
282   }
283
284   return anEntries;
285 }
286
287 /**
288   Set objects with the given entries selected (other objects will deselected).
289   @param theEntries the list of entries
290 */
291 void HYDROGUI_OrderedListWidget::setSelectedEntries( const QStringList& theEntries ) const
292 {
293   QSortFilterProxyModel* aFilterModel = dynamic_cast<QSortFilterProxyModel*>( myList->model() );
294   if( !aFilterModel ) {
295     return;
296   }
297   HYDROGUI_ListModel* aSourceModel = dynamic_cast<HYDROGUI_ListModel*>( aFilterModel->sourceModel() );
298   if ( !aSourceModel ) {
299     return;
300   }
301   QItemSelectionModel* aSelectionModel = myList->selectionModel();
302   if ( !aSelectionModel ) {
303     return;
304   }
305   
306   for ( int aRow = 0 ; aRow < aSourceModel->rowCount() ; aRow++ ) {
307     QModelIndex anIndex = aSourceModel->index( aRow, 0 );
308     if ( !anIndex.isValid() ) {
309       continue;
310     }
311
312     QString anEntry = aSourceModel->data( anIndex, HYDROGUI_EntryRole ).toString();
313
314     bool isToSelect = theEntries.contains( anEntry );
315     QModelIndex aProxyModelIndex = aFilterModel->mapFromSource( anIndex );
316     QItemSelectionModel::SelectionFlags aSelectionFlags =
317       isToSelect ? QItemSelectionModel::Select : QItemSelectionModel::Deselect;
318     aSelectionModel->select( aProxyModelIndex, aSelectionFlags );
319   }
320 }
321
322 /**
323   Get names of the selected objects.
324   @return the list of names
325 */
326 QStringList HYDROGUI_OrderedListWidget::getSelectedNames() const
327 {
328   QStringList aNames;
329
330   QSortFilterProxyModel* aFilterModel = 
331     dynamic_cast<QSortFilterProxyModel*>( myList->model() );
332   if ( aFilterModel ) {
333     HYDROGUI_ListModel* aSourceModel = 
334       dynamic_cast<HYDROGUI_ListModel*>( aFilterModel->sourceModel() );
335     if ( aSourceModel ) {
336       QModelIndexList aSelectedIndexes = myList->selectionModel()->selectedIndexes();
337       foreach ( const QModelIndex& anIndex, aSelectedIndexes ) {
338         QModelIndex aSourceIndex = aFilterModel->mapToSource( anIndex );
339         QString anEntry = aSourceModel->data( aSourceIndex, Qt::DisplayRole ).toString();
340         aNames << anEntry;
341       }
342     }
343   }
344
345   return aNames;
346 }
347
348 /**
349   Get names of all objects.
350   @return the list of names
351 */
352 QStringList HYDROGUI_OrderedListWidget::getAllNames() const
353 {
354   QStringList aNames;
355
356
357   foreach ( const Handle(HYDROData_Entity)& anObject, getObjects() ) {
358     aNames << anObject->GetName();
359   }
360
361   return aNames;
362 }
363
364 /**
365   Slot called on top, up, down and bottom button click.
366   @param theType the move operation type
367 */
368 void HYDROGUI_OrderedListWidget::onMove( int theType )
369 {
370   bool isMoved = false;
371
372   QSortFilterProxyModel* aFilterModel = dynamic_cast<QSortFilterProxyModel*>( myList->model() );
373   if( aFilterModel ) {
374     HYDROGUI_ListModel* aModel = dynamic_cast<HYDROGUI_ListModel*>( aFilterModel->sourceModel() );
375     if( aModel ) {
376       QModelIndexList aSelectedIndexes = myList->selectionModel()->selectedIndexes();
377       QModelIndexList aSelectedSourceIndexes;
378       foreach ( const QModelIndex& anIndex, aSelectedIndexes ) {
379         aSelectedSourceIndexes << aFilterModel->mapToSource( anIndex );
380       }
381       QList<int> aSelectedIds = aModel->getIds( aSelectedSourceIndexes );
382       isMoved = aModel->move( aSelectedIds, ( HYDROGUI_ListModel::OpType )theType, 
383                               !myIsHiddenObjectsShown );
384     }
385   }
386
387   if ( isMoved )
388   {
389     emit orderChanged();
390   }
391 }
392
393 /**
394   Returns the list source model.
395   @return the source model
396 */
397 HYDROGUI_ListModel* HYDROGUI_OrderedListWidget::getSourceModel() const
398 {
399   HYDROGUI_ListModel* aSourceModel = 0;
400
401   QSortFilterProxyModel* aFilterModel = dynamic_cast<QSortFilterProxyModel*>( myList->model() );
402   if( aFilterModel ) {
403     aSourceModel = dynamic_cast<HYDROGUI_ListModel*>( aFilterModel->sourceModel() );
404   }
405
406   return aSourceModel;
407 }
408
409 /**
410   Enable/disable ordering (i.e. enable/disable arrow buttons and drag and drop).
411   @param theIsToEnable if true - ordering will bw enabled
412 */
413 void HYDROGUI_OrderedListWidget::setOrderingEnabled( const bool theIsToEnable )
414 {
415   // enable/disable arrow buttons
416   if ( myTop && myUp && myDown && myBottom ) {
417     myTop->setEnabled( theIsToEnable );
418     myUp->setEnabled( theIsToEnable );
419     myDown->setEnabled( theIsToEnable );
420     myBottom->setEnabled( theIsToEnable );
421   }
422
423   // enable/disable drag and drop
424   myList->setDragEnabled( theIsToEnable );
425 }
426
427 void HYDROGUI_OrderedListWidget::undoLastMove()
428 {
429   HYDROGUI_ListModel* aModel = getSourceModel();
430   if( aModel )
431     aModel->undoLastMove();
432 }