Salome HOME
Renaming, add selector for selection synchronization.
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_OrderedListWidget.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_OrderedListWidget.h"
24
25 #include "HYDROGUI_ListModel.h"
26
27 #include <SUIT_Session.h>
28 #include <SUIT_ResourceMgr.h>
29
30 #include <QLayout>
31 #include <QListView>
32 #include <QToolButton>
33 #include <QSignalMapper>
34 #include <QSortFilterProxyModel>
35
36
37 /**
38   Constructor.
39   @param theParent the parent widget
40 */
41 HYDROGUI_OrderedListWidget::HYDROGUI_OrderedListWidget( QWidget* theParent )
42 : QWidget( theParent )
43 {
44   // Main layout
45   QHBoxLayout* aMainLayout = new QHBoxLayout( this );
46   aMainLayout->setSpacing( 5 );
47
48   // List view
49   myList = new QListView( this );
50   myList->setSelectionMode( QAbstractItemView::ExtendedSelection );
51   myList->setDragEnabled( true );
52   myList->setAcceptDrops( true );
53   myList->viewport()->setAcceptDrops( true );
54   myList->setDropIndicatorShown( true );
55   myList->setDragDropMode( QAbstractItemView::InternalMove );
56
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   // Buttons top, up, down, bottom
66   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
67   myTop = new QToolButton;
68   myTop->setIcon( aResMgr->loadPixmap( "HYDRO", tr( "ARROW_TOP_ICO" ) ) );
69   myTop->setIconSize( QSize( 32, 32 ) );
70   myUp = new QToolButton;
71   myUp->setIcon( aResMgr->loadPixmap( "HYDRO", tr( "ARROW_UP_ICO" ) ) );
72   myUp->setIconSize( myTop->iconSize() );
73   myDown = new QToolButton;
74   myDown->setIcon( aResMgr->loadPixmap( "HYDRO", tr( "ARROW_DOWN_ICO" ) ) );
75   myDown->setIconSize( myTop->iconSize() );
76   myBottom = new QToolButton;
77   myBottom->setIcon( aResMgr->loadPixmap( "HYDRO", tr( "ARROW_BOTTOM_ICO" ) ) );
78   myBottom->setIconSize( myTop->iconSize() );
79
80   // Layout
81   // buttons
82   QVBoxLayout* aListButtonsLayout = new QVBoxLayout();
83   aListButtonsLayout->addWidget( myTop );
84   aListButtonsLayout->addWidget( myUp );
85   aListButtonsLayout->addWidget( myDown );
86   aListButtonsLayout->addWidget( myBottom );
87   aListButtonsLayout->addStretch();
88   // main
89   aMainLayout->addWidget( myList );
90   aMainLayout->addLayout( aListButtonsLayout );
91
92   // Connections
93   QSignalMapper* aSignalMapper = new QSignalMapper( this );
94   aSignalMapper->setMapping( myTop, HYDROGUI_ListModel::Top );
95   aSignalMapper->setMapping( myUp, HYDROGUI_ListModel::Up );
96   aSignalMapper->setMapping( myDown, HYDROGUI_ListModel::Down );
97   aSignalMapper->setMapping( myBottom, HYDROGUI_ListModel::Bottom );
98   connect( myTop, SIGNAL( clicked() ), aSignalMapper, SLOT( map() ) );
99   connect( myUp, SIGNAL( clicked() ), aSignalMapper, SLOT( map() ) );
100   connect( myDown, SIGNAL( clicked() ), aSignalMapper, SLOT( map() ) );
101   connect( myBottom, SIGNAL( clicked() ), aSignalMapper, SLOT( map() ) );
102   connect( aSignalMapper, SIGNAL( mapped( int ) ), this, SLOT( onMove( int ) ) );
103
104   connect ( myList->selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), 
105             this, SIGNAL( selectionChanged() ) );
106
107   // Initialize
108   setHiddenObjectsShown( true );
109 }
110
111 /**
112   Destructor.
113 */
114 HYDROGUI_OrderedListWidget::~HYDROGUI_OrderedListWidget()
115 {
116 }
117
118 /**
119   Set the list of objects (which supposed to be ordered by the widget).
120   @param theObjects the list of pairs (object; visibility)
121 */
122 void HYDROGUI_OrderedListWidget::setObjects( const HYDROGUI_ListModel::Object2VisibleList& theObjects )
123 {
124   HYDROGUI_ListModel* aModel = getSourceModel();
125   if( aModel ) {
126     aModel->setObjects( theObjects );
127   }
128 }
129
130 /**
131   Returns the ordered list of objects.
132   @return the list of objects
133 */
134 QList<Handle(HYDROData_Entity)> HYDROGUI_OrderedListWidget::getObjects() const
135 {
136   QList<Handle(HYDROData_Entity)> anObjects;
137
138   HYDROGUI_ListModel* aModel = getSourceModel();
139   if( aModel ) {
140     anObjects = aModel->getObjects();
141   }
142
143   return anObjects;
144 }
145
146 /**
147   Set whether the hidden objects are presented in the list.
148   @param theIsToShow if true - the hidden objects will be shown in the list
149 */
150 void HYDROGUI_OrderedListWidget::setHiddenObjectsShown( const bool theIsToShow )
151 {
152   myIsHiddenObjectsShown = theIsToShow; 
153
154   QSortFilterProxyModel* aFilterModel = dynamic_cast<QSortFilterProxyModel*>( myList->model() );
155   QString anExpr = theIsToShow ? "true|false" : "true";
156   aFilterModel->setFilterRegExp( anExpr );
157 }
158
159 /**
160   Get entries of the selected objects.
161   @return the list of entries
162 */
163 QStringList HYDROGUI_OrderedListWidget::getSelectedEntries() const
164
165   QStringList anEntries;
166
167   QSortFilterProxyModel* aFilterModel = 
168     dynamic_cast<QSortFilterProxyModel*>( myList->model() );
169   if( aFilterModel ) {
170     HYDROGUI_ListModel* aSourceModel = 
171       dynamic_cast<HYDROGUI_ListModel*>( aFilterModel->sourceModel() );
172     if ( aSourceModel ) {
173       QModelIndexList aSelectedIndexes = myList->selectionModel()->selectedIndexes();
174       foreach ( const QModelIndex& anIndex, aSelectedIndexes ) {
175         QModelIndex aSourceIndex = aFilterModel->mapToSource( anIndex );
176         QString anEntry = aSourceModel->data( aSourceIndex, HYDROGUI_EntryRole ).toString();
177         anEntries << anEntry;
178       }
179     }
180   }
181
182   return anEntries;
183 }
184
185 /**
186   Set objects with the given entries selected (other objects will deselected).
187   @param theEntries the list of entries
188 */
189 void HYDROGUI_OrderedListWidget::setSelectedEntries( const QStringList& theEntries ) const
190 {
191   QSortFilterProxyModel* aFilterModel = dynamic_cast<QSortFilterProxyModel*>( myList->model() );
192   if( !aFilterModel ) {
193     return;
194   }
195   HYDROGUI_ListModel* aSourceModel = dynamic_cast<HYDROGUI_ListModel*>( aFilterModel->sourceModel() );
196   if ( !aSourceModel ) {
197     return;
198   }
199   QItemSelectionModel* aSelectionModel = myList->selectionModel();
200   if ( !aSelectionModel ) {
201     return;
202   }
203   
204   for ( int aRow = 0 ; aRow < aSourceModel->rowCount() ; aRow++ ) {
205     QModelIndex anIndex = aSourceModel->index( aRow, 0 );
206     if ( !anIndex.isValid() ) {
207       continue;
208     }
209
210     QString anEntry = aSourceModel->data( anIndex, HYDROGUI_EntryRole ).toString();
211
212     bool isToSelect = theEntries.contains( anEntry );
213     QModelIndex aProxyModelIndex = aFilterModel->mapFromSource( anIndex );
214     QItemSelectionModel::SelectionFlags aSelectionFlags =
215       isToSelect ? QItemSelectionModel::Select : QItemSelectionModel::Deselect;
216     aSelectionModel->select( aProxyModelIndex, aSelectionFlags );
217   }
218 }
219
220 /**
221   Slot called on top, up, down and bottom button click.
222   @param theType the move operation type
223 */
224 void HYDROGUI_OrderedListWidget::onMove( int theType )
225 {
226   QSortFilterProxyModel* aFilterModel = dynamic_cast<QSortFilterProxyModel*>( myList->model() );
227   if( aFilterModel ) {
228     HYDROGUI_ListModel* aModel = dynamic_cast<HYDROGUI_ListModel*>( aFilterModel->sourceModel() );
229     if( aModel ) {
230       QModelIndexList aSelectedIndexes = myList->selectionModel()->selectedIndexes();
231       QModelIndexList aSelectedSourceIndexes;
232       foreach ( const QModelIndex& anIndex, aSelectedIndexes ) {
233         aSelectedSourceIndexes << aFilterModel->mapToSource( anIndex );
234       }
235       QList<int> aSelectedIds = aModel->getIds( aSelectedSourceIndexes );
236       aModel->move( aSelectedIds, ( HYDROGUI_ListModel::OpType )theType, 
237                     !myIsHiddenObjectsShown );      
238     }
239   }
240 }
241
242 /**
243   Returns the list source model.
244   @return the source model
245 */
246 HYDROGUI_ListModel* HYDROGUI_OrderedListWidget::getSourceModel() const
247 {
248   HYDROGUI_ListModel* aSourceModel = 0;
249
250   QSortFilterProxyModel* aFilterModel = dynamic_cast<QSortFilterProxyModel*>( myList->model() );
251   if( aFilterModel ) {
252     aSourceModel = dynamic_cast<HYDROGUI_ListModel*>( aFilterModel->sourceModel() );
253   }
254
255   return aSourceModel;
256 }