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