From c5b6deb54b470e71d9673c2eab919afd029bdd15 Mon Sep 17 00:00:00 2001 From: akl Date: Fri, 28 Jun 2013 08:18:20 +0000 Subject: [PATCH] Implementation of 0021855: EDF 2321 GEOM : Add folders to group objects in the object browser. --- doc/salome/examples/Makefile.am | 1 + .../examples/arranging_study_objects.py | 25 +++ doc/salome/gui/GEOM/images/arranging1.png | Bin 0 -> 165243 bytes doc/salome/gui/GEOM/images/arranging2.png | Bin 0 -> 298049 bytes doc/salome/gui/GEOM/images/arranging3.png | Bin 0 -> 222158 bytes .../input/arranging_study_objects_page.doc | 27 +++ doc/salome/gui/GEOM/input/geompy.doc | 1 + doc/salome/gui/GEOM/input/index.doc | 7 +- .../input/tui_arranging_study_objects.doc | 8 + idl/GEOM_Gen.idl | 49 ++++++ resources/Makefile.am | 1 + resources/folder.png | Bin 0 -> 378 bytes src/GEOM/GEOM_Engine.cxx | 65 +++++--- src/GEOM/GEOM_Engine.hxx | 4 + src/GEOMGUI/GEOMGUI_Selection.cxx | 26 +++ src/GEOMGUI/GEOMGUI_Selection.h | 1 + src/GEOMGUI/GEOM_Displayer.cxx | 4 +- src/GEOMGUI/GEOM_images.ts | 4 + src/GEOMGUI/GEOM_msg_en.ts | 12 ++ src/GEOMGUI/GEOM_msg_fr.ts | 12 ++ src/GEOMGUI/GeometryGUI.cxx | 156 +++++++++++++++++- src/GEOMGUI/GeometryGUI.h | 5 + src/GEOMGUI/GeometryGUI_Operations.h | 1 + src/GEOMToolsGUI/GEOMToolsGUI.cxx | 3 + src/GEOMToolsGUI/GEOMToolsGUI.h | 1 + src/GEOMToolsGUI/GEOMToolsGUI_1.cxx | 29 ++++ src/GEOM_I/GEOM_DumpPython.cc | 55 ++++++ src/GEOM_I/GEOM_Gen_i.cc | 147 +++++++++++++++++ src/GEOM_I/GEOM_Gen_i.hh | 17 ++ src/GEOM_SWIG/geomBuilder.py | 52 ++++++ 30 files changed, 679 insertions(+), 34 deletions(-) create mode 100644 doc/salome/examples/arranging_study_objects.py create mode 100644 doc/salome/gui/GEOM/images/arranging1.png create mode 100644 doc/salome/gui/GEOM/images/arranging2.png create mode 100644 doc/salome/gui/GEOM/images/arranging3.png create mode 100644 doc/salome/gui/GEOM/input/arranging_study_objects_page.doc create mode 100644 doc/salome/gui/GEOM/input/tui_arranging_study_objects.doc create mode 100644 resources/folder.png diff --git a/doc/salome/examples/Makefile.am b/doc/salome/examples/Makefile.am index 211c7932e..034ad1597 100644 --- a/doc/salome/examples/Makefile.am +++ b/doc/salome/examples/Makefile.am @@ -35,6 +35,7 @@ GOOD_TESTS = \ advanced_geom_objs_ex02.py \ advanced_geom_objs_ex03.py \ angle.py \ + arranging_study_objects.py \ basic_geom_objs_ex01.py \ basic_geom_objs_ex02.py \ basic_geom_objs_ex03.py \ diff --git a/doc/salome/examples/arranging_study_objects.py b/doc/salome/examples/arranging_study_objects.py new file mode 100644 index 000000000..bedbe6161 --- /dev/null +++ b/doc/salome/examples/arranging_study_objects.py @@ -0,0 +1,25 @@ +# Using SALOME NoteBook + +import salome +salome.salome_init() + +import GEOM +from salome.geom import geomBuilder +geompy = geomBuilder.New(salome.myStudy) + +Circle_1 = geompy.MakeCircle(None, None, 100) +Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) +Cylinder_1 = geompy.MakeCylinderRH(100, 300) +geompy.addToStudy( Circle_1, 'Circle_1' ) +geompy.addToStudy( Box_1, 'Box_1' ) +geompy.addToStudy( Cylinder_1, 'Cylinder_1' ) + +### Folders and it's content +Basic = geompy.NewFolder('Basic') +geompy.PutToFolder(Circle_1, Basic) +Primitives = geompy.NewFolder('Primitives') +geompy.PutListToFolder([Box_1, Cylinder_1], Primitives) + + +if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser(1) diff --git a/doc/salome/gui/GEOM/images/arranging1.png b/doc/salome/gui/GEOM/images/arranging1.png new file mode 100644 index 0000000000000000000000000000000000000000..5a50eda361877f0f4a5283a2c72c1a59d80746b8 GIT binary patch literal 165243 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 WwYdwv`iqXK7hGDk;#)uX<^Kazo9l`I literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/images/arranging2.png b/doc/salome/gui/GEOM/images/arranging2.png new file mode 100644 index 0000000000000000000000000000000000000000..2ca6c536e6841fabe908c39f1a909efa97964d75 GIT binary patch literal 298049 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/images/arranging3.png b/doc/salome/gui/GEOM/images/arranging3.png new file mode 100644 index 0000000000000000000000000000000000000000..04cc29ad6119427c4c5d84a565aaf75f9a88305d GIT binary patch literal 222158 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 QILFDSpHsT@w9DuGe{@liJOBUy literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/input/arranging_study_objects_page.doc b/doc/salome/gui/GEOM/input/arranging_study_objects_page.doc new file mode 100644 index 000000000..44df8f830 --- /dev/null +++ b/doc/salome/gui/GEOM/input/arranging_study_objects_page.doc @@ -0,0 +1,27 @@ +/*! + +\page arranging_study_objects_page Arranging objects in study + +The possibility to classify the geometrical objects by moving it into early created container (folder) was introduced to Geometry module. + +\image html arranging1.png "Classified objects in folders" + +To create a folder select "Create folder" popup menu item for root "Geometry" object or another folder. + +\image html arranging2.png "Creation of folder" + +"Drag&Drop" mechanism was integrated to arrange objects. + +\image html arranging3.png "Moving object into folder" + +\note Only two categories of objects can be moved into folder: +

    +
  • geometrical model(s) under root "Geometry" item or under any folder +
  • folder(s) +
