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