Salome HOME
Enable simultaneous usage of several StdMeshersGUI_SubShapeSelectorWdg's
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_SubShapeSelectorWdg.cxx
1 // Copyright (C) 2007-2020  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, or (at your option) any later version.
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   : StdMeshersGUI_SubShapeSelectorWdg.cxx
21 // Author : Open CASCADE S.A.S. (dmv)
22 // SMESH includes
23 //
24 #include "StdMeshersGUI_SubShapeSelectorWdg.h"
25
26 // SMESH Includes
27 #include "SMESHGUI_Utils.h"
28 #include "SMESHGUI_VTKUtils.h"
29 #include "SMESH_Actor.h"
30 #include "SMESH_Gen_i.hxx"
31 #include "SMESH_LogicalFilter.hxx"
32 #include "SMESH_PreviewActorsCollection.h"
33 #include "SMESH_Type.h"
34
35 // SALOME GUI includes
36 #include <LightApp_SelectionMgr.h>
37 #include <SALOME_ListIO.hxx>
38 #include <SUIT_OverrideCursor.h>
39 #include <SUIT_ResourceMgr.h>
40 #include <SUIT_Session.h>
41 #include <SVTK_Selector.h>
42 #include <SVTK_ViewModel.h>
43 #include <SVTK_ViewWindow.h>
44
45 // GEOM Includes
46 #include <GEOMBase.h>
47 #include <GEOM_TypeFilter.h>
48 #include <GEOM_CompoundFilter.h>
49
50 // Qt includes
51 #include <QPushButton>
52 #include <QGridLayout>
53 #include <QListWidget>
54 #include <QCheckBox>
55 #include <QLineEdit>
56
57 // OCCT includes
58 #include <TColStd_MapOfInteger.hxx>
59 #include <TopoDS_Shape.hxx>
60 #include <TopExp.hxx>
61 #include <TopExp_Explorer.hxx>
62
63
64 #define SPACING 6
65 #define MARGIN 0
66
67 //================================================================================
68 /*!
69  *  Constructor
70  */
71 //================================================================================
72
73 StdMeshersGUI_SubShapeSelectorWdg
74 ::StdMeshersGUI_SubShapeSelectorWdg( QWidget *        parent,
75                                      TopAbs_ShapeEnum subShType,
76                                      const bool       toShowList,
77                                      const bool       toShowActivateBtn,
78                                      const int        minListWidth ):
79   QWidget( parent ),
80   myMaxSize( -1 ),
81   myPreviewActor( 0 )
82 {
83   QPixmap image0( SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap( "SMESH", tr( "ICON_SELECT" ) ) );
84
85   QGridLayout* layout = new QGridLayout( this );
86   layout->setMargin( MARGIN );
87   layout->setSpacing( SPACING );
88
89   if ( toShowList )
90   {
91     QPixmap iconSelect (SUIT_Session::session()->resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT")));
92     myListWidget     = new QListWidget( this );
93     myActivateButton = new QPushButton( iconSelect, "", this );
94     myAddButton      = new QPushButton( tr( "SMESH_BUT_ADD" ),    this );
95     myRemoveButton   = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );
96     myListWidget->setSelectionMode( QListWidget::ExtendedSelection );
97     myListWidget->setMinimumWidth( minListWidth );
98     myListWidget->setWrapping( true );
99     myActivateButton->setCheckable( true );
100   }
101   else
102   {
103     myListWidget     = 0;
104     myActivateButton = 0;
105     myAddButton      = 0;
106     myRemoveButton   = 0;
107   }
108   myInfoLabel    = new QLabel( this );
109   myPrevButton   = new QPushButton( "<<", this );
110   myNextButton   = new QPushButton( ">>", this );
111
112   if ( myListWidget )
113   {
114     int row = 0;
115     layout->addWidget(myListWidget,   row, 0, 3+toShowActivateBtn, 3);
116     if ( toShowActivateBtn )
117       layout->addWidget( myActivateButton, row++, 3 );
118     else
119       myActivateButton->hide();
120     layout->addWidget(myAddButton,      row, 3);
121     layout->addWidget(myRemoveButton, ++row, 3);
122     ++row;
123     layout->addWidget(myInfoLabel,    ++row, 0, 1, 3);
124     layout->addWidget(myPrevButton,   ++row, 0);
125     layout->addWidget(myNextButton,     row, 2);
126
127     layout->setRowStretch(row-2, 5);
128     layout->setColumnStretch(1, 5);
129   }
130   else // show only Prev and Next buttons
131   {
132     layout->addWidget(myInfoLabel,    0, 0, 1, 2);
133     layout->addWidget(myPrevButton,   1, 0);
134     layout->addWidget(myNextButton,   1, 1);
135   }
136   //myInfoLabel->setMinimumWidth(300);
137   //myInfoLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
138   myInfoLabel->setAlignment(Qt::AlignCenter);
139
140   mySubShType = subShType;
141
142   init();
143 }
144
145 //================================================================================
146 /*!
147  *  Destructor
148  */
149 //================================================================================
150
151 StdMeshersGUI_SubShapeSelectorWdg::~StdMeshersGUI_SubShapeSelectorWdg()
152 {
153   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
154     if ( myPreviewActor ) {
155       myPreviewActor->RemoveFromRender( myRenderer );
156       aViewWindow->Repaint();
157
158       delete myPreviewActor;
159       myPreviewActor = 0;
160     }
161   }
162   myEntry = "";
163   myParamValue = "";
164   myMainShape.Nullify();
165
166   if ( mySelectionMgr && myFilter )
167     mySelectionMgr->removeFilter( myFilter );
168   delete myFilter; myFilter=0;
169
170   mySelectionMgr->clearSelected();
171
172   SUIT_SelectionFilter* filter;
173   foreach( filter, myGeomFilters )
174     delete filter;
175 }
176
177 //================================================================================
178 /*!
179  *  Create a layout, initialize fields
180  */
181 //================================================================================
182
183 void StdMeshersGUI_SubShapeSelectorWdg::init()
184 {
185   myParamValue = "";
186   myListOfIDs.clear();
187   mySelectedIDs.clear();
188
189   mySMESHGUI     = SMESHGUI::GetSMESHGUI();
190   mySelectionMgr = SMESH::GetSelectionMgr( mySMESHGUI );
191   mySelector     = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
192
193   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
194     aViewWindow->SetSelectionMode( ActorSelection );
195
196   myFilter=0;
197
198   if ( myListWidget )
199   {
200     myAddButton->setEnabled( false );
201     myRemoveButton->setEnabled( false );
202
203     connect( myListWidget,   SIGNAL(itemSelectionChanged()),    this, SLOT(onListSelectionChanged()));
204     connect( myActivateButton, SIGNAL( toggled(bool) ), SLOT( ActivateSelection(bool)));
205     connect( myAddButton,    SIGNAL(clicked()), SLOT(onAdd()));
206     connect( myRemoveButton, SIGNAL(clicked()), SLOT(onRemove()));
207   }
208   connect( myPrevButton,   SIGNAL(clicked()), SLOT(onPrevious()));
209   connect( myNextButton,   SIGNAL(clicked()), SLOT(onNext()));
210
211   connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(selectionIntoArgument()));
212
213   updateState();
214 }
215
216 //================================================================================
217 /*!
218  * \brief Install filters to select sub-shapes of mySubShType or their groups
219  */
220 //================================================================================
221
222 void StdMeshersGUI_SubShapeSelectorWdg::setFilter()
223 {
224   // if ( !myFilter )
225   // {
226   //   SalomeApp_Study* study = mySMESHGUI->activeStudy();
227   //   GEOM_TypeFilter* typeFilter = new GEOM_TypeFilter(study, mySubShType, /*isShapeType=*/true );
228   //   GEOM_CompoundFilter* gpoupFilter = new GEOM_CompoundFilter(study);
229   //   gpoupFilter->addSubType( mySubShType );
230   //   myGeomFilters.append( typeFilter );
231   //   myGeomFilters.append( gpoupFilter );
232   //   myFilter = new SMESH_LogicalFilter( myGeomFilters, SMESH_LogicalFilter::LO_OR );
233   // }
234   // mySelectionMgr->installFilter( myFilter );
235 }
236
237 //================================================================================
238 /*!
239  *  Create a layout, initialize fields
240  */
241 //================================================================================
242
243 void StdMeshersGUI_SubShapeSelectorWdg::ShowPreview( bool visible)
244 {
245   if ( !myPreviewActor )
246     return;
247
248   if ( myIsShown != visible ) {
249     myPreviewActor->SetShown( visible );
250     
251     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
252       aViewWindow->Repaint();
253
254     myIsShown = visible;
255   }
256 }
257
258 //================================================================================
259 /*!
260  * \brief Connect selection slots
261   * \param other - another StdMeshersGUI_ObjectReferenceParamWdg
262  */
263 //================================================================================
264
265 void StdMeshersGUI_SubShapeSelectorWdg::
266 AvoidSimultaneousSelection ( StdMeshersGUI_SubShapeSelectorWdg* other)
267 {
268   connect(other, SIGNAL(selectionActivated()), this, SLOT(deactivateSelection()));
269   connect(this, SIGNAL(selectionActivated()), other, SLOT(deactivateSelection()));
270 }
271
272 //================================================================================
273 /*!
274  * \brief Connect/disconnect to change of selection
275  */
276 //================================================================================
277
278 void StdMeshersGUI_SubShapeSelectorWdg::ActivateSelection( bool toActivate )
279 {
280   // adjust state of myActivateButton
281   if ( myActivateButton &&
282        myActivateButton != sender() &&
283        myActivateButton->isChecked() != toActivate )
284   {
285     myActivateButton->toggle();
286     return;
287   }
288
289   if ( !mySelectionMgr ) return;
290
291   if ( toActivate )
292   {
293     connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(selectionIntoArgument()));
294   }
295   else
296   {
297     disconnect(mySelectionMgr, 0, this, 0 );
298   }
299
300   if ( sender() == myActivateButton )
301     ShowPreview( toActivate );
302
303   if ( toActivate )
304     emit selectionActivated();
305 }
306
307 //================================================================================
308 /*!
309  * \brief Clears selected IDs. This is a workaround of a bug that
310  *        SUIT_SelectionMgr::clearSelected() does not emit currentSelectionChanged
311  */
312 //================================================================================
313
314 void StdMeshersGUI_SubShapeSelectorWdg::ClearSelected()
315 {
316   mySelectedIDs.clear();
317   selectionIntoArgument();
318 }
319
320 //=================================================================================
321 // function : selectionIntoArgument()
322 // purpose  : Called when selection has changed or in other cases
323 //=================================================================================
324 void StdMeshersGUI_SubShapeSelectorWdg::selectionIntoArgument()
325 {
326   if ( !myPreviewActor )
327     return;
328
329   mySelectedIDs.clear();
330
331   // get selected mesh
332   SALOME_ListIO aList;
333   mySelectionMgr->selectedObjects( aList );
334   int nbSel = aList.Extent();
335
336   if (nbSel > 0) {
337     SALOME_ListIteratorOfListIO anIt (aList);
338
339     for ( ; anIt.More(); anIt.Next()) // Loop on selected objects
340     {
341       Handle(SALOME_InteractiveObject) IO = anIt.Value();
342
343       GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( IO->getEntry() );
344       if ( !CORBA::is_nil( aGeomObj ) ) { // Selected Object From Study
345         // commented for IPAL52836
346         //
347         // GEOM::GEOM_Object_var aGeomFatherObj = aGeomObj->GetMainShape();
348         // QString aFatherEntry = "";
349         // QString aMainFatherEntry = "";
350         // TopoDS_Shape shape;
351         // if ( !CORBA::is_nil( aGeomFatherObj ) ) {
352         //   // Get Main Shape
353         //   GEOM::GEOM_Object_var aGeomMain = GetGeomObjectByEntry( myEntry.c_str() );
354         //   if ( !CORBA::is_nil( aGeomMain ) && aGeomMain->GetType() == 37 ) {  // Main Shape is a Group
355         //     GEOM::GEOM_Object_var aMainFatherObj = aGeomMain->GetMainShape();
356         //     if ( !CORBA::is_nil( aMainFatherObj ) )
357         //       aMainFatherEntry = aMainFatherObj->GetStudyEntry();
358         //   }
359         //   aFatherEntry = aGeomFatherObj->GetStudyEntry();
360         // }
361
362         // if (( ! aFatherEntry.isEmpty() ) &&
363         //     ( aFatherEntry == myEntry.c_str() || aFatherEntry == aMainFatherEntry ) )
364         {
365           TopoDS_Shape shape;
366           if ( aGeomObj->GetType() == 37 /*GEOM_GROUP*/ ) { // Selected Group that belongs the main object
367             GEOMBase::GetShape(aGeomObj, shape);
368             if ( !shape.IsNull() ) {
369               TopExp_Explorer exp( shape, mySubShType );
370               for ( ; exp.More(); exp.Next() ) {
371                 int index = myPreviewActor->GetIndexByShape( exp.Current() );
372                 if ( index ) {
373                   mySelectedIDs.append( index );
374                   myPreviewActor->HighlightID( index );
375                 }
376               }
377             }
378           } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/ ||
379                       myEntry == IO->getEntry() )
380           {
381             GEOMBase::GetShape(aGeomObj, shape);
382             if ( !shape.IsNull() && shape.ShapeType() == mySubShType ) {
383               int index = myPreviewActor->GetIndexByShape( shape );
384               if ( index ) {
385                 mySelectedIDs.append( index );
386                 myPreviewActor->HighlightID( index );
387               }
388             }
389           }
390         }
391       } else { // Selected Actor from Actor Collection
392         QString anEntry = IO->getEntry();
393         QString str = "_";
394         int index = anEntry.lastIndexOf( str );
395         anEntry.remove(0, index+1);
396         int ind = anEntry.toInt();
397         if ( ind )
398           mySelectedIDs.append( ind );
399       }
400     }
401   }
402   // update add button
403   if ( myListWidget )
404   {
405     myAddButton->setEnabled(( myListWidget->count() < myMaxSize || myMaxSize == -1 ) &&
406                             ( mySelectedIDs.size() > 0                             ) &&
407                             ( mySelectedIDs.size() <= myMaxSize || myMaxSize == -1 ) );
408     myRemoveButton->setEnabled( mySelectedIDs.size() > 0 );
409
410     //Connect Selected Ids in viewer and dialog's Ids list
411     bool signalsBlocked = myListWidget->blockSignals( true );
412     myListWidget->clearSelection();
413     if ( mySelectedIDs.size() > 0 ) {
414       for (int i = 0; i < mySelectedIDs.size(); i++) {
415         QString anID = QString(" %1").arg( mySelectedIDs.at(i) );
416         QList<QListWidgetItem*> anItems = myListWidget->findItems ( anID, Qt::MatchExactly );
417         QListWidgetItem* item;
418         foreach(item, anItems)
419           item->setSelected(true);
420       }
421     }
422     myListWidget->blockSignals( signalsBlocked );
423   }
424
425   emit shapeSelected();
426 }
427
428 //=================================================================================
429 // function : onAdd()
430 // purpose  : Called when Add Button Clicked
431 //=================================================================================
432 void StdMeshersGUI_SubShapeSelectorWdg::onAdd()
433 {
434   if ( mySelectedIDs.size() < 1 || !myListWidget )
435     return;
436
437   myListWidget->blockSignals( true );
438   for (int i = 0; i < mySelectedIDs.size() && (myMaxSize == -1 || myListOfIDs.size() < myMaxSize); i++) {
439     if ( myListOfIDs.indexOf( mySelectedIDs.at(i) ) == -1 ) {
440       QString anID = QString(" %1").arg( mySelectedIDs.at(i) );
441
442       QListWidgetItem* anItem = new QListWidgetItem( anID, myListWidget );
443       anItem->setSelected(true);
444       
445       myListOfIDs.append( mySelectedIDs.at(i) );
446     }
447   }
448   onListSelectionChanged();
449   myListWidget->blockSignals( false );
450
451   mySelectedIDs.clear();
452   myAddButton->setEnabled( false );
453 }
454          
455 //=================================================================================
456 // function : onRemove()
457 // purpose  : Called when Remove Button Clicked
458 //=================================================================================
459 void StdMeshersGUI_SubShapeSelectorWdg::onRemove()
460 {
461   if ( myListWidget->count() < 1 || !myListWidget )
462     return;
463
464   myListWidget->blockSignals( true );
465   QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
466   QListWidgetItem* item;
467   foreach(item, selItems) {
468     QString idStr = item->text();
469     int id = idStr.toInt();
470
471     int index = myListOfIDs.indexOf( id );
472     myListOfIDs.removeAt( index );
473     delete item;
474   }
475
476   onListSelectionChanged();
477   myListWidget->blockSignals( false );
478   
479   myAddButton->setEnabled( !mySelectedIDs.isEmpty() );
480 }
481
482 void StdMeshersGUI_SubShapeSelectorWdg::onPrevious()
483 {
484   if ( myPreviewActor ) {
485     myPreviewActor->previous();
486     if ( myListWidget )
487       myListWidget->clearSelection();
488     updateButtons();
489     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
490       aViewWindow->Repaint();
491   }
492 }
493
494 void StdMeshersGUI_SubShapeSelectorWdg::onNext()
495 {
496   if ( myPreviewActor ) {
497     myPreviewActor->next();
498     if ( myListWidget )
499       myListWidget->clearSelection();
500     updateButtons();
501     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
502       aViewWindow->Repaint();
503   }
504 }
505
506 //=================================================================================
507 // function : onListSelectionChanged()
508 // purpose  : Called when selection in element list is changed
509 //=================================================================================
510 void StdMeshersGUI_SubShapeSelectorWdg::onListSelectionChanged()
511 {
512   if ( !myPreviewActor )
513     return;
514
515   myPreviewActor->HighlightAll( false );
516   QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
517   QListWidgetItem* anItem;
518   foreach(anItem, selItems)
519     myPreviewActor->HighlightID( anItem->text().toInt() );
520
521   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
522     aViewWindow->Repaint();
523
524   // update remove button
525   myRemoveButton->setEnabled( selItems.size() > 0 );
526
527   emit selectionChanged();
528 }
529
530 //=================================================================================
531 // function : setGeomShape
532 // purpose  : Called to set geometry whose sub-shapes are selected
533 //================================================================================
534 void StdMeshersGUI_SubShapeSelectorWdg::SetGeomShapeEntry( const QString& theEntry,
535                                                            const QString& theMainShapeEntry )
536 {
537   if ( !theEntry.isEmpty() || theMainShapeEntry.isEmpty() )
538   {
539     myParamValue = theEntry;
540     myEntry      = theEntry.toStdString();
541     myMainEntry  = theMainShapeEntry.toStdString();
542
543     if ( myMainEntry.empty() ) myMainEntry = myEntry;
544     if ( myEntry.empty() )     myEntry     = myMainEntry;
545     if ( myMainEntry.length() > myEntry.length() &&
546          theMainShapeEntry.startsWith( theEntry ))
547       std::swap( myMainEntry, myEntry );
548
549     myGeomShape = GetTopoDSByEntry( myEntry.c_str() );
550     if ( myEntry == myMainEntry )
551       myMainShape = myGeomShape;
552     else
553       myMainShape = GetTopoDSByEntry( myMainEntry.c_str() );
554     updateState();
555   }
556 }
557
558 //=================================================================================
559 // function : updateState
560 // purpose  : update Widget state
561 //=================================================================================
562 void StdMeshersGUI_SubShapeSelectorWdg::updateState()
563 {
564   bool state = ( !myGeomShape.IsNull() );
565
566   myInfoLabel ->setVisible( false );
567   myPrevButton->setVisible( false );
568   myNextButton->setVisible( false );
569
570   if ( myListWidget )
571   {
572     myListWidget->setEnabled( state );
573     myAddButton->setEnabled( mySelectedIDs.size() > 0 );
574   }
575   if ( state ) {
576     SUIT_OverrideCursor wc;
577     if ( !myPreviewActor )
578       myPreviewActor = new SMESH_PreviewActorsCollection();
579     myPreviewActor->SetSelector( mySelector );
580     myPreviewActor->Init( myGeomShape, myMainShape, mySubShType, myEntry.c_str() );
581     myPreviewActor->SetShown( false );
582     myIsShown = false;
583     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
584       myRenderer = aViewWindow->getRenderer();
585       myPreviewActor->AddToRender( myRenderer );
586       aViewWindow->Repaint();
587     }
588     updateButtons();
589   }
590 }
591
592 //=================================================================================
593 // function : GetGeomObjectByEntry
594 // purpose  : Called to get GeomObject
595 //=================================================================================
596 GEOM::GEOM_Object_var StdMeshersGUI_SubShapeSelectorWdg::GetGeomObjectByEntry( const QString& theEntry )
597 {
598   GEOM::GEOM_Object_var aGeomObj;
599   SALOMEDS::SObject_var aSObj = SMESH_Gen_i::getStudyServant()->FindObjectID( theEntry.toUtf8().data() );
600   if (!aSObj->_is_nil() )
601   {
602     CORBA::Object_var obj = aSObj->GetObject();
603     aGeomObj = GEOM::GEOM_Object::_narrow(obj);
604     aSObj->UnRegister();
605   }
606   return aGeomObj._retn();
607 }
608
609 //=================================================================================
610 // function : setObjectByEntry
611 // purpose  : Called to get GeomObject
612 //=================================================================================
613 TopoDS_Shape StdMeshersGUI_SubShapeSelectorWdg::GetTopoDSByEntry( const QString& theEntry )
614 {
615   TopoDS_Shape shape;
616   GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( theEntry );
617   GEOMBase::GetShape(aGeomObj, shape);
618   return shape;
619 }
620
621 //=================================================================================
622 // function : GetListOfIds
623 // purpose  : Called to get the list of SubShapes IDs
624 //=================================================================================
625 SMESH::long_array_var StdMeshersGUI_SubShapeSelectorWdg::GetListOfIDs()
626 {
627   SMESH::long_array_var anArray = new SMESH::long_array;
628
629   int size = myListOfIDs.size();
630   anArray->length( size );
631   for (int i = 0; i < size; i++)
632     anArray[i] = myListOfIDs.at(i);
633
634   return anArray;
635 }
636
637 //=================================================================================
638 // function : SetListOfIds
639 // purpose  : Called to set the list of SubShapes IDs. Returns false if any ID is invalid
640 //=================================================================================
641 bool StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theIds)
642 {
643   mySelectedIDs.clear();
644   myListOfIDs.clear();
645   int size = theIds->length();
646   for ( int i = 0; i < size; i++ )
647     mySelectedIDs.append( theIds[ i ] );
648
649   if ( myListWidget )
650   {
651     myListWidget->blockSignals( true );
652     myListWidget->clear();
653     myListWidget->blockSignals( false );
654   }
655
656   bool isOk = true;
657   if ( myPreviewActor )
658   {
659     for ( int i = 0; i < size && isOk; i++ )
660       isOk = myPreviewActor->IsValidIndex( theIds[ i ] );
661   }
662   else if ( !myMainShape.IsNull() )
663   {
664     TopTools_IndexedMapOfShape aMainMap;
665     TopExp::MapShapes(myMainShape, aMainMap);
666     for ( int i = 0; i < size && isOk; i++ )
667       isOk = ( theIds[ i ] > 0 && theIds[ i ] <= aMainMap.Extent() );
668   }
669   onAdd();
670   return isOk;
671 }
672
673 //=================================================================================
674 // function : GetMainShapeEntry
675 // purpose  : Called to get the Main Object Entry
676 //=================================================================================
677 const char* StdMeshersGUI_SubShapeSelectorWdg::GetMainShapeEntry()
678 {
679   if ( myMainEntry.empty() ) myMainEntry = "";
680   return myMainEntry.c_str();
681 }
682
683 void StdMeshersGUI_SubShapeSelectorWdg::updateButtons()
684 {
685   if ( myPreviewActor ) {
686     int total = myPreviewActor->count();
687     int chunk = myPreviewActor->currentChunk();
688     int chunkSize = myPreviewActor->chunkSize();
689     int imin = chunk*chunkSize+1;
690     int imax = std::min((chunk+1)*chunkSize, total);
691     bool vis = imax > 0 && total > chunkSize;
692     myInfoLabel->setVisible( vis );
693     myPrevButton->setVisible( vis );
694     myNextButton->setVisible( vis );
695     myInfoLabel->setText( tr( "X_FROM_Y_ITEMS_SHOWN" ).arg(imin).arg(imax).arg(total) );
696     myPrevButton->setEnabled( myPreviewActor->hasPrevious() );
697     myNextButton->setEnabled( myPreviewActor->hasNext() );
698   }
699 }