]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
Implementation of 0021855: EDF 2321 GEOM : Add folders to group objects in the object...
authorakl <akl@opencascade.com>
Fri, 28 Jun 2013 08:18:20 +0000 (08:18 +0000)
committerakl <akl@opencascade.com>
Fri, 28 Jun 2013 08:18:20 +0000 (08:18 +0000)
30 files changed:
doc/salome/examples/Makefile.am
doc/salome/examples/arranging_study_objects.py [new file with mode: 0644]
doc/salome/gui/GEOM/images/arranging1.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/arranging2.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/arranging3.png [new file with mode: 0644]
doc/salome/gui/GEOM/input/arranging_study_objects_page.doc [new file with mode: 0644]
doc/salome/gui/GEOM/input/geompy.doc
doc/salome/gui/GEOM/input/index.doc
doc/salome/gui/GEOM/input/tui_arranging_study_objects.doc [new file with mode: 0644]
idl/GEOM_Gen.idl
resources/Makefile.am
resources/folder.png [new file with mode: 0644]
src/GEOM/GEOM_Engine.cxx
src/GEOM/GEOM_Engine.hxx
src/GEOMGUI/GEOMGUI_Selection.cxx
src/GEOMGUI/GEOMGUI_Selection.h
src/GEOMGUI/GEOM_Displayer.cxx
src/GEOMGUI/GEOM_images.ts
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GEOM_msg_fr.ts
src/GEOMGUI/GeometryGUI.cxx
src/GEOMGUI/GeometryGUI.h
src/GEOMGUI/GeometryGUI_Operations.h
src/GEOMToolsGUI/GEOMToolsGUI.cxx
src/GEOMToolsGUI/GEOMToolsGUI.h
src/GEOMToolsGUI/GEOMToolsGUI_1.cxx
src/GEOM_I/GEOM_DumpPython.cc
src/GEOM_I/GEOM_Gen_i.cc
src/GEOM_I/GEOM_Gen_i.hh
src/GEOM_SWIG/geomBuilder.py

index 211c7932efadb5cc623e93947854d6357affcb0f..034ad15976c562c933fb054b0244c0de565d6630 100644 (file)
@@ -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 (file)
index 0000000..bedbe61
--- /dev/null
@@ -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 (file)
index 0000000..5a50eda
Binary files /dev/null and b/doc/salome/gui/GEOM/images/arranging1.png differ
diff --git a/doc/salome/gui/GEOM/images/arranging2.png b/doc/salome/gui/GEOM/images/arranging2.png
new file mode 100644 (file)
index 0000000..2ca6c53
Binary files /dev/null and b/doc/salome/gui/GEOM/images/arranging2.png differ
diff --git a/doc/salome/gui/GEOM/images/arranging3.png b/doc/salome/gui/GEOM/images/arranging3.png
new file mode 100644 (file)
index 0000000..04cc29a
Binary files /dev/null and b/doc/salome/gui/GEOM/images/arranging3.png differ
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 (file)
index 0000000..44df8f8
--- /dev/null
@@ -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:
+<ul> 
+<li> geometrical model(s) under root "Geometry" item or under any folder
+<li> folder(s)
+</ul>
+
+Our <b>TUI Scripts</b> provide you with useful examples of 
+\ref tui_arranging_study_objects "Arranging objects in study".
+
+*/
+
index b339d3b64b95883fa9010af8f175b716aefa58da..43cee55d2523616bc1f61d5804ac37023b2476e7 100644 (file)
@@ -44,6 +44,7 @@ provided by Geometry module.
   </ul>
   <li>\subpage tui_measurement_tools_page</li>
   <li>\subpage tui_notebook_geom_page</li>
+  <li>\subpage tui_arranging_study_objects_page</li>
   <li>\subpage tui_swig_examples_page</li>
   <ul>
     <li>\ref tui_test_others_page</li>
index 55a17a2309f6086e84dbf387d748952ea3eceb76..db275aa4a807978f1c3fefab39f0d940a7a9e625 100644 (file)
 - 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 <a class="el" target="_new" href="../../tui/GEOM/docutils/index.html">salome.geom python package</a>.
+
 You can find the answer to some Frequently Asked Questions in this page:
 - \subpage faq "Frequently Asked Questions"
 
-Other functions are available in <a class="el" target="_new" href="../../tui/GEOM/docutils/index.html">salome.geom python package</a>.
-
 \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 (file)
index 0000000..b93b85b
--- /dev/null
@@ -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}
+
+*/
index bbd4cf7c11932dbfd5f36fefd28709f5ebc74ee1..23083c1f450e88f4c670b0bf8046cd019bdfaa6b 100644 (file)
@@ -219,6 +219,7 @@ module GEOM
   interface GEOM_Object;
 
   typedef sequence<GEOM_Object> ListOfGO;
+  typedef sequence<SALOMEDS::SObject> 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 );
   };
 };
 
index b36757b3bea6fe67a96e25e88256c6efad512f2a..90ca30a6756b08a2da9fac0960f7503924b9c92a 100644 (file)
@@ -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 (file)
index 0000000..841eba0
Binary files /dev/null and b/resources/folder.png differ
index 6f0addd83b4a6f94fd1cefeb1f1cac7721276cb8..900a70113064274449001fb6d47f96cc8b2c7f41 100644 (file)
@@ -153,31 +153,28 @@ void PublishObject (TObjectData&                              theObjectData,
                     std::map< int, TCollection_AsciiString >& theEntryToCmdMap,
                     std::set<TCollection_AsciiString>&        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;
index 07684af8835036e55051a87562d5a6127775fed0..38d954a0e34c4c048d6298ed8033e16dc4b2218d 100644 (file)
@@ -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);       
   
