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