Salome HOME
439bfe7ee600945b137f04eb86f00b68b9128146
[modules/geom.git] / src / GEOMBase / GEOMBase_Helper.cxx
1 // Copyright (C) 2007-2014  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
23 //  GEOM GEOMGUI : GUI for Geometry component
24 //  File   : GEOMBase_Helper.cxx
25 //  Author : Sergey ANIKIN, Open CASCADE S.A.S. (sergey.anikin@opencascade.com)
26
27 #include "GEOMBase_Helper.h"
28 #include "GEOMBase.h"
29 #include "GEOM_Operation.h"
30
31 #include <GeometryGUI.h>
32
33 #include <SUIT_Desktop.h>
34 #include <SUIT_Session.h>
35 #include <SUIT_ViewManager.h>
36 #include <SUIT_ViewWindow.h>
37 #include <SUIT_ViewModel.h>
38 #include <SUIT_MessageBox.h>
39 #include <SUIT_OverrideCursor.h>
40 #include <SUIT_ResourceMgr.h>
41
42 #include <SalomeApp_Module.h>
43 #include <SalomeApp_Application.h>
44 #include <SalomeApp_Study.h>
45 #include <LightApp_SelectionMgr.h>
46 #include <LightApp_DataOwner.h>
47 #include <SalomeApp_Tools.h>
48 #include <SALOME_ListIO.hxx>
49
50 #include <SALOME_Prs.h>
51
52 #include <OCCViewer_ViewModel.h>
53 #include <SVTK_ViewModel.h>
54
55 #include <TColStd_MapOfInteger.hxx>
56 #include <TCollection_AsciiString.hxx>
57 #include <TColStd_IndexedMapOfInteger.hxx>
58
59 //To disable automatic genericobj management, the following line should be commented.
60 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
61 #define WITHGENERICOBJ
62
63 //================================================================
64 // Function : getActiveView
65 // Purpose  : Get active view window, returns 0 if no open study frame
66 //================================================================
67 SUIT_ViewWindow* GEOMBase_Helper::getActiveView()
68 {
69   SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
70   if ( activeStudy )
71     return SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
72
73   return 0;
74 }
75
76
77 //================================================================
78 // Function : getGeomEngine
79 // Purpose  : Static method
80 //================================================================
81 GEOM::GEOM_Gen_ptr GEOMBase_Helper::getGeomEngine()
82 {
83   return GeometryGUI::GetGeomGen();
84 }
85
86 //================================================================
87 // Function : GEOMBase_Helper
88 // Purpose  :
89 //================================================================
90 GEOMBase_Helper::GEOMBase_Helper( SUIT_Desktop* desktop )
91   : myDesktop( desktop ), myViewWindow( 0 ), myDisplayer( 0 ), myCommand( 0 ), isPreview( false ),
92     myIsApplyAndClose( false ), myIsOptimizedBrowsing( false ), myIsWaitCursorEnabled( true ),
93     myIsDisableBrowsing(false), myIsDisplayResult(true)
94 {
95 }
96
97 //================================================================
98 // Function : ~GEOMBase_Helper
99 // Purpose  :
100 //================================================================
101 GEOMBase_Helper::~GEOMBase_Helper()
102 {
103   //rnv: Fix for the "IPAL21922 : WinTC5.1.4: incorrect quit salome"
104   if ( !SUIT_Session::session()->activeApplication() || !SUIT_Session::session()->activeApplication()->desktop() )
105     return;
106
107   if ( myPreview.size() )
108     erasePreview();
109   if ( hasCommand() )
110     abortCommand();
111   SalomeApp_Application* app = (SalomeApp_Application*)(SUIT_Session::session()->activeApplication());
112   if (app) {
113     GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( app->module( "Geometry" ) );
114     if(aGeomGUI)
115       globalSelection(aGeomGUI->getLocalSelectionMode() , true );
116   }
117
118   if (myDisplayer)
119     delete myDisplayer;
120   if ( !CORBA::is_nil( myOperation ) )
121     myOperation->UnRegister();
122 }
123
124 //================================================================
125 // Function : display
126 // Purpose  :
127 //================================================================
128 void GEOMBase_Helper::display( const ObjectList& objList, const bool updateView )
129 {
130   ObjectList::const_iterator it;
131   for ( it = objList.begin(); it != objList.end(); it++ ) {
132     display( *it, false );
133   }
134   if ( !objList.empty() && updateView )
135     getDisplayer()->UpdateViewer();
136 }
137
138 //================================================================
139 // Function  : display
140 // Purpose   : Display object.
141 // Important : Object must be already in study
142 //================================================================
143 void GEOMBase_Helper::display( GEOM::GEOM_Object_ptr object, const bool updateView )
144 {
145   // Unset color of shape ( this color may be set during preview displaying )
146   // Default color will be used
147 //   getDisplayer()->UnsetColor();
148   getDisplayer()->UnsetWidth();
149   
150   MESSAGE("GEOMBase_Helper::display myTexture = "<<getDisplayer()->GetTexture())
151
152   // Enable activisation of selection
153   getDisplayer()->SetToActivate( true );
154
155   // Display object
156   getDisplayer()->Display( object, updateView );
157 }
158
159 //================================================================
160 // Function : erase
161 // Purpose  :
162 //================================================================
163 void GEOMBase_Helper::erase( const ObjectList& objList, const bool updateView )
164 {
165   ObjectList::const_iterator it = objList.begin();
166   for ( ; it != objList.end(); it++ ) {
167     erase( *it, false );
168   }
169   if ( !objList.empty() && updateView )
170     getDisplayer()->UpdateViewer();
171 }
172
173 //================================================================
174 // Function : erase
175 // Purpose  :
176 //================================================================
177 void GEOMBase_Helper::erase( GEOM::GEOM_Object_ptr object, const bool updateView )
178 {
179   if ( !object->_is_nil() ) {
180     QString entry = getEntry( object );
181     getDisplayer()->Erase( new SALOME_InteractiveObject(
182       entry.toLatin1().constData(), 
183       "GEOM", strdup( GEOMBase::GetName( object ).toLatin1().constData() ) ), true, updateView );
184   }
185 }
186
187 //================================================================
188 // Function : redisplay
189 // Purpose  :
190 //================================================================
191 void GEOMBase_Helper::redisplay( const ObjectList& objList,
192                                  const bool withChildren,
193                                  const bool updateView )
194 {
195   ObjectList::const_iterator it = objList.begin();
196   for ( ; it != objList.end(); it++ ) {
197     redisplay( *it, withChildren, false );
198   }
199   if ( !objList.empty() && updateView )
200     getDisplayer()->UpdateViewer();
201 }
202
203 //================================================================
204 // Function : redisplay
205 // Purpose  :
206 //================================================================
207 void GEOMBase_Helper::redisplay( GEOM::GEOM_Object_ptr object,
208                                  const bool withChildren,
209                                  const bool updateView )
210 {
211   if ( !object->_is_nil() ) {
212     // Unset color of shape ( this color may be set during preview displaying )
213     // Default color will be used
214     getDisplayer()->UnsetColor();
215     getDisplayer()->UnsetWidth();
216
217     // Enable activisation of selection
218     getDisplayer()->SetToActivate( true );
219
220     QString entry = getEntry( object );
221     getDisplayer()->Redisplay(new SALOME_InteractiveObject
222                               (entry.toLatin1().constData(), "GEOM", strdup(GEOMBase::GetName(object).toLatin1().constData())), false);
223   }
224
225   if ( withChildren ) {
226     SalomeApp_Study* aDoc = getStudy();
227     if ( aDoc && aDoc->studyDS() ) {
228       _PTR(Study) aStudy = aDoc->studyDS();
229       CORBA::String_var objStr = SalomeApp_Application::orb()->object_to_string(object);
230       _PTR(SObject) aSObj (aStudy->FindObjectIOR(std::string(objStr.in())));
231       if ( aSObj  ) {
232         _PTR(ChildIterator) anIt ( aStudy->NewChildIterator( aSObj ) );
233         for ( anIt->InitEx( true ); anIt->More(); anIt->Next() ) {
234           GEOM::GEOM_Object_var aChild = GEOM::GEOM_Object::_narrow
235             (GeometryGUI::ClientSObjectToObject(anIt->Value()));
236           if ( !CORBA::is_nil( aChild ) ) {
237             if ( !aChild->_is_nil() ) {
238               QString entry = getEntry( aChild );
239               getDisplayer()->Redisplay( new SALOME_InteractiveObject(
240                 entry.toLatin1().constData(), "GEOM", strdup( GEOMBase::GetName( aChild ).toLatin1().constData() ) ), false );
241             }
242           }
243         }
244       }
245     }
246   }
247
248   if ( updateView )
249     getDisplayer()->UpdateViewer();
250 }
251
252 //================================================================
253 // Function : displayPreview
254 // Purpose  : Method for displaying preview based on execute() results
255 //================================================================
256 void GEOMBase_Helper::displayPreview( const bool   display,
257                                       const bool   activate,
258                                       const bool   update,
259                                       const bool   toRemoveFromEngine,
260                                       const double lineWidth,
261                                       const int    displayMode,
262                                       const int    color,
263                                       const bool   append )
264 {
265   if(!display) {
266     erasePreview( update );
267     return;
268   }
269   
270   isPreview = true;
271   QString msg;
272   if ( !isValid( msg ) )
273   {
274     erasePreview( update );
275     isPreview = false;
276     return;
277   }
278
279   if( !append )
280     erasePreview( false );
281
282   try {
283     SUIT_OverrideCursor wc;
284     ObjectList objects;
285  
286     if ( !isWaitCursorEnabled() )
287       wc.suspend();
288     
289     if ( !execute( objects ) || !getOperation()->IsDone() ) {
290       wc.suspend();
291     }
292     else {
293       for ( ObjectList::iterator it = objects.begin(); it != objects.end(); ++it )
294       {
295             GEOM::GEOM_Object_var obj=*it;
296         displayPreview( obj, true, activate, false, lineWidth, displayMode, color );
297         if ( toRemoveFromEngine )
298               obj->UnRegister();
299       }
300     }
301   }
302   catch( const SALOME::SALOME_Exception& e ) {
303     SalomeApp_Tools::QtCatchCorbaException( e );
304   }
305
306   isPreview = false;
307
308   if ( update )
309     updateViewer();
310 }
311
312 //================================================================
313 // Function : displayPreview
314 // Purpose  : Method for displaying preview of resulting shape
315 //================================================================
316 void GEOMBase_Helper::displayPreview( GEOM::GEOM_Object_ptr object,
317                                       const bool            append,
318                                       const bool            activate,
319                                       const bool            update,
320                                       const double          lineWidth,
321                                       const int             displayMode,
322                                       const int             color )
323 {
324   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();    
325
326   // Set color for preview shape
327   getDisplayer()->SetColor( color == -1 ? Quantity_NOC_VIOLET : color );
328
329   // set width of displayed shape
330   getDisplayer()->SetWidth( lineWidth == -1 ? resMgr->integerValue("Geometry", "preview_edge_width", -1) : lineWidth );
331
332   // set display mode of displayed shape
333   int aPrevDispMode = getDisplayer()->SetDisplayMode( displayMode == -1 ? resMgr->integerValue( "Geometry", "display_mode", 0 ) : displayMode );
334
335   // Disable activation of selection
336   getDisplayer()->SetToActivate( activate );
337
338   // Make a reference to GEOM_Object
339   CORBA::String_var objStr = SalomeApp_Application::orb()->object_to_string( object );
340   getDisplayer()->SetName( objStr.in() );
341
342   // Build prs
343   SALOME_Prs* aPrs = getDisplayer()->BuildPrs( object );
344   if ( aPrs == 0 || aPrs->IsNull() )
345     return;
346     
347   // Make preview not clippable
348   aPrs->SetClippable (false);
349
350   // Display prs
351   displayPreview( aPrs, append, update );
352
353   getDisplayer()->UnsetName();
354   getDisplayer()->UnsetColor();
355   getDisplayer()->SetDisplayMode( aPrevDispMode );
356
357   // Enable activation of displayed objects
358   getDisplayer()->SetToActivate( true );
359 }
360
361 //================================================================
362 // Function : displayPreview
363 // Purpose  : Method for displaying arbitrary preview objects (not limited to shapes)
364 //================================================================
365 void GEOMBase_Helper::displayPreview( const SALOME_Prs* prs,
366                                       const bool        append,
367                                       const bool        update )
368 {
369   if ( !append )
370     erasePreview( false );
371
372   // remember current view frame to make correct erase preview later
373   myViewWindow = getActiveView();
374
375   if ( myViewWindow == 0 )
376     return;
377   
378   // Display prs
379   SUIT_ViewManager* aViewManager = myViewWindow->getViewManager();
380   if ( aViewManager->getType() == OCCViewer_Viewer::Type() ||
381        aViewManager->getType() == SVTK_Viewer::Type() )
382     {
383       SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
384       SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
385       if (aView)
386         aView->Display( getDisplayer(), prs );
387     }
388
389   // Add prs to the preview list
390   myPreview.push_back( (SALOME_Prs*)prs );
391
392   // Update viewer
393   if ( update )
394     getDisplayer()->UpdateViewer();
395 }
396
397 //================================================================
398 // Function : erasePreview
399 // Purpose  :
400 //================================================================
401 void GEOMBase_Helper::erasePreview( const bool update )
402 {
403   // check view frame where the preview was displayed
404   bool vfOK = checkViewWindow() && myViewWindow;
405   // Iterate through presentations and delete them
406   for ( PrsList::iterator anIter = myPreview.begin(); anIter != myPreview.end(); ++anIter )
407   {
408     if ( vfOK )
409     {
410       SUIT_ViewManager* aViewManager = myViewWindow->getViewManager();
411       if ( aViewManager->getType() == OCCViewer_Viewer::Type() ||
412            aViewManager->getType() == SVTK_Viewer::Type() )
413       {
414         SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
415         SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
416         if (aView)
417           aView->Erase( getDisplayer(), *anIter, true );
418       }
419     }
420     delete *anIter;
421   }
422   myPreview.clear();
423
424   // Update viewer
425   if ( update )
426     updateViewer();
427 }
428
429 //================================================================
430 // Function  : localSelection
431 // Purpose   : Activate selection of objects of a given type
432 // IMPORTANT : Works after localSelection( ... ) method call only
433 //================================================================
434 void GEOMBase_Helper::activate( const int theType )
435 {
436   if (!getStudy()) return;
437   _PTR(Study) aStudy = getStudy()->studyDS();
438   _PTR(SComponent) aGeom ( aStudy->FindComponent( "GEOM" ) );
439   if ( !aGeom )
440     return;
441
442   SALOME_ListIO aList;
443   _PTR(ChildIterator) anIter ( aStudy->NewChildIterator( aGeom ) );
444   for ( ; anIter->More(); anIter->Next() )
445   {
446     _PTR(SObject) aSO ( anIter->Value() );
447     if ( aSO )
448     {
449       _PTR(SObject) aRefSO;
450       if ( !aSO->ReferencedObject( aRefSO ) )
451       {
452         GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_narrow
453           (GeometryGUI::ClientSObjectToObject(aSO));
454         if ( !anObj->_is_nil() && anObj->GetType() == theType )
455           aList.Append( new SALOME_InteractiveObject( aSO->GetID().c_str(), "GEOM", aSO->GetName().c_str()) );
456       }
457     }
458   }
459
460   getDisplayer()->LocalSelection( aList, 0 );
461 }
462
463 //================================================================
464 // Function : localSelection
465 // Purpose  : Activate selection of sub-shapes in accordance with mode
466 //            modes are from TopAbs_ShapeEnum
467 //================================================================
468 void GEOMBase_Helper::localSelection( const ObjectList& theObjs, const std::list<int> modes )
469 {
470   SALOME_ListIO aListOfIO;
471
472   ObjectList::const_iterator anIter = theObjs.begin();
473   for ( ; anIter != theObjs.end(); ++anIter )
474   {
475     GEOM::GEOM_Object_ptr anObj = *anIter;
476     if ( anObj->_is_nil() )
477       continue;
478     QString anEntry = getEntry( anObj );
479     if ( anEntry != "" )
480       aListOfIO.Append( new SALOME_InteractiveObject(
481         anEntry.toLatin1().constData(), "GEOM", strdup( GEOMBase::GetName( anObj ).toLatin1().constData() ) ) );
482   }
483
484   getDisplayer()->LocalSelection( aListOfIO, modes );
485 }
486
487 //================================================================
488 // Function : localSelection
489 // Purpose  : Activate selection of sub-shapes in accordance with mode
490 //            theMode is from TopAbs_ShapeEnum
491 //================================================================
492 void GEOMBase_Helper::localSelection( const ObjectList& theObjs, const int theMode )
493 {
494   std::list<int> modes;
495   modes.push_back( theMode );
496   localSelection( theObjs, modes );
497 }
498
499 //================================================================
500 // Function : localSelection
501 // Purpose  : Activate selection of sub-shapes in accordance with mode
502 //            modes are from TopAbs_ShapeEnum
503 //================================================================
504 void GEOMBase_Helper::localSelection( GEOM::GEOM_Object_ptr obj, const std::list<int> modes )
505 {
506   // If object is null local selection for all objects is activated
507   if ( obj->_is_nil() ) {
508     getDisplayer()->LocalSelection( Handle(SALOME_InteractiveObject)(), modes );
509     return;
510   }
511
512   ObjectList objList;
513   objList.push_back( obj );
514   localSelection( objList, modes );
515 }
516
517 //================================================================
518 // Function : localSelection
519 // Purpose  : Activate selection of sub-shapes in accordance with mode
520 //            mode is from TopAbs_ShapeEnum
521 //================================================================
522 void GEOMBase_Helper::localSelection( GEOM::GEOM_Object_ptr obj, const int mode )
523 {
524   std::list<int> modes;
525   modes.push_back( mode );
526   localSelection( obj, modes );
527 }
528
529 //================================================================
530 // Function : globalSelection
531 // Purpose  : Activate selection of sub-shapes. Set selection filters
532 //            in accordance with mode. theMode is from GEOMImpl_Types
533 //================================================================
534 void GEOMBase_Helper::globalSelection( const int theMode, const bool update )
535 {
536   getDisplayer()->GlobalSelection( theMode, update );
537 }
538
539 //================================================================
540 // Function : globalSelection
541 // Purpose  : Activate selection of sub-shapes. Set selection filters
542 //            in accordance with mode. theMode is from GEOMImpl_Types
543 //================================================================
544 void GEOMBase_Helper::globalSelection( const TColStd_MapOfInteger& theModes,
545                                        const bool update )
546 {
547   getDisplayer()->GlobalSelection( theModes, update );
548 }
549
550 //================================================================
551 // Function : globalSelection
552 // Purpose  : Activate selection of sub-shapes. Set selection filters
553 //            in accordance with mode. theMode is from GEOMImpl_Types
554 //================================================================
555 void GEOMBase_Helper::globalSelection( const TColStd_MapOfInteger& theModes,
556                                        const QList<int>& subShapes,
557                                        const bool update )
558 {
559   getDisplayer()->GlobalSelection( theModes, update, &subShapes );
560 }
561
562 //================================================================
563 // Function : addInStudy
564 // Purpose  : Add object in study
565 //================================================================
566 QString GEOMBase_Helper::addInStudy( GEOM::GEOM_Object_ptr theObj, const char* theName )
567 {
568   if ( !hasCommand() )
569     return QString();
570
571   _PTR(Study) aStudy = getStudy()->studyDS();
572   if ( !aStudy || theObj->_is_nil() )
573     return QString();
574
575   SALOMEDS::Study_var aStudyDS = GeometryGUI::ClientStudyToStudy(aStudy);
576
577   GEOM::GEOM_Object_ptr aFatherObj = getFather( theObj );
578
579   SALOMEDS::SObject_var aSO =
580     getGeomEngine()->AddInStudy(aStudyDS, theObj, theName, aFatherObj);
581
582   QString anEntry;
583   if ( !aSO->_is_nil() ) {
584     CORBA::String_var entry = aSO->GetID();
585     anEntry = entry.in();
586   }
587   // Each dialog is responsible for this method implementation,
588   // default implementation does nothing
589   restoreSubShapes(aStudyDS, aSO);
590   aSO->UnRegister();
591
592   return anEntry;
593 }
594
595 //================================================================
596 // Function : restoreSubShapes
597 // Purpose  : restore tree of argument's sub-shapes under the resulting shape
598 //================================================================
599 void GEOMBase_Helper::restoreSubShapes (SALOMEDS::Study_ptr   /*theStudy*/,
600                                         SALOMEDS::SObject_ptr /*theSObject*/)
601 {
602   // do nothing by default
603
604   // example of implementation in particular dialog:
605   // GEOM::ListOfGO anArgs;
606   // anArgs.length(0); // empty list means that all arguments should be restored
607   // getGeomEngine()->RestoreSubShapesSO(theStudy, theSObject, anArgs,
608   //                                     /*theFindMethod=*/GEOM::FSM_GetInPlace,
609   //                                     /*theInheritFirstArg=*/false);
610 }
611
612 //================================================================
613 // Function : updateObjBrowser
614 // Purpose  : Update object browser
615 //================================================================
616 void GEOMBase_Helper::updateObjBrowser() const
617 {
618   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
619   if (app) {
620     CAM_Module* module = app->module( "Geometry" );
621     SalomeApp_Module* appMod = dynamic_cast<SalomeApp_Module*>( module );
622     if ( appMod ) {
623       appMod->updateObjBrowser( true );
624     }
625   }
626 }
627
628 //================================================================
629 // Function : updateViewer
630 // Purpose  : Update active 3D view
631 //================================================================
632 void GEOMBase_Helper::updateViewer()
633 {
634   getDisplayer()->UpdateViewer();
635 }
636
637 //================================================================
638 // Function : getStudyId
639 // Purpose  : Get study Id
640 //================================================================
641 int GEOMBase_Helper::getStudyId() const
642 {
643   int anId = -1;
644   if ( getStudy() )
645     anId = getStudy()->id();
646   return anId;
647 }
648
649 //================================================================
650 // Function : getStudy
651 // Purpose  : Returns the active study. It is recommended to use
652 //            this method instead of direct desktop->getActiveStudy() calls
653 //================================================================
654 SalomeApp_Study* GEOMBase_Helper::getStudy() const
655 {
656   SUIT_Desktop* aDesktop = getDesktop();
657   if (!aDesktop)
658     return 0;
659
660   QList<SUIT_Application*> anAppList = SUIT_Session::session()->applications();
661
662   SUIT_Application* anApp = 0;
663   QListIterator<SUIT_Application*> it( anAppList );
664   while ( it.hasNext() )
665     {
666       anApp = it.next();
667       if ( anApp && anApp->desktop() == aDesktop )
668         break;
669     }
670
671   return dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
672 }
673
674 //================================================================
675 // Function : getEntry
676 // Purpose  :
677 //================================================================
678 QString GEOMBase_Helper::getEntry( GEOM::GEOM_Object_ptr object ) const
679 {
680   SalomeApp_Study* study = getStudy();
681   if ( study )  {
682     QString objIOR = GEOMBase::GetIORFromObject( object );
683     if ( objIOR != "" ) {
684       _PTR(SObject) SO ( study->studyDS()->FindObjectIOR( objIOR.toLatin1().constData() ) );
685       if ( SO )
686         return QString::fromStdString(SO->GetID());
687     }
688   }
689   return "";
690 }
691
692 //================================================================
693 // Function : getDisplayer
694 // Purpose  :
695 //================================================================
696 GEOM_Displayer* GEOMBase_Helper::getDisplayer()
697 {
698   if ( !myDisplayer )
699     myDisplayer = new GEOM_Displayer( getStudy() );
700   return myDisplayer;
701 }
702
703 //================================================================
704 // Function : clearShapeBuffer
705 // Purpose  :
706 //================================================================
707 void GEOMBase_Helper::clearShapeBuffer( GEOM::GEOM_Object_ptr theObj )
708 {
709   GeometryGUI::ClearShapeBuffer(theObj);
710 }
711
712 //================================================================
713 // Function : openCommand
714 // Purpose  :
715 //================================================================
716 bool GEOMBase_Helper::openCommand()
717 {
718   bool res = false;
719   if ( !getStudy() || hasCommand() )
720   {
721     MESSAGE("Getting out from openCommand()")
722     return res;
723   }
724
725   GEOM::GEOM_IOperations_var anOp = GEOM::GEOM_IOperations::_narrow( getOperation() );
726   if ( !anOp->_is_nil() ) {
727     myCommand = new GEOM_Operation( SUIT_Session::session()->activeApplication(), anOp.in() );
728     myCommand->start();
729     res = true;
730   }
731   else
732   {
733     MESSAGE("anOp->_is_nil() = true")
734   }
735
736   return res;
737 }
738
739 //================================================================
740 // Function : abortCommand
741 // Purpose  :
742 //================================================================
743 bool GEOMBase_Helper::abortCommand()
744 {
745   if ( !hasCommand() )
746     return false;
747
748   myCommand->abort();
749   delete myCommand; // I don't know where to delete this object here ?
750   myCommand = 0;
751
752   return true;
753 }
754
755 //================================================================
756 // Function : commitCommand
757 // Purpose  :
758 //================================================================
759 bool GEOMBase_Helper::commitCommand( const char* )
760 {
761   if ( !hasCommand() )
762     return false;
763
764   myCommand->commit();
765   delete myCommand; // I don't know where to delete this object here ?
766   myCommand = 0;
767
768   return true;
769 }
770
771 //================================================================
772 // Function : hasCommand
773 // Purpose  :
774 //================================================================
775 bool GEOMBase_Helper::hasCommand() const
776 {
777   return (bool)myCommand;
778 }
779
780 //================================================================
781 // Function : getOperation
782 // Purpose  :
783 //================================================================
784 GEOM::GEOM_IOperations_ptr GEOMBase_Helper::getOperation()
785 {
786   if ( myOperation->_is_nil() )
787     myOperation = createOperation();
788
789   return myOperation;
790 }
791
792
793
794 //================================================================
795 // Function : checkViewWindow
796 // Purpose  :
797 //================================================================
798 bool GEOMBase_Helper::checkViewWindow()
799 {
800   if ( myViewWindow ){
801     QList<SUIT_ViewWindow*> aViewWindowsList = SUIT_Session::session()->activeApplication()->desktop()->windows();
802     QListIterator<SUIT_ViewWindow*> it( aViewWindowsList );
803     while ( it.hasNext() )
804       {
805         if ( myViewWindow == it.next() )
806           return true;
807       }
808   }
809   myViewWindow = 0;
810   return false;
811 }
812
813 //================================================================
814 // Function : onAccept
815 // Purpose  : This method should be called from dialog's slots onOk() and onApply()
816 //            It perfroms user input validation, then it
817 //            performs a proper operation and manages transactions, etc.
818 //================================================================
819 bool GEOMBase_Helper::onAccept( const bool publish, const bool useTransaction, bool erasePreviewFlag )
820 {
821   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
822   if ( !appStudy ) 
823   {
824     MESSAGE("appStudy is empty")
825     return false;
826   }
827   _PTR(Study) aStudy = appStudy->studyDS();
828
829   bool aLocked = (_PTR(AttributeStudyProperties) (aStudy->GetProperties()))->IsLocked();
830   if ( aLocked ) {
831     MESSAGE("GEOMBase_Helper::onAccept - ActiveStudy is locked");
832     SUIT_MessageBox::warning ( (QWidget*)SUIT_Session::session()->activeApplication()->desktop(),
833                                QObject::tr("WRN_WARNING"),
834                                QObject::tr("WRN_STUDY_LOCKED"),
835                                QObject::tr("BUT_OK") );
836     return false;
837   }
838
839   QString msg;
840   if ( !isValid( msg ) ) {
841     showError( msg );
842     return false;
843   }
844   
845   if(erasePreviewFlag)
846     erasePreview( false );
847
848   bool result = false;
849
850   try {
851     if ( ( !publish && !useTransaction ) || openCommand() ) {
852       SUIT_OverrideCursor wc;
853       SUIT_Session::session()->activeApplication()->putInfo( "" );
854       ObjectList objects;
855       if ( !execute( objects ) || !getOperation()->IsDone() ) {
856         wc.suspend();
857         abortCommand();
858         showError();
859       }
860       else {
861         addSubshapesToStudy(); // add Sub-shapes if local selection
862         const int nbObjs = objects.size();
863         QStringList anEntryList;
864         int currObj = 1, aNumber = 1;
865         for ( ObjectList::iterator it = objects.begin(); it != objects.end(); ++it, currObj++ ) {
866           GEOM::GEOM_Object_var obj=*it;
867           if ( publish ) {
868             QString aName = getObjectName(obj);
869             if (aName.isEmpty()) {
870               aName = getNewObjectName(currObj);
871                     if ( nbObjs > 1 ) {
872                             if (aName.isEmpty())
873                               aName = getPrefix(obj);
874                               if (nbObjs <= 30) {
875                                 // Try to find a unique name
876                                 aName = GEOMBase::GetDefaultName(aName, extractPrefix());
877                               } else {
878                                 // Don't check name uniqueness in case of numerous objects
879                                 aName = aName + "_" + QString::number(aNumber++);
880                               }
881                     } else {
882                             // PAL6521: use a prefix, if some dialog box doesn't reimplement getNewObjectName()
883                             if ( aName.isEmpty() )
884                               aName = GEOMBase::GetDefaultName( getPrefix( obj ) );
885                     }
886             }
887             anEntryList << addInStudy( obj, aName.toLatin1().constData() );
888             // updateView=false
889             if( isDisplayResult() )
890               display( obj, false );
891 #ifdef WITHGENERICOBJ
892             // obj has been published in study. Its refcount has been incremented.
893             // It is safe to decrement its refcount
894             // so that it will be destroyed when the entry in study will be removed
895             obj->UnRegister();
896 #endif
897           }
898           else {
899             // asv : fix of PAL6454. If publish==false, then the original shape
900             // was modified, and need to be re-cached in GEOM_Client before redisplay
901             clearShapeBuffer( obj );
902             // withChildren=true, updateView=false
903             if( isDisplayResult() )
904               redisplay( obj, true, false );
905           }
906         }
907
908         if ( nbObjs ) {
909           commitCommand();
910           updateObjBrowser();
911           if( SUIT_Application* anApp = SUIT_Session::session()->activeApplication() ) {
912             LightApp_Application* aLightApp = dynamic_cast<LightApp_Application*>( anApp );
913             if(aLightApp) {
914               QString anOpName( typeid(*this).name() );
915               aLightApp->emitOperationFinished( "Geometry", anOpName, anEntryList );
916
917               if ( !isDisableBrowsing() )
918                 aLightApp->browseObjects( anEntryList, isApplyAndClose(), isOptimizedBrowsing() );
919             }
920             anApp->putInfo( QObject::tr("GEOM_PRP_DONE") );
921           }
922           result = true;
923         }
924         else
925           abortCommand();
926       }
927     }
928   }
929   catch( const SALOME::SALOME_Exception& e ) {
930     SalomeApp_Tools::QtCatchCorbaException( e );
931     abortCommand();
932     MESSAGE("Exception catched")
933   }
934
935   updateViewer();
936
937   MESSAGE("result ="<<result)
938   return result;
939 }
940
941
942 //================================================================
943 // Function : showError
944 // Purpose  : Shows a message box with infromation about an error taken from getOperation()->GetErrorCode()
945 //================================================================
946 void GEOMBase_Helper::showError()
947 {
948   QString msg;
949   if ( !getOperation()->_is_nil() )
950     msg = QObject::tr( getOperation()->GetErrorCode() );
951
952   if ( msg.isEmpty() )
953     msg = QObject::tr( "GEOM_PRP_ABORT" );
954
955   SUIT_MessageBox::critical( SUIT_Session::session()->activeApplication()->desktop(),
956                              QObject::tr( "GEOM_ERROR_STATUS" ),
957                              msg,
958                              QObject::tr( "BUT_OK" ) );
959 }
960
961 //================================================================
962 // Function : showError
963 // Purpose  : Shows a error message followed by <msg>
964 //================================================================
965 void GEOMBase_Helper::showError( const QString& msg )
966 {
967   QString str( QObject::tr( "GEOM_INCORRECT_INPUT" ) );
968   if ( !msg.isEmpty() )
969     str += "\n" + msg;
970   SUIT_MessageBox::critical(SUIT_Session::session()->activeApplication()->desktop(), QObject::tr( "GEOM_ERROR" ), str, QObject::tr( "BUT_OK" ) );
971 }
972
973 //////////////////////////////////////////////////////////////////
974 // Virtual methods to be redefined in dialogs
975 //////////////////////////////////////////////////////////////////
976
977 //================================================================
978 // Function : createOperation
979 // Purpose  : Redefine this method to return proper IOperation reference
980 //================================================================
981 GEOM::GEOM_IOperations_ptr GEOMBase_Helper::createOperation()
982 {
983   GEOM::GEOM_IOperations_var aNilOp;
984   return aNilOp._retn();
985 }
986
987 //================================================================
988 // Function : isValid
989 // Purpose  : Called by onAccept(). Redefine this method to check validity of user input in dialog boxes.
990 //================================================================
991 bool GEOMBase_Helper::isValid( QString& )
992 {
993   return true;
994 }
995
996 //================================================================
997 // Function : execute
998 // Purpose  : This method is called by onAccept().
999 //            It should perform the required operation and put all new or modified objects into
1000 //            <objects> argument.Should return <false> if some error occurs during its execution.
1001 //================================================================
1002 bool GEOMBase_Helper::execute( ObjectList& objects )
1003 {
1004   return false;
1005 }
1006
1007 //================================================================
1008 // Function : getFather
1009 // Purpose  : This method is called by addInStudy(). It should return a father object
1010 //            for <theObj> or a nil reference if <theObj> should be published
1011 //            as a top-level object.
1012 //================================================================
1013 GEOM::GEOM_Object_ptr GEOMBase_Helper::getFather( GEOM::GEOM_Object_ptr theObj )
1014 {
1015   return GEOM::GEOM_Object::_nil();
1016 }
1017
1018 //================================================================
1019 // Function : getObjectName
1020 // Purpose  : Redefine this method to return proper name for the given object
1021 //================================================================
1022 QString GEOMBase_Helper::getObjectName(GEOM::GEOM_Object_ptr object) const
1023 {
1024   return QString();
1025 }
1026
1027 //================================================================
1028 // Function : getNewObjectName
1029 // Purpose  : Redefine this method to return proper name for a new object
1030 //================================================================
1031 QString GEOMBase_Helper::getNewObjectName (int) const
1032 {
1033   return QString();
1034 }
1035
1036 //================================================================
1037 // Function : extractPrefix
1038 // Purpose  : Redefine this method to return \c true if necessary
1039 //            to extract prefix when generating new name for the
1040 //            object(s) being created
1041 //================================================================
1042 bool GEOMBase_Helper::extractPrefix() const
1043 {
1044   return false;
1045 }
1046
1047 //================================================================
1048 // Function : getPrefix
1049 // Purpose  : Get prefix for name of created object
1050 //================================================================
1051 QString GEOMBase_Helper::getPrefix( GEOM::GEOM_Object_ptr theObj ) const
1052 {
1053   if ( !myPrefix.isEmpty() || theObj->_is_nil() )
1054     return myPrefix;
1055
1056   GEOM::shape_type aType = theObj->GetShapeType();
1057
1058   switch ( aType )
1059   {
1060     case GEOM::VERTEX   : return QObject::tr( "GEOM_VERTEX" );
1061     case GEOM::EDGE     : return QObject::tr( "GEOM_EDGE" );
1062     case GEOM::WIRE     : return QObject::tr( "GEOM_WIRE" );
1063     case GEOM::FACE     : return QObject::tr( "GEOM_FACE" );
1064     case GEOM::SHELL    : return QObject::tr( "GEOM_SHELL" );
1065     case GEOM::SOLID    : return QObject::tr( "GEOM_SOLID" );
1066     case GEOM::COMPSOLID: return QObject::tr( "GEOM_COMPOUNDSOLID" );
1067     case GEOM::COMPOUND : return QObject::tr( "GEOM_COMPOUND" );
1068     default : return "";
1069   }
1070 }
1071
1072 //================================================================
1073 // Function : getDesktop
1074 // Purpose  : Returns myDesktop field. Initialized in constructor,
1075 //            usually as dynamic_cast<SUIT_Desktop*>(parentWidget())
1076 //================================================================
1077 SUIT_Desktop* GEOMBase_Helper::getDesktop() const
1078 {
1079   return myDesktop;
1080 }
1081
1082 //================================================================
1083 // Function : selectObjects
1084 // Purpose  : Selects list of objects
1085 //================================================================
1086 bool GEOMBase_Helper::selectObjects( ObjectList& objects )
1087 {
1088   SUIT_DataOwnerPtrList aList;
1089   ObjectList::iterator anIter;
1090   for ( anIter = objects.begin(); anIter != objects.end(); ++anIter )
1091   {
1092     QString anEntry = getEntry( *anIter );
1093     LightApp_DataOwner* anOwher = new LightApp_DataOwner( anEntry );
1094     aList.append( anOwher );
1095   }
1096
1097   SUIT_Session* session = SUIT_Session::session();
1098   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
1099   if ( !app )
1100     return false;
1101
1102   LightApp_SelectionMgr* aMgr = app->selectionMgr();
1103   if ( !aMgr )
1104     return false;
1105
1106   aMgr->setSelected( aList, false );
1107
1108   return true;
1109 }
1110
1111 //================================================================
1112 // Function : findObjectInFather
1113 // Purpose  : It should return an object if its founded in study or
1114 //            return Null object if the object is not founded
1115 //================================================================
1116 GEOM::GEOM_Object_ptr GEOMBase_Helper::findObjectInFather (GEOM::GEOM_Object_ptr theFather,
1117                                                            const QString& theName)
1118 {
1119   SalomeApp_Application* app =
1120     dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
1121   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
1122   _PTR(Study) aDStudy = appStudy->studyDS();
1123   QString IOR = GEOMBase::GetIORFromObject( theFather );
1124   _PTR(SObject) SObj ( aDStudy->FindObjectIOR( IOR.toLatin1().constData() ) );
1125
1126   bool inStudy = false;
1127   GEOM::GEOM_Object_var aReturnObject;
1128   for (_PTR(ChildIterator) iit (aDStudy->NewChildIterator( SObj )); iit->More() && !inStudy; iit->Next()) {
1129     _PTR(SObject) child (iit->Value());
1130     QString aChildName = child->GetName().c_str();
1131     if (aChildName == theName) {
1132       inStudy = true;
1133       CORBA::Object_var corbaObj = GeometryGUI::ClientSObjectToObject(iit->Value());
1134       aReturnObject = GEOM::GEOM_Object::_narrow( corbaObj );
1135     }
1136   }
1137   if (inStudy)
1138     return aReturnObject._retn();
1139   
1140   return GEOM::GEOM_Object::_nil();
1141 }
1142
1143 //================================================================
1144 // Function : findObjectInFather
1145 // Purpose  : It should return an object if its founded in study or
1146 //            return Null object if the object is not founded
1147 //================================================================
1148 GEOM::GEOM_Object_ptr GEOMBase_Helper::findObjectInFather( GEOM::GEOM_Object_ptr theFather,
1149                                                            int theIndex )
1150 {
1151   GEOM::GEOM_Object_var object;
1152   
1153   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
1154   if ( study ) {
1155     _PTR(Study) studyDS = study->studyDS();
1156     QString IOR = GEOMBase::GetIORFromObject( theFather );
1157     _PTR(SObject) sobject( studyDS->FindObjectIOR( IOR.toLatin1().constData() ) );
1158     if ( sobject ) {
1159       _PTR(ChildIterator) it( studyDS->NewChildIterator( sobject ) );
1160       for ( ; it->More(); it->Next() ) {
1161         GEOM::GEOM_Object_var cobject = GEOM::GEOM_Object::_narrow( GeometryGUI::ClientSObjectToObject( it->Value() ) );
1162         if ( !CORBA::is_nil( cobject ) ) {
1163           GEOM::ListOfLong_var indices = cobject->GetSubShapeIndices();
1164           int length = indices->length();
1165           // VSR 18/03/2014: we need only sub-shapes with single sub-shape index (to exclude groups, etc)
1166           if ( length == 1 && indices[0] == theIndex ) {
1167             object = cobject;
1168             break;
1169           }
1170         }
1171       }
1172     }
1173   }
1174   
1175   return object._retn();
1176 }
1177
1178 //================================================================
1179 // Function : addSubshapesToStudy
1180 // Purpose  : Virtual method to add sub-shapes if needs
1181 //================================================================
1182 void GEOMBase_Helper::addSubshapesToStudy()
1183 {
1184   //Impemented in Dialogs, called from Accept method
1185 }
1186
1187 //================================================================
1188 // Function : getSelected
1189 // Purpose  : Get selected object by specified type
1190 //
1191 // Returns valid object if only one object of the specified type is selected
1192 // (no matter global or local selection is activated). If \a type is TopAbs_SHAPE,
1193 // geometrical object of any valid type is expected.
1194 // 
1195 // \param type type of the object to be obtained from selection
1196 // \return selected geometrical object or nil object if selection is not satisfactory
1197 //================================================================
1198 GEOM::GeomObjPtr GEOMBase_Helper::getSelected( TopAbs_ShapeEnum type )
1199 {
1200   QList<TopAbs_ShapeEnum> types;
1201   types << type;
1202   return getSelected( types );
1203 }
1204
1205 //================================================================
1206 // Function : getSelected
1207 // Purpose  : Get selected object by specified types
1208 //
1209 // Returns valid object if only one object of the specified type is selected
1210 // (no matter global or local selection is activated). The list of allowed
1211 // shape types is passed via \a types. If \a types includes TopAbs_SHAPE,
1212 // geometrical object of any valid type is expected.
1213 // 
1214 // \param types list of allowed shape types for the objects to be obtained from selection
1215 // \return selected geometrical object or nil object if selection is not satisfactory
1216 //================================================================
1217 GEOM::GeomObjPtr GEOMBase_Helper::getSelected( const QList<TopAbs_ShapeEnum>& types )
1218 {
1219   QList<GEOM::GeomObjPtr> selected = getSelected( types, 1 );
1220   return selected.count() > 0 ? selected[0] : GEOM::GeomObjPtr();
1221 }
1222
1223 //================================================================
1224 // Function : getSelected
1225 // Purpose  : Get selected object(s) by specified type
1226 //
1227 // Returns list of selected objects if selection satisfies specifies selection options.
1228 // (no matter global or local selection is activated). If \a type is TopAbs_SHAPE,
1229 // geometrical objects of any valid type are expected.
1230 //
1231 // The \a type parameter specifies allowed type of the object(s) being selected.
1232 // The \a count parameter specifies exact number of the objects to be retrieved from selection.
1233 // The \a strict parameter specifies policy being applied to the selection. 
1234 // If \a count < 0, then any number of the selected objects is valid (including 0).
1235 // In this case, if \a strict is \c true (default), all selected objects should satisfy
1236 // the specified \a type.
1237 // If \a count > 0, only specified number of the objects is retrieved from the selection.
1238 // In this case, if \a strict is \c true (default), function returns empty list if total number of selected
1239 // objects does not correspond to the \a count parameter. Otherwise (if \a strict is \c false),
1240 // function returns valid list of objects if at least \a count objects satisfy specified \a type.
1241 // 
1242 // \param type type of the object(s) to be obtained from selection
1243 // \param count number of items to be retrieved from selection
1244 // \param strict selection policy
1245 // \return list of selected geometrical objects or empty list if selection is not satisfactory
1246 //================================================================
1247 QList<GEOM::GeomObjPtr> GEOMBase_Helper::getSelected( TopAbs_ShapeEnum type, int count, bool strict )
1248 {
1249   QList<TopAbs_ShapeEnum> types;
1250   types << type;
1251   return getSelected( types, count, strict );
1252 }
1253
1254 static bool typeInList( TopAbs_ShapeEnum type, const QList<TopAbs_ShapeEnum>& types )
1255 {
1256   bool ok = false;
1257   for ( int i = 0; i < types.count() && !ok; i++ )
1258     ok = types[i] == TopAbs_SHAPE || types[i] == type;
1259   return ok;
1260 }
1261
1262 //================================================================
1263 // Function : getSelected
1264 // Purpose  : Get selected objects by specified types
1265 //
1266 // Returns list of selected objects if selection satisfies specifies selection options.
1267 // (no matter global or local selection is activated). If \a types includes TopAbs_SHAPE,
1268 // geometrical objects of any valid type are expected.
1269 //
1270 // The \a types parameter specifies allowed types of the object(s) being selected.
1271 // The \a count parameter specifies exact number of the objects to be retrieved from selection.
1272 // The \a strict parameter specifies policy being applied to the selection. 
1273 // If \a count < 0, then any number of the selected objects is valid (including 0).
1274 // In this case, if \a strict is \c true (default), all selected objects should satisfy
1275 // the specified \a type.
1276 // If \a count > 0, only specified number of the objects is retrieved from the selection.
1277 // In this case, if \a strict is \c true (default), function returns empty list if total number of selected
1278 // objects does not correspond to the \a count parameter. Otherwise (if \a strict is \c false),
1279 // function returns valid list of objects if at least \a count objects satisfy specified \a type.
1280 // 
1281 // \param types list of allowed shape types for the objects to be obtained from selection
1282 // \param count number of items to be retrieved from selection
1283 // \param strict selection policy
1284 // \return list of selected geometrical objects or empty list if selection is not satisfactory
1285 //================================================================
1286 QList<GEOM::GeomObjPtr> GEOMBase_Helper::getSelected( const QList<TopAbs_ShapeEnum>& types, int count, bool strict )
1287 {
1288   SUIT_Session* session = SUIT_Session::session();
1289   QList<GEOM::GeomObjPtr> result;
1290
1291   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
1292   if ( app ) {
1293     LightApp_SelectionMgr* selMgr = app->selectionMgr();
1294     if ( selMgr ) {
1295       SALOME_ListIO selected;
1296       selMgr->selectedObjects( selected );
1297       SALOME_ListIteratorOfListIO it( selected );
1298       bool stopped = false;
1299       for ( ; it.More() && !stopped; it.Next() ) {
1300         Handle(SALOME_InteractiveObject) IO = it.Value();
1301         GEOM::GeomObjPtr object = GEOMBase::ConvertIOinGEOMObject( IO );
1302         if ( object ) {
1303           TColStd_IndexedMapOfInteger subShapes;
1304           selMgr->GetIndexes( IO, subShapes );
1305           int nbSubShapes = subShapes.Extent();
1306           if ( nbSubShapes == 0 ) {
1307             // global selection
1308             if ( typeInList( (TopAbs_ShapeEnum)(object->GetShapeType()), types ) ) {
1309               result << object;
1310               if ( count > 0 ) {
1311                 if ( strict && result.count() > count ) {
1312                   result.clear();
1313                   stopped = true;
1314                 }
1315                 else if ( !strict && result.count() == count )
1316                   stopped = true;
1317               }
1318             }
1319             else if ( strict ) {
1320               result.clear();
1321               stopped = true;
1322             }
1323           }
1324           else {
1325             // local selection
1326             for ( int i = 1; i <= nbSubShapes && !stopped; i++ ) {
1327               int idx = subShapes( i );
1328               GEOM::GeomObjPtr subShape = findObjectInFather( object.get(), idx );
1329               if ( !subShape ) {
1330                 // sub-shape is not yet published in the study
1331                 GEOM::ShapesOpPtr shapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
1332                 subShape.take( shapesOp->GetSubShape( object.get(), idx ) ); // take ownership!
1333               }
1334               if ( typeInList( (TopAbs_ShapeEnum)(subShape->GetShapeType()), types ) ) {
1335                 result << subShape;
1336                 if ( count > 0 ) {
1337                   if ( strict && result.count() > count ) {
1338                     result.clear();
1339                     stopped = true;
1340                   }
1341                   else if ( !strict && result.count() == count )
1342                     stopped = true;
1343                 }
1344               }
1345               else if ( strict ) {
1346                 result.clear();
1347                 stopped = true;
1348               }
1349             }
1350           }
1351         }
1352       }
1353     }
1354   }
1355   return result;
1356 }
1357
1358 //================================================================
1359 // Function : setIsApplyAndClose
1360 // Purpose  : Set value of the flag indicating that the dialog is
1361 //            accepted by Apply & Close button
1362 //================================================================
1363 void GEOMBase_Helper::setIsApplyAndClose( const bool theFlag )
1364 {
1365   myIsApplyAndClose = theFlag;
1366 }
1367
1368 //================================================================
1369 // Function : isApplyAndClose
1370 // Purpose  : Get value of the flag indicating that the dialog is
1371 //            accepted by Apply & Close button
1372 //================================================================
1373 bool GEOMBase_Helper::isApplyAndClose() const
1374 {
1375   return myIsApplyAndClose;
1376 }
1377
1378 //================================================================
1379 // Function : setIsOptimizedBrowsing
1380 // Purpose  : Set value of the flag switching to optimized
1381 //            browsing mode (to select the first published
1382 //            object only)
1383 //================================================================
1384 void GEOMBase_Helper::setIsOptimizedBrowsing( const bool theFlag )
1385 {
1386   myIsOptimizedBrowsing = theFlag;
1387 }
1388
1389 //================================================================
1390 // Function : isOptimizedBrowsing
1391 // Purpose  : Get value of the flag switching to optimized
1392 //            browsing mode (to select the first published
1393 //            object only)
1394 //================================================================
1395 bool GEOMBase_Helper::isOptimizedBrowsing() const
1396 {
1397   return myIsOptimizedBrowsing;
1398 }