Salome HOME
Merge from BR_phase16 branch (09/12/09)
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MeshOrderDlg.cxx
1 //  Copyright (C) 2007-2008  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 // File   : SMESHGUI_MeshOrderDlg.cxx
23 // Author : Pavel TELKOV, Open CASCADE S.A.S.
24 // SMESH includes
25 //
26 #include "SMESHGUI_MeshOrderDlg.h"
27
28 // Qt includes
29 #include <Qt>
30 #include <QFrame>
31 #include <QLabel>
32 #include <QBoxLayout>
33 #include <QSpacerItem>
34 #include <QToolButton>
35 #include <QListWidget>
36 #include <QListWidgetItem>
37
38 #define SPACING 6
39 #define MARGIN  11
40
41 /*! 
42  * Enumeartion of list widget item types (mesh name or separator)
43  */
44 enum MeshOrderItemType { MeshItem = QListWidgetItem::UserType, SeparatorItem };
45
46 // =========================================================================================
47 /*!
48  * \brief Constructor
49  */
50 // =========================================================================================
51
52 SMESHGUI_MeshOrderBox::SMESHGUI_MeshOrderBox(QWidget* theParent)
53 : QGroupBox( theParent ), myIsChanged( false ), myUpBtn(0), myDownBtn(0)
54 {
55   QHBoxLayout* hBoxLayout = new QHBoxLayout(this);
56   hBoxLayout->setMargin( MARGIN );
57   hBoxLayout->setSpacing( SPACING );
58   
59   myMeshNames = new QListWidget(this);
60   myMeshNames->setSelectionMode(QAbstractItemView::SingleSelection);
61   myMeshNames->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding ));
62   hBoxLayout->addWidget(myMeshNames);
63   
64   QGroupBox* btnGrp = new QGroupBox(this);
65   hBoxLayout->addWidget(btnGrp);
66
67   myUpBtn   = new QToolButton(btnGrp);
68   myDownBtn = new QToolButton(btnGrp);
69   myUpBtn->  setArrowType( Qt::UpArrow );
70   myDownBtn->setArrowType( Qt::DownArrow );
71   
72   QVBoxLayout* vBoxLayout = new QVBoxLayout(btnGrp);
73   vBoxLayout->addSpacerItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
74   vBoxLayout->addWidget( myUpBtn );
75   vBoxLayout->addWidget( myDownBtn );
76   vBoxLayout->addSpacerItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
77
78   connect( myUpBtn,   SIGNAL( clicked() ), this, SLOT( onMoveItem() ) );
79   connect( myDownBtn, SIGNAL( clicked() ), this, SLOT( onMoveItem() ) );
80   connect( myMeshNames, SIGNAL( itemSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
81   
82   onSelectionChanged();
83 }
84
85 // =========================================================================================
86 /*!
87  * \brief Destructor
88  */
89 //=======================================================================
90
91 SMESHGUI_MeshOrderBox::~SMESHGUI_MeshOrderBox()
92 {
93 }
94
95 // =========================================================================================
96 /*!
97  * \brief add separator item
98  */
99 // =========================================================================================
100
101 static void addSeparator( QListWidget* theList )
102 {
103   QListWidgetItem* item = new QListWidgetItem( theList, SeparatorItem );
104   QFrame* hline = new QFrame( theList );
105   hline->setFrameStyle( QFrame::HLine | QFrame::Sunken );
106   theList->addItem( item );
107   theList->setItemWidget( item, hline );
108 }
109
110 // =========================================================================================
111 /*!
112  * \brief add sub-mesh item
113  */
114 // =========================================================================================
115
116 static void addMeshItem( QListWidget* theList,
117                          const QString& theName,
118                          const int      theId )
119 {
120   QListWidgetItem* item = new QListWidgetItem( theName, theList, MeshItem );
121   item->setData( Qt::UserRole, theId );
122   theList->addItem( item );
123 }
124
125 // =========================================================================================
126 /*!
127  * \brief Clear submesh names and indeces
128  */
129 // =========================================================================================
130
131 void SMESHGUI_MeshOrderBox::Clear()
132 {
133   myMeshNames->clear();
134   myIsChanged = false;
135 }
136
137 // =========================================================================================
138 /*!
139  * \brief Set submesh names and indeces
140  */
141 // =========================================================================================
142
143 void SMESHGUI_MeshOrderBox::SetMeshes(const ListListName& theMeshNames,
144                                       const ListListId&   theMeshIds)
145 {
146   Clear();
147   ListListName::const_iterator nLIt = theMeshNames.constBegin();
148   ListListId::const_iterator idLIt  = theMeshIds.constBegin();
149   for ( ; nLIt != theMeshNames.constEnd(); ++nLIt, ++idLIt )
150   {
151     const QStringList& names = (*nLIt);
152     const QList<int>& ids = (*idLIt);
153     if ( myMeshNames->count() )
154       addSeparator( myMeshNames );
155     QStringList::const_iterator nameIt = names.constBegin();
156     QList<int>::const_iterator idIt = ids.constBegin();
157     for ( ; nameIt != names.constEnd(); ++nameIt, ++idIt )
158       addMeshItem( myMeshNames, *nameIt, *idIt );
159   }
160 }
161
162 // =========================================================================================
163 /*!
164  * \brief cehck that item exists and not a separator
165  */
166 // =========================================================================================
167
168 static bool checkItem(QListWidgetItem* theItem)
169 {
170   return theItem && (int)theItem->type() != (int)SeparatorItem;
171 }
172
173 // =========================================================================================
174 /*!
175  * \brief Returns result (ordered by user) mesh names
176  */
177 // =========================================================================================
178
179 ListListId SMESHGUI_MeshOrderBox::GetMeshIds() const
180 {
181   ListListId aLLIds;
182   aLLIds.append( QList<int>() );
183   for ( int i = 0, n = myMeshNames->count(); i < n; i++ )
184   {
185     QListWidgetItem* it = myMeshNames->item( i );
186     if (checkItem( it ))
187       aLLIds.last().append( it->data( Qt::UserRole ).toInt() );
188     else // separator before next list of mesh items
189       aLLIds.append( QList<int>() );
190   }
191   return aLLIds;
192 }
193
194 // =========================================================================================
195 /*!
196  * \brief Returns result (ordered by user) mesh indeces
197  */
198 // =========================================================================================
199
200 ListListName SMESHGUI_MeshOrderBox::GetMeshNames() const
201 {
202   ListListName aLLNames;
203   aLLNames.append( QStringList() );
204   for ( int i = 0, n = myMeshNames->count(); i < n; i++ )
205   {
206     QListWidgetItem* it = myMeshNames->item( i );
207     if (checkItem( it ))
208       aLLNames.last().append( it->text() );
209     else // separator before next list of mesh items
210       aLLNames.append( QStringList() );
211   }
212   return aLLNames;
213 }
214
215 // =========================================================================================
216 /*!
217  * \brief update state of arrow buttons according to selection
218  */
219 // =========================================================================================
220
221 void SMESHGUI_MeshOrderBox::onSelectionChanged()
222 {
223   bool isUp = false;
224   bool isDown = false;
225   QList<QListWidgetItem *> items = myMeshNames->selectedItems();
226   if ( !items.isEmpty() )
227   {
228     QListWidgetItem* selItem = (*(items.begin()));
229     if (checkItem(selItem))
230     {
231       const int rowId = myMeshNames->row( selItem );
232       isUp   = checkItem( myMeshNames->item( rowId - 1 ) );
233       isDown = checkItem( myMeshNames->item( rowId + 1 ) );
234     }
235   }
236   myUpBtn->  setEnabled( isUp );
237   myDownBtn->setEnabled( isDown );
238 }
239
240 // =========================================================================================
241 /*!
242  * \brief move item according to clicked arrow button
243  */
244 // =========================================================================================
245
246 void SMESHGUI_MeshOrderBox::onMoveItem()
247 {
248   moveItem( sender() == myUpBtn );
249 }
250
251 // =========================================================================================
252 /*!
253  * \brief move mesh in order up or down
254  */
255 // =========================================================================================
256
257 void SMESHGUI_MeshOrderBox::moveItem(const bool theIsUp)
258 {
259   // move selected list item up or down
260   QList<QListWidgetItem *> items = myMeshNames->selectedItems();
261   if ( items.isEmpty() )
262     return;
263   QListWidgetItem * selItem = (*(items.begin()));
264   if (!checkItem(selItem))
265     return;
266   int rowId = myMeshNames->row( selItem );
267   if ( rowId == -1 )
268     return;
269
270   // move item in list widget
271   myIsChanged = true;
272   myMeshNames->takeItem( rowId );
273   myMeshNames->insertItem(theIsUp ? rowId-1 : rowId+1, selItem );
274
275   // restore selection and current status
276   selItem->setSelected( true );
277   myMeshNames->setCurrentItem( selItem );
278 }
279
280 // =========================================================================================
281 /*!
282  * \brief returns status is order changed by user
283  */
284 // =========================================================================================
285
286 bool SMESHGUI_MeshOrderBox:: IsOrderChanged() const
287 {
288   return myIsChanged;
289 }
290
291 // =========================================================================================
292 /*!
293  * \brief Constructor
294  */
295 // =========================================================================================
296
297 SMESHGUI_MeshOrderDlg::SMESHGUI_MeshOrderDlg(QWidget* theParent)
298 : SMESHGUI_Dialog( theParent, false, false, OK | Cancel | Help )
299 {
300   setWindowTitle( tr( "SMESH_MESHORDER_TITLE") );
301   QFrame* main = mainFrame();
302
303   QVBoxLayout* aDlgLay = new QVBoxLayout (main);
304   aDlgLay->setMargin( 0 );
305   aDlgLay->setSpacing( SPACING );
306
307   myBox = new SMESHGUI_MeshOrderBox( main );
308
309   aDlgLay->addWidget(myBox);
310   aDlgLay->setStretchFactor(main, 1);
311 }
312
313 // =========================================================================================
314 /*!
315  * \brief Destructor
316  */
317 // =========================================================================================
318
319 SMESHGUI_MeshOrderDlg::~SMESHGUI_MeshOrderDlg()
320 {
321 }
322
323 // =========================================================================================
324 /*!
325  * \brief return Box widget to show mesh order
326  */
327 // =========================================================================================
328
329 SMESHGUI_MeshOrderBox* SMESHGUI_MeshOrderDlg::GetMeshOrderBox() const
330 {
331   return myBox;
332 }