Salome HOME
PAL13091: dump study echec. Correctly remove all sub-objects on removal of main object.
[modules/geom.git] / src / GEOMToolsGUI / GEOMToolsGUI.cxx
1 //  GEOM GEOMGUI : GUI for Geometry component
2 //
3 //  Copyright (C) 2003  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_Tools.cxx
25 //  Author : Damien COQUERET
26 //  Module : GEOM
27 //  $Header$
28
29 #include "GEOMToolsGUI.h"
30
31 #include "GeometryGUI.h"
32 #include "GEOM_Actor.h"
33 #include "GEOMBase.h"
34 #include "GEOM_Operation.h"
35 #include "GEOM_Displayer.h"
36
37 #include <SUIT_Session.h>
38 #include <SUIT_Application.h>
39 #include <SUIT_OverrideCursor.h>
40 #include <SUIT_MessageBox.h>
41 #include <SUIT_Tools.h>
42 #include <SUIT_FileDlg.h>
43 #include <SUIT_Desktop.h>
44 #include <SUIT_ViewModel.h>
45
46 #include <SalomeApp_Application.h>
47 #include <SalomeApp_Study.h>
48 #include <LightApp_SelectionMgr.h>
49
50 #include <SALOME_ListIteratorOfListIO.hxx>
51 #include <SALOME_Prs.h>
52
53 #include "utilities.h"
54
55 // QT Includes
56 #include <qapplication.h>
57 #include <qmap.h>
58
59 // OCCT Includes
60 #include <TCollection_AsciiString.hxx>
61
62 using namespace std;
63
64 typedef QMap<QString, QString> FilterMap;
65
66 //=======================================================================
67 // function : getFileName
68 // purpose  : Selection of a file name for Import/Export. Returns also
69 //            the selected file type code through <filter> argument.
70 //=======================================================================
71 static QString getFileName( QWidget*           parent,
72                             const QString&     initial,
73                             const FilterMap&   filterMap,
74                             const QString&     caption,
75                             bool               open,
76                             QString&           format )
77 {
78   static QString lastUsedFilter;
79   QStringList filters;
80   for ( FilterMap::const_iterator it = filterMap.begin(); it != filterMap.end(); ++it )
81     filters.push_back( it.key() );
82
83   SUIT_FileDlg* fd = new SUIT_FileDlg( parent, open, true, true );
84   if ( !caption.isEmpty() )
85     fd->setCaption( caption );
86
87   if ( !initial.isEmpty() )
88     fd->setSelection( initial );
89
90   if ( !lastUsedFilter.isEmpty() && filterMap.contains( lastUsedFilter ) )
91     fd->setSelectedFilter( lastUsedFilter );
92
93   fd->setFilters( filters );
94
95   fd->exec();
96   QString filename = fd->selectedFile();
97   format = filterMap[fd->selectedFilter()];
98   lastUsedFilter = fd->selectedFilter();
99   delete fd;
100   qApp->processEvents();
101   return filename;
102 }
103
104 //=======================================================================
105 // function : GEOMToolsGUI()
106 // purpose  : Constructor
107 //=======================================================================
108 GEOMToolsGUI::GEOMToolsGUI( GeometryGUI* parent )
109 : GEOMGUI( parent )
110 {
111 }
112
113
114 //=======================================================================
115 // function : ~GEOMToolsGUI()
116 // purpose  : Destructor
117 //=======================================================================
118 GEOMToolsGUI::~GEOMToolsGUI()
119 {
120 }
121
122
123 //=======================================================================
124 // function : OnGUIEvent()
125 // purpose  :
126 //=======================================================================
127 bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent)
128 {
129   getGeometryGUI()->EmitSignalDeactivateDialog();
130
131   switch (theCommandID)
132     {
133     case 31: // COPY
134       {
135         OnEditCopy();
136         break;
137       }
138     case 33: // DELETE
139       {
140         OnEditDelete();
141         break;
142       }
143     case 111: // IMPORT BREP
144     case 112: // IMPORT IGES
145     case 113: // IMPORT STEP
146       {
147         Import();
148         break;
149       }
150     case 121: // EXPORT BREP
151     case 122: // EXPORT IGES
152     case 123: // EXPORT STEP
153       {
154         Export();
155         break;
156       }
157     case 411: // SETTINGS - ADD IN STUDY
158       {
159         // SAN -- TO BE REMOVED !!!
160         break;
161       }
162     case 412: // SETTINGS - SHADING COLOR
163       {
164         OnSettingsColor();
165         break;
166       }
167     case 413: // SETTINGS - ISOS
168       {
169         OnSettingsIsos();
170         break;
171       }
172     case 414: // SETTINGS : STEP VALUE FOR SPIN BOXES
173       {
174         OnSettingsStep();
175         break;
176       }
177     case 804: // ADD IN STUDY - POPUP VIEWER
178       {
179         // SAN -- TO BE REMOVED !!!!
180         break;
181       }
182     case 901: // RENAME
183       {
184         OnRename();
185         break;
186       }
187     case 5103: // CHECK GEOMETRY
188       {
189         OnCheckGeometry();
190         break;
191       }
192     case 8032: // COLOR - POPUP VIEWER
193       {
194         OnColor();
195         break;
196       }
197     case 8033: // TRANSPARENCY - POPUP VIEWER
198       {
199         OnTransparency();
200         break;
201       }
202     case 8034: // ISOS - POPUP VIEWER
203       {
204         OnNbIsos();
205         break;
206       }
207     case 9024 : // OPEN - OBJBROSER POPUP
208       {
209         OnOpen();
210         break;
211       }
212     default:
213       {
214         SUIT_Session::session()->activeApplication()->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID));
215         break;
216       }
217     }
218   return true;
219 }
220
221
222
223 //===============================================================================
224 // function : OnEditDelete()
225 // purpose  :
226 //===============================================================================
227 void GEOMToolsGUI::OnEditDelete()
228 {
229   SALOME_ListIO selected;
230   SalomeApp_Application* app =
231     dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
232   if ( app ) {
233     LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
234     SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
235     if ( aSelMgr && appStudy ) {
236       aSelMgr->selectedObjects( selected, QString::null, false );
237       if ( !selected.IsEmpty() ) {
238         _PTR(Study) aStudy = appStudy->studyDS();
239
240         bool aLocked = (_PTR(AttributeStudyProperties)(aStudy->GetProperties()))->IsLocked();
241         if ( aLocked ) {
242           SUIT_MessageBox::warn1 ( app->desktop(),
243                                    QObject::tr("WRN_WARNING"),
244                                    QObject::tr("WRN_STUDY_LOCKED"),
245                                    QObject::tr("BUT_OK") );
246           return;
247         }
248
249         // VSR 17/11/04: check if all objects selected belong to GEOM component --> start
250         // modifications of ASV 01.06.05
251         QString parentComp = getParentComponent( aStudy, selected );
252         const char* geomIOR = app->orb()->object_to_string( GeometryGUI::GetGeomGen() );
253         QString geomComp = getParentComponent( aStudy->FindObjectIOR( geomIOR ) );
254
255         if ( parentComp != geomComp )  {
256           SUIT_MessageBox::warn1 ( app->desktop(),
257                                   QObject::tr("ERR_ERROR"),
258                                   QObject::tr("NON_GEOM_OBJECTS_SELECTED").arg( getGeometryGUI()->moduleName() ),
259                                   QObject::tr("BUT_OK") );
260           return;
261         }
262         // VSR 17/11/04: check if all objects selected belong to GEOM component <-- finish
263
264         if ( SUIT_MessageBox::warn2( app->desktop(),
265                                      QObject::tr( "GEOM_WRN_WARNING" ),
266                                      QObject::tr( "GEOM_REALLY_DELETE" ),
267                                      QObject::tr( "GEOM_BUT_YES" ),
268                                      QObject::tr( "GEOM_BUT_NO" ), 1, 0, 0 ) != 1 )
269           return;
270
271         //      QAD_Operation* op = new SALOMEGUI_ImportOperation(.....);
272         //      op->start();
273
274         // prepare list of SALOME_Views
275         QPtrList<SALOME_View> views;
276         SALOME_View* view;
277         // fill the list
278         ViewManagerList vmans = app->viewManagers();
279         SUIT_ViewManager* vman;
280         for ( vman = vmans.first(); vman; vman = vmans.next() ) {
281           SUIT_ViewModel* vmod = vman->getViewModel();
282           view = dynamic_cast<SALOME_View*> ( vmod ); // must work for OCC and VTK views
283           if ( view )
284             views.append( view );
285         }
286
287         _PTR(StudyBuilder) aStudyBuilder (aStudy->NewBuilder());
288         _PTR(GenericAttribute) anAttr;
289         GEOM_Displayer* disp = new GEOM_Displayer( appStudy );
290
291         // MAIN LOOP OF SELECTED OBJECTS
292         for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
293
294           Handle(SALOME_InteractiveObject) io = It.Value();
295           if ( !io->hasEntry() )
296             continue;
297
298           _PTR(SObject) obj ( aStudy->FindObjectID( io->getEntry() ) );
299
300           // disable removal of "Geometry" component object
301           if ( !strcmp( obj->GetIOR().c_str(), geomIOR ) )
302             continue;
303
304           RemoveObjectWithChildren(obj, aStudy, views, disp);
305
306           // Remove objects from Study
307           aStudyBuilder->RemoveObject( obj );
308
309           //deleted = true;
310         } // MAIN LOOP of selected
311
312         selected.Clear();
313         aSelMgr->setSelectedObjects( selected );
314         getGeometryGUI()->updateObjBrowser();
315       } // if ( selected not empty )
316     } // if ( selMgr && appStudy )
317
318     app->updateActions(); //SRN: To update a Save button in the toolbar
319
320   } // if ( app )
321
322
323   //  if ( deleted )
324   //    op->finish();
325   //  else
326   //    op->abort();
327 }
328
329
330 //==============================================================================
331 // function : OnEditCopy()
332 // purpose  :
333 //==============================================================================
334 void GEOMToolsGUI::OnEditCopy()
335 {
336 /*
337  SALOME_Selection* Sel = SALOME_Selection::Selection(QAD_Application::getDesktop()->getActiveStudy()->getSelection() );
338   GEOM::string_array_var listIOR = new GEOM::string_array;
339
340   const SALOME_ListIO& List = Sel->StoredIObjects();
341
342   myGeomBase->ConvertListOfIOInListOfIOR(List, listIOR);
343
344   Sel->ClearIObjects();
345
346   SALOMEDS::Study_var aStudy = QAD_Application::getDesktop()->getActiveStudy()->getStudyDocument();
347   int aStudyID = aStudy->StudyId();
348
349   for (unsigned int ind = 0; ind < listIOR->length();ind++) {
350     GEOM::GEOM_Object_var aShapeInit = myGeom->GetIORFromString(listIOR[ind]);
351     try {
352       GEOM::GEOM_IInsertOperations_var IOp =  myGeom->GetIInsertOperations(aStudyID);
353       GEOM::GEOM_Object_var result = IOp->MakeCopy(aShapeInit);
354       myGeomBase->Display(result);
355     }
356     catch  (const SALOME::SALOME_Exception& S_ex) {
357       QtCatchCorbaException(S_ex);
358     }
359   }
360
361   QAD_Application::getDesktop()->putInfo(tr("GEOM_PRP_READY"));
362 */
363 }
364
365
366 //=====================================================================================
367 // function : Import
368 // purpose  : BRep, Iges, Step
369 //=====================================================================================
370 bool GEOMToolsGUI::Import()
371 {
372   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( getGeometryGUI()->getApp() );
373   //SUIT_Application* app = getGeometryGUI()->getApp();
374   if (! app) return false;
375
376   SalomeApp_Study* stud = dynamic_cast<SalomeApp_Study*> ( app->activeStudy() );
377   if ( !stud ) {
378     cout << "FAILED to cast active study to SalomeApp_Study" << endl;
379     return false;
380   }
381   _PTR(Study) aStudy = stud->studyDS();
382
383   bool aLocked = (_PTR(AttributeStudyProperties)(aStudy->GetProperties()))->IsLocked();
384   if ( aLocked ) {
385     SUIT_MessageBox::warn1 ( app->desktop(),
386                             QObject::tr("WRN_WARNING"),
387                             QObject::tr("WRN_STUDY_LOCKED"),
388                             QObject::tr("BUT_OK") );
389     return false;
390   }
391
392   GEOM::GEOM_Gen_var eng = GeometryGUI::GetGeomGen();
393   if ( CORBA::is_nil( eng ) ) {
394     SUIT_MessageBox::error1( app->desktop(),
395                             QObject::tr("WRN_WARNING"),
396                             QObject::tr( "GEOM Engine is not started" ),
397                             QObject::tr("BUT_OK") );
398       return false;
399     }
400
401   GEOM::GEOM_IInsertOperations_var aInsOp = eng->GetIInsertOperations( aStudy->StudyId() );
402   if ( aInsOp->_is_nil() )
403     return false;
404
405   GEOM::GEOM_Object_var anObj;
406
407   // Obtain a list of available import formats
408   FilterMap aMap;
409   GEOM::string_array_var aFormats, aPatterns;
410   aInsOp->ImportTranslators( aFormats, aPatterns );
411
412   for ( int i = 0, n = aFormats->length(); i < n; i++ )
413     aMap.insert( (char*)aPatterns[i], (char*)aFormats[i] );
414
415   QString fileType;
416
417   QString fileName = getFileName(app->desktop(), "", aMap,
418                                  tr("GEOM_MEN_IMPORT"), true, fileType);
419
420   if (fileType.isEmpty() )
421     {
422       // Trying to detect file type
423       QFileInfo aFileInfo( fileName );
424       QString aPossibleType = (aFileInfo.extension(false)).upper() ;
425
426       if ( (aMap.values()).contains(aPossibleType) )
427         fileType = aPossibleType;
428     }
429
430   if (fileName.isEmpty() || fileType.isEmpty())
431     return false;
432
433   GEOM_Operation* anOp = new GEOM_Operation (app, aInsOp.in());
434   try {
435     SUIT_OverrideCursor wc;
436
437     app->putInfo(tr("GEOM_PRP_LOADING").arg(SUIT_Tools::file(fileName, /*withExten=*/true)));
438
439     anOp->start();
440
441     CORBA::String_var fileN = fileName.latin1();
442     CORBA::String_var fileT = fileType.latin1();
443     anObj = aInsOp->Import(fileN, fileT);
444
445     if ( !anObj->_is_nil() && aInsOp->IsDone() ) {
446       anObj->SetName(GEOMBase::GetDefaultName(QObject::tr("GEOM_IMPORT")).latin1());
447       QString aPublishObjName =
448         GEOMBase::GetDefaultName(SUIT_Tools::file(fileName, /*withExten=*/true));
449
450       SALOMEDS::Study_var aDSStudy = GeometryGUI::ClientStudyToStudy(aStudy);
451       GeometryGUI::GetGeomGen()->PublishInStudy(aDSStudy,
452                                                 SALOMEDS::SObject::_nil(),
453                                                 anObj,
454                                                 aPublishObjName);
455
456       GEOM_Displayer( stud ).Display( anObj.in() );
457
458       // update data model and object browser
459       getGeometryGUI()->updateObjBrowser( true );
460
461       anOp->commit();
462     }
463     else {
464       anOp->abort();
465       wc.suspend();
466       SUIT_MessageBox::error1( app->desktop(),
467                               QObject::tr( "GEOM_ERROR" ),
468                               QObject::tr("GEOM_PRP_ABORT") + "\n" + QString( aInsOp->GetErrorCode() ),
469                               QObject::tr("BUT_OK") );
470     }
471   }
472   catch( const SALOME::SALOME_Exception& S_ex ) {
473     //QtCatchCorbaException(S_ex);
474     anOp->abort();
475     return false;
476   }
477
478   app->updateActions(); //SRN: To update a Save button in the toolbar
479
480   return true;
481 }
482
483
484 //=====================================================================================
485 // function : Export
486 // purpose  : BRep, Iges, Step
487 //=====================================================================================
488 bool GEOMToolsGUI::Export()
489 {
490   SalomeApp_Application* app = getGeometryGUI()->getApp();
491   if (!app) return false;
492
493   SalomeApp_Study* stud = dynamic_cast<SalomeApp_Study*> ( app->activeStudy() );
494   if ( !stud ) {
495     cout << "FAILED to cast active study to SalomeApp_Study" << endl;
496     return false;
497   }
498   _PTR(Study) aStudy = stud->studyDS();
499
500   GEOM::GEOM_Gen_var eng = GeometryGUI::GetGeomGen();
501   if ( CORBA::is_nil( eng ) ) {
502     SUIT_MessageBox::error1( app->desktop(),
503                              QObject::tr("WRN_WARNING"),
504                              QObject::tr( "GEOM Engine is not started" ),
505                              QObject::tr("BUT_OK") );
506     return false;
507   }
508
509   GEOM::GEOM_IInsertOperations_var aInsOp = eng->GetIInsertOperations( aStudy->StudyId() );
510   if ( aInsOp->_is_nil() )
511     return false;
512
513   // Obtain a list of available export formats
514   FilterMap aMap;
515   GEOM::string_array_var aFormats, aPatterns;
516   aInsOp->ExportTranslators( aFormats, aPatterns );
517   for ( int i = 0, n = aFormats->length(); i < n; i++ )
518     aMap.insert( (char*)aPatterns[i], (char*)aFormats[i] );
519
520   // Get selected objects
521   LightApp_SelectionMgr* sm = app->selectionMgr();
522   if ( !sm )
523     return false;
524
525   SALOME_ListIO selectedObjects;
526   sm->selectedObjects( selectedObjects );
527
528   SALOME_ListIteratorOfListIO It( selectedObjects );
529   for(;It.More();It.Next()) {
530     Handle(SALOME_InteractiveObject) IObject = It.Value();
531     Standard_Boolean found;
532     GEOM::GEOM_Object_var anObj = GEOMBase::ConvertIOinGEOMObject(IObject, found);
533
534     if ( !found || anObj->_is_nil() )
535       continue;
536
537     QString fileType;
538     QString file = getFileName(app->desktop(), QString( IObject->getName() ), aMap,
539                                tr("GEOM_MEN_EXPORT"), false, fileType);
540
541     // User has pressed "Cancel" --> stop the operation
542     if ( file.isEmpty() || fileType.isEmpty() )
543       return false;
544
545     GEOM_Operation* anOp = new GEOM_Operation( app, aInsOp.in() );
546     try {
547       SUIT_OverrideCursor wc;
548
549       app->putInfo( tr("GEOM_PRP_EXPORT").arg(SUIT_Tools::file( file, /*withExten=*/true )) );
550
551       anOp->start();
552
553
554       aInsOp->Export( anObj, file, fileType.latin1() );
555
556       if ( aInsOp->IsDone() )
557         anOp->commit();
558       else
559         {
560           anOp->abort();
561           wc.suspend();
562           SUIT_MessageBox::error1( app->desktop(),
563                                    QObject::tr( "GEOM_ERROR" ),
564                                    QObject::tr("GEOM_PRP_ABORT") + "\n" + QString( aInsOp->GetErrorCode() ),
565                                    QObject::tr("BUT_OK") );
566           return false;
567         }
568     }
569     catch (const SALOME::SALOME_Exception& S_ex) {
570       //QtCatchCorbaException(S_ex);
571       anOp->abort();
572       return false;
573     }
574   }
575
576   return true;
577 }
578
579
580 QString GEOMToolsGUI::getParentComponent( _PTR( Study ) study, const SALOME_ListIO& iobjs )
581 {
582   QString parentComp;
583
584   for ( SALOME_ListIteratorOfListIO it( iobjs ); it.More(); it.Next() ) {
585
586     Handle(SALOME_InteractiveObject) io = it.Value();
587     if ( !io->hasEntry() )
588       continue;
589
590     QString compName = getParentComponent( study->FindObjectID( io->getEntry() ) );
591
592     if ( parentComp.isNull() )
593       parentComp = compName;
594     else if ( parentComp.compare( compName) != 0 ) { // objects belonging to different components are selected
595       parentComp = QString::null;
596       break;
597     }
598   }
599
600   return parentComp;
601 }
602
603 QString GEOMToolsGUI::getParentComponent( _PTR( SObject ) obj )
604 {
605   if ( obj ) {
606     _PTR(SComponent) comp = obj->GetFatherComponent();
607     if ( comp ) {
608       _PTR(GenericAttribute) anAttr;
609       if ( comp->FindAttribute( anAttr, "AttributeName") ) {
610         _PTR(AttributeName) aName( anAttr );
611         return QString( aName->Value().c_str() );
612       }
613     }
614   }
615   return QString();
616 }
617
618 //=====================================================================================
619 // function : RemoveObjectWithChildren
620 // purpose  : to be used by OnEditDelete() method
621 //=====================================================================================
622 void GEOMToolsGUI::RemoveObjectWithChildren(_PTR(SObject) obj,
623                                             _PTR(Study) aStudy,
624                                             QPtrList<SALOME_View> views,
625                                             GEOM_Displayer* disp)
626 {
627   // iterate through all children of obj
628   for (_PTR(ChildIterator) it (aStudy->NewChildIterator(obj)); it->More(); it->Next()) {
629     _PTR(SObject) child (it->Value());
630     RemoveObjectWithChildren(child, aStudy, views, disp);
631   }
632
633   // erase object and remove it from engine
634   _PTR(GenericAttribute) anAttr;
635   if (obj->FindAttribute(anAttr, "AttributeIOR")) {
636     _PTR(AttributeIOR) anIOR (anAttr);
637
638     // Delete shape in Client
639     const TCollection_AsciiString ASCIor ((char*)anIOR->Value().c_str());
640     getGeometryGUI()->GetShapeReader().RemoveShapeFromBuffer(ASCIor);
641
642     CORBA::Object_var corbaObj = GeometryGUI::ClientSObjectToObject(obj);
643     GEOM::GEOM_Object_var geomObj = GEOM::GEOM_Object::_narrow( corbaObj );
644     if (!CORBA::is_nil(geomObj)) {
645       // Erase graphical object
646       SALOME_View* view = views.first();
647       for (; view; view = views.next()) {
648         disp->Erase(geomObj, true, view);
649       }
650
651       // Remove object from Engine
652       GeometryGUI::GetGeomGen()->RemoveObject( geomObj );
653     }
654   }
655 }
656
657 //=====================================================================================
658 // EXPORTED METHODS
659 //=====================================================================================
660 extern "C"
661 {
662 #ifdef WNT
663         __declspec( dllexport )
664 #endif
665   GEOMGUI* GetLibGUI( GeometryGUI* parent )
666   {
667     return new GEOMToolsGUI( parent );
668   }
669 }