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