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