Salome HOME
Merge remote-tracking branch 'origin/master' into gni/documentation
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_BlockRenumberCreator.cxx
1 // Copyright (C) 2007-2020  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, or (at your option) any later version.
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   : StdMeshersGUI_BlockRenumberCreator.cxx
23 // Author : Open CASCADE S.A.S.
24
25 #include "StdMeshersGUI_BlockRenumberCreator.h"
26
27 #include "SMESHGUI.h"
28 #include "SMESHGUI_Utils.h"
29 #include "SMESHGUI_VTKUtils.h"
30 #include "SMESHGUI_HypothesesUtils.h"
31
32 #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
33
34 #include <GEOMBase.h>
35 #include <LightApp_SelectionMgr.h>
36 #include <SALOMEDSClient_SObject.hxx>
37 #include <SALOMEDSClient_Study.hxx>
38 #include <SALOME_InteractiveObject.hxx>
39 #include <SALOME_ListIO.hxx>
40 #include <SUIT_ResourceMgr.h>
41 #include <SalomeApp_Tools.h>
42
43 #include <QApplication>
44 #include <QButtonGroup>
45 #include <QGridLayout>
46 #include <QGridLayout>
47 #include <QGroupBox>
48 #include <QHeaderView>
49 #include <QLabel>
50 #include <QLineEdit>
51 #include <QPushButton>
52 #include <QString>
53 #include <QTreeWidget>
54 #include <QTreeWidgetItem>
55
56 #define SPACING 6
57 #define MARGIN  11
58
59 namespace {
60
61   //================================================================================
62   /*!
63    * \brief Textual representation of GEOM_Object in QTreeWidget
64    */
65   //================================================================================
66
67   QString toText( const GEOM::GEOM_Object_var& theGO,
68                   const QString &              /*theLabel*/,
69                   QString&                     theEntry )
70   {
71     QString txt;
72     if ( !theGO->_is_nil() )
73     {
74       CORBA::String_var  name = theGO->GetName();
75       CORBA::String_var entry = theGO->GetStudyEntry();
76       theEntry = entry.in();
77
78       txt = name.in();
79       //txt = theLabel + name.in() + " [" + theEntry + "]";
80       //txt += " ";//" (";
81       //txt += entry.in();
82       //txt += ")";
83     }
84     return txt;
85   }
86
87   //================================================================================
88   /*!
89    * \brief Find GEOM_Object by study entry
90    */
91   //================================================================================
92
93   GEOM::GEOM_Object_var toGeom( const QString& entry )
94   {
95     return SMESH::EntryToInterface<GEOM::GEOM_Object>( entry );
96   }
97
98
99   //================================================================================
100   /*!
101    * \brief Find GEOM_Object in the tree
102    */
103   //================================================================================
104
105   QTreeWidgetItem* findSolidInTree( const GEOM::GEOM_Object_var& go, QTreeWidget* tree )
106   {
107     if ( go->_is_nil() || !tree )
108       return nullptr;
109
110     for ( int i = 0; i < tree->topLevelItemCount(); ++i )
111     {
112       QTreeWidgetItem* item = tree->topLevelItem( i );
113       if ( item->data( 1, Qt::UserRole ).toString() == SMESH::toQStr( go->GetStudyEntry() ))
114         return item;
115     }
116     return nullptr;
117   }
118 }
119
120 //================================================================================
121 /*!
122  * \brief StdMeshersGUI_BlockRenumberCreator constructor
123  */
124 //================================================================================
125
126 StdMeshersGUI_BlockRenumberCreator::StdMeshersGUI_BlockRenumberCreator(const QString& aHypType)
127   : StdMeshersGUI_StdHypothesisCreator( aHypType ),
128     mySolidFilter( "", TopAbs_SOLID, 1, TopAbs_SOLID ),
129     myVertexFilter( "", TopAbs_VERTEX, 1, TopAbs_VERTEX )
130 {
131 }
132
133 //================================================================================
134 /*!
135  * \brief StdMeshersGUI_BlockRenumberCreator destructor
136  */
137 //================================================================================
138
139 StdMeshersGUI_BlockRenumberCreator::~StdMeshersGUI_BlockRenumberCreator()
140 {
141   SMESHGUI::selectionMgr()->clearFilters();
142 }
143
144 //================================================================================
145 /*!
146  * \brief Create widgets
147  */
148 //================================================================================
149
150 QFrame* StdMeshersGUI_BlockRenumberCreator::buildFrame()
151 {
152   QFrame* fr = new QFrame();
153   //fr->setMinimumWidth(460);
154
155   QGridLayout* frLayout = new QGridLayout( fr );
156   frLayout->setSpacing( SPACING );
157   frLayout->setMargin( MARGIN );
158
159   // name
160   myName = 0;
161   int row = 0;
162   if( isCreation() )
163   {
164     myName = new QLineEdit( fr );
165     frLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), fr ), row, 0 );
166     frLayout->addWidget( myName,                               row, 1 );
167     row++;
168   }
169
170   QGroupBox* groupBox = new QGroupBox( tr( "BLOCK_CS_GROUPBOX" ), fr );
171   frLayout->addWidget( groupBox, row, 0, 1, 2 );
172
173   QGridLayout* layout = new QGridLayout( groupBox );
174   layout->setSpacing( SPACING );
175   layout->setMargin( MARGIN );
176   layout->setColumnStretch( 0, 1 );
177
178   // tree
179   row = 0;
180   myBlockTree = new QTreeWidget( groupBox );
181   myBlockTree->setColumnCount( 2 );
182   myBlockTree->header()->hide();
183   // myBlockTree->setHeaderLabels( QStringList()
184   //                               << tr("COLUMN_BLOCK") << tr("COLUMN_V000") << tr("COLUMN_V001"));
185   layout->addWidget( myBlockTree, row, 0, row + 7, 1 );
186
187   // selection widgets
188   myButGroup = new QButtonGroup( groupBox );
189   myButGroup->setExclusive( true );
190   QLabel* label[3] = { new QLabel( tr( "SOLID" ), groupBox ),
191                        new QLabel( tr( "V000" ),  groupBox ),
192                        new QLabel( tr( "V001" ),  groupBox ) };
193   QIcon icon( SMESHGUI::resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT")));
194   for ( int i = 0; i < 3; ++i )
195   {
196     myShapeSelectBut[i] = new QPushButton( icon, "", groupBox );
197     myLineEdit      [i] = new QLineEdit( groupBox );
198     layout->addWidget( label[i],            row, 1 );
199     layout->addWidget( myShapeSelectBut[i], row, 2 );
200     layout->addWidget( myLineEdit[i],       row, 3 );
201     myShapeSelectBut[i]->setCheckable( true );
202     myButGroup->addButton( myShapeSelectBut[i], i );
203     row++;
204   }
205
206   // buttons
207   myAddBut    = new QPushButton( tr("ADD"),    groupBox );
208   myModifBut  = new QPushButton( tr("MODIFY"),       groupBox );
209   myRemoveBut = new QPushButton( tr("SMESH_REMOVE"), groupBox );
210   layout->addWidget( myAddBut, row, 1, 1, 3 );
211   row++;
212   layout->addWidget( myModifBut, row, 1, 1, 3 );
213   row++;
214   layout->addWidget( myRemoveBut, row, 1, 1, 3 );
215   row++;
216   layout->setRowStretch( row, 1 );
217
218   LightApp_SelectionMgr* selMgr = SMESH::GetSelectionMgr( SMESHGUI::GetSMESHGUI() );
219
220   connect( selMgr,              SIGNAL( currentSelectionChanged()), SLOT( onSelectionChange()));
221   connect( myBlockTree,         SIGNAL( itemSelectionChanged() ),   SLOT( onTreeSelectionChange()));
222   connect( myShapeSelectBut[0], SIGNAL( clicked(bool)),             SLOT( onSelectBtnClick() ));
223   connect( myShapeSelectBut[1], SIGNAL( clicked(bool)),             SLOT( onSelectBtnClick() ));
224   connect( myShapeSelectBut[2], SIGNAL( clicked(bool)),             SLOT( onSelectBtnClick() ));
225   connect( myAddBut,            SIGNAL( clicked() ),                SLOT( onAddBtnClick() ));
226   connect( myModifBut,          SIGNAL( clicked() ),                SLOT( onModifBtnClick() ));
227   connect( myRemoveBut,         SIGNAL( clicked() ),                SLOT( onRemoveBtnClick() ));
228
229   return fr;
230 }
231
232 //================================================================================
233 /*!
234  * \brief Set myGO's to the tree
235  */
236 //================================================================================
237
238 void StdMeshersGUI_BlockRenumberCreator::setBlockToTree(QTreeWidgetItem* solidItem)
239 {
240   if ( !myGO[0]->_is_nil() && !myGO[1]->_is_nil() && !myGO[2]->_is_nil() )
241   {
242     if ( !solidItem ) solidItem = new QTreeWidgetItem( myBlockTree );
243     solidItem->setExpanded( true );
244     QTreeWidgetItem* item = solidItem;
245
246     QFont boldFont = item->font( 0 );
247     boldFont.setBold( true );
248
249     QString entry, label[3] = { tr("BLOCK_LABEL"), tr("V000_LABEL"), tr("V001_LABEL") };
250     for ( int i = 0; i < 3; ++i )
251     {
252       if ( i > 0 && ! (item = solidItem->child( i - 1 )))
253         item = new QTreeWidgetItem( solidItem );
254
255       item->setText( 0, label[i] );
256       item->setText( 1, toText( myGO[i], label[i], entry ));
257       item->setData( 1, Qt::UserRole, entry );
258       item->setFont( 1, boldFont );
259       item->setToolTip( 1, entry );
260     }
261     myBlockTree->resizeColumnToContents( 0 );
262     myBlockTree->resizeColumnToContents( 1 );
263   }
264   for ( int i = 0; i < 3; ++i )
265   {
266     myGO[i] = GEOM::GEOM_Object::_nil();
267     myLineEdit[i]->setText("");
268   }
269 }
270
271 //================================================================================
272 /*!
273  * \brief Transfer parameters from hypothesis to widgets
274  */
275 //================================================================================
276
277 void StdMeshersGUI_BlockRenumberCreator::retrieveParams() const
278 {
279   StdMeshersGUI_BlockRenumberCreator* me = const_cast<StdMeshersGUI_BlockRenumberCreator*>( this );
280
281   StdMeshers::StdMeshers_BlockRenumber_var h =
282     StdMeshers::StdMeshers_BlockRenumber::_narrow( initParamsHypothesis() );
283
284   if( myName )
285     me->myName->setText( hypName() );
286
287   me->myBlockTree->clear();
288
289   StdMeshers::blockcs_array_var blkArray = h->GetBlocksOrientation();
290   for ( CORBA::ULong i = 0; i < blkArray->length(); ++i )
291   {
292     me->myGO[0] = GEOM::GEOM_Object::_duplicate( blkArray[i].solid.in()     );
293     me->myGO[1] = GEOM::GEOM_Object::_duplicate( blkArray[i].vertex000.in() );
294     me->myGO[2] = GEOM::GEOM_Object::_duplicate( blkArray[i].vertex001.in() );
295     me->setBlockToTree();
296   }
297
298   me->myShapeSelectBut[0]->click();
299
300   me->updateButtons();
301 }
302
303 //================================================================================
304 /*!
305  * \brief Transfer parameters from widgets to hypothesis
306  */
307 //================================================================================
308
309 QString StdMeshersGUI_BlockRenumberCreator::storeParams() const
310 {
311   StdMeshers::StdMeshers_BlockRenumber_var h =
312     StdMeshers::StdMeshers_BlockRenumber::_narrow( hypothesis() );
313
314   try
315   {
316     if( isCreation() )
317       SMESH::SetName( SMESH::FindSObject( h ), myName->text().toUtf8().constData() );
318
319     StdMeshers::blockcs_array_var array = new StdMeshers::blockcs_array();
320     array->length( myBlockTree->topLevelItemCount() );
321
322     for ( int i = 0; i < myBlockTree->topLevelItemCount(); ++i )
323     {
324       StdMeshers::BlockCS& bcs = array[i];
325       QTreeWidgetItem*   item0 = myBlockTree->topLevelItem( i );
326       QTreeWidgetItem*   item1 = item0->child( 0 );
327       QTreeWidgetItem*   item2 = item0->child( 1 );
328
329       bcs.solid     = toGeom( item0->data( 1, Qt::UserRole ).toString() )._retn();
330       bcs.vertex000 = toGeom( item1->data( 1, Qt::UserRole ).toString() )._retn();
331       bcs.vertex001 = toGeom( item2->data( 1, Qt::UserRole ).toString() )._retn();
332     }
333     h->SetBlocksOrientation( array );
334
335   }
336   catch(const SALOME::SALOME_Exception& ex)
337   {
338     SalomeApp_Tools::QtCatchCorbaException(ex);
339   }
340   return "";
341 }
342
343 //================================================================================
344 /*!
345  * \brief Take selected object
346  */
347 //================================================================================
348
349 void StdMeshersGUI_BlockRenumberCreator::onSelectionChange()
350 {
351   SALOME_ListIO list;
352   SMESHGUI::GetSMESHGUI()->selectionMgr()->selectedObjects( list );
353
354   int shapeID = myButGroup->checkedId();
355   if ( shapeID < 0 || shapeID > 2 )
356     shapeID = 0;
357
358   myGO[ shapeID ] = GEOM::GEOM_Object::_nil();
359   myLineEdit[ shapeID ]->clear();
360
361   if ( list.IsEmpty() )
362     return;
363
364   Handle(SALOME_InteractiveObject) io = list.First();
365   if ( !io->hasEntry() )
366     return;
367
368   myGO[ shapeID ] = SMESH::IObjectToInterface<GEOM::GEOM_Object>( io );
369
370   if ( !myGO[ shapeID ]->_is_nil() )
371     myLineEdit[ shapeID ]->setText( SMESH::toQStr( myGO[ shapeID ]->GetName() ));
372
373   updateButtons();
374 }
375
376 //================================================================================
377 /*!
378  * \brief Display selected block CS in myLineEdit's
379  */
380 //================================================================================
381
382 void StdMeshersGUI_BlockRenumberCreator::onTreeSelectionChange()
383 {
384   QList<QTreeWidgetItem *> items = myBlockTree->selectedItems();
385   for ( QTreeWidgetItem* item : items )
386   {
387     if ( item->parent() )
388       item = item->parent();
389
390     QTreeWidgetItem* items[3] = { item, item->child( 0 ), item->child( 1 ) };
391     if ( items[1] && items[2] )
392       for ( int i = 0; i < 3; ++i )
393       {
394         myGO[i] = toGeom( items[i]->data( 1, Qt::UserRole ).toString() );
395         myLineEdit[i]->setText( items[i]->text( 1 ));
396       }
397
398     break;
399   }
400
401   updateButtons();
402 }
403
404 //================================================================================
405 /*!
406  * \brief Activate/deactivate buttons
407  */
408 //================================================================================
409
410 void StdMeshersGUI_BlockRenumberCreator::updateButtons()
411 {
412   bool isSolidInTree = findSolidInTree( myGO[0], myBlockTree );
413   myAddBut   ->setEnabled( !isSolidInTree &&
414                            !myGO[0]->_is_nil() && !myGO[1]->_is_nil() && !myGO[2]->_is_nil() );
415   myModifBut ->setEnabled( isSolidInTree );
416   myRemoveBut->setEnabled( !myBlockTree->selectedItems().isEmpty() ||
417                            myBlockTree->topLevelItemCount() == 1 );
418 }
419
420 //================================================================================
421 /*!
422  * \brief Install filter upon activation of another object selection
423  */
424 //================================================================================
425
426 void StdMeshersGUI_BlockRenumberCreator::onSelectBtnClick()
427 {
428   int shapeID = myButGroup->checkedId();
429   LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
430   selMgr->clearFilters();
431   selMgr->installFilter( shapeID > 0 ? &myVertexFilter : &mySolidFilter );
432 }
433
434 //================================================================================
435 /*!
436  * \brief Add shapes to the tree
437  */
438 //================================================================================
439
440 void StdMeshersGUI_BlockRenumberCreator::onAddBtnClick()
441 {
442   setBlockToTree();
443   updateButtons();
444 }
445
446 //================================================================================
447 /*!
448  * \brief Modify a current block
449  */
450 //================================================================================
451
452 void StdMeshersGUI_BlockRenumberCreator::onModifBtnClick()
453 {
454   if ( QTreeWidgetItem* item = findSolidInTree( myGO[0], myBlockTree ))
455   {
456     setBlockToTree( item );
457   }
458   updateButtons();
459 }
460
461 //================================================================================
462 /*!
463  * \brief Remove selected block from the tree
464  */
465 //================================================================================
466
467 void StdMeshersGUI_BlockRenumberCreator::onRemoveBtnClick()
468 {
469   QList<QTreeWidgetItem *> items = myBlockTree->selectedItems();
470   if ( items.isEmpty() && myBlockTree->topLevelItemCount() == 1 )
471     items.push_back( myBlockTree->topLevelItem( 0 ));
472
473   for ( QTreeWidgetItem* item : items )
474   {
475     if ( item->parent() )
476       item = item->parent();
477     delete item;
478   }
479
480   updateButtons();
481 }
482
483
484 //================================================================================
485 /*!
486  * \brief Validate parameters
487  */
488 //================================================================================
489
490 bool StdMeshersGUI_BlockRenumberCreator::checkParams( QString& /*msg*/ ) const
491 {
492   return true;
493 }
494
495 //================================================================================
496 /*!
497  * \brief Returns a name of help page
498  */
499 //================================================================================
500
501 QString StdMeshersGUI_BlockRenumberCreator::helpPage() const
502 {
503   return "3d_meshing_hypo.html#renumber-hypothesis";
504 }
505
506 //================================================================================
507 /*!
508  * \brief Type name
509  */
510 //================================================================================
511
512 QString  StdMeshersGUI_BlockRenumberCreator::hypTypeName( const QString& ) const
513 {
514   return "BLOCK_RENUMBER";
515 }