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