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