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