Salome HOME
ca6f6d3f2226b01c1f1004c8a00c20d192ae75ad
[modules/geom.git] / src / GEOMToolsGUI / GEOMToolsGUI.cxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : GEOMBase_Tools.cxx
25 // Author : Damien COQUERET, Open CASCADE S.A.S.
26
27 #include "GEOMToolsGUI.h"
28 #include "GEOMToolsGUI_DeleteDlg.h"
29
30 #include <GeometryGUI.h>
31 #include "GeometryGUI_Operations.h"
32 #include <GEOM_Operation.h>
33 #include <GEOM_Displayer.h>
34
35 #include <SUIT_Session.h>
36 #include <SUIT_OverrideCursor.h>
37 #include <SUIT_MessageBox.h>
38 #include <SUIT_Tools.h>
39 #include <SUIT_FileDlg.h>
40 #include <SUIT_Desktop.h>
41 #include <SUIT_ViewModel.h>
42 #include <SUIT_ViewManager.h>
43
44 #include <SalomeApp_Application.h>
45 #include <SalomeApp_Study.h>
46 #include <LightApp_SelectionMgr.h>
47 #include <GEOMImpl_Types.hxx>
48
49 #include <SALOME_ListIO.hxx>
50 #include <SALOME_ListIteratorOfListIO.hxx>
51 #include <SALOME_Prs.h>
52
53 // QT Includes
54 #include <QApplication>
55 #include <QMap>
56 #include <QRegExp>
57
58 // OCCT Includes
59 #include <TCollection_AsciiString.hxx>
60
61 typedef QMap<QString, QString> FilterMap;
62 static QString lastUsedFilter;
63
64 //=======================================================================
65 // function : getFileName
66 // purpose  : Selection of a file name for Import/Export. Returns also
67 //            the selected file type code through <filter> argument.
68 //=======================================================================
69 static QString getFileName( QWidget*           parent,
70                             const QString&     initial,
71                             const FilterMap&   filterMap,
72                             const QStringList& filters,
73                             const QString&     caption,
74                             bool               open,
75                             QString&           format,
76                             bool               showCurrentDirInitially = false )
77 {
78   //QStringList filters;
79   QString aBrepFilter;
80   for (FilterMap::const_iterator it = filterMap.begin(); it != filterMap.end(); ++it) {
81     //filters.push_back( it.key() );
82     if (it.key().contains( "BREP", Qt::CaseInsensitive ))
83       aBrepFilter = it.key();
84   }
85
86   SUIT_FileDlg* fd = new SUIT_FileDlg( parent, open, true, true );
87   if ( !caption.isEmpty() )
88     fd->setWindowTitle( caption );
89
90   if ( !initial.isEmpty() )
91     fd->selectFile( initial );
92
93   if ( showCurrentDirInitially && SUIT_FileDlg::getLastVisitedPath().isEmpty() )
94     fd->setDirectory( QDir::currentPath() );
95
96   fd->setFilters( filters );
97
98   if ( !lastUsedFilter.isEmpty() && filterMap.contains( lastUsedFilter ) ) {
99     fd->selectFilter( lastUsedFilter );
100   }
101   else if ( !aBrepFilter.isEmpty() ) {
102     fd->selectFilter( aBrepFilter );
103   }
104
105   QString filename;
106   if ( fd->exec() == QDialog::Accepted ) {
107     filename = fd->selectedFile();
108     format = filterMap[fd->selectedFilter()];
109     lastUsedFilter = fd->selectedFilter();
110   }
111
112   delete fd;
113   qApp->processEvents();
114   return filename;
115 }
116
117 //=======================================================================
118 // function : getFileNames
119 // purpose  : Select list of files for Import operation. Returns also
120 //            the selected file type code through <format> argument.
121 //=======================================================================
122 static QStringList getFileNames( QWidget*           parent,
123                                  const QString&     initial,
124                                  const FilterMap&   filterMap,
125                                  const QString&     caption,
126                                  QString&           format,
127                                  bool               showCurrentDirInitially = false)
128 {
129   QString aBrepFilter;
130   QStringList allFilters;
131   QStringList filters;
132   QRegExp re( "\\((.*)\\)" );
133   re.setMinimal( true );
134   for ( FilterMap::const_iterator it = filterMap.begin(); it != filterMap.end(); ++it ) {
135     if ( it.value().contains( "BREP", Qt::CaseInsensitive ) && aBrepFilter.isEmpty() )
136       aBrepFilter = it.key();
137     filters.append( it.key() );
138     int pos = 0;
139     while ( re.indexIn( it.key(), pos ) >= 0 ) {
140       QString f = re.cap(1);
141       pos = re.pos() + f.length() + 2;
142       allFilters.append( f.simplified() );
143     }
144   }
145   filters.append( QObject::tr( "GEOM_ALL_IMPORT_FILES" ).arg( allFilters.join( " " ) ) );
146
147   SUIT_FileDlg fd( parent, true, true, true );
148   fd.setFileMode( SUIT_FileDlg::ExistingFiles );
149   if ( !caption.isEmpty() )
150     fd.setWindowTitle( caption );
151   if ( !initial.isEmpty() )
152     fd.selectFile( initial );
153
154   if ( showCurrentDirInitially && SUIT_FileDlg::getLastVisitedPath().isEmpty() )
155     fd.setDirectory( QDir::currentPath() );
156
157   fd.setFilters( filters );
158
159   if ( !lastUsedFilter.isEmpty() && filterMap.contains( lastUsedFilter ) )
160     fd.selectFilter( lastUsedFilter );
161   else if ( !aBrepFilter.isEmpty() )
162     fd.selectFilter( aBrepFilter );
163
164   QStringList filenames;
165   if ( fd.exec() ) {
166     filenames = fd.selectedFiles();
167     format = filterMap.contains( fd.selectedFilter() ) ? filterMap[ fd.selectedFilter() ] : QString();
168     lastUsedFilter = fd.selectedFilter();
169   }
170   qApp->processEvents();
171   return filenames;
172 }
173
174 //=======================================================================
175 // function : getParentComponent
176 // purpose  : Get object's parent component entry
177 //=======================================================================
178 static QString getParentComponent( _PTR( SObject ) obj )
179 {
180   if ( obj ) {
181     _PTR(SComponent) comp = obj->GetFatherComponent();
182     if ( comp )
183       return QString( comp->GetID().c_str() );
184   }
185   return QString();
186 }
187
188 //=====================================================================================
189 // function : inUse
190 // purpose  : check if the object(s) passed as the the second arguments are used
191 //            by the other objects in the study
192 //=====================================================================================
193 static bool inUse( _PTR(Study) study, const QString& component, const QMap<QString,QString>& objects )
194 {
195   _PTR(SObject) comp = study->FindObjectID( component.toLatin1().data() );
196   if ( !comp )
197     return false;
198
199   // collect all GEOM objects being deleted
200   QMap<QString, GEOM::GEOM_BaseObject_var> gobjects;
201   QMap<QString, QString>::ConstIterator oit;
202   std::list<_PTR(SObject)> aSelectedSO;
203   for ( oit = objects.begin(); oit != objects.end(); ++oit ) {
204     _PTR(SObject) so = study->FindObjectID( oit.key().toLatin1().data() );
205     if ( !so )
206       continue;
207     aSelectedSO.push_back(so);
208     CORBA::Object_var corbaObj_rem = GeometryGUI::ClientSObjectToObject( so );
209     GEOM::GEOM_BaseObject_var geomObj_rem = GEOM::GEOM_BaseObject::_narrow( corbaObj_rem );
210     if( CORBA::is_nil( geomObj_rem ) )
211       continue;
212     gobjects.insert( oit.key(), geomObj_rem );
213   }
214
215   // Search References with other Modules
216   std::list< _PTR(SObject) >::iterator itSO = aSelectedSO.begin();
217   for ( ; itSO != aSelectedSO.end(); ++itSO ) {
218     std::vector<_PTR(SObject)> aReferences = study->FindDependances( *itSO  );
219     int aRefLength = aReferences.size();
220     if (aRefLength) {
221       for (int i = 0; i < aRefLength; i++) {
222         _PTR(SObject) firstSO( aReferences[i] );
223         _PTR(SComponent) aComponent = firstSO->GetFatherComponent();
224         QString type = aComponent->ComponentDataType().c_str();
225         if ( type == "SMESH" )
226           return true;
227       }
228     }
229   }
230
231   // browse through all GEOM data tree
232   _PTR(ChildIterator) it ( study->NewChildIterator( comp ) );
233   for ( it->InitEx( true ); it->More(); it->Next() ) {
234     _PTR(SObject) child( it->Value() );
235     CORBA::Object_var corbaObj = GeometryGUI::ClientSObjectToObject( child );
236     GEOM::GEOM_Object_var geomObj = GEOM::GEOM_Object::_narrow( corbaObj );
237     if( CORBA::is_nil( geomObj ) )
238       continue;
239
240     GEOM::ListOfGBO_var list = geomObj->GetDependency();
241     if( list->length() == 0 )
242       continue;
243
244     for( int i = 0; i < list->length(); i++ ) {
245       bool depends = false;
246       bool deleted = false;
247       QMap<QString, GEOM::GEOM_BaseObject_var>::Iterator git;
248       for ( git = gobjects.begin(); git != gobjects.end() && ( !depends || !deleted ); ++git ) {
249         depends = depends || list[i]->_is_equivalent( *git );
250         deleted = deleted || git.key() == child->GetID().c_str() ;//geomObj->_is_equivalent( *git );
251       }
252       if ( depends && !deleted )
253         return true;
254     }
255   }
256   return false;
257 }
258
259 //=======================================================================
260 // function : getGeomChildrenAndFolders
261 // purpose  : Get direct (1-level) GEOM objects under each folder, sub-folder, etc. and these folders itself
262 //=======================================================================
263 static void getGeomChildrenAndFolders( _PTR(SObject) theSO, 
264                                        QMap<QString,QString>& geomObjList, 
265                                        QMap<QString,QString>& folderList ) {
266   if ( !theSO ) return;
267   _PTR(Study) aStudy = theSO->GetStudy();
268   if ( !aStudy ) return;
269   _PTR(UseCaseBuilder) aUseCaseBuilder = aStudy->GetUseCaseBuilder();
270
271   bool isFolder = false;
272   _PTR(GenericAttribute) anAttr;
273   if ( theSO->FindAttribute(anAttr, "AttributeLocalID") ) {
274     _PTR(AttributeLocalID) aLocalID( anAttr );
275     isFolder = aLocalID->Value() == 999;
276   }
277   QString anEntry = theSO->GetID().c_str();
278   QString aName = theSO->GetName().c_str();
279   if ( isFolder ) {
280     folderList.insert( anEntry, aName );
281     _PTR(UseCaseIterator) ucit ( aUseCaseBuilder->GetUseCaseIterator( theSO ) );
282     for ( ucit->Init( false ); ucit->More(); ucit->Next() ) {
283       getGeomChildrenAndFolders( ucit->Value(), geomObjList, folderList );
284     }
285   } else {
286     geomObjList.insert( anEntry, aName );
287   }
288 }
289
290 //=======================================================================
291 // function : GEOMToolsGUI()
292 // purpose  : Constructor
293 //=======================================================================
294 GEOMToolsGUI::GEOMToolsGUI( GeometryGUI* parent )
295 : GEOMGUI( parent )
296 {
297 }
298
299 //=======================================================================
300 // function : ~GEOMToolsGUI()
301 // purpose  : Destructor
302 //=======================================================================
303 GEOMToolsGUI::~GEOMToolsGUI()
304 {
305 }
306
307 //=======================================================================
308 // function : OnGUIEvent()
309 // purpose  :
310 //=======================================================================
311 bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent)
312 {
313   getGeometryGUI()->EmitSignalDeactivateDialog();
314
315   switch ( theCommandID ) {
316   case GEOMOp::OpDelete:         // EDIT - DELETE
317     OnEditDelete();
318     break;
319   case GEOMOp::OpImport:         // FILE - IMPORT
320     Import();
321     break;
322   case GEOMOp::OpExport:         // FILE - EXPORT
323     Export();
324     break;
325   case GEOMOp::OpCheckGeom:      // TOOLS - CHECK GEOMETRY
326     OnCheckGeometry();
327     break;
328   case GEOMOp::OpSelectVertex:   // POPUP - SELECT ONLY - VERTEX
329     OnSelectOnly( GEOM_POINT );
330     break;
331   case GEOMOp::OpSelectEdge:     // POPUP - SELECT ONLY - EDGE
332     OnSelectOnly( GEOM_EDGE );
333     break;
334   case GEOMOp::OpSelectWire:     // POPUP - SELECT ONLY - WIRE
335     OnSelectOnly( GEOM_WIRE );
336     break;
337   case GEOMOp::OpSelectFace:     // POPUP - SELECT ONLY - FACE
338     OnSelectOnly( GEOM_FACE );
339     break;
340   case GEOMOp::OpSelectShell:    // POPUP - SELECT ONLY - SHELL
341     OnSelectOnly( GEOM_SHELL );
342     break;
343   case GEOMOp::OpSelectSolid:    // POPUP - SELECT ONLY - SOLID
344     OnSelectOnly( GEOM_SOLID );
345     break;
346   case GEOMOp::OpSelectCompound: // POPUP - SELECT ONLY - COMPOUND
347     OnSelectOnly( GEOM_COMPOUND );
348     break;
349   case GEOMOp::OpSelectAll:      // POPUP - SELECT ONLY - SELECT ALL
350     OnSelectOnly( GEOM_ALLOBJECTS );
351     break;
352   case GEOMOp::OpDeflection:     // POPUP - DEFLECTION ANGLE
353     OnDeflection();
354     break;
355   case GEOMOp::OpColor:          // POPUP - COLOR
356     OnColor();
357     break;
358   case GEOMOp::OpSetTexture:     // POPUP - TEXTURE
359     OnTexture();
360     break;
361   case GEOMOp::OpTransparency:   // POPUP - TRANSPARENCY
362     OnTransparency();
363     break;
364   case GEOMOp::OpIncrTransparency: // SHORTCUT   - INCREASE TRANSPARENCY
365     OnChangeTransparency( true );
366     break;
367   case GEOMOp::OpDecrTransparency: // SHORTCUT   - DECREASE TRANSPARENCY
368     OnChangeTransparency( false );
369     break;
370   case GEOMOp::OpIsos:           // POPUP - ISOS
371     OnNbIsos();
372     break;
373   case GEOMOp::OpIncrNbIsos:     // SHORTCUT   - INCREASE NB ISOLINES
374     OnNbIsos( INCR );
375     break;
376   case GEOMOp::OpDecrNbIsos:     // SHORTCUT   - DECREASE NB ISOLINES
377     OnNbIsos( DECR );
378     break;
379   case GEOMOp::OpMaterialProperties: // POPUP - MATERIAL PROPERTIES
380     OnMaterialProperties();
381     break;
382   case GEOMOp::OpPredefMaterCustom:  // POPUP  - MATERIAL PROPERTIES - CUSTOM...
383     OnMaterialProperties();
384     break;
385   case GEOMOp::OpMaterialsLibrary:    // POPUP MENU - MATERIAL PROPERTIES
386     OnMaterialsLibrary();
387     break;
388   case GEOMOp::OpAutoColor:      // POPUP - AUTO COLOR
389     OnAutoColor();
390     break;
391   case GEOMOp::OpNoAutoColor:    // POPUP - DISABLE AUTO COLOR
392     OnDisableAutoColor();
393     break;
394   case GEOMOp::OpDiscloseChildren:   // POPUP - SHOW CHILDREN
395   case GEOMOp::OpConcealChildren:   // POPUP - HIDE CHILDREN
396     OnDiscloseConcealChildren( theCommandID == GEOMOp::OpDiscloseChildren );
397     break;
398   case GEOMOp::OpPointMarker:    // POPUP - POINT MARKER
399     OnPointMarker();
400     break;
401   case GEOMOp::OpUnpublishObject:// POPUP - UNPUBLISH
402     OnUnpublishObject();
403     break;
404   case GEOMOp::OpPublishObject:// GEOM ROOT OBJECT - POPUP - PUBLISH
405     OnPublishObject();
406     break;
407   case GEOMOp::OpEdgeWidth:
408     OnEdgeWidth();
409     break;
410   case GEOMOp::OpIsosWidth:
411     OnIsosWidth();
412     break;
413   case GEOMOp::OpBringToFront:
414     OnBringToFront();
415     break;
416   case GEOMOp::OpClsBringToFront:
417     OnClsBringToFront();
418      break;
419   case GEOMOp::OpCreateFolder:
420     OnCreateFolder();
421      break;
422   case GEOMOp::OpSortChildren:
423     OnSortChildren();
424      break;
425   default:
426     SUIT_Session::session()->activeApplication()->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID));
427     break;
428   }
429   return true;
430 }
431
432 //=======================================================================
433 // function : OnGUIEvent()
434 // purpose  :
435 //=======================================================================
436 bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent, const QVariant& theParam )
437 {
438   getGeometryGUI()->EmitSignalDeactivateDialog();
439
440   switch ( theCommandID ) {
441   case GEOMOp::OpPredefMaterial:         // POPUP MENU - MATERIAL PROPERTIES - <SOME MATERIAL>
442     OnSetMaterial( theParam );
443     break;
444   default:
445     SUIT_Session::session()->activeApplication()->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID));
446     break;
447   }
448   return true;
449 }
450
451 //===============================================================================
452 // function : OnEditDelete()
453 // purpose  :
454 //===============================================================================
455 void GEOMToolsGUI::OnEditDelete()
456 {
457   SALOME_ListIO selected;
458   SalomeApp_Application* app =
459     dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
460   if ( !app )
461     return;
462
463   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
464   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
465   if ( !aSelMgr || !appStudy )
466     return;
467
468   // get selection
469   aSelMgr->selectedObjects( selected, "ObjectBrowser", false );
470   if ( selected.IsEmpty() )
471     return;
472
473   _PTR(Study) aStudy = appStudy->studyDS();
474   _PTR(UseCaseBuilder) aUseCaseBuilder = aStudy->GetUseCaseBuilder();
475
476   // check if study is locked
477   if ( _PTR(AttributeStudyProperties)( aStudy->GetProperties() )->IsLocked() ) {
478     SUIT_MessageBox::warning( app->desktop(),
479                               tr("WRN_WARNING"),
480                               tr("WRN_STUDY_LOCKED") );
481     return; // study is locked
482   }
483
484   // get GEOM component
485   CORBA::String_var geomIOR = app->orb()->object_to_string( GeometryGUI::GetGeomGen() );
486   QString geomComp = getParentComponent( aStudy->FindObjectIOR( geomIOR.in() ) );
487
488   // check each selected object: if belongs to GEOM, if not reference...
489   QMap<QString,QString> toBeDeleted;
490   QMap<QString,QString> allDeleted;
491   QMap<QString,QString> toBeDelFolders;
492   bool isComponentSelected = false;
493
494   for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
495     Handle(SALOME_InteractiveObject) anIObject = It.Value();
496     if ( !anIObject->hasEntry() )
497       continue; // invalid object
498     // ...
499     QString entry = anIObject->getEntry();
500     _PTR(SObject) obj = aStudy->FindObjectID( entry.toLatin1().data() );
501     // check parent component
502     QString parentComp = getParentComponent( obj );
503     if ( parentComp != geomComp )  {
504       SUIT_MessageBox::warning( app->desktop(),
505                                 QObject::tr("ERR_ERROR"),
506                                 QObject::tr("NON_GEOM_OBJECTS_SELECTED").arg( getGeometryGUI()->moduleName() ) );
507       return; // not GEOM object selected
508     }
509
510     ///////////////////////////////////////////////////////
511     // if GEOM component is selected, so skip other checks
512     if ( isComponentSelected ) continue;
513     ///////////////////////////////////////////////////////
514
515     // check if object is reference
516     _PTR(SObject) refobj;
517     if ( obj && obj->ReferencedObject( refobj ) ) {
518       // get the main object by reference IPAL 21354
519       obj = refobj;
520       entry = obj->GetID().c_str();
521     }
522     // ...
523     QString aName = obj->GetName().c_str();
524     if ( entry == geomComp ) {
525       // GEOM component is selected, skip other checks
526       isComponentSelected = true;
527       continue;
528     }
529     // all sub-objects of folder have to be deleted
530     getGeomChildrenAndFolders( obj, toBeDeleted, toBeDelFolders );
531     allDeleted.insert( entry, aName ); // skip GEOM component
532     // browse through all children recursively
533     _PTR(UseCaseIterator) it ( aUseCaseBuilder->GetUseCaseIterator( obj ) );
534     for ( it->Init( true ); it->More(); it->Next() ) {
535       _PTR(SObject) child( it->Value() );
536       if ( child && child->ReferencedObject( refobj ) )
537         continue; // skip references
538       aName = child->GetName().c_str();
539       if ( !aName.isEmpty() )
540         allDeleted.insert( child->GetID().c_str(), aName );
541     }
542   }
543
544   // is there is anything to delete?
545   if ( !isComponentSelected && allDeleted.count() <= 0 )
546     return; // nothing to delete
547
548   // show confirmation dialog box
549   GEOMToolsGUI_DeleteDlg dlg( app->desktop(), allDeleted, isComponentSelected );
550   if ( !dlg.exec() )
551     return; // operation is cancelled by user
552
553   // get currently opened views
554   QList<SALOME_View*> views;
555   SALOME_View* view;
556   ViewManagerList vmans = app->viewManagers();
557   SUIT_ViewManager* vman;
558   foreach ( vman, vmans ) {
559     SUIT_ViewModel* vmod = vman->getViewModel();
560     view = dynamic_cast<SALOME_View*> ( vmod ); // must work for OCC and VTK views
561     if ( view )
562       views.append( view );
563   }
564
565   _PTR(StudyBuilder) aStudyBuilder (aStudy->NewBuilder());
566   GEOM_Displayer* disp = new GEOM_Displayer( appStudy );
567
568   if ( isComponentSelected ) {
569     // GEOM component is selected: delete all objects recursively
570     _PTR(SObject) comp = aStudy->FindObjectID( geomComp.toLatin1().data() );
571     if ( !comp )
572       return;
573     _PTR(ChildIterator) it ( aStudy->NewChildIterator( comp ) );
574     // remove top-level objects only
575     for ( it->InitEx( false ); it->More(); it->Next() ) {
576       _PTR(SObject) child( it->Value() );
577       // remove object from GEOM engine
578       removeObjectWithChildren( child, aStudy, views, disp );
579       // remove object from study
580       aStudyBuilder->RemoveObjectWithChildren( child );
581       // remove object from use case tree
582       aUseCaseBuilder->Remove( child );
583     }
584   }
585   else {
586     // GEOM component is not selected: check if selected objects are in use
587     if ( inUse( aStudy, geomComp, allDeleted ) && 
588          SUIT_MessageBox::question( app->desktop(),
589                                     QObject::tr("WRN_WARNING"),
590                                     QObject::tr("DEP_OBJECT"),
591                                     SUIT_MessageBox::Yes | SUIT_MessageBox::No,
592                                     SUIT_MessageBox::No ) != SUIT_MessageBox::Yes ) {
593       return; // object(s) in use
594     }
595     // ... and then delete all objects
596     QMap<QString, QString>::Iterator it;
597     for ( it = toBeDeleted.begin(); it != toBeDeleted.end(); ++it ) {
598       _PTR(SObject) obj ( aStudy->FindObjectID( it.key().toLatin1().data() ) );
599       // remove object from GEOM engine
600       removeObjectWithChildren( obj, aStudy, views, disp );
601       // remove objects from study
602       aStudyBuilder->RemoveObjectWithChildren( obj );
603       // remove object from use case tree
604       aUseCaseBuilder->Remove( obj );
605     }
606     // ... and then delete all folders
607     for ( it = toBeDelFolders.begin(); it != toBeDelFolders.end(); ++it ) {
608       _PTR(SObject) obj ( aStudy->FindObjectID( it.key().toLatin1().data() ) );
609       // remove object from GEOM engine
610       removeObjectWithChildren( obj, aStudy, views, disp );
611       // remove objects from study
612       aStudyBuilder->RemoveObjectWithChildren( obj );
613       // remove object from use case tree
614       aUseCaseBuilder->Remove( obj );
615     }
616   }
617
618   selected.Clear();
619   aSelMgr->setSelectedObjects( selected );
620   getGeometryGUI()->updateObjBrowser();
621   app->updateActions(); //SRN: To update a Save button in the toolbar
622 }
623
624 //=====================================================================================
625 // function : Import
626 // purpose  : BRep, Iges, Step, ...
627 //=====================================================================================
628 bool GEOMToolsGUI::Import()
629 {
630   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( getGeometryGUI()->getApp() );
631   if ( !app ) return false;
632
633   SalomeApp_Study* stud = dynamic_cast<SalomeApp_Study*> ( app->activeStudy() );
634   if ( !stud ) {
635     MESSAGE ( "FAILED to cast active study to SalomeApp_Study" );
636     return false;
637   }
638   _PTR(Study) aStudy = stud->studyDS();
639
640   // check if study is locked
641   bool aLocked = (_PTR(AttributeStudyProperties)(aStudy->GetProperties()))->IsLocked();
642   if ( aLocked ) {
643     SUIT_MessageBox::warning( app->desktop(),
644                               QObject::tr("WRN_WARNING"),
645                               QObject::tr("WRN_STUDY_LOCKED") );
646     return false;
647   }
648
649   // check if GEOM engine is available
650   GEOM::GEOM_Gen_var eng = GeometryGUI::GetGeomGen();
651   if ( CORBA::is_nil( eng ) ) {
652     SUIT_MessageBox::critical( app->desktop(),
653                                QObject::tr("WRN_WARNING"),
654                                QObject::tr( "GEOM Engine is not started" ) );
655     return false;
656   }
657
658   GEOM::GEOM_IInsertOperations_var aInsOp = eng->GetIInsertOperations( aStudy->StudyId() );
659   if ( aInsOp->_is_nil() )
660     return false;
661
662   // obtain a list of available import formats
663   FilterMap aMap;
664   GEOM::string_array_var aFormats, aPatterns;
665   aInsOp->ImportTranslators( aFormats, aPatterns );
666
667   for ( int i = 0, n = aFormats->length(); i < n; i++ )
668     aMap.insert( (char*)aPatterns[i], (char*)aFormats[i] );
669
670   // select files to be imported
671   QString fileType;
672   QStringList fileNames = getFileNames( app->desktop(), "", aMap,
673                                         tr( "GEOM_MEN_IMPORT" ), fileType, true );
674
675   // set Wait cursor
676   SUIT_OverrideCursor wc;
677
678   if ( fileNames.count() == 0 )
679     return false; // nothing selected, return
680
681   QStringList errors;
682
683   QList< GEOM::GEOM_Object_var > objsForDisplay;
684
685   QStringList anEntryList;
686
687   // iterate through all selected files
688
689   SUIT_MessageBox::StandardButton igesAnswer = SUIT_MessageBox::NoButton;
690   SUIT_MessageBox::StandardButton acisAnswer = SUIT_MessageBox::NoButton;
691
692   for ( int i = 0; i < fileNames.count(); i++ ) {
693     QString fileName = fileNames[i];
694
695     if ( fileName.isEmpty() )
696       continue;
697
698     QString aCurrentType;
699     if ( fileType.isEmpty() ) {
700       // file type is not defined, try to detect
701       QString ext = QFileInfo( fileName ).suffix().toUpper();
702       QRegExp re( "\\*\\.(\\w+)" );
703       for ( FilterMap::const_iterator it = aMap.begin();
704             it != aMap.end() && aCurrentType.isEmpty(); ++it ) {
705         int pos = 0;
706         while ( re.indexIn( it.key(), pos ) >= 0 ) {
707           QString f = re.cap(1).trimmed().toUpper();
708           if ( ext == f ) { aCurrentType = it.value(); break; }
709           pos = re.pos() + re.cap(1).length() + 2;
710         }
711       }
712     }
713     else {
714       aCurrentType = fileType;
715     }
716
717     if ( aCurrentType.isEmpty() ) {
718       errors.append( QString( "%1 : %2" ).arg( fileName ).arg( tr( "GEOM_UNSUPPORTED_TYPE" ) ) );
719       continue;
720     }
721
722     GEOM_Operation* anOp = new GEOM_Operation( app, aInsOp.in() );
723     try {
724       app->putInfo( tr( "GEOM_PRP_LOADING" ).arg( SUIT_Tools::file( fileName, /*withExten=*/true ) ) );
725       anOp->start();
726
727       CORBA::String_var fileN = fileName.toUtf8().constData();
728       CORBA::String_var fileT = aCurrentType.toUtf8().constData();
729
730       // jfa 21.08.2012 for mantis issue 21511 (STEP file units)
731       CORBA::String_var aUnits = aInsOp->ReadValue(fileN, fileT, "LEN_UNITS");
732       QString aUnitsStr (aUnits.in());
733       bool needConvert = true;
734       if (aUnitsStr.isEmpty() || aUnitsStr == "M" || aUnitsStr.toLower() == "metre")
735         needConvert = false;
736
737       if (needConvert) {
738         if (igesAnswer == SUIT_MessageBox::NoToAll) {
739           // converting for all files is already approved
740           fileT = (aCurrentType + "_SCALE").toLatin1().constData();
741         }
742         else if (igesAnswer != SUIT_MessageBox::YesToAll) {
743           SUIT_MessageBox::StandardButtons btns = SUIT_MessageBox::Yes | SUIT_MessageBox::No;
744           if (i < fileNames.count() - 1) btns = btns | SUIT_MessageBox::YesToAll | SUIT_MessageBox::NoToAll;
745           igesAnswer = SUIT_MessageBox::question(app->desktop(),
746                                                  "Question",//tr("WRN_WARNING"),
747                                                  tr("GEOM_SCALE_DIMENSIONS").arg(aUnitsStr),
748                                                  btns | SUIT_MessageBox::Cancel,
749                                                  SUIT_MessageBox::No);
750           switch (igesAnswer) {
751           case SUIT_MessageBox::Cancel:
752             return false;                // cancel (break) import operation
753           case SUIT_MessageBox::Yes:
754           case SUIT_MessageBox::YesToAll:
755             break;                       // scaling is confirmed
756           case SUIT_MessageBox::No:
757           case SUIT_MessageBox::NoAll:
758             fileT = (aCurrentType + "_SCALE").toLatin1().constData();
759           default:
760             break;                       // scaling is rejected
761           } // switch ( igesAnswer )
762         } // if ( igeAnswer != NoToAll )
763       } // if ( needConvert )
764
765       /*
766       // skl 29.05.2009
767       if ( aCurrentType == "IGES" ) {
768         GEOM::GEOM_Object_var anObj = aInsOp->ImportFile( fileN, "IGES_UNIT" );
769         bool needConvert = false;
770         TCollection_AsciiString aUnitName = aInsOp->GetErrorCode();
771         if ( aUnitName.SubString( 1, 4 ) == "UNIT" )
772           needConvert = aUnitName.SubString( 6, aUnitName.Length() ) != "M";
773
774         if ( needConvert ) {
775           if ( igesAnswer == SUIT_MessageBox::NoToAll ) {
776             // converting for all files is already approved
777             fileT = "IGES_SCALE";
778           }
779           else if ( igesAnswer != SUIT_MessageBox::YesToAll ) {
780             SUIT_MessageBox::StandardButtons btns = SUIT_MessageBox::Yes | SUIT_MessageBox::No;
781             if ( i < fileNames.count()-1 ) btns = btns | SUIT_MessageBox::YesToAll | SUIT_MessageBox::NoToAll;
782             igesAnswer = SUIT_MessageBox::question( app->desktop(),
783                                                     "Question",//tr("WRN_WARNING"),
784                                                     tr("GEOM_SCALE_DIMENSIONS"),
785                                                     btns | SUIT_MessageBox::Cancel,
786                                                     SUIT_MessageBox::No );
787             switch ( igesAnswer ) {
788             case SUIT_MessageBox::Cancel:
789               return false;                // cancel (break) import operation
790             case SUIT_MessageBox::Yes:
791             case SUIT_MessageBox::YesToAll:
792               break;                       // scaling is confirmed
793             case SUIT_MessageBox::No:
794             case SUIT_MessageBox::NoAll:
795               fileT = "IGES_SCALE";
796             default:
797               break;                       // scaling is rejected
798             } // switch ( igesAnswer )
799           } // if ( igeAnswer != NoToAll )
800         } // if ( needConvert )
801       } // if ( aCurrentType == "IGES" )
802       else if ( aCurrentType == "ACIS" ) {
803       */
804
805       if ( aCurrentType == "ACIS" ) {
806         if ( acisAnswer != SUIT_MessageBox::YesToAll && acisAnswer != SUIT_MessageBox::NoToAll ) {
807           SUIT_MessageBox::StandardButtons btns = SUIT_MessageBox::Yes | SUIT_MessageBox::No;
808           if ( i < fileNames.count()-1 ) btns = btns | SUIT_MessageBox::YesToAll | SUIT_MessageBox::NoToAll;
809           acisAnswer = SUIT_MessageBox::question( app->desktop(),
810                                                   "Question",//tr("WRN_WARNING"),
811                                                   tr("GEOM_PUBLISH_NAMED_SHAPES"),
812                                                   btns | SUIT_MessageBox::Cancel,
813                                                   SUIT_MessageBox::No );
814           if ( acisAnswer == SUIT_MessageBox::Cancel )
815             return false; // cancel (break) import operation
816         } // if ( acisAnswer != YesToAll && acisAnswer != NoToAll )
817       } // else if ( aCurrentType == "ACIS" )
818
819       // IMPORT
820       GEOM::ListOfGO_var anObj = aInsOp->ImportFile( fileN, fileT );
821
822       if ( anObj->length() > 0 && aInsOp->IsDone() ) {
823         GEOM::GEOM_Object_ptr aFather = anObj[0]._retn();
824         QString aPublishObjName =
825           GEOMBase::GetDefaultName( SUIT_Tools::file( fileName, /*withExten=*/true ) );
826
827         SALOMEDS::Study_var aDSStudy = GeometryGUI::ClientStudyToStudy( aStudy );
828         SALOMEDS::SObject_var aSO =
829           GeometryGUI::GetGeomGen()->PublishInStudy( aDSStudy,
830                                                      SALOMEDS::SObject::_nil(),
831                                                      aFather,
832                                                      aPublishObjName.toLatin1().constData() );
833         if ( ( !aSO->_is_nil() ) )
834           anEntryList.append( aSO->GetID() );
835
836         objsForDisplay.append( aFather );
837
838         if ( aCurrentType == "ACIS" ) {
839           if ( acisAnswer == SUIT_MessageBox::Yes || acisAnswer == SUIT_MessageBox::YesToAll )
840             GeometryGUI::GetGeomGen()->PublishNamedShapesInStudy( aDSStudy, aFather );
841         }
842
843         anOp->commit();
844
845         // Treat group objects.
846         for (int i = 1, n = anObj->length(); i < n; i++) {
847           GEOM::GEOM_Object_ptr anObject = anObj[i]._retn();
848           GeometryGUI::GetGeomGen()->AddInStudy(aDSStudy,
849             anObject, tr(anObject->GetName()).toStdString().c_str(), aFather);
850         }
851       }
852       else {
853         anOp->abort();
854         errors.append( QString( "%1 : %2" ).arg( fileName ).arg( aInsOp->GetErrorCode() ) );
855       }
856     }
857     catch( const SALOME::SALOME_Exception& S_ex ) {
858       anOp->abort();
859       errors.append( QString( "%1 : %2" ).arg( fileName ).arg( tr( "GEOM_UNKNOWN_IMPORT_ERROR" ) ) );
860     }
861   }
862
863   // update object browser
864   getGeometryGUI()->updateObjBrowser( true );
865
866   // browse published objects
867   app->browseObjects( anEntryList );
868
869   // display imported model (if only one file is selected)
870   if ( objsForDisplay.count() == 1 )
871     GEOM_Displayer( stud ).Display( objsForDisplay[0].in() );
872
873   if ( errors.count() > 0 ) {
874     SUIT_MessageBox::critical( app->desktop(),
875                                QObject::tr( "GEOM_ERROR" ),
876                                QObject::tr( "GEOM_IMPORT_ERRORS" ) + "\n" + errors.join( "\n" ) );
877   }
878
879   app->updateActions(); //SRN: To update a Save button in the toolbar
880
881   return objsForDisplay.count() > 0;
882 }
883
884 //=====================================================================================
885 // function : Export
886 // purpose  : BRep, Iges, Step
887 //=====================================================================================
888 bool GEOMToolsGUI::Export()
889 {
890   SalomeApp_Application* app = getGeometryGUI()->getApp();
891   if (!app) return false;
892
893   SalomeApp_Study* stud = dynamic_cast<SalomeApp_Study*> ( app->activeStudy() );
894   if ( !stud ) {
895     MESSAGE ( "FAILED to cast active study to SalomeApp_Study" );
896     return false;
897   }
898   _PTR(Study) aStudy = stud->studyDS();
899
900   GEOM::GEOM_Gen_var eng = GeometryGUI::GetGeomGen();
901   if ( CORBA::is_nil( eng ) ) {
902     SUIT_MessageBox::critical( app->desktop(),
903                                QObject::tr("WRN_WARNING"),
904                                QObject::tr( "GEOM Engine is not started" ) );
905     return false;
906   }
907
908   GEOM::GEOM_IInsertOperations_var aInsOp = eng->GetIInsertOperations( aStudy->StudyId() );
909   if ( aInsOp->_is_nil() )
910     return false;
911
912   // Obtain a list of available export formats
913   FilterMap aMap;
914   QStringList filters;
915   GEOM::string_array_var aFormats, aPatterns;
916   aInsOp->ExportTranslators( aFormats, aPatterns );
917   for ( int i = 0, n = aFormats->length(); i < n; i++ ) {
918     aMap.insert( (char*)aPatterns[i], (char*)aFormats[i] );
919     filters.push_back( (char*)aPatterns[i] );
920   }
921
922   // Get selected objects
923   LightApp_SelectionMgr* sm = app->selectionMgr();
924   if ( !sm )
925     return false;
926
927   SALOME_ListIO selectedObjects;
928   sm->selectedObjects( selectedObjects );
929   bool appropriateObj = false;
930
931   SALOME_ListIteratorOfListIO It( selectedObjects );
932   for (; It.More(); It.Next()) {
933     Handle(SALOME_InteractiveObject) IObject = It.Value();
934     GEOM::GEOM_Object_var anObj = GEOMBase::ConvertIOinGEOMObject( IObject );
935
936     if ( anObj->_is_nil() )
937       continue;
938
939     QString fileType;
940     QString file = getFileName(app->desktop(), QString( IObject->getName() ), aMap, filters,
941                                tr("GEOM_MEN_EXPORT"), false, fileType, true);
942
943     // User has pressed "Cancel" --> stop the operation
944     if ( file.isEmpty() || fileType.isEmpty() )
945       return false;
946
947     GEOM_Operation* anOp = new GEOM_Operation( app, aInsOp.in() );
948     try {
949       SUIT_OverrideCursor wc;
950
951       app->putInfo( tr("GEOM_PRP_EXPORT").arg(SUIT_Tools::file( file, /*withExten=*/true )) );
952
953       anOp->start();
954
955       aInsOp->Export( anObj, file.toUtf8().constData(), fileType.toUtf8().constData() );
956
957       if (aInsOp->IsDone())
958         anOp->commit();
959       else {
960         anOp->abort();
961         wc.suspend();
962         SUIT_MessageBox::critical(app->desktop(),
963                                   QObject::tr("GEOM_ERROR"),
964                                   QObject::tr("GEOM_PRP_ABORT") + "\n" + QObject::tr(aInsOp->GetErrorCode()));
965         return false;
966       }
967     }
968     catch (const SALOME::SALOME_Exception& S_ex) {
969       //QtCatchCorbaException(S_ex);
970       anOp->abort();
971       return false;
972     }
973     appropriateObj = true;
974   }
975
976   if ( !appropriateObj )
977     SUIT_MessageBox::warning( app->desktop(),
978                               QObject::tr("WRN_WARNING"),
979                               QObject::tr("GEOM_WRN_NO_APPROPRIATE_SELECTION") );
980   return true;
981 }
982
983 //=====================================================================================
984 // function : RemoveObjectWithChildren
985 // purpose  : used by OnEditDelete() method
986 //=====================================================================================
987 void GEOMToolsGUI::removeObjectWithChildren(_PTR(SObject) obj,
988                                             _PTR(Study) aStudy,
989                                             QList<SALOME_View*> views,
990                                             GEOM_Displayer* disp)
991 {
992   // iterate through all children of obj
993   for (_PTR(ChildIterator) it (aStudy->NewChildIterator(obj)); it->More(); it->Next()) {
994   // for (_PTR(UseCaseIterator) it (aStudy->GetUseCaseBuilder()->GetUseCaseIterator(obj)); it->More(); it->Next()) {
995     _PTR(SObject) child (it->Value());
996     removeObjectWithChildren(child, aStudy, views, disp);
997   }
998
999   // erase object and remove it from engine
1000   _PTR(GenericAttribute) anAttr;
1001   if (obj->FindAttribute(anAttr, "AttributeIOR")) {
1002     _PTR(AttributeIOR) anIOR (anAttr);
1003
1004     SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
1005
1006     // Delete shape in Client
1007     const TCollection_AsciiString ASCIor ((char*)anIOR->Value().c_str());
1008     getGeometryGUI()->GetShapeReader().RemoveShapeFromBuffer(ASCIor);
1009
1010     CORBA::Object_var corbaObj = GeometryGUI::ClientSObjectToObject(obj);
1011     GEOM::GEOM_Object_var geomObj = GEOM::GEOM_Object::_narrow( corbaObj );
1012     if (!CORBA::is_nil(geomObj)) {
1013
1014       //Remove visual properties of the object
1015       appStudy->removeObjectFromAll(obj->GetID().c_str());
1016
1017       // Erase graphical object
1018       QListIterator<SALOME_View*> it( views );
1019       while ( it.hasNext() )
1020         if ( SALOME_View* view = it.next() )
1021           disp->Erase(geomObj, true, true, view);
1022
1023       // Remove object from Engine
1024       // We can't directly remove object from engine. All we can do is to unpublish the object
1025       // from the study. Another client could be using the object.
1026       // Unpublishing is done just after in aStudyBuilder->RemoveObjectWithChildren( child );
1027       //GeometryGUI::GetGeomGen()->RemoveObject( geomObj );
1028     }
1029   }
1030 }
1031
1032 //=================================================================================
1033 // function : deactivate()
1034 // purpose  : Called when GEOM component is deactivated
1035 //=================================================================================
1036 void GEOMToolsGUI::deactivate()
1037 {
1038   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
1039   if ( app ) {
1040     SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
1041     GEOM_Displayer aDisp (appStudy);
1042     aDisp.GlobalSelection();
1043     getGeometryGUI()->setLocalSelectionMode(GEOM_ALLOBJECTS);
1044   }
1045 }
1046
1047 //=======================================================================
1048 // function : 
1049 // purpose  : 
1050 //=======================================================================
1051 std::string GEOMToolsGUI::getDependencyTree( QStringList rootObjectIORs )
1052 {
1053   // fill in the tree structure
1054   DependencyTree tree;
1055   foreach( QString ior, rootObjectIORs ) {
1056     GEOM::GEOM_Object_ptr anObj = GEOMBase::GetObjectFromIOR( ior );
1057     QList<NodeLevel> upLevelList;
1058     getUpwardDependency( anObj, upLevelList );
1059     QList<NodeLevel> downLevelList;
1060     getDownwardDependency( anObj, downLevelList );
1061     tree.insert( ior, QPair<QList<NodeLevel>, QList<NodeLevel> >( upLevelList, downLevelList ) );
1062   }
1063   // translation the tree into string
1064   std::string treeStr;
1065   DependencyTree::iterator i;
1066   for ( i = tree.begin(); i != tree.end(); ++i ) {
1067     treeStr.append( i.key().toUtf8().constData() );
1068     treeStr.append( "-" );
1069     QList<NodeLevel> upLevelList = i.value().first;
1070     treeStr.append( "upward" );
1071     treeStr.append( "{" );
1072     foreach( NodeLevel level, upLevelList ) {
1073       NodeLevel::iterator upIter;
1074       for ( upIter = level.begin(); upIter != level.end(); ++upIter ) {
1075         treeStr.append( upIter.key().toUtf8().constData() );
1076         treeStr.append( "_" );
1077         treeStr.append( QStringList(upIter.value()).join("_").toUtf8().constData() );
1078         treeStr.append( upIter+1 == level.end() ? ";" : "," );
1079       }
1080     }
1081     treeStr.append( "}" );
1082     QList<NodeLevel> downLevelList = i.value().second;
1083     treeStr.append( "downward" );
1084     treeStr.append( "{" );
1085     foreach( NodeLevel level, downLevelList ) {
1086       NodeLevel::iterator downIter;
1087       for ( downIter = level.begin(); downIter != level.end(); ++downIter ) {
1088         treeStr.append( downIter.key().toUtf8().constData() );
1089         treeStr.append( "_" );
1090         treeStr.append( QStringList(downIter.value()).join("_").toUtf8().constData() );
1091         treeStr.append( downIter+1 == level.end() ? ";" : "," );
1092       }
1093     }
1094     treeStr.append("}");
1095   }
1096   return treeStr;
1097 }
1098
1099 //=======================================================================
1100 // function : 
1101 // purpose  : 
1102 //=======================================================================
1103 void GEOMToolsGUI::getUpwardDependency( GEOM::GEOM_BaseObject_ptr gbo, 
1104                                         QList<NodeLevel> &upLevelList,  
1105                                         int level )
1106 {
1107   QString aGboIOR = GEOMBase::GetIORFromObject(GEOM::GEOM_Object::_narrow(gbo));
1108   GEOM::ListOfGBO_var depList = gbo->GetDependency();
1109   for( int j = 0; j < depList->length(); j++ ) {
1110     if ( level > 0 ) {
1111       QStringList anIORs;
1112       NodeLevel aLevelMap;
1113       if ( level-1 >= upLevelList.size() ) {
1114         upLevelList.append( aLevelMap );
1115       } else {
1116         aLevelMap = upLevelList.at(level-1);
1117         if ( aLevelMap.contains( aGboIOR ) )
1118           anIORs = aLevelMap.value( aGboIOR );
1119       }
1120       anIORs << GEOMBase::GetIORFromObject(GEOM::GEOM_Object::_narrow(depList[j]));
1121       aLevelMap.insert( aGboIOR, anIORs );
1122     }
1123     getUpwardDependency(depList[j], upLevelList, level++);
1124   }
1125 }
1126
1127 //=======================================================================
1128 // function : 
1129 // purpose  : 
1130 //=======================================================================
1131 void GEOMToolsGUI::getDownwardDependency( GEOM::GEOM_BaseObject_ptr gbo, 
1132                                           QList<NodeLevel> &downLevelList, 
1133                                           int level )
1134 {
1135   SalomeApp_Application* app =
1136     dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
1137   if ( !app )
1138     return;
1139
1140   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
1141   if ( !appStudy )
1142     return;
1143
1144   _PTR(Study) aStudy = appStudy->studyDS();
1145
1146   // get GEOM component
1147   CORBA::String_var geomIOR = app->orb()->object_to_string( GeometryGUI::GetGeomGen() );
1148   QString geomComp = getParentComponent( aStudy->FindObjectIOR( geomIOR.in() ) );
1149
1150   _PTR(SObject) comp = aStudy->FindObjectID( geomComp.toLatin1().data() );
1151   if ( !comp )
1152     return;
1153
1154   _PTR(ChildIterator) it ( aStudy->NewChildIterator( comp ) );
1155   for ( it->InitEx( true ); it->More(); it->Next() ) {
1156     _PTR(SObject) child( it->Value() );
1157     CORBA::Object_var corbaObj = GeometryGUI::ClientSObjectToObject( child );
1158     GEOM::GEOM_Object_var geomObj = GEOM::GEOM_Object::_narrow( corbaObj );
1159     if( CORBA::is_nil( geomObj ) )
1160       continue;
1161
1162     GEOM::ListOfGBO_var depList = geomObj->GetDependency();
1163     if( depList->length() == 0 )
1164       continue;
1165     QString aGoIOR = GEOMBase::GetIORFromObject( geomObj );
1166
1167     for( int i = 0; i < depList->length(); i++ ) {
1168       if ( depList[i]->IsSame( gbo ) ) {
1169         QStringList anIORs;
1170         NodeLevel aLevelMap;
1171         if ( level >= downLevelList.size() ) {
1172           aLevelMap = NodeLevel();
1173           downLevelList.append( aLevelMap );
1174         } else {
1175           aLevelMap = downLevelList.at(level);
1176           if ( aLevelMap.contains( aGoIOR ) )
1177             anIORs = aLevelMap.value( aGoIOR );
1178         }
1179         anIORs << GEOMBase::GetIORFromObject(GEOM::GEOM_Object::_narrow(depList[i]));
1180         aLevelMap.insert( aGoIOR, anIORs );
1181       }
1182     }
1183     getDownwardDependency(geomObj, downLevelList, level++);
1184   }
1185 }
1186
1187 //=====================================================================================
1188 // EXPORTED METHODS
1189 //=====================================================================================
1190 extern "C"
1191 {
1192 #ifdef WIN32
1193   __declspec( dllexport )
1194 #endif
1195   GEOMGUI* GetLibGUI( GeometryGUI* parent )
1196   {
1197     return new GEOMToolsGUI( parent );
1198   }
1199 }