+ +Our TUI Scripts provide you with useful examples of +\ref tui_arranging_study_objects "Arranging objects in study". + +*/ + diff --git a/doc/salome/gui/GEOM/input/geompy.doc b/doc/salome/gui/GEOM/input/geompy.doc index b339d3b64..43cee55d2 100644 --- a/doc/salome/gui/GEOM/input/geompy.doc +++ b/doc/salome/gui/GEOM/input/geompy.doc @@ -44,6 +44,7 @@ provided by Geometry module.
  • \subpage tui_measurement_tools_page
  • \subpage tui_notebook_geom_page
  • +
  • \subpage tui_arranging_study_objects_page
  • \subpage tui_swig_examples_page
    • \ref tui_test_others_page
    • diff --git a/doc/salome/gui/GEOM/input/index.doc b/doc/salome/gui/GEOM/input/index.doc index 55a17a230..db275aa4a 100644 --- a/doc/salome/gui/GEOM/input/index.doc +++ b/doc/salome/gui/GEOM/input/index.doc @@ -21,17 +21,20 @@ - easily setting parameters via the variables predefined in \subpage using_notebook_geom_page "SALOME notebook". +The possibility to classify the created geometrical objects by moving it into early created container (folder) is detailed on +\subpage arranging_study_objects_page section. + Geometry module preferences are described in the \subpage geometry_preferences_page section of SALOME Geometry Help. Almost all geometry module functionalities are accessible via \subpage geompy_page "Geometry module Python Interface" +Other functions are available in salome.geom python package. + You can find the answer to some Frequently Asked Questions in this page: - \subpage faq "Frequently Asked Questions" -Other functions are available in salome.geom python package. - \image html image3.png "Example of Geometry module usage for engineering tasks" There are also \subpage related_docs_page "additional reference documents" diff --git a/doc/salome/gui/GEOM/input/tui_arranging_study_objects.doc b/doc/salome/gui/GEOM/input/tui_arranging_study_objects.doc new file mode 100644 index 000000000..b93b85bb2 --- /dev/null +++ b/doc/salome/gui/GEOM/input/tui_arranging_study_objects.doc @@ -0,0 +1,8 @@ +/*! + +\page tui_arranging_study_objects_page Arranging objects in study + +\anchor tui_arranging_study_objects +\tui_script{arranging_study_objects.py} + +*/ diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index bbd4cf7c1..23083c1f4 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -219,6 +219,7 @@ module GEOM interface GEOM_Object; typedef sequence ListOfGO; + typedef sequence object_list; //# GEOM_Object /*! @@ -4638,6 +4639,54 @@ module GEOM ListOfGO PublishNamedShapesInStudy(in SALOMEDS::Study theStudy, //in SObject theSObject, in Object theObject); + + /*! + * \brief Creates a new folder + * + * Creates a new container (folder) for any GEOM objects. + * Folder will have name theName. + * If theFather is not NULL, the folder is placed under theFather object. + * Otherwise, the folder takes place under root 'Geometry' object. + * + * \param theName name of the folder + * \param theFather parent object + * \return SObject represented the created folder. + */ + SALOMEDS::SObject CreateFolder (in string theName, + in SALOMEDS::SObject theFather); + + /*! + * \brief Moves object to the specified folder + * + * The moved object should be first published in the study. + * \param theObject GEOM object to move + * \param theFolder target folder + */ + void MoveToFolder (in GEOM_Object theObject, + in SALOMEDS::SObject theFolder); + + /*! + * \brief Moves list of objects to the specified folder + * + * The moved objects should be first published in the study. + * \param theListOfGO list of GEOM objects to move + * \param theFolder target folder + */ + void MoveListToFolder (in ListOfGO theListOfGO, + in SALOMEDS::SObject theFolder); + + /*! + * \brief Moves objects to the specified position + * + * This function is used in the drag-n-drop functionality. + * + * \param what objects being moved + * \param where parent object where objects are moved to + * \param row position in the parent object's children list at which objects are moved + */ + void Move( in object_list what, + in SALOMEDS::SObject where, + in long row ); }; }; diff --git a/resources/Makefile.am b/resources/Makefile.am index b36757b3b..90ca30a67 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -97,6 +97,7 @@ filletedge.png \ filletwire.png \ filletface.png \ filling.png \ +folder.png \ fuse.png \ fuse_collinear_edges.png \ geometry.png \ diff --git a/resources/folder.png b/resources/folder.png new file mode 100644 index 0000000000000000000000000000000000000000..841eba0a6903afb9283ca0273ba07fc3b3ffb131 GIT binary patch literal 378 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ zFzyCnMyofE9{~j=OI#yLg7ec#$`gxH8OqDc^)mCai<1)zQuXqS(r3T3kpe3E?&;zf zQgLhPWkau{4gzcs>eJHApDF&3ddtGE*bzPH#_1S?mTJUFZ(Z1A}I8X;)yu<^ZBh$St6OP-H(6!@!+dhKkqYV^z1&;6VGeC-#W*N&KPB6v#B`1hRyZG}B+G@Kcvl^s`A8S^-w z*EoJ{mqPd2y=5JLmx!*}5w=V2;4P`8`i?9me& theEntryToCmdMap, std::set& theMapOfPublished); -namespace -{ - - //================================================================================ - /*! - * \brief Fix up the name of python variable - */ - //================================================================================ +//================================================================================ +/*! + * \brief Fix up the name of python variable + */ +//================================================================================ - void healPyName( TCollection_AsciiString& pyName, - const TCollection_AsciiString& anEntry, - Resource_DataMapOfAsciiStringAsciiString& aNameToEntry) - { - const TCollection_AsciiString allowedChars - ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_"); +void GEOM_Engine::healPyName( TCollection_AsciiString& pyName, + const TCollection_AsciiString& anEntry, + Resource_DataMapOfAsciiStringAsciiString& aNameToEntry) +{ + const TCollection_AsciiString allowedChars + ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_"); - if ( pyName.IsIntegerValue() ) { // pyName must not start with a digit - pyName.Insert( 1, 'a' ); - } - int p, p2=1; // replace not allowed chars - while ((p = pyName.FirstLocationNotInSet(allowedChars, p2, pyName.Length()))) { - pyName.SetValue(p, '_'); - p2=p; - } - if ( aNameToEntry.IsBound( pyName ) && anEntry != aNameToEntry( pyName )) + if ( pyName.IsIntegerValue() ) { // pyName must not start with a digit + pyName.Insert( 1, 'a' ); + } + int p, p2=1; // replace not allowed chars + while ((p = pyName.FirstLocationNotInSet(allowedChars, p2, pyName.Length()))) { + pyName.SetValue(p, '_'); + p2=p; + } + if ( aNameToEntry.IsBound( pyName ) && anEntry != aNameToEntry( pyName )) { // diff objects have same name - make a new name by appending a digit TCollection_AsciiString aName2; Standard_Integer i = 0; @@ -186,7 +183,6 @@ namespace } while ( aNameToEntry.IsBound( aName2 ) && anEntry != aNameToEntry( aName2 )); pyName = aName2; } - } } //======================================================================= @@ -777,6 +773,21 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, } } + // // add commands of folders creation and putting objects into it + // TCollection_AsciiString createFolderCmd("\n"); + // createFolderCmd += "\t"; + // createFolderCmd += "geompy.CreateFolder("; + // for (aStEntry2ObjDataPtrIt = aStEntry2ObjDataPtr.begin(); + // aStEntry2ObjDataPtrIt != aStEntry2ObjDataPtr.end(); + // ++aStEntry2ObjDataPtrIt) + // { + // const TCollection_AsciiString& studyEntry = aStEntry2ObjDataPtrIt->first; + // const TObjectData* data = aStEntry2ObjDataPtrIt->second; + // if ( data->_unpublished && !data->_pyName.IsEmpty() ) { + // aScript += createFolderCmd + data->_pyName + ")"; + // } + // } + //aScript += "\n\tpass\n"; aScript += "\n"; aValidScript = true; @@ -1491,6 +1502,7 @@ void ReplaceEntriesByNames (TCollection_AsciiString& theScript, Standard_Integer& objectCounter, Resource_DataMapOfAsciiStringAsciiString& aNameToEntry) { + GEOM_Engine* engine = GEOM_Engine::GetEngine(); Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(theScript); Standard_Integer aLen = aSeq->Length(), aStart = 1, aScriptLength = theScript.Length(); @@ -1508,7 +1520,7 @@ void ReplaceEntriesByNames (TCollection_AsciiString& theScript, if ( data._pyName.IsEmpty() ) { // encounted for the 1st time if ( !data._name.IsEmpty() ) { // published object data._pyName = data._name; - healPyName( data._pyName, anEntry, aNameToEntry); + engine->healPyName( data._pyName, anEntry, aNameToEntry); } else { do { @@ -1700,6 +1712,7 @@ void PublishObject (TObjectData& theObjectData, std::map< int, TCollection_AsciiString >& theEntryToCmdMap, std::set< TCollection_AsciiString>& theIgnoreMap) { + GEOM_Engine* engine = GEOM_Engine::GetEngine(); if ( theObjectData._studyEntry.IsEmpty() ) return; // was not published if ( theIgnoreMap.count( theObjectData._entry ) ) @@ -1725,7 +1738,7 @@ void PublishObject (TObjectData& theObjectData, if ( data0._pyName.IsEmpty() ) return; // something wrong theObjectData._pyName = theObjectData._name; - healPyName( theObjectData._pyName, theObjectData._entry, theNameToEntry); + engine->healPyName( theObjectData._pyName, theObjectData._entry, theNameToEntry); TCollection_AsciiString aCreationCommand("\n\t"); aCreationCommand += theObjectData._pyName + " = " + data0._pyName; diff --git a/src/GEOM/GEOM_Engine.hxx b/src/GEOM/GEOM_Engine.hxx index 07684af88..38d954a0e 100644 --- a/src/GEOM/GEOM_Engine.hxx +++ b/src/GEOM/GEOM_Engine.hxx @@ -178,6 +178,10 @@ class GEOM_Engine static const Standard_GUID& GetTextureGUID(); + Standard_EXPORT void healPyName( TCollection_AsciiString& pyName, + const TCollection_AsciiString& anEntry, + Resource_DataMapOfAsciiStringAsciiString& aNameToEntry); + protected: Standard_EXPORT static void SetEngine(GEOM_Engine* theEngine); diff --git a/src/GEOMGUI/GEOMGUI_Selection.cxx b/src/GEOMGUI/GEOMGUI_Selection.cxx index dd19cf2ba..fdf8f8451 100644 --- a/src/GEOMGUI/GEOMGUI_Selection.cxx +++ b/src/GEOMGUI/GEOMGUI_Selection.cxx @@ -171,6 +171,8 @@ QVariant GEOMGUI_Selection::parameter( const int idx, const QString& p ) const v = isImported( idx ); else if ( p == "isPhysicalMaterial" ) v = isPhysicalMaterial(idx); + else if ( p == "isFolder" ) + v = isFolder(idx); else v = LightApp_Selection::parameter( idx, p ); @@ -187,6 +189,8 @@ QString GEOMGUI_Selection::typeName( const int index ) const { if ( isComponent( index ) ) return "Component"; + if ( isFolder( index ) ) + return "Folder"; static QString aGroup( "Group" ); static QString aShape( "Shape" ); @@ -618,3 +622,25 @@ bool GEOMGUI_Selection::isPhysicalMaterial( const int idx ) const return res; } + +bool GEOMGUI_Selection::isFolder( const int index ) const +{ + SalomeApp_Study* appStudy = dynamic_cast( study() ); + + if ( appStudy ) { + QString anEntry = entry( index ); + _PTR(Study) study = appStudy->studyDS(); + if ( study && !anEntry.isNull() ) { + _PTR(SObject) aSO( study->FindObjectID( anEntry.toStdString() ) ); + if ( aSO ) { + _PTR(GenericAttribute) anAttr; + if ( aSO->FindAttribute(anAttr, "AttributeLocalID") ) { + _PTR(AttributeLocalID) aLocalID( anAttr ); + return aLocalID->Value() == 999; + } + } + } + } + return false; +} + diff --git a/src/GEOMGUI/GEOMGUI_Selection.h b/src/GEOMGUI/GEOMGUI_Selection.h index 8e367b1c3..c8c1230d9 100644 --- a/src/GEOMGUI/GEOMGUI_Selection.h +++ b/src/GEOMGUI/GEOMGUI_Selection.h @@ -74,6 +74,7 @@ private: bool isPhysicalMaterial( const int ) const; bool isComponent( const int ) const; + bool isFolder( const int ) const; GEOM::GEOM_Object_ptr getObject( const int ) const; bool hasImported() const; diff --git a/src/GEOMGUI/GEOM_Displayer.cxx b/src/GEOMGUI/GEOM_Displayer.cxx index 95b50621c..8f832c9d3 100644 --- a/src/GEOMGUI/GEOM_Displayer.cxx +++ b/src/GEOMGUI/GEOM_Displayer.cxx @@ -1700,7 +1700,9 @@ void GEOM_Displayer::setShape( const TopoDS_Shape& theShape ) bool GEOM_Displayer::canBeDisplayed( const QString& entry, const QString& viewer_type ) const { - return viewer_type == SOCC_Viewer::Type() || viewer_type == SVTK_Viewer::Type(); + _PTR(SObject) anObj = getStudy()->studyDS()->FindObjectID( (const char*)entry.toLatin1() ); + GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(anObj)); // enable displaying of GEOM objects only + return !CORBA::is_nil( aGeomObj ) && (viewer_type == SOCC_Viewer::Type() || viewer_type == SVTK_Viewer::Type()); } int GEOM_Displayer::SetDisplayMode( const int theMode ) diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index 1ff0697a7..667c07514 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -3,6 +3,10 @@ @default + + ICON_FOLDER + folder.png + ICON_DLG_ADD_POINT_ON_EDGE pointonedge.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 211ee3541..32cb42f36 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -4640,6 +4640,18 @@ Please, select face, shell or solid and try again STB_POP_DISABLE_AUTO_COLOR Disable auto color + + MEN_POP_CREATE_FOLDER + Create folder + + + STB_POP_CREATE_FOLDER + Create a new folder + + + NEW_FOLDER_NAME + NewFolder + GEOM_RESULT_NAME_GRP Result name diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 8f8e537f6..065f5fb7b 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -4646,6 +4646,18 @@ Choisissez une face, une coque ou un solide et essayez de nouveau STB_POP_DISABLE_AUTO_COLOR Désactiver la couleur automatique + + MEN_POP_CREATE_FOLDER + Create folder + + + STB_POP_CREATE_FOLDER + Create a new folder + + + NEW_FOLDER_NAME + NewFolder + GEOM_RESULT_NAME_GRP Nom du résultat diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 3a786e03a..0d79f320d 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -77,6 +77,8 @@ #include #include +#include + #include // External includes @@ -388,7 +390,8 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) << GEOMOp::OpConcealChildren << GEOMOp::OpUnpublishObject << GEOMOp::OpPublishObject - << GEOMOp::OpPointMarker; + << GEOMOp::OpPointMarker + << GEOMOp::OpCreateFolder; if ( !ViewOCC && !ViewVTK && !NotViewerDependentCommands.contains( id ) ) return; @@ -440,6 +443,7 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) case GEOMOp::OpIsosWidth: // POPUP MENU - LINE WIDTH - ISOS WIDTH case GEOMOp::OpBringToFront: // POPUP MENU - BRING TO FRONT case GEOMOp::OpClsBringToFront: // + case GEOMOp::OpCreateFolder: // POPUP MENU - CREATE FOLDER libName = "GEOMToolsGUI"; break; case GEOMOp::OpDMWireframe: // MENU VIEW - WIREFRAME @@ -900,6 +904,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpPointMarker, "POP_POINT_MARKER" ); createGeomAction( GEOMOp::OpMaterialProperties, "POP_MATERIAL_PROPERTIES" ); createGeomAction( GEOMOp::OpPredefMaterCustom, "POP_PREDEF_MATER_CUSTOM" ); + createGeomAction( GEOMOp::OpCreateFolder, "POP_CREATE_FOLDER" ); createGeomAction( GEOMOp::OpPipeTShape, "PIPETSHAPE" ); @@ -1268,7 +1273,7 @@ void GeometryGUI::initialize( CAM_Application* app ) QtxPopupMgr* mgr = popupMgr(); mgr->insert( action( GEOMOp::OpDelete ), -1, -1 ); // delete - mgr->setRule( action( GEOMOp::OpDelete ), QString("$type in {'Shape' 'Group'} and selcount>0"), QtxPopupMgr::VisibleRule ); + mgr->setRule( action( GEOMOp::OpDelete ), QString("$type in {'Shape' 'Group' 'Folder'} and selcount>0"), QtxPopupMgr::VisibleRule ); mgr->insert( action( GEOMOp::OpGroupCreatePopup ), -1, -1 ); // create group mgr->setRule( action( GEOMOp::OpGroupCreatePopup ), QString("type='Shape' and selcount=1 and isOCC=true"), QtxPopupMgr::VisibleRule ); mgr->insert( action( GEOMOp::OpDiscloseChildren ), -1, -1 ); // disclose child items @@ -1282,7 +1287,7 @@ void GeometryGUI::initialize( CAM_Application* app ) #if OCC_VERSION_LARGE > 0x06050200 //QString bringRule = clientOCCorOB + " and ($component={'GEOM'}) and (selcount>0) and isOCC=true and topLevel=false"; - QString bringRule = clientOCCorOB + " and ($component={'GEOM'}) and (selcount>0) and isOCC=true"; + QString bringRule = clientOCCorOB + " and ($component={'GEOM'}) and isFolder=false and (selcount>0) and isOCC=true"; mgr->insert( action(GEOMOp::OpBringToFront ), -1, -1 ); // bring to front mgr->setRule(action(GEOMOp::OpBringToFront), bringRule, QtxPopupMgr::VisibleRule ); mgr->setRule(action(GEOMOp::OpBringToFront), "topLevel=true", QtxPopupMgr::ToggleRule ); @@ -1400,6 +1405,10 @@ void GeometryGUI::initialize( CAM_Application* app ) mgr->insert( action( GEOMOp::OpReimport ), -1, -1 ); // delete mgr->setRule( action( GEOMOp::OpReimport ), QString("$imported in {'true'} and selcount>0"), QtxPopupMgr::VisibleRule ); + mgr->insert( separator(), -1, -1 ); // ----------- + mgr->insert( action( GEOMOp::OpCreateFolder ), -1, -1 ); // Create Folder + mgr->setRule( action( GEOMOp::OpCreateFolder ), QString("client='ObjectBrowser' and (isComponent=true or isFolder=true)"), QtxPopupMgr::VisibleRule ); + mgr->hide( mgr->actionId( action( myEraseAll ) ) ); SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); @@ -2591,12 +2600,12 @@ bool GeometryGUI::renameObject( const QString& entry, const QString& name) if ( obj->FindAttribute(anAttr, "AttributeName") ) { _PTR(AttributeName) aName (anAttr); + aName->SetValue( name.toLatin1().data() ); // rename the SObject GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(obj)); if (!CORBA::is_nil(anObj)) { - aName->SetValue( name.toLatin1().data() ); // rename the SObject anObj->SetName( name.toLatin1().data() ); // Rename the corresponding GEOM_Object - result = true; } + result = true; } } return result; @@ -2620,3 +2629,140 @@ void GeometryGUI::updateMaterials() } } } + +/*! + \brief Check if the module allows "drag" operation of its objects. + + Overloaded from LightApp_Module class. + + This function is a part of the general drag-n-drop mechanism. + The goal of this function is to check data object passed as a parameter + and decide if it can be dragged or no. + + \param what data object being tested for drag operation + \return \c true if module allows dragging of the specified object + \sa isDropAccepted(), dropObjects() +*/ +bool GeometryGUI::isDraggable( const SUIT_DataObject* what ) const +{ + // we allow dragging object under root and object from folder + int aLevel = what->level(); + bool anObjectInFolder = false; + if ( aLevel > 2 ) { + const SalomeApp_DataObject* dataObj = dynamic_cast( what ); + if ( dataObj ) { + _PTR(SObject) aSO = dataObj->object(); + if ( aSO ) { + _PTR(GenericAttribute) anAttr; + _PTR(SObject) aFatherSO = aSO->GetStudy()->GetUseCaseBuilder()->GetFather( aSO ); + if ( aFatherSO && aFatherSO->FindAttribute(anAttr, "AttributeLocalID") ) { + _PTR(AttributeLocalID) aLocalID( anAttr ); + anObjectInFolder = aLocalID->Value() == 999; + } + } + } + } + return aLevel == 2 || anObjectInFolder; +} + +/*! + \brief Check if the module allows "drop" operation on the given object. + + Overloaded from LightApp_Module class. + + This function is a part of the general drag-n-drop mechanism. + The goal of this function is to check data object passed as a parameter + and decide if it can be used as a target for the "drop" operation. + The processing of the drop operation itself is done in the dropObjects() function. + + \param where target data object + \return \c true if module supports dropping on the \a where data object + \sa isDraggable(), dropObjects() +*/ +bool GeometryGUI::isDropAccepted( const SUIT_DataObject* where ) const +{ + // we allow dropping into folder and top-level GEOM object + int aLevel = where->level(); + bool isFolder = false; + if ( aLevel > 1 ) { + const SalomeApp_DataObject* dataObj = dynamic_cast( where ); + if ( dataObj ) { + _PTR(SObject) aSO = dataObj->object(); + if ( aSO ) { + _PTR(GenericAttribute) anAttr; + if ( aSO->FindAttribute(anAttr, "AttributeLocalID") ) { + _PTR(AttributeLocalID) aLocalID( anAttr ); + isFolder = aLocalID->Value() == 999; + } + } + } + } + return aLevel == 1 || isFolder; +} + +/*! + \brief Complete drag-n-drop operation. + + Overloaded from LightApp_Module class. + + This function is a part of the general drag-n-drop mechanism. + Its goal is to handle dropping of the objects being dragged according + to the chosen operation (move). The dropping is performed in the + context of the parent data object \a where and the \a row (position in the + children index) at which the data should be dropped. If \a row is equal to -1, + this means that objects are added to the end of the children list. + + \param what objects being dropped + \param where target data object + \param row child index at which the drop operation is performed + \param action drag-n-drop operation (Qt::DropAction) - move + + \sa isDraggable(), isDropAccepted() +*/ +void GeometryGUI::dropObjects( const DataObjectList& what, SUIT_DataObject* where, + const int row, Qt::DropAction action ) +{ + if (action != Qt::CopyAction && action != Qt::MoveAction) + return; // unsupported action + + // get parent object + SalomeApp_DataObject* dataObj = dynamic_cast( where ); + if ( !dataObj ) return; // wrong parent + _PTR(SObject) parentObj = dataObj->object(); + + // Find the current Study and StudyBuilder + _PTR(Study) aStudy = parentObj->GetStudy(); + _PTR(UseCaseBuilder) aUseCaseBuilder = aStudy->GetUseCaseBuilder(); + // collect all parents of the target node + QStringList parentIDs; + _PTR(SObject) parent = parentObj; + while( !parent->IsNull() ) { + parentIDs << parent->GetID().c_str(); + parent = aUseCaseBuilder->GetFather(parent); + } + + // collect objects being dropped + GEOM::object_list_var objects = new GEOM::object_list(); + objects->length( what.count() ); + int count = 0; + for ( int i = 0; i < what.count(); i++ ) { + dataObj = dynamic_cast( what[i] ); + if ( !dataObj ) continue; // skip wrong objects + _PTR(SObject) sobj = dataObj->object(); + // check that dropped object is not a parent of target object + if ( parentIDs.contains( sobj->GetID().c_str() ) ) { + return; // it's not allowed to move node into it's child + } + objects[i] = _CAST(SObject, sobj)->GetSObject(); + count++; + } + objects->length( count ); + + // call engine function + GetGeomGen()->Move( objects.in(), // what + _CAST(SObject, parentObj)->GetSObject(), // where + row ); // row + + // update Object browser + getApp()->updateObjectBrowser( false ); +} diff --git a/src/GEOMGUI/GeometryGUI.h b/src/GEOMGUI/GeometryGUI.h index fb23e5683..d7b820851 100644 --- a/src/GEOMGUI/GeometryGUI.h +++ b/src/GEOMGUI/GeometryGUI.h @@ -143,6 +143,11 @@ public: static QString GetIORFromObject( GEOM::GEOM_Object_ptr object ); + virtual bool isDraggable( const SUIT_DataObject* what ) const; + virtual bool isDropAccepted( const SUIT_DataObject* where ) const; + virtual void dropObjects( const DataObjectList& what, + SUIT_DataObject* where, + const int row, Qt::DropAction action ); public slots: virtual bool deactivateModule( SUIT_Study* ); diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index 04b339917..77ca348a3 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -59,6 +59,7 @@ namespace GEOMOp { OpPublishObject = 1254, // GEOM ROOT OBJECT - POPUP MENU - PUBLISH OpEdgeWidth = 1260, // POPUP MENU - LINE WIDTH - EDGE WIDTH OpIsosWidth = 1261, // POPUP MENU - LINE WIDTH - ISOS WIDTH + OpCreateFolder = 1262, // POPUP MENU - CREATE FOLDER // DisplayGUI ------------------//-------------------------------- OpSwitchVectors = 2001, // MENU VIEW - DISPLAY MODE - SHOW/HIDE EDGE DIRECTION OpShowAll = 2002, // MENU VIEW - SHOW ALL diff --git a/src/GEOMToolsGUI/GEOMToolsGUI.cxx b/src/GEOMToolsGUI/GEOMToolsGUI.cxx index 31e2fca51..0ebb58902 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI.cxx @@ -386,6 +386,9 @@ bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent) case GEOMOp::OpClsBringToFront: OnClsBringToFront(); break; + case GEOMOp::OpCreateFolder: + OnCreateFolder(); + break; default: SUIT_Session::session()->activeApplication()->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID)); break; diff --git a/src/GEOMToolsGUI/GEOMToolsGUI.h b/src/GEOMToolsGUI/GEOMToolsGUI.h index 05f1a1708..b5fe325e3 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI.h +++ b/src/GEOMToolsGUI/GEOMToolsGUI.h @@ -88,6 +88,7 @@ private: void OnIsosWidth(); void OnBringToFront(); void OnClsBringToFront(); + void OnCreateFolder(); // Shortcut commands void OnChangeTransparency( bool ); diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx index f2ede2679..5d158445f 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx @@ -51,6 +51,8 @@ #include #include +#include + #include #include @@ -806,3 +808,30 @@ void GEOMToolsGUI::OnSetMaterial( const QVariant& theParam ) } displayer.UpdateViewer(); } + +void GEOMToolsGUI::OnCreateFolder() +{ + SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() ); + if ( !app ) return; + + SalomeApp_Study* appStudy = dynamic_cast< SalomeApp_Study* >( app->activeStudy() ); + if ( !appStudy ) return; + + LightApp_SelectionMgr* aSelMgr = app->selectionMgr(); + if ( !aSelMgr ) return; + + SALOME_ListIO selected; + aSelMgr->selectedObjects( selected ); + if ( selected.IsEmpty() ) return; + + Handle(SALOME_InteractiveObject) anIObject = selected.First(); + + _PTR(Study) aStudy = appStudy->studyDS(); + if( !aStudy ) return; + _PTR(SObject) aFatherSO(aStudy->FindObjectID(anIObject->getEntry())); + if ( !aFatherSO ) return; + + GeometryGUI::GetGeomGen()->CreateFolder( tr("NEW_FOLDER_NAME").toLatin1().constData(), + _CAST(SObject, aFatherSO)->GetSObject() ); + app->updateObjectBrowser( false ); +} diff --git a/src/GEOM_I/GEOM_DumpPython.cc b/src/GEOM_I/GEOM_DumpPython.cc index 010a24842..4e982647a 100644 --- a/src/GEOM_I/GEOM_DumpPython.cc +++ b/src/GEOM_I/GEOM_DumpPython.cc @@ -183,6 +183,61 @@ Engines::TMPFile* GEOM_Gen_i::DumpPython(CORBA::Object_ptr theStudy, } } } + + TCollection_AsciiString aDirScript, aNodeName, aNodeEntry, aFatherName, aFatherEntry; + aDirScript += "\n\t### Folders and it's content\n"; + Resource_DataMapOfAsciiStringAsciiString aNameToEntry; + SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder(); + SALOMEDS::UseCaseIterator_var Itr = useCaseBuilder->GetUseCaseIterator(aSO); + SALOMEDS::SObject_var aNodeSO; + SALOMEDS::SObject_var aFatherSO; + SALOMEDS::GenericAttribute_var anIDAttr; + for(Itr->Init(true); Itr->More(); Itr->Next()) { + aFatherName.Clear(); + aFatherEntry.Clear(); + aNodeSO = Itr->Value(); + // get father info + aFatherSO = useCaseBuilder->GetFather( aNodeSO ); + if ( aFatherSO->FindAttribute(anIDAttr, "AttributeLocalID") ) { + SALOMEDS::AttributeLocalID_var aLocalID = SALOMEDS::AttributeLocalID::_narrow(anIDAttr); + if ( aLocalID->Value() == 999 ) { + aFatherName = aFatherSO->GetName(); + aFatherEntry = aFatherSO->GetID(); + _impl->healPyName( aFatherName, aFatherEntry, aNameToEntry); + } + aLocalID->UnRegister(); + } + // get node info + if ( aNodeSO->FindAttribute(anIDAttr, "AttributeLocalID") ) { + SALOMEDS::AttributeLocalID_var aLocalID = SALOMEDS::AttributeLocalID::_narrow(anIDAttr); + if ( aLocalID->Value() == 999 ) { + // the node is folder + aNodeName = aNodeSO->GetName(); + aNodeEntry = aNodeSO->GetID(); + _impl->healPyName( aNodeName, aNodeEntry, aNameToEntry); + aDirScript += aNodeName; + aDirScript += " = geompy.NewFolder('"; + aDirScript += aNodeSO->GetName(); + aDirScript += "'"; + if ( !aFatherName.IsEmpty() && !aFatherEntry.IsEmpty() ) { + // the folder takes place under another folder + aDirScript += ", "; + aDirScript += aFatherName; + } + aDirScript += ")\n"; + aNameToEntry.Bind( aNodeName, aNodeEntry ); + } + aLocalID->UnRegister(); + } else if ( !aFatherName.IsEmpty() && !aFatherEntry.IsEmpty() ) { + // the node is Geom object under folder + aDirScript += "geompy.PutToFolder("; + aDirScript += GetDumpName( aNodeSO->GetID() ); + aDirScript += ", "; + aDirScript += aFatherName; + aDirScript += ")\n"; + } + } + aScript += aDirScript; //Output the script that sets up the visual parameters. char* script = aStudy->GetDefaultScript(ComponentDataType(), "\t"); diff --git a/src/GEOM_I/GEOM_Gen_i.cc b/src/GEOM_I/GEOM_Gen_i.cc index b94b5f81f..326810804 100644 --- a/src/GEOM_I/GEOM_Gen_i.cc +++ b/src/GEOM_I/GEOM_Gen_i.cc @@ -176,6 +176,7 @@ SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy, SALOMEDS::GenericAttribute_var anAttr; SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder(); + SALOMEDS::UseCaseBuilder_var useCaseBuilder = theStudy->GetUseCaseBuilder(); SALOMEDS::SComponent_var aFather = theStudy->FindComponent("GEOM"); if (aFather->_is_nil()) { @@ -189,6 +190,10 @@ SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy, aPixMap->SetPixMap("ICON_OBJBROWSER_Geometry"); aPixMap->UnRegister(); aStudyBuilder->DefineComponentInstance(aFather, (GEOM::GEOM_Gen_var)GEOM_Gen::_this()); + // add component to the use case tree + // (to support tree representation customization and drag-n-drop) + useCaseBuilder->SetRootCurrent(); + useCaseBuilder->Append( aFather ); // component object is added as the top level item } if (aFather->_is_nil()) return aResultSO; @@ -348,6 +353,10 @@ SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy, //Set a name of the GEOM object aShape->SetName(aShapeName.ToCString()); + // add object to the use case tree + // (to support tree representation customization and drag-n-drop) + useCaseBuilder->AppendTo( aResultSO->GetFather(), aResultSO ); + return aResultSO._retn(); } @@ -577,6 +586,18 @@ CORBA::Boolean GEOM_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent, // Remove the created file and tmp directory if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true); + // creation of tree nodes for all data objects in the study + // to support tree representation customization and drag-n-drop: + SALOMEDS::UseCaseBuilder_var useCaseBuilder = theComponent->GetStudy()->GetUseCaseBuilder(); + if ( !useCaseBuilder->IsUseCaseNode( theComponent ) ) { + useCaseBuilder->SetRootCurrent(); + useCaseBuilder->Append( theComponent ); // component object is added as the top level item + SALOMEDS::ChildIterator_var it = theComponent->GetStudy()->NewChildIterator( theComponent ); + for (it->Init(); it->More(); it->Next()) { + useCaseBuilder->AppendTo( theComponent, it->Value() ); + } + } + return true; } @@ -2570,6 +2591,132 @@ char* GEOM_Gen_i::getVersion() #endif } +//================================================================================= +// function : CreateFolder() +// purpose : Creates and returns a new folder object +//================================================================================= +SALOMEDS::SObject_ptr GEOM_Gen_i::CreateFolder(const char* theName, + SALOMEDS::SObject_ptr theFather) +{ + SALOMEDS::SObject_var aFolderSO; + + if ( CORBA::is_nil(theFather) ) return aFolderSO._retn(); + + SALOMEDS::GenericAttribute_var anAttr; + if ( strcmp(theFather->GetFatherComponent()->GetID(), theFather->GetID()) != 0 ) { + // not a GEOM component object was selected + if ( !theFather->FindAttribute(anAttr, "AttributeLocalID") ) return aFolderSO._retn(); + SALOMEDS::AttributeLocalID_var aLocalID = SALOMEDS::AttributeLocalID::_narrow(anAttr); + if( aLocalID->Value() != 999 ) { + // not a Folder object was selected + GEOM::GEOM_Object_var aGeomObject = GEOM::GEOM_Object::_narrow(theFather); + if ( CORBA::is_nil(aGeomObject) ) return aFolderSO._retn(); + // another GEOM object was selected, so get GEOM component as father object + theFather = theFather->GetFatherComponent(); + } + aLocalID->UnRegister(); + } + + SALOMEDS::Study_var aStudy = theFather->GetStudy(); + SALOMEDS::StudyBuilder_var aStudyBuilder( aStudy->NewBuilder() ); + aFolderSO = aStudyBuilder->NewObject( theFather ); + + anAttr = aStudyBuilder->FindOrCreateAttribute(aFolderSO, "AttributeLocalID"); + SALOMEDS::AttributeLocalID_var aLocalID = SALOMEDS::AttributeLocalID::_narrow(anAttr); + aLocalID->SetValue( 999 ); // mark of the "Folder" object + aLocalID->UnRegister(); + + anAttr = aStudyBuilder->FindOrCreateAttribute(aFolderSO, "AttributeName"); + SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr); + aName->SetValue( theName ); + aName->UnRegister(); + + anAttr = aStudyBuilder->FindOrCreateAttribute(aFolderSO, "AttributePixMap"); + SALOMEDS::AttributePixMap_var aPixMap = SALOMEDS::AttributePixMap::_narrow(anAttr); + aPixMap->SetPixMap("ICON_FOLDER"); + aPixMap->UnRegister(); + + // add object to the use case tree + // (to support tree representation customization and drag-n-drop) + SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder(); + useCaseBuilder->AppendTo( theFather, aFolderSO ); + + return aFolderSO._retn(); +} + +//================================================================================= +// function : MoveToFolder() +// purpose : Moves GEOM object to the specified folder +//================================================================================= +void GEOM_Gen_i::MoveToFolder(GEOM::GEOM_Object_ptr theObject, + SALOMEDS::SObject_ptr theFolder) { + GEOM::object_list_var objects = new GEOM::object_list(); + objects->length( 1 ); + SALOMEDS::SObject_var aSO = theFolder->GetStudy()->FindObjectID( theObject->GetStudyEntry() ); + objects[0] = aSO; + Move( objects, theFolder, -1 ); +} + +//================================================================================= +// function : MoveListToFolder() +// purpose : Moves list of GEOM objects to the specified folder +//================================================================================= +void GEOM_Gen_i::MoveListToFolder (const GEOM::ListOfGO& theListOfGO, + SALOMEDS::SObject_ptr theFolder) { + int aLen = theListOfGO.length(); + GEOM::object_list_var objects = new GEOM::object_list(); + objects->length( aLen ); + GEOM::GEOM_Object_var aGO; + SALOMEDS::SObject_var aSO; + for (int i = 0; i < aLen; i++) { + aGO = GEOM::GEOM_Object::_duplicate( theListOfGO[i] ); + aSO = theFolder->GetStudy()->FindObjectID( aGO->GetStudyEntry() ); + objects[i] = aSO; + } + if ( objects->length() > 0 ) + Move( objects, theFolder, -1 ); +} + +//================================================================================= +// function : Move() +// purpose : Moves objects to the specified position. +// Is used in the drag-n-drop functionality. +//================================================================================= +void GEOM_Gen_i::Move( const GEOM::object_list& what, + SALOMEDS::SObject_ptr where, + CORBA::Long row ) +{ + if ( CORBA::is_nil( where ) ) return; + + SALOMEDS::Study_var study = where->GetStudy(); + SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder(); + SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder(); + SALOMEDS::SComponent_var father = where->GetFatherComponent(); + std::string dataType = father->ComponentDataType(); + if ( dataType != "GEOM" ) return; // not a GEOM component + + SALOMEDS::SObject_var objAfter; + if ( row >= 0 && useCaseBuilder->HasChildren( where ) ) { + // insert at given row -> find insertion position + SALOMEDS::UseCaseIterator_var useCaseIt = useCaseBuilder->GetUseCaseIterator( where ); + int i; + for ( i = 0; i < row && useCaseIt->More(); i++, useCaseIt->Next() ); + if ( i == row && useCaseIt->More() ) { + objAfter = useCaseIt->Value(); + } + } + + for ( int i = 0; i < what.length(); i++ ) { + SALOMEDS::SObject_var sobj = what[i]; + if ( CORBA::is_nil( sobj ) ) continue; // skip bad object + // insert the object to the use case tree + if ( !CORBA::is_nil( objAfter ) ) + useCaseBuilder->InsertBefore( sobj, objAfter ); // insert at given row + else + useCaseBuilder->AppendTo( where, sobj ); // append to the end of list + } +} + //===================================================================================== // EXPORTED METHODS //===================================================================================== diff --git a/src/GEOM_I/GEOM_Gen_i.hh b/src/GEOM_I/GEOM_Gen_i.hh index 35fc9ad75..0b264cfd0 100644 --- a/src/GEOM_I/GEOM_Gen_i.hh +++ b/src/GEOM_I/GEOM_Gen_i.hh @@ -272,6 +272,23 @@ class GEOM_I_EXPORT GEOM_Gen_i: virtual public POA_GEOM::GEOM_Gen, virtual publi // Version information virtual char* getVersion(); + // Create a new folder object + SALOMEDS::SObject_ptr CreateFolder(const char* theName, + SALOMEDS::SObject_ptr theFather); + + // Move GEOM object to the specified folder + void MoveToFolder(GEOM::GEOM_Object_ptr theObject, + SALOMEDS::SObject_ptr theFolder); + + // Move list of GEOM objects to the specified folder + void MoveListToFolder (const GEOM::ListOfGO& theListOfGO, + SALOMEDS::SObject_ptr theFolder); + + // Move objects to the specified position + void Move( const GEOM::object_list& what, + SALOMEDS::SObject_ptr where, + CORBA::Long row ); + //-----------------------------------------------------------------------// // Internal methods // //-----------------------------------------------------------------------// diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 013c70a6a..1b63d3904 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -685,6 +685,10 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): self.BlocksOp = self.GetIBlocksOperations (self.myStudyId) self.GroupOp = self.GetIGroupOperations (self.myStudyId) self.AdvOp = self.GetIAdvancedOperations (self.myStudyId) + # set GEOM as root in the use case tree + self.myUseCaseBuilder = self.myStudy.GetUseCaseBuilder() + self.myUseCaseBuilder.SetRootCurrent() + self.myUseCaseBuilder.Append(self.father) pass ## Enable / disable results auto-publishing @@ -12365,6 +12369,54 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): RaiseIfFailed("AddTexture", self.InsertOp) return ID + ## Creates a new folder object. It is a container for any GEOM objects. + # @param Name name of the container + # @param Father parent object. If None, + # folder under 'Geometry' root object will be created. + # @return a new created folder + def NewFolder(self, Name, Father=None): + """ + Create a new folder object. It is an auxiliary container for any GEOM objects. + + Parameters: + Name name of the container + Father parent object. If None, + folder under 'Geometry' root object will be created. + + Returns: + a new created folder + """ + if not Father: Father = self.father + return self.CreateFolder(Name, Father) + + ## Move object to the specified folder + # @param Object object to move + # @param Folder target folder + def PutToFolder(self, Object, Folder): + """ + Move object to the specified folder + + Parameters: + Object object to move + Folder target folder + """ + self.MoveToFolder(Object, Folder) + pass + + ## Move list of objects to the specified folder + # @param ListOfSO list of objects to move + # @param Folder target folder + def PutListToFolder(self, ListOfSO, Folder): + """ + Move list of objects to the specified folder + + Parameters: + ListOfSO list of objects to move + Folder target folder + """ + self.MoveListToFolder(ListOfSO, Folder) + pass + import omniORB # Register the new proxy for GEOM_Gen omniORB.registerObjref(GEOM._objref_GEOM_Gen._NP_RepositoryId, geomBuilder) -- 2.39.2