index dd19cf2ba4abde08ffb791ded07f2cd2cf4282e5..fdf8f84512c9095cef7cd053218f3e1391d7bab9 100644 (file)
@@ -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<SalomeApp_Study*>( 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;
+}
+
index 8e367b1c34fcee7ddf5786bf23ebac9f25b95d14..c8c1230d937a26a117fe0186557e3c6f16abcb0c 100644 (file)
@@ -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;
index 95b50621ccd42f5adb0958bd2b801d84d6420c7d..8f832c9d30f6b582debee9d6b31ed0f07cb4fb8f 100644 (file)
@@ -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 )
index 1ff0697a77d2eaf0677c14b71b74751454e1027d..667c075145ff3ecf2f3841c3e8eabd3d88f01d58 100644 (file)
@@ -3,6 +3,10 @@
 <TS version="2.0" language="en_US">
     <context>
         <name>@default</name>
+        <message>
+            <source>ICON_FOLDER</source>
+            <translation>folder.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_ADD_POINT_ON_EDGE</source>
             <translation>pointonedge.png</translation>
index 211ee35418ccff55a41154bb0829b20f9802d999..32cb42f361240e2582bf25b414d6793dfd328263 100644 (file)
@@ -4640,6 +4640,18 @@ Please, select face, shell or solid and try again</translation>
         <source>STB_POP_DISABLE_AUTO_COLOR</source>
         <translation>Disable auto color</translation>
     </message>
+    <message>
+        <source>MEN_POP_CREATE_FOLDER</source>
+        <translation>Create folder</translation>
+    </message>
+    <message>
+        <source>STB_POP_CREATE_FOLDER</source>
+        <translation>Create a new folder</translation>
+    </message>
+    <message>
+        <source>NEW_FOLDER_NAME</source>
+        <translation>NewFolder</translation>
+    </message>
     <message>
         <source>GEOM_RESULT_NAME_GRP</source>
         <translation>Result name</translation>
index 8f8e537f6f7a6b2bd409b24057fae8628ce62da0..065f5fb7b0810cf7bc907f49bae3b12d3fcb4e43 100644 (file)
@@ -4646,6 +4646,18 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
         <source>STB_POP_DISABLE_AUTO_COLOR</source>
         <translation>Désactiver la couleur automatique</translation>
     </message>
+    <message>
+        <source>MEN_POP_CREATE_FOLDER</source>
+        <translation type="unfinished">Create folder</translation>
+    </message>
+    <message>
+        <source>STB_POP_CREATE_FOLDER</source>
+        <translation type="unfinished">Create a new folder</translation>
+    </message>
+    <message>
+        <source>NEW_FOLDER_NAME</source>
+        <translation type="unfinished">NewFolder</translation>
+    </message>
     <message>
         <source>GEOM_RESULT_NAME_GRP</source>
         <translation>Nom du résultat</translation>
index 3a786e03a0dcc00bb19bfcdce72b1e2bccaead11..0d79f320d2af505e6199d0d42ac6ecea9c3a1972 100644 (file)
@@ -77,6 +77,8 @@
 #include <SALOMEDSClient_ClientFactory.hxx>
 #include <SALOMEDSClient_IParameters.hxx>
 
+#include <SALOMEDS_SObject.hxx>
+
 #include <Basics_OCCTVersion.hxx>
 
 // 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<const SalomeApp_DataObject*>( 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<const SalomeApp_DataObject*>( 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<SalomeApp_DataObject*>( 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<SalomeApp_DataObject*>( 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 );
+}
index fb23e5683b90dd429c5b98cdf91323bc644d07a1..d7b820851f801629408a3f311a0678b992f345c0 100644 (file)
@@ -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* );
index 04b33991713387746cb7fe7970646c0810033751..77ca348a3675791e2e52086af0526f91e6e2d23f 100644 (file)
@@ -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
index 31e2fca51a60d6b50621a6b26a5a0eb6031cfc89..0ebb58902519837ad794656a16edac8b6ee12854 100644 (file)
@@ -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;
index 05f1a1708419aac2eb026b45ca393bfa30801aac..b5fe325e37446aa94f612f46ed31c24a63af3b46 100644 (file)
@@ -88,6 +88,7 @@ private:
   void         OnIsosWidth();
   void         OnBringToFront();
   void         OnClsBringToFront();
+  void         OnCreateFolder();
 
   // Shortcut commands
   void         OnChangeTransparency( bool );
index f2ede26792947a88385f3c86328b2e656c7f638d..5d158445fe3051b29e15ddbf0752175257e30fc8 100644 (file)
@@ -51,6 +51,8 @@
 #include <SALOME_ListIO.hxx>
 #include <SALOME_ListIteratorOfListIO.hxx>
 
+#include <SALOMEDS_SObject.hxx>
+
 #include <SOCC_Prs.h>
 
 #include <SVTK_Prs.h>
@@ -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 );
+}
index 010a24842ba07e88723af569b53fc2db2f788dec..4e982647a4fe42268b8eedf22217dc675e6c5a59 100644 (file)
@@ -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");
index b94b5f81f5f6594778c4fed07cff9b5b617ebf54..326810804e25f82a13a7d26f9476c88bd31d20c9 100644 (file)
@@ -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
 //=====================================================================================
index 35fc9ad75102663eac6c42a1b5b71f4fd0a1255a..0b264cfd0800e1b37c2a8c2b795dc99e75194d46 100644 (file)
@@ -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                                                      //
   //-----------------------------------------------------------------------//
index 013c70a6af3c5b8998fda05a6f418eebfb2174e5..1b63d3904e58de1097444764871209e8c4296c6d 100644 (file)
@@ -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)