]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge branch 'master' of newgeom:newgeom.git
authorsbh <sergey.belash@opencascade.com>
Thu, 22 May 2014 09:46:23 +0000 (13:46 +0400)
committersbh <sergey.belash@opencascade.com>
Thu, 22 May 2014 09:46:23 +0000 (13:46 +0400)
Conflicts:
src/XGUI/XGUI_Workshop.h

51 files changed:
CMakeCommon/FindSolveSpace.cmake
CMakeLists.txt
linux_env.sh
src/Config/Config_ModuleReader.cpp
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Events.cpp
src/Model/Model_Events.h
src/Model/Model_PluginManager.cpp
src/Model/Model_PluginManager.h
src/ModelAPI/ModelAPI_Document.h
src/ModelAPI/ModelAPI_Feature.h
src/ModelAPI/ModelAPI_PluginManager.h
src/PartSet/CMakeLists.txt
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_OperationEditLine.cpp
src/PartSet/PartSet_OperationEditLine.h
src/PartSet/PartSet_OperationSketch.cpp
src/PartSet/PartSet_OperationSketch.h
src/PartSet/PartSet_OperationSketchBase.cpp
src/PartSet/PartSet_OperationSketchBase.h
src/PartSet/PartSet_OperationSketchLine.cpp
src/PartSet/PartSet_OperationSketchLine.h
src/PartSetPlugin/CMakeLists.txt
src/PartSetPlugin/PartSetPlugin_Duplicate.cpp [new file with mode: 0644]
src/PartSetPlugin/PartSetPlugin_Duplicate.h [new file with mode: 0644]
src/PartSetPlugin/PartSetPlugin_Plugin.cpp
src/PartSetPlugin/PartSetPlugin_Remove.cpp [new file with mode: 0644]
src/PartSetPlugin/PartSetPlugin_Remove.h [new file with mode: 0644]
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_Constraint.h
src/SketchPlugin/SketchPlugin_ConstraintCoincidence.h
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchSolver/CMakeLists.txt
src/SketchSolver/SketchSolver_ConstraintManager.cpp
src/SketchSolver/SketchSolver_ConstraintManager.h
src/SketchSolver/SketchSolver_Solver.h
src/XGUI/XGUI_ContextMenuMgr.cpp
src/XGUI/XGUI_DataTreeModel.h
src/XGUI/XGUI_DocumentDataModel.cpp
src/XGUI/XGUI_DocumentDataModel.h
src/XGUI/XGUI_ObjectsBrowser.cpp
src/XGUI/XGUI_ObjectsBrowser.h
src/XGUI/XGUI_PartDataModel.cpp
src/XGUI/XGUI_PartDataModel.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h
src/XGUI/XGUI_pictures.qrc
src/XGUI/pictures/delete.png [new file with mode: 0644]
src/XGUI/pictures/rename_edit.png [new file with mode: 0644]

index b373d2c407bdc94a52350e142c282171fcd3843e..d3c0811e0d30278be45bebf4a42eb4b028160174 100644 (file)
@@ -3,4 +3,4 @@ SET(SLVS_ROOT_DIR $ENV{SOLVESPACE_ROOT_DIR})
 INCLUDE_DIRECTORIES(${SLVS_ROOT_DIR}/include)
 LINK_DIRECTORIES(${SLVS_ROOT_DIR}/lib)
 
-SET(SLVS_LIBRARIES ${SLVS_ROOT_DIR}/lib/slvs.lib)
+SET(SLVS_LIBRARIES slvs)
index 18fbdfc7ca1c0001200b8802ed1aec2b4e92c936..bef4cdee832db553cbc8fc76202f5bfcf6f52b3b 100644 (file)
@@ -17,6 +17,7 @@ IF(UNIX)
         MESSAGE(STATUS "Setting -std=c++0x flag for the gcc...")
         MESSAGE(STATUS "Now gcc flags are: " ${CMAKE_CXX_FLAGS})
         
+       SET(CMAKE_SHARED_LINKER_FLAGS "${SMAKE_SHARED_LINKER_FLAGS} -Wl,-E")
     ENDIF(CMAKE_COMPILER_IS_GNUCC)
 ENDIF(UNIX)
 
index 8fb9f33ff6c1dacff7fe498a82373748eebd3249..4466e33553acbf71c2c99283360fcc87b4ab907c 100644 (file)
@@ -27,8 +27,8 @@ export PATH=${QT4_ROOT_DIR}/bin:${PATH}
 export LD_LIBRARY_PATH=${QT4_ROOT_DIR}/lib:${LD_LIBRARY_PATH}
 ##
 #------ boost ------
-#export BOOST_ROOT_DIR=${PDIR}/boost-1.52.0
-#export LD_LIBRARY_PATH ${BOOST_ROOT_DIR}/lib
+export BOOST_ROOT_DIR=${PDIR}/boost-1.52.0
+export LD_LIBRARY_PATH ${BOOST_ROOT_DIR}/lib
 ##
 #------ swig ------
 export SWIG_ROOT_DIR=${PDIR}/swig-2.0.8
index 9d9a78a021bff806585e244192c4236934a69ddb..c533e3e3e92b69565f2a5494ee1bbdb9aeaef5d6 100644 (file)
@@ -96,7 +96,7 @@ void Config_ModuleReader::loadLibrary(const std::string theLibName)
     Events_Error::send(errorMsg);
   }
 #else
-  void* aModLib = dlopen( aFileName.c_str(), RTLD_LAZY );
+  void* aModLib = dlopen( aFileName.c_str(), RTLD_LAZY | RTLD_GLOBAL );
   if ( !aModLib ) {
     std::cerr << "Failed to load " << aFileName.c_str() << std::endl;
   }
index 8208461788b13859e6d1d7f4f0d13ce9d4f4dbf2..37f1a8673a860b8e35152136df6729f400b62037 100644 (file)
@@ -20,6 +20,9 @@
 #include <TDataStd_Name.hxx>
 
 #include <climits>
+#ifndef WIN32
+#include <sys/stat.h>
+#endif
 
 #ifdef WIN32
 # define _separator_ '\\'
@@ -164,7 +167,8 @@ void Model_Document::close()
     subDocument(*aSubIter)->close();
   mySubs.clear();
   // close this
-  myDoc->Close();
+  if (myDoc->CanClose() == CDM_CCS_OK)
+    myDoc->Close();
   Model_Application::getApplication()->deleteDocument(myID);
 }
 
@@ -296,6 +300,8 @@ static void AddToRefArray(TDF_Label& theArrayLab, TDF_Label& theReferenced) {
 
 void Model_Document::addFeature(const boost::shared_ptr<ModelAPI_Feature> theFeature)
 {
+  if (theFeature->isAction()) return; // do not add action to the data model
+
   boost::shared_ptr<ModelAPI_Document> aThis = 
     Model_Application::getApplication()->getDocument(myID);
   TDF_Label aFeaturesLab = groupLabel(FEATURES_GROUP);
@@ -325,7 +331,8 @@ void Model_Document::addFeature(const boost::shared_ptr<ModelAPI_Feature> theFea
   TDF_Label anObjLab = aGroupLab.NewChild();
   TCollection_ExtendedString aName(theFeature->data()->getName().c_str());
   TDataStd_Name::Set(anObjLab, aName);
-  AddToRefArray(aGroupLab.FindChild(1), anObjLab); // reference to names is on the first sub
+  TDF_Label aGrLabChild = aGroupLab.FindChild(1);
+  AddToRefArray(aGrLabChild, anObjLab); // reference to names is on the first sub
 
   // event: feature is added
   static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_CREATED);
@@ -333,6 +340,63 @@ void Model_Document::addFeature(const boost::shared_ptr<ModelAPI_Feature> theFea
   Events_Loop::loop()->send(aMsg);
 }
 
+/// Appenad to the array of references a new referenced label.
+/// If theIndex is not -1, removes element at thisindex, not theReferenced.
+/// \returns the index of removed element
+static int RemoveFromRefArray(
+  TDF_Label theArrayLab, TDF_Label theReferenced, const int theIndex = -1) {
+  int aResult = -1; // no returned
+  Handle(TDataStd_ReferenceArray) aRefs;
+  if (theArrayLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
+    if (aRefs->Length() == 1) { // just erase an array
+      if ((theIndex == -1 && aRefs->Value(0) == theReferenced) || theIndex == 0)
+        theArrayLab.ForgetAttribute(TDataStd_ReferenceArray::GetID());
+      aResult = 0;
+    } else { // reduce the array
+      Handle(TDataStd_HLabelArray1) aNewArray = 
+        new TDataStd_HLabelArray1(aRefs->Lower(), aRefs->Upper() - 1);
+      int aCount = aRefs->Lower();
+      for(int a = aCount; a <= aRefs->Upper(); a++, aCount++) {
+        if ((theIndex == -1 && aRefs->Value(a) == theReferenced) || theIndex == a) {
+          aCount--;
+          aResult = a;
+        } else {
+          aNewArray->SetValue(aCount, aRefs->Value(a));
+        }
+      }
+    aRefs->SetInternalArray(aNewArray);
+    }
+  }
+  return aResult;
+}
+
+void Model_Document::removeFeature(boost::shared_ptr<ModelAPI_Feature> theFeature)
+{
+  boost::shared_ptr<Model_Data> aData = boost::static_pointer_cast<Model_Data>(theFeature->data());
+  TDF_Label aFeatureLabel = aData->label();
+  // remove the object
+  TDF_Label aGroupLabel = groupLabel(theFeature->getGroup());
+  int aRemovedIndex = RemoveFromRefArray(aGroupLabel, aFeatureLabel);
+  RemoveFromRefArray(aGroupLabel.FindChild(1), TDF_Label(), aRemovedIndex);
+  // remove feature from the myFeatures list
+  std::vector<boost::shared_ptr<ModelAPI_Feature> >::iterator aFIter = myFeatures.begin();
+  while(aFIter != myFeatures.end()) {
+    if (*aFIter == theFeature) {
+      aFIter = myFeatures.erase(aFIter);
+    } else {
+      aFIter++;
+    }
+  }
+  // erase all attributes under the label of feature
+  aFeatureLabel.ForgetAllAttributes();
+  // remove it from the references array
+  RemoveFromRefArray(groupLabel(FEATURES_GROUP), aData->label());
+
+  // event: feature is added
+  Model_FeatureDeletedMessage aMsg(theFeature->document(), theFeature->getGroup());
+  Events_Loop::loop()->send(aMsg);
+}
+
 boost::shared_ptr<ModelAPI_Feature> Model_Document::feature(TDF_Label& theLabel)
 {
   // iterate all features, may be optimized later by keeping labels-map
@@ -443,6 +507,7 @@ void Model_Document::setUniqueName(boost::shared_ptr<ModelAPI_Feature> theFeatur
         aNumObjects++;
         stringstream aNameStream;
         aNameStream<<theFeature->getKind()<<"_"<<aNumObjects + 1;
+        aName = aNameStream.str();
         // reinitialize iterator to make sure a new name is unique
         a = 0;
       } else a++;
index ce16a5de7b9874df9af7fe58d63758d26d2add71..b1945bae1eb878d7df5615b07e3ef4c6781d33c1 100644 (file)
@@ -63,6 +63,9 @@ public:
   //! \param creates feature and puts it in the document
   MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> addFeature(std::string theID);
 
+  //! Removes the feature from the document
+  MODEL_EXPORT virtual void removeFeature(boost::shared_ptr<ModelAPI_Feature> theFeature);
+
   //! Returns the existing feature by the label
   //! \param theLabel base label of the feature
   MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> feature(TDF_Label& theLabel);
@@ -105,7 +108,10 @@ protected:
   //! Creates new document with binary file format
   Model_Document(const std::string theID);
 
+  Handle_TDocStd_Document document() {return myDoc;}
+
   friend class Model_Application;
+  friend class Model_PluginManager;
 
 private:
   std::string myID; ///< identifier of the document in the application
index f4bede4e44ebc09faf54dfac9af7b84e0f09f1c7..cbf4859979003d74a98e762ac767ca08f87ef000 100644 (file)
@@ -17,3 +17,26 @@ const Events_ID Model_FeatureDeletedMessage::messageId()
   static Events_ID MY_ID = Events_Loop::eventByName(EVENT_FEATURE_DELETED);
   return MY_ID;
 }
+
+Model_FeaturesMovedMessage::Model_FeaturesMovedMessage()
+: Events_Message(messageId(), 0)
+{
+}
+
+const Events_ID Model_FeaturesMovedMessage::messageId()
+{
+  static Events_ID MY_ID = Events_Loop::eventByName(EVENT_FEATURES_MOVED);
+  return MY_ID;
+}
+
+void Model_FeaturesMovedMessage::setFeatures(
+                                const std::list<boost::shared_ptr<ModelAPI_Feature> >& theFeatures)
+{
+  myFeatures = theFeatures;  
+}
+
+const std::list<boost::shared_ptr<ModelAPI_Feature> >& Model_FeaturesMovedMessage::features() const
+{
+  return myFeatures;
+}
+
index ba0b7ea3438c66a73be4c744e5f719aab1739375..c9c60b65ffd77a2be6b9fb3a2e4dc1c5a832da55 100644 (file)
@@ -7,8 +7,10 @@
 
 #include <Model.h>
 #include <Events_Message.h>
+#include <Events_Loop.h>
 #include <boost/shared_ptr.hpp>
 #include <string>
+#include <list>
 
 class ModelAPI_Feature;
 class ModelAPI_Document;
@@ -19,6 +21,8 @@ static const char * EVENT_FEATURE_CREATED = "FeatureCreated";
 static const char * EVENT_FEATURE_UPDATED = "FeatureUpdated";
 /// Event ID that data of feature is deleted (comes with Model_FeatureDeletedMessage)
 static const char * EVENT_FEATURE_DELETED = "FeatureDeleted";
+/// Event ID that data of feature is updated (comes with Model_FeaturesMovedMessage)
+static const char * EVENT_FEATURES_MOVED = "FeaturesMoved";
 
 /// Message that feature was changed (used for Object Browser update)
 class Model_FeatureUpdatedMessage : public Events_Message {
@@ -53,4 +57,21 @@ public:
   const std::string& group() const {return myGroup;}
 };
 
+/// Message that features were moved (used for the feature preview update)
+class Model_FeaturesMovedMessage : public Events_Message {
+  std::list<boost::shared_ptr<ModelAPI_Feature> > myFeatures; ///< which features are moved
+public:
+  /// creates a message by initialization of fields
+  MODEL_EXPORT Model_FeaturesMovedMessage();
+
+  /// Returns the ID of this message (EVENT_FEATURES_MOVED)
+  static const Events_ID messageId();
+
+  /// Sets a list of features
+  MODEL_EXPORT void setFeatures(const std::list<boost::shared_ptr<ModelAPI_Feature> >& theFeatures);
+
+  /// Returns a list of features
+  MODEL_EXPORT const std::list<boost::shared_ptr<ModelAPI_Feature> >& features() const;
+};
+
 #endif
index cbb917a76fa9a7238bbd401865464e239cc4fba0..7a0a20d0a009958e1b4e4b1073aaefdbe5d00bf8 100644 (file)
@@ -9,9 +9,16 @@
 #include <Model_Document.h>
 #include <Model_Application.h>
 #include <Events_Loop.h>
+#include <Events_Error.h>
 #include <Config_FeatureMessage.h>
 #include <Config_ModuleReader.h>
 
+#include <TDF_CopyTool.hxx>
+#include <TDF_DataSet.hxx>
+#include <TDF_RelocationTable.hxx>
+#include <TDF_ClosureTool.hxx>
+
+
 using namespace std;
 
 static Model_PluginManager* myImpl = new Model_PluginManager();
@@ -30,7 +37,13 @@ boost::shared_ptr<ModelAPI_Feature> Model_PluginManager::createFeature(string th
     if (myPluginObjs.find(myCurrentPluginName) != myPluginObjs.end()) {
       boost::shared_ptr<ModelAPI_Feature> aCreated = 
         myPluginObjs[myCurrentPluginName]->createFeature(theFeatureID);
+      if (!aCreated) {
+        Events_Error::send(string("Can not initialize feature '") + theFeatureID +
+          "' in plugin '" + myCurrentPluginName + "'");
+      }
       return aCreated;
+    } else {
+      Events_Error::send(string("Can not load plugin '") + myCurrentPluginName + "'");
     }
   }
 
@@ -50,7 +63,7 @@ bool Model_PluginManager::hasRootDocument()
 
 boost::shared_ptr<ModelAPI_Document> Model_PluginManager::currentDocument()
 {
-  if (!myCurrentDoc)
+  if (!myCurrentDoc || !Model_Application::getApplication()->hasDocument(myCurrentDoc->id()))
     myCurrentDoc = rootDocument();
   return myCurrentDoc;
 }
@@ -60,6 +73,27 @@ void Model_PluginManager::setCurrentDocument(boost::shared_ptr<ModelAPI_Document
   myCurrentDoc = theDoc;
 }
 
+boost::shared_ptr<ModelAPI_Document> Model_PluginManager::copy(
+  boost::shared_ptr<ModelAPI_Document> theSource, std::string theID) 
+{
+  // create a new document
+  boost::shared_ptr<Model_Document> aNew = boost::dynamic_pointer_cast<Model_Document>(
+    Model_Application::getApplication()->getDocument(theID));
+  // make a copy of all labels
+  TDF_Label aSourceRoot = 
+    boost::dynamic_pointer_cast<Model_Document>(theSource)->document()->Main().Father();
+  TDF_Label aTargetRoot = aNew->document()->Main().Father();
+  Handle(TDF_DataSet) aDS = new TDF_DataSet;
+  aDS->AddLabel(aSourceRoot);
+  TDF_ClosureTool::Closure(aDS);
+  Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable;
+  aRT->SetRelocation(aSourceRoot, aTargetRoot);
+  TDF_CopyTool::Copy(aDS, aRT);
+
+  aNew->synchronizeFeatures();
+  return aNew;
+}
+
 Model_PluginManager::Model_PluginManager()
 {
   myPluginsInfoLoaded = false;
index 7f405573fea644010a96dc6c53757e2be75b83af..aa230700a1dc5d44e33bd8020402a25ad5971a8a 100644 (file)
@@ -47,6 +47,10 @@ public:
   /// Processes the configuration file reading
   MODEL_EXPORT virtual void processEvent(const Events_Message* theMessage);
 
+  /// Copies the document to the new one wit hthe given id
+  MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Document> copy(
+    boost::shared_ptr<ModelAPI_Document> theSource, std::string theID);
+
   /// Is called only once, on startup of the application
   Model_PluginManager();
 
index bed11f88617854a642e8676659ade04bb3dda2c8..9070718b48974151d3b0a4ea2332f65438340f71 100644 (file)
@@ -69,8 +69,12 @@ public:
   //! \param creates feature and puts it in the document
   MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> addFeature(std::string theID) = 0;
 
+  //! Removes the feature from the document
+  MODELAPI_EXPORT virtual void removeFeature(boost::shared_ptr<ModelAPI_Feature> theFeature) = 0;
+
   ///! Adds a new sub-document by the identifier, or returns existing one if it is already exist
-  MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Document> subDocument(std::string theDocID) = 0;
+  MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Document> 
+    subDocument(std::string theDocID) = 0;
 
   ///! Returns the id of hte document
   MODELAPI_EXPORT virtual const std::string& id() const = 0;
index eb4ba54f992dc60664127fa71ba529a540dea8c8..dd98c597a02c7f466f9caa61a01ec77d804e5c38 100644 (file)
@@ -40,6 +40,10 @@ public:
   /// Returns true if this feature must be displayed in the history (top level of Part tree)
   MODELAPI_EXPORT virtual bool isInHistory() {return true;}
 
+  /// Returns true if this feature must not be created: this is just an action
+  /// that is not stored in the features history (like delete part).
+  MODELAPI_EXPORT virtual bool isAction() {return false;}
+
   /// Returns the data manager of this feature
   MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Data> data() {return myData;}
 
index 47c42562ffdcd87682973ccdd152d595593a0290..6b25bf4a378dfc68758dc6f500b33ee692219054 100644 (file)
@@ -43,6 +43,10 @@ public:
   /// Defines the current document that used for current work in the application
   virtual void setCurrentDocument(boost::shared_ptr<ModelAPI_Document> theDoc) = 0;
 
+  /// Copies the document to the new one wit hthe given id
+  virtual boost::shared_ptr<ModelAPI_Document> copy(
+    boost::shared_ptr<ModelAPI_Document> theSource, std::string theID) = 0;
+
   /// Is needed for python wrapping by swig, call Get to get an instance
   ModelAPI_PluginManager();
 
index 7461196d2aabfa03c6ce7dec0bc9dce119c631a9..7e4e35034339559c403e7ef4276fbc66e64cf2e0 100644 (file)
@@ -80,7 +80,7 @@ ADD_LIBRARY(PartSet SHARED
 )
 
 # The Qt5Widgets_LIBRARIES variable also includes QtGui and QtCore
-TARGET_LINK_LIBRARIES(PartSet ${PROJECT_LIBRARIES} XGUI ModelAPI GeomAlgoAPI)
+TARGET_LINK_LIBRARIES(PartSet ${PROJECT_LIBRARIES} XGUI ModelAPI Model GeomAlgoAPI)
 
 ADD_DEPENDENCIES(PartSet ModuleBase)
 
index f3d1113353700fd328aec98a106fc1cf37ca771d..b54dc192afca8965a7bb3250fbbdc6222cd8b3b6 100644 (file)
@@ -164,15 +164,6 @@ void PartSet_Module::onKeyRelease(QKeyEvent* theEvent)
 void PartSet_Module::onPlaneSelected(double theX, double theY, double theZ)
 {
   myWorkshop->viewer()->setViewProjection(theX, theY, theZ);
-
-  ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
-  if (anOperation) {
-    PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
-    if (aPreviewOp) {
-      visualizePreview(aPreviewOp->feature(), false);
-    }
-  }
-
   myWorkshop->actionsMgr()->setNestedActionsEnabled(true);
 }
 
@@ -216,11 +207,36 @@ void PartSet_Module::onSetSelection(const std::list<XGUI_ViewerPrs>& theFeatures
   aDisplayer->UpdateViewer();
 }
 
+void PartSet_Module::onCloseLocalContext()
+{
+  XGUI_Displayer* aDisplayer = myWorkshop->displayer();
+  aDisplayer->CloseLocalContexts();
+}
+
 void PartSet_Module::onFeatureConstructed(boost::shared_ptr<ModelAPI_Feature> theFeature,
                                           int theMode)
 {
-  bool isDisplay = theMode != PartSet_OperationSketchBase::FM_Abort;
+  bool isDisplay = theMode != PartSet_OperationSketchBase::FM_Hide;
   visualizePreview(theFeature, isDisplay, false);
+  if (!isDisplay) {
+    ModuleBase_Operation* aCurOperation = myWorkshop->operationMgr()->currentOperation();
+    boost::shared_ptr<ModelAPI_Feature> aSketch;
+    PartSet_OperationSketchBase* aPrevOp = dynamic_cast<PartSet_OperationSketchBase*>(aCurOperation);
+    if (aPrevOp) {
+      std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
+                                                                         aList = aPrevOp->subPreview();
+      XGUI_Displayer* aDisplayer = myWorkshop->displayer();
+      std::list<int> aModes = aPrevOp->getSelectionModes(aPrevOp->feature());
+
+      std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >::const_iterator
+                                                             anIt = aList.begin(), aLast = aList.end();
+      for (; anIt != aLast; anIt++) {
+        boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).first;
+        visualizePreview(aFeature, false, false);
+      }
+      aDisplayer->UpdateViewer();
+    }
+  }
 
   if (theMode == PartSet_OperationSketchBase::FM_Activation ||
       theMode == PartSet_OperationSketchBase::FM_Deactivation)
@@ -279,6 +295,9 @@ ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdI
     connect(aPreviewOp, SIGNAL(setSelection(const std::list<XGUI_ViewerPrs>&)),
             this, SLOT(onSetSelection(const std::list<XGUI_ViewerPrs>&)));
 
+     connect(aPreviewOp, SIGNAL(closeLocalContext()),
+             this, SLOT(onCloseLocalContext()));
+
     PartSet_OperationSketch* aSketchOp = dynamic_cast<PartSet_OperationSketch*>(aPreviewOp);
     if (aSketchOp) {
       connect(aSketchOp, SIGNAL(planeSelected(double, double, double)),
@@ -316,7 +335,7 @@ void PartSet_Module::visualizePreview(boost::shared_ptr<ModelAPI_Feature> theFea
                           aPreview ? aPreview->impl<TopoDS_Shape>() : TopoDS_Shape(), false);
   }
   else
-    aDisplayer->Erase(anOperation->feature(), false);
+    aDisplayer->Erase(theFeature, false);
 
   if (isUpdateViewer)
     aDisplayer->UpdateViewer();
@@ -349,7 +368,7 @@ void PartSet_Module::updateCurrentPreview(const std::string& theCmdId)
     return;
 
   std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
-                                                                     aList = aPreviewOp->preview();
+                                                                     aList = aPreviewOp->subPreview();
   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
   std::list<int> aModes = aPreviewOp->getSelectionModes(aPreviewOp->feature());
 
index acd5502572b839c9a9db9448fe6109b1aa7071fd..17dc2034820d6cdef49ddde5c1ae81ce6a548c00 100644 (file)
@@ -101,6 +101,9 @@ public slots:
   /// \param theFeatures a list of features to be selected
   void onSetSelection(const std::list<XGUI_ViewerPrs>& theFeatures);
 
+  /// SLOT, to close the viewer local context
+  void onCloseLocalContext();
+
   /// SLOT, to visualize the feature in another local context mode
   /// \param theFeature the feature to be put in another local context mode
   /// \param theMode the mode appeared on the feature
index 5383e0d493393863abec6cb728bed0cf49a156d6..7b37976e8a0f041f2f19f85a18b9aa9ec11437dd 100644 (file)
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Document.h>
 
+#include <Model_Events.h>
+
+#include <Events_Loop.h>
+
 #include <SketchPlugin_Line.h>
 
 #include <V3d_View.hxx>
@@ -97,6 +101,8 @@ void PartSet_OperationEditLine::mouseMoved(QMouseEvent* theEvent, Handle(V3d_Vie
       moveLinePoint(aFeature, aDeltaX, aDeltaY, LINE_ATTR_END);
     }
   }
+  sendFeatures();
+
   myCurPoint.setPoint(aPoint);
 }
 
@@ -149,7 +155,7 @@ boost::shared_ptr<ModelAPI_Feature> PartSet_OperationEditLine::createFeature()
   return boost::shared_ptr<ModelAPI_Feature>();
 }
 
-void  PartSet_OperationEditLine::moveLinePoint(boost::shared_ptr<ModelAPI_Feature> theFeature,
+void PartSet_OperationEditLine::moveLinePoint(boost::shared_ptr<ModelAPI_Feature> theFeature,
                                                double theDeltaX, double theDeltaY,
                                                const std::string& theAttribute)
 {
@@ -162,3 +168,20 @@ void  PartSet_OperationEditLine::moveLinePoint(boost::shared_ptr<ModelAPI_Featur
 
   aPoint->setValue(aPoint->x() + theDeltaX, aPoint->y() + theDeltaY);
 }
+
+void PartSet_OperationEditLine::sendFeatures()
+{
+  std::list<boost::shared_ptr<ModelAPI_Feature> > aFeatures;
+  std::list<XGUI_ViewerPrs>::const_iterator anIt = myFeatures.begin(), aLast = myFeatures.end();
+  for (; anIt != aLast; anIt++) {
+    boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).feature();
+    if (!aFeature || aFeature == feature())
+      continue;
+  }
+
+  static Events_ID aModuleEvent = Events_Loop::eventByName("PartSetEditEvent");
+  Model_FeaturesMovedMessage aMessage;
+  aMessage.setFeatures(aFeatures);
+  Events_Loop::loop()->send(aMessage);
+}
+
index 5f447c7305bcd7425703b13458c92b7c85453fdf..14fd56959cfebedd8688389b7c6140c40ca797b9 100644 (file)
@@ -16,7 +16,7 @@ class QMouseEvent;
  \class PartSet_OperationEditLine
  * \brief The operation for the sketch feature creation
 */
-class PARTSET_EXPORT PartSet_OperationEditLine : public PartSet_OperationSketchBase
+class PARTSET_EXPORT PartSet_OperationEditLine : public PartSet_OperationSketchBase                                                 
 {
   Q_OBJECT
   /// Struct to define gp point, with the state is the point is initialized
@@ -118,6 +118,8 @@ protected:
   void  moveLinePoint(boost::shared_ptr<ModelAPI_Feature> theFeature,
                       double theDeltaX, double theDeltaY,
                       const std::string& theAttribute);
+  /// Sends the features
+  void sendFeatures();
 
 private:
   boost::shared_ptr<ModelAPI_Feature> mySketch; ///< the sketch feature
index 4c4aa241db6b01c3237c72cf9789ec955f7ed7ca..d527cd0f3f1aee9d07598e9a2b2c36c40f1cbf6f 100644 (file)
@@ -100,7 +100,7 @@ void PartSet_OperationSketch::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View)
 }
 
 std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
-                                                        PartSet_OperationSketch::preview() const
+                                                        PartSet_OperationSketch::subPreview() const
 {
   std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> > aPreviewMap;
 
@@ -122,6 +122,13 @@ std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
   return aPreviewMap;
 }
 
+void PartSet_OperationSketch::stopOperation()
+{
+  PartSet_OperationSketchBase::stopOperation();
+  emit featureConstructed(feature(), FM_Hide);
+  emit closeLocalContext();
+}
+
 void PartSet_OperationSketch::setSketchPlane(const TopoDS_Shape& theShape)
 {
   if (theShape.IsNull())
@@ -160,5 +167,7 @@ void PartSet_OperationSketch::setSketchPlane(const TopoDS_Shape& theShape)
     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_DIRY));
   aDirY->setValue(aC, anA, aB);
   boost::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
+  emit featureConstructed(feature(), FM_Hide);
+  emit closeLocalContext();
   emit planeSelected(aDir->x(), aDir->y(), aDir->z());
 }
index e964939d4607c2b2c930fec8224a500fb949731c..fbb0eb376afba999656a2a675bb42d6e37a76f15 100644 (file)
@@ -58,7 +58,12 @@ public:
   /// Returns the map of the operation previews including the nested feature previews
   /// \return the map of feature to the feature preview
   virtual std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
-                                                                           preview() const;
+                                                                           subPreview() const;
+
+  /// Virtual method called when operation stopped - committed or aborted.
+  /// Emits a signal to hide the preview of the operation
+  virtual void stopOperation();
+
 signals:
   /// signal about the sketch plane is selected
   /// \param theX the value in the X direction of the plane
index 3a02de8b88ccba22a22ab639a4e29e927f35916f..45981e24402b8b827621b20efdb7e558e3b916c9 100644 (file)
@@ -36,11 +36,13 @@ boost::shared_ptr<GeomAPI_Shape> PartSet_OperationSketchBase::preview(
     if (anObj) 
       aFeature = boost::dynamic_pointer_cast<SketchPlugin_Feature>(anObj->featureRef());
   }
+  if (!aFeature)
+    return boost::shared_ptr<GeomAPI_Shape>();
   return aFeature->preview();
 }
 
 std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
-                                                     PartSet_OperationSketchBase::preview() const
+                                                     PartSet_OperationSketchBase::subPreview() const
 {
   return std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >();
 }
@@ -55,7 +57,8 @@ std::list<int> PartSet_OperationSketchBase::getSelectionModes(boost::shared_ptr<
 boost::shared_ptr<ModelAPI_Feature> PartSet_OperationSketchBase::createFeature()
 {
   boost::shared_ptr<ModelAPI_Feature> aFeature = ModuleBase_Operation::createFeature();
-  emit featureConstructed(aFeature, FM_Activation);
+  if (aFeature)
+    emit featureConstructed(aFeature, FM_Activation);
   return aFeature;
 }
 
index 33b9e1d04ee38bc4236255ebf9128be49bb5696d..0045a8e87b1a6c19b2cf227188974d3ea7099387 100644 (file)
@@ -31,7 +31,7 @@ class PARTSET_EXPORT PartSet_OperationSketchBase : public ModuleBase_Operation
 {
   Q_OBJECT
 public:
-  enum FeatureActionMode { FM_Activation, FM_Deactivation, FM_Abort };
+  enum FeatureActionMode { FM_Activation, FM_Deactivation, FM_Hide };
 
 public:
   /// Constructor
@@ -47,7 +47,7 @@ public:
 
   /// Returns the map of the operation previews including the nested feature previews
   /// \return the map of feature to the feature preview
-  virtual std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> > preview() const;
+  virtual std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> > subPreview() const;
 
   /// Returns the operation local selection mode
   /// \param theFeature the feature object to get the selection mode
@@ -112,9 +112,8 @@ signals:
   /// \param theFeatures a list of features to be disabled
   void setSelection(const std::list<XGUI_ViewerPrs>& theFeatures);
 
-  /// signal to enable/disable usual selection in the viewer
-  /// \param theEnabled the boolean state
-  void selectionEnabled(bool theEnabled);
+  /// signal to close the operation local context if it is opened
+  void closeLocalContext();
 
 protected:
   /// Creates an operation new feature
index dc67cae98597bc69e3eb376851b9f01fa54b9dcd..6b64cd2759cff1930c142411f11a40d44ab5d1bc 100644 (file)
@@ -147,9 +147,7 @@ void PartSet_OperationSketchLine::mouseReleased(QMouseEvent* theEvent, Handle(V3
     break;
     case SM_SecondPoint: {
       setLinePoint(feature(), aX, anY, LINE_ATTR_END);
-      commit();
-      emit featureConstructed(feature(), FM_Deactivation);
-      emit launchOperation(PartSet_OperationSketchLine::Type(), feature());
+      myPointSelectionMode = SM_DonePoint;
     }
     break;
     default:
@@ -161,12 +159,26 @@ void PartSet_OperationSketchLine::mouseMoved(QMouseEvent* theEvent, Handle(V3d_V
 {
   switch (myPointSelectionMode)
   {
+    case SM_FirstPoint: {
+      double aX, anY;
+      gp_Pnt aPoint = PartSet_Tools::ConvertClickToPoint(theEvent->pos(), theView);
+      PartSet_Tools::ConvertTo2D(aPoint, sketch(), theView, aX, anY);
+      setLinePoint(feature(), aX, anY, LINE_ATTR_START);
+      setLinePoint(feature(), aX, anY, LINE_ATTR_END);
+    }
+    break;
     case SM_SecondPoint:
     {
       gp_Pnt aPoint = PartSet_Tools::ConvertClickToPoint(theEvent->pos(), theView);
       setLinePoint(aPoint, theView, LINE_ATTR_END);
     }
     break;
+    case SM_DonePoint:
+    {
+      commit();
+      emit featureConstructed(feature(), FM_Deactivation);
+      emit launchOperation(PartSet_OperationSketchLine::Type(), feature());
+    }
     default:
       break;
   }
@@ -176,7 +188,13 @@ void PartSet_OperationSketchLine::keyReleased(const int theKey)
 {
   switch (theKey) {
     case Qt::Key_Return: {
-      abort();
+      if (myPointSelectionMode == SM_DonePoint)
+      {
+        commit();
+        emit featureConstructed(feature(), FM_Deactivation);
+      }
+      else
+        abort();
       emit launchOperation(PartSet_OperationSketchLine::Type(), boost::shared_ptr<ModelAPI_Feature>());
     }
     break;
@@ -195,7 +213,7 @@ void PartSet_OperationSketchLine::startOperation()
 
 void PartSet_OperationSketchLine::abortOperation()
 {
-  emit featureConstructed(feature(), FM_Abort);
+  emit featureConstructed(feature(), FM_Hide);
   PartSet_OperationSketchBase::abortOperation();
 }
 
index e6cabaa88094279333330d2e6a6bf8ac42df1ce3..09c33f6f452621540d8d17e9ede546f703c417e7 100644 (file)
@@ -128,7 +128,7 @@ protected:
 
 protected:
   ///< Structure to lists the possible types of point selection modes
-  enum PointSelectionMode {SM_FirstPoint, SM_SecondPoint};
+  enum PointSelectionMode {SM_FirstPoint, SM_SecondPoint, SM_DonePoint};
 
 private:
   boost::shared_ptr<ModelAPI_Feature> mySketch; ///< the sketch feature
index d9715d5901bb3c088e605ae9d799a08705bc283c..119d74843b938d8318c0fd2cb42eee5bcde9a2a8 100644 (file)
@@ -4,11 +4,15 @@ SET(PROJECT_HEADERS
     PartSetPlugin.h
     PartSetPlugin_Plugin.h
     PartSetPlugin_Part.h
+    PartSetPlugin_Duplicate.h
+    PartSetPlugin_Remove.h
 )
 
 SET(PROJECT_SOURCES
     PartSetPlugin_Plugin.cpp
     PartSetPlugin_Part.cpp
+    PartSetPlugin_Duplicate.cpp
+    PartSetPlugin_Remove.cpp
 )
 
 ADD_DEFINITIONS(-DPARTSETPLUGIN_EXPORTS ${BOOST_DEFINITIONS})
diff --git a/src/PartSetPlugin/PartSetPlugin_Duplicate.cpp b/src/PartSetPlugin/PartSetPlugin_Duplicate.cpp
new file mode 100644 (file)
index 0000000..9b6a47e
--- /dev/null
@@ -0,0 +1,40 @@
+// File:        PartSetPlugin_Duplicate.cxx
+// Created:     20 May 2014
+// Author:      Mikhail PONIKAROV
+
+#include "PartSetPlugin_Duplicate.h"
+#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeDocRef.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Document.h>
+
+using namespace std;
+
+PartSetPlugin_Duplicate::PartSetPlugin_Duplicate()
+{
+}
+
+void PartSetPlugin_Duplicate::initAttributes()
+{
+  PartSetPlugin_Part::initAttributes();
+  data()->addAttribute(PART_DUPLICATE_ATTR_REF, ModelAPI_AttributeRefAttr::type());
+
+  boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef = data()->refattr(PART_DUPLICATE_ATTR_REF);
+  if (!aRef->attr()) { // create a copy: if not created yet attribute is not initialized
+    boost::shared_ptr<ModelAPI_PluginManager> aPManager = ModelAPI_PluginManager::get();
+    boost::shared_ptr<ModelAPI_Document> aRoot = aPManager->rootDocument();
+    boost::shared_ptr<PartSetPlugin_Part> aSource; // searching for source document attribute
+    for(int a = aRoot->size(getGroup()) - 1; a >= 0; a--) {
+      aSource = boost::dynamic_pointer_cast<PartSetPlugin_Part>(
+        aRoot->feature(getGroup(), a, true));
+      if (aSource->data()->docRef(PART_ATTR_DOC_REF)->value() == aPManager->currentDocument())
+        break;
+      aSource.reset();
+    }
+    if (aSource) {
+      boost::shared_ptr<ModelAPI_Document> aCopy = 
+        aPManager->copy(aSource->data()->docRef(PART_ATTR_DOC_REF)->value(), data()->getName());
+      aRef->setFeature(aSource);
+    }
+  }
+}
diff --git a/src/PartSetPlugin/PartSetPlugin_Duplicate.h b/src/PartSetPlugin/PartSetPlugin_Duplicate.h
new file mode 100644 (file)
index 0000000..9bab4d6
--- /dev/null
@@ -0,0 +1,27 @@
+// File:        PartSetPlugin_Duplicate.h
+// Created:     20 May 2014
+// Author:      Mikhail PONIKAROV
+
+#ifndef PartSetPlugin_Duplicate_HeaderFile
+#define PartSetPlugin_Duplicate_HeaderFile
+
+#include "PartSetPlugin_Part.h"
+
+/// the reference to copy: reference to the attribute
+const std::string PART_DUPLICATE_ATTR_REF = "Origin";
+
+/**\class PartSetPlugin_Duplicate
+ * \ingroup DataModel
+ * \brief Duplicates the active part (not root). Creates a new "part" feature.
+ */
+class PartSetPlugin_Duplicate: public PartSetPlugin_Part
+{
+public:
+  /// Makes a new part, copy of active
+  PartSetPlugin_Duplicate();
+
+  /// Request for initialization of data model of the feature: adding all attributes
+  PARTSETPLUGIN_EXPORT virtual void initAttributes();
+};
+
+#endif
index 85ea1c37eacf527337a523ae115b3684134ef227..76ea7b441c0f6ae5375b48bdb1ed5c4bc498ddcc 100644 (file)
@@ -1,5 +1,7 @@
 #include "PartSetPlugin_Plugin.h"
 #include "PartSetPlugin_Part.h"
+#include "PartSetPlugin_Duplicate.h"
+#include "PartSetPlugin_Remove.h"
 #include <ModelAPI_PluginManager.h>
 #include <ModelAPI_Document.h>
 
@@ -19,6 +21,12 @@ boost::shared_ptr<ModelAPI_Feature> PartSetPlugin_Plugin::createFeature(string t
   if (theFeatureID == "Part") {
     return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_Part);
   }
-  // feature of such kind is not found
+  if (theFeatureID == "duplicate") {
+    return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_Duplicate);
+  }
+  if (theFeatureID == "remove") {
+    return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_Remove);
+  }
+    // feature of such kind is not found
   return boost::shared_ptr<ModelAPI_Feature>();
 }
diff --git a/src/PartSetPlugin/PartSetPlugin_Remove.cpp b/src/PartSetPlugin/PartSetPlugin_Remove.cpp
new file mode 100644 (file)
index 0000000..5e99cb1
--- /dev/null
@@ -0,0 +1,29 @@
+// File:        PartSetPlugin_Remove.cxx
+// Created:     20 May 2014
+// Author:      Mikhail PONIKAROV
+
+#include "PartSetPlugin_Remove.h"
+#include "PartSetPlugin_Part.h"
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_AttributeDocRef.h>
+
+void PartSetPlugin_Remove::execute()
+{
+  boost::shared_ptr<ModelAPI_PluginManager> aPManager = ModelAPI_PluginManager::get();
+  boost::shared_ptr<ModelAPI_Document> aRoot = aPManager->rootDocument();
+  boost::shared_ptr<ModelAPI_Document> aCurrent;
+  boost::shared_ptr<PartSetPlugin_Part> a;
+  for(int a = aRoot->size(getGroup()) - 1; a >= 0; a--) {
+    boost::shared_ptr<ModelAPI_Feature> aFeature = aRoot->feature(getGroup(), a, true);
+    if (aFeature->getKind() == "Part") {
+      boost::shared_ptr<PartSetPlugin_Part> aPart = 
+        boost::static_pointer_cast<PartSetPlugin_Part>(aFeature);
+      if (aPart->data()->docRef(PART_ATTR_DOC_REF)->value() == aPManager->currentDocument()) {
+        // do remove
+        aPart->data()->docRef(PART_ATTR_DOC_REF)->value()->close();
+        aRoot->removeFeature(aPart);
+      }
+    }
+  }
+}
diff --git a/src/PartSetPlugin/PartSetPlugin_Remove.h b/src/PartSetPlugin/PartSetPlugin_Remove.h
new file mode 100644 (file)
index 0000000..f12066c
--- /dev/null
@@ -0,0 +1,39 @@
+// File:        PartSetPlugin_Remove.h
+// Created:     20 May 2014
+// Author:      Mikhail PONIKAROV
+
+#ifndef PartSetPlugin_Remove_HeaderFile
+#define PartSetPlugin_Remove_HeaderFile
+
+#include "PartSetPlugin.h"
+#include <ModelAPI_Feature.h>
+
+/**\class PartSetPlugin_Remove
+ * \ingroup DataModel
+ * \brief Feature for creation of the new part in PartSet.
+ */
+class PartSetPlugin_Remove: public ModelAPI_Feature
+{
+public:
+  /// Returns the kind of a feature
+  PARTSETPLUGIN_EXPORT virtual const std::string& getKind() 
+  {static std::string MY_KIND = "Remove"; return MY_KIND;}
+
+  /// Returns to which group in the document must be added feature
+  PARTSETPLUGIN_EXPORT virtual const std::string& getGroup() 
+  {static std::string MY_GROUP = "Parts"; return MY_GROUP;}
+
+  /// Request for initialization of data model of the feature: adding all attributes
+  PARTSETPLUGIN_EXPORT virtual void initAttributes() {}
+
+  /// Not normal feature that stored in the tree
+  PARTSETPLUGIN_EXPORT virtual bool isAction() {return true;}
+
+  /// Performs the "remove"
+  PARTSETPLUGIN_EXPORT virtual void execute();
+
+  /// Use plugin manager for features creation
+  PartSetPlugin_Remove() {}
+};
+
+#endif
index eb5956ec2a58ba921311c12eb593b55d1c8ecd84..60fb882c0c186e5f45047274c60be0088e2799d4 100644 (file)
@@ -23,11 +23,12 @@ SET(PROJECT_SOURCES
 SET(PROJECT_LIBRARIES
     GeomAPI
     GeomAlgoAPI
+    ModelAPI
 )
 
 ADD_DEFINITIONS(-DSKETCHPLUGIN_EXPORTS ${BOOST_DEFINITIONS})
-ADD_LIBRARY(SketchPlugin SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
-TARGET_LINK_LIBRARIES(SketchPlugin ${PROJECT_LIBRARIES} ModelAPI GeomAPI GeomAlgoAPI)
+ADD_LIBRARY(SketchPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS})
+TARGET_LINK_LIBRARIES(SketchPlugin ${PROJECT_LIBRARIES})
 
 INCLUDE_DIRECTORIES(
   ../ModelAPI
index 61cd2bf0554bc18567dbc87e17c4d48e078be365..98680830ae87b92b2152e7d2cb45b0ad72d4fd29 100644 (file)
@@ -49,11 +49,11 @@ class SketchPlugin_Constraint: public SketchPlugin_Feature
 {
 public:
   /// \brief Returns the kind of a feature
-  SKETCHPLUGIN_EXPORT virtual const std::string& getKind() 
+  SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
   {static std::string MY_KIND = "SketchConstraint"; return MY_KIND;}
 
   /// \brief Returns to which group in the document must be added feature
-  SKETCHPLUGIN_EXPORT virtual const std::string& getGroup() 
+  SKETCHPLUGIN_EXPORT virtual const std::string& getGroup()
   {static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
 
   /** \brief Adds sub-feature of the higher level feature (sub-element of the sketch)
@@ -62,6 +62,7 @@ public:
   SKETCHPLUGIN_EXPORT virtual const void addSub(
     const boost::shared_ptr<ModelAPI_Feature>& theFeature) {}
 
+protected:
   /// \brief Use plugin manager for features creation
   SketchPlugin_Constraint() {}
 };
index fe75115e9ca5a80e56067757a979b67cc3f8cc16..57e95f5ba0260ea0e4b68fb0ec9368552f40a4dc 100644 (file)
@@ -12,7 +12,7 @@
 
 /** \class SketchPlugin_ConstraintCoincidence
  *  \ingroup DataModel
- *  \brief Feature for creation of a new constraint which defines equvalence of two points
+ *  \brief Feature for creation of a new constraint which defines equivalence of two points
  *
  *  These constraint has two attributes: CONSTRAINT_ATTR_POINT_A and CONSTRAINT_ATTR_POINT_B
  */
index 6691c6f85e5230299161e16484d53b0e3647cbcc..13b61db1fbfaf04c26121633d179d7b75d351804 100644 (file)
@@ -13,9 +13,6 @@
 
 using namespace std;
 
-/// the active sketch
-boost::shared_ptr<SketchPlugin_Sketch> MY_ACITVE_SKETCH;
-
 // face of the square-face displayed for selection of general plane
 const double PLANE_SIZE = 200;
 
index 70b9fecbbc4b97fcc43737dfc9d4febd20c76781..4656f25d530a1f00f4ed054757ab26a3d4c36f63 100644 (file)
@@ -14,8 +14,9 @@ SET(PROJECT_SOURCES
 
 SET(PROJECT_LIBRARIES
     ${SLVS_LIBRARIES}
-    SketchPlugin
     Events
+    ModelAPI
+    Model
 )
 
 INCLUDE_DIRECTORIES(
@@ -29,7 +30,7 @@ INCLUDE_DIRECTORIES(
 
 ADD_DEFINITIONS(-DSKETCHSOLVER_EXPORTS ${BOOST_DEFINITIONS})
 
-ADD_LIBRARY(SketchSolver SHARED 
+ADD_LIBRARY(SketchSolver MODULE 
     ${PROJECT_SOURCES} 
     ${PROJECT_HEADERS}
 )
index bf9ad5e101ab3fb092cb81a3ab9246f0ce64ab79..4a47879faab6da65aadfed7598a0fe0620468d31 100644 (file)
@@ -19,6 +19,7 @@
 #include <SketchPlugin_Sketch.h>
 
 #include <math.h>
+#include <assert.h>
 
 /// Tolerance for value of parameters
 const double tolerance = 1.e-10;
@@ -26,7 +27,7 @@ const double tolerance = 1.e-10;
 // Initialization of constraint manager self pointer
 SketchSolver_ConstraintManager* SketchSolver_ConstraintManager::_self = 0;
 
-/// Global constaint manager object
+/// Global constraint manager object
 SketchSolver_ConstraintManager* myManager = SketchSolver_ConstraintManager::Instance();
 
 /// This value is used to give unique index to the groups
@@ -60,6 +61,7 @@ SketchSolver_ConstraintManager::SketchSolver_ConstraintManager()
   Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED));
   Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_UPDATED));
   Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_DELETED));
+  Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURES_MOVED));
 }
 
 SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager()
@@ -75,33 +77,25 @@ void SketchSolver_ConstraintManager::processEvent(const Events_Message* theMessa
     const Model_FeatureUpdatedMessage* aUpdateMsg = dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
 
     // Only sketches and constraints can be added by Create event
-    boost::shared_ptr<SketchPlugin_Sketch> aSketch = 
-      boost::dynamic_pointer_cast<SketchPlugin_Sketch>(aUpdateMsg->feature());
-    if (aSketch)
+    const std::string& aFeatureKind = aUpdateMsg->feature()->getKind();
+    if (aFeatureKind.compare("Sketch") == 0)
     {
+      boost::shared_ptr<SketchPlugin_Feature> aSketch =
+        boost::dynamic_pointer_cast<SketchPlugin_Feature>(aUpdateMsg->feature());
       changeWorkplane(aSketch);
       return ;
     }
-    boost::shared_ptr<SketchPlugin_Constraint> aConstraint = 
+    boost::shared_ptr<SketchPlugin_Constraint> aConstraint =
       boost::dynamic_pointer_cast<SketchPlugin_Constraint>(aUpdateMsg->feature());
     if (aConstraint)
-    {
       changeConstraint(aConstraint);
-
-      // Solve the set of constraints
-      resolveConstraints();
-      return ;
-    }
-
-    // Sketch plugin features only can be updated
-    boost::shared_ptr<SketchPlugin_Feature> aFeature = 
-      boost::dynamic_pointer_cast<SketchPlugin_Feature>(aUpdateMsg->feature());
-    if (aFeature)
+    else
     {
-      updateEntity(aFeature);
-
-      // Solve the set of constraints
-      resolveConstraints();
+      // Sketch plugin features can be only updated
+      boost::shared_ptr<SketchPlugin_Feature> aFeature =
+        boost::dynamic_pointer_cast<SketchPlugin_Feature>(aUpdateMsg->feature());
+      if (aFeature)
+        updateEntity(aFeature);
     }
   }
   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_DELETED))
@@ -124,9 +118,14 @@ void SketchSolver_ConstraintManager::processEvent(const Events_Message* theMessa
       }
     }
   }
+  else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURES_MOVED))
+  {
+    // Solve the set of constraints
+    resolveConstraints();
+  }
 }
 
-bool SketchSolver_ConstraintManager::changeWorkplane(boost::shared_ptr<SketchPlugin_Sketch> theSketch)
+bool SketchSolver_ConstraintManager::changeWorkplane(boost::shared_ptr<SketchPlugin_Feature> theSketch)
 {
   bool aResult = true; // changed when a workplane wrongly updated
   bool isUpdated = false;
@@ -164,7 +163,7 @@ bool SketchSolver_ConstraintManager::changeConstraint(
   // Process the groups list
   if (aGroups.size() == 0)
   { // There are no groups applicable for this constraint => create new one
-    boost::shared_ptr<SketchPlugin_Sketch> aWP = findWorkplaneForConstraint(theConstraint);
+    boost::shared_ptr<SketchPlugin_Feature> aWP = findWorkplaneForConstraint(theConstraint);
     if (!aWP) return false;
     SketchSolver_ConstraintGroup* aGroup = new SketchSolver_ConstraintGroup(aWP);
     if (!aGroup->changeConstraint(theConstraint))
@@ -196,15 +195,12 @@ void SketchSolver_ConstraintManager::updateEntity(boost::shared_ptr<SketchPlugin
 {
   // Create list of attributes depending on type of the feature
   std::vector<std::string> anAttrList;
+  const std::string& aFeatureKind = theFeature->getKind();
   // Point
-  boost::shared_ptr<SketchPlugin_Point> aPoint = 
-    boost::dynamic_pointer_cast<SketchPlugin_Point>(theFeature);
-  if (aPoint)
+  if (aFeatureKind.compare("SketchPoint") == 0)
     anAttrList.push_back(POINT_ATTR_COORD);
   // Line
-  boost::shared_ptr<SketchPlugin_Line> aLine = 
-    boost::dynamic_pointer_cast<SketchPlugin_Line>(theFeature);
-  if (aLine)
+  else if (aFeatureKind.compare("SketchLine") == 0)
   {
     anAttrList.push_back(LINE_ATTR_START);
     anAttrList.push_back(LINE_ATTR_END);
@@ -218,7 +214,7 @@ void SketchSolver_ConstraintManager::updateEntity(boost::shared_ptr<SketchPlugin
     std::vector<SketchSolver_ConstraintGroup*>::iterator aGroupIter;
     for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
     {
-      boost::shared_ptr<ModelAPI_Attribute> anAttribute = 
+      boost::shared_ptr<ModelAPI_Attribute> anAttribute =
         boost::dynamic_pointer_cast<ModelAPI_Attribute>(theFeature->data()->attribute(*anAttrIter));
       (*aGroupIter)->updateEntityIfPossible(anAttribute);
     }
@@ -227,10 +223,10 @@ void SketchSolver_ConstraintManager::updateEntity(boost::shared_ptr<SketchPlugin
 
 
 void SketchSolver_ConstraintManager::findGroups(
-              boost::shared_ptr<SketchPlugin_Constraint> theConstraint, 
+              boost::shared_ptr<SketchPlugin_Constraint> theConstraint,
               std::vector<Slvs_hGroup>&                  theGroupIDs) const
 {
-  boost::shared_ptr<SketchPlugin_Sketch> aWP = findWorkplaneForConstraint(theConstraint);
+  boost::shared_ptr<SketchPlugin_Feature> aWP = findWorkplaneForConstraint(theConstraint);
 
   std::vector<SketchSolver_ConstraintGroup*>::const_iterator aGroupIter;
   for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
@@ -238,14 +234,14 @@ void SketchSolver_ConstraintManager::findGroups(
       theGroupIDs.push_back((*aGroupIter)->getId());
 }
 
-boost::shared_ptr<SketchPlugin_Sketch> SketchSolver_ConstraintManager::findWorkplaneForConstraint(
+boost::shared_ptr<SketchPlugin_Feature> SketchSolver_ConstraintManager::findWorkplaneForConstraint(
               boost::shared_ptr<SketchPlugin_Constraint> theConstraint) const
 {
   std::vector<SketchSolver_ConstraintGroup*>::const_iterator aGroupIter;
   for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
   {
-    boost::shared_ptr<SketchPlugin_Sketch> aWP = (*aGroupIter)->getWorkplane();
-    boost::shared_ptr<ModelAPI_AttributeRefList> aWPFeatures = 
+    boost::shared_ptr<SketchPlugin_Feature> aWP = (*aGroupIter)->getWorkplane();
+    boost::shared_ptr<ModelAPI_AttributeRefList> aWPFeatures =
       boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(aWP->data()->attribute(SKETCH_ATTR_FEATURES));
     std::list< boost::shared_ptr<ModelAPI_Feature> > aFeaturesList = aWPFeatures->list();
     std::list< boost::shared_ptr<ModelAPI_Feature> >::const_iterator anIter;
@@ -254,12 +250,12 @@ boost::shared_ptr<SketchPlugin_Sketch> SketchSolver_ConstraintManager::findWorkp
         return aWP; // workplane is found
   }
 
-  return boost::shared_ptr<SketchPlugin_Sketch>();
+  return boost::shared_ptr<SketchPlugin_Feature>();
 }
 
 void SketchSolver_ConstraintManager::resolveConstraints()
 {
-  std::vector<SketchSolver_ConstraintGroup*>::iterator aGroupIter; 
+  std::vector<SketchSolver_ConstraintGroup*>::iterator aGroupIter;
   for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
     (*aGroupIter)->resolveConstraints();
 }
@@ -271,7 +267,7 @@ void SketchSolver_ConstraintManager::resolveConstraints()
 // ========================================================
 
 SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::
-  SketchSolver_ConstraintGroup(boost::shared_ptr<SketchPlugin_Sketch> theWorkplane)
+  SketchSolver_ConstraintGroup(boost::shared_ptr<SketchPlugin_Feature> theWorkplane)
   : myID(++myGroupIndexer),
     myParamMaxID(0),
     myEntityMaxID(0),
@@ -286,7 +282,7 @@ SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::
 
   // Initialize workplane
   myWorkplane.h = SLVS_E_UNKNOWN;
-  addWorkplane(theWorkplane);
+  assert(addWorkplane(theWorkplane));
 }
 
 SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::~SketchSolver_ConstraintGroup()
@@ -302,7 +298,7 @@ SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::~SketchSolver_Cons
 }
 
 bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::isBaseWorkplane(
-                boost::shared_ptr<SketchPlugin_Sketch> theWorkplane) const
+                boost::shared_ptr<SketchPlugin_Feature> theWorkplane) const
 {
   return theWorkplane == mySketch;
 }
@@ -337,7 +333,7 @@ bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeConstra
 
   // Get constraint type and verify the constraint parameters are correct
   int aConstrType = getConstraintType(theConstraint);
-  if (aConstrType == SLVS_C_UNKNOWN || 
+  if (aConstrType == SLVS_C_UNKNOWN ||
      (aConstrMapIter != myConstraintMap.end() && aConstrIter->type != aConstrType))
     return false;
 
@@ -359,7 +355,7 @@ bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeConstra
   for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
   {
     aConstrEnt[indAttr] = SLVS_E_UNKNOWN;
-    boost::shared_ptr<ModelAPI_AttributeRefAttr> aConstrAttr = 
+    boost::shared_ptr<ModelAPI_AttributeRefAttr> aConstrAttr =
       boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
         theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
       );
@@ -370,8 +366,8 @@ bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeConstra
   if (aConstrMapIter == myConstraintMap.end())
   {
     // Create SolveSpace constraint structure
-    Slvs_Constraint aConstraint = 
-      Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType, myWorkplane.h, 
+    Slvs_Constraint aConstraint =
+      Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType, myWorkplane.h,
                           aDistance, aConstrEnt[0], aConstrEnt[1], aConstrEnt[2], aConstrEnt[3]);
     myConstraints.push_back(aConstraint);
     myConstraintMap[theConstraint] = aConstraint.h;
@@ -398,7 +394,7 @@ Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::chang
   // Look over supported types of entities
 
   // Point in 3D
-  boost::shared_ptr<GeomDataAPI_Point> aPoint = 
+  boost::shared_ptr<GeomDataAPI_Point> aPoint =
     boost::dynamic_pointer_cast<GeomDataAPI_Point>(theEntity);
   if (aPoint)
   {
@@ -417,7 +413,7 @@ Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::chang
   }
 
   // Point in 2D
-  boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D = 
+  boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
     boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(theEntity);
   if (aPoint2D)
   {
@@ -438,29 +434,29 @@ Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::chang
   }
 
   /// \todo Other types of entities
-  
+
   // Unsupported or wrong entity type
   return SLVS_E_UNKNOWN;
 }
 
 Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeNormal(
-                boost::shared_ptr<ModelAPI_Attribute> theDirX, 
-                boost::shared_ptr<ModelAPI_Attribute> theDirY, 
+                boost::shared_ptr<ModelAPI_Attribute> theDirX,
+                boost::shared_ptr<ModelAPI_Attribute> theDirY,
                 boost::shared_ptr<ModelAPI_Attribute> theNorm)
 {
-  boost::shared_ptr<GeomDataAPI_Dir> aDirX = 
+  boost::shared_ptr<GeomDataAPI_Dir> aDirX =
     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(theDirX);
-  boost::shared_ptr<GeomDataAPI_Dir> aDirY = 
+  boost::shared_ptr<GeomDataAPI_Dir> aDirY =
     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(theDirY);
-  if (!aDirX || !aDirY || 
+  if (!aDirX || !aDirY ||
      (fabs(aDirX->x()) + fabs(aDirX->y()) + fabs(aDirX->z()) < tolerance) ||
      (fabs(aDirY->x()) + fabs(aDirY->y()) + fabs(aDirY->z()) < tolerance))
     return SLVS_E_UNKNOWN;
 
   // quaternion parameters of normal vector
   double qw, qx, qy, qz;
-  Slvs_MakeQuaternion(aDirX->x(), aDirX->y(), aDirX->z(), 
-                      aDirY->x(), aDirY->y(), aDirY->z(), 
+  Slvs_MakeQuaternion(aDirX->x(), aDirX->y(), aDirX->z(),
+                      aDirY->x(), aDirY->y(), aDirY->z(),
                       &qw, &qx, &qy, &qz);
   double aNormCoord[4] = {qw, qx, qy, qz};
 
@@ -486,7 +482,7 @@ Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::chang
     return aEntIter->second;
 
   // Create a normal
-  Slvs_Entity aNormal = Slvs_MakeNormal3d(++myEntityMaxID, myID, 
+  Slvs_Entity aNormal = Slvs_MakeNormal3d(++myEntityMaxID, myID,
                 aNormParams[0], aNormParams[1], aNormParams[2], aNormParams[3]);
   myEntities.push_back(aNormal);
   myEntityMap[theNorm] = aNormal.h;
@@ -495,13 +491,14 @@ Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::chang
 
 
 bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addWorkplane(
-                boost::shared_ptr<SketchPlugin_Sketch> theSketch)
+                boost::shared_ptr<SketchPlugin_Feature> theSketch)
 {
-  if (myWorkplane.h)
-    return false; // the workplane already exists
+  if (myWorkplane.h || theSketch->getKind().compare("Sketch") != 0)
+    return false; // the workplane already exists or the function parameter is not Sketch
 
   mySketch = theSketch;
-  return updateWorkplane();
+  updateWorkplane();
+  return true;
 }
 
 bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateWorkplane()
@@ -529,7 +526,7 @@ bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateWorkpla
 
 
 Slvs_hParam SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeParameter(
-                const double&                            theParam, 
+                const double&                            theParam,
                 std::vector<Slvs_Param>::const_iterator& thePrmIter)
 {
   if (thePrmIter != myParams.end())
@@ -556,23 +553,22 @@ Slvs_hParam SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::change
 int SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::getConstraintType(
                 const boost::shared_ptr<SketchPlugin_Constraint>& theConstraint) const
 {
+  const std::string& aConstraintKind = theConstraint->getKind();
   // Constraint for coincidence of two points
-  boost::shared_ptr<SketchPlugin_ConstraintCoincidence> aPtEquiv = 
-    boost::dynamic_pointer_cast<SketchPlugin_ConstraintCoincidence>(theConstraint);
-  if (aPtEquiv)
+  if (aConstraintKind.compare("SketchConstraintCoincidence") == 0)
   {
     // Verify the constraint has only two attributes and they are points
-    int aPt2d = 0; // bit-mapped field, each bit indicates whether the attribute is 2D point 
+    int aPt2d = 0; // bit-mapped field, each bit indicates whether the attribute is 2D point
     int aPt3d = 0; // bit-mapped field, the same information for 3D points
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
     {
-      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = 
+      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
         boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
           theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
         );
       if (!anAttr) continue;
       // Verify the attribute is a 2D point
-      boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D = 
+      boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
       if (aPoint2D)
       {
@@ -580,7 +576,7 @@ int SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::getConstraintT
         continue;
       }
       // Verify the attribute is a 3D point
-      boost::shared_ptr<GeomDataAPI_Point> aPoint3D = 
+      boost::shared_ptr<GeomDataAPI_Point> aPoint3D =
         boost::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->attr());
       if (aPoint3D)
       {
@@ -658,7 +654,7 @@ bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateGroup()
     if (aConstrPos < (int)myConstraints.size())
     {
       Slvs_hEntity aConstrEnt[] = {
-        myConstraints[aConstrPos].ptA,     myConstraints[aConstrPos].ptB, 
+        myConstraints[aConstrPos].ptA,     myConstraints[aConstrPos].ptB,
         myConstraints[aConstrPos].entityA, myConstraints[aConstrPos].entityB};
       for (int i = 0; i < 4; i++)
         if (aConstrEnt[i] != SLVS_E_UNKNOWN)
@@ -697,7 +693,7 @@ bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateGroup()
         myParamMaxID -= aNbParams;
       // Remove parameters of the entity
       int aParamPos = Search(aEntIter->param[0], myParams);
-      myParams.erase(myParams.begin() + aParamPos, 
+      myParams.erase(myParams.begin() + aParamPos,
                      myParams.begin() + aParamPos + aNbParams);
 
       // Remove entity
@@ -718,7 +714,7 @@ bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateGroup()
 }
 
 void SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateAttribute(
-                boost::shared_ptr<ModelAPI_Attribute> theAttribute, 
+                boost::shared_ptr<ModelAPI_Attribute> theAttribute,
                 const Slvs_hEntity&                   theEntityID)
 {
   // Search the position of the first parameter of the entity
@@ -728,7 +724,7 @@ void SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateAttribu
   // Look over supported types of entities
 
   // Point in 3D
-  boost::shared_ptr<GeomDataAPI_Point> aPoint = 
+  boost::shared_ptr<GeomDataAPI_Point> aPoint =
     boost::dynamic_pointer_cast<GeomDataAPI_Point>(theAttribute);
   if (aPoint)
   {
@@ -739,7 +735,7 @@ void SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateAttribu
   }
 
   // Point in 2D
-  boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D = 
+  boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
     boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
   if (aPoint2D)
   {
@@ -756,9 +752,9 @@ void SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateEntityI
 {
   if (myEntityMap.find(theEntity) != myEntityMap.end())
   {
-    // If the attribute is a point and it is changed (the group needs to rebuild), 
-    // probably user has dragged this point into this position, 
-    // so it is necessary to add constraint which will quarantee the point will not change
+    // If the attribute is a point and it is changed (the group needs to rebuild),
+    // probably user has dragged this point into this position,
+    // so it is necessary to add constraint which will guarantee the point will not change
 
     // Store myNeedToSolve flag to verify the entity is really changed
     bool aNeedToSolveCopy = myNeedToSolve;
@@ -769,9 +765,9 @@ void SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateEntityI
     if (myNeedToSolve) // the entity is changed
     {
       // Verify the entity is a point and add temporary constraint of permanency
-      boost::shared_ptr<GeomDataAPI_Point> aPoint = 
+      boost::shared_ptr<GeomDataAPI_Point> aPoint =
         boost::dynamic_pointer_cast<GeomDataAPI_Point>(theEntity);
-      boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D = 
+      boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(theEntity);
       if (aPoint || aPoint2D)
         addTemporaryConstraintWhereDragged(theEntity);
@@ -790,7 +786,7 @@ void SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addTemporaryC
     anEntIter = myEntityMap.find(theEntity);
 
   // Create WHERE_DRAGGED constraint
-  Slvs_Constraint aWDConstr = Slvs_MakeConstraint(++myConstrMaxID, myID, SLVS_C_WHERE_DRAGGED, 
+  Slvs_Constraint aWDConstr = Slvs_MakeConstraint(++myConstrMaxID, myID, SLVS_C_WHERE_DRAGGED,
                                                   myWorkplane.h, 0.0, anEntIter->second, 0, 0, 0);
   myConstraints.push_back(aWDConstr);
   myTempConstraints.push_back(aWDConstr.h);
index b96b6ea19fc85a40489da0781472fc0d4060db0e..9cbb23bab85a60b03f8b6758f3e2e070ca1d06a1 100644 (file)
@@ -26,7 +26,7 @@
 
 /** \class   SketchSolver_ConstraintManager
  *  \ingroup DataModel
- *  \brief   Listens the changes of SketchPlugin features and transforms the Constraint 
+ *  \brief   Listens the changes of SketchPlugin features and transforms the Constraint
  *           feature into the format understandable by SolveSpace library.
  *
  *  Constraints created for SolveSpace library are divided into the groups.
@@ -66,11 +66,12 @@ protected:
 
   /** \brief Adds or updates a workplane in the manager
    *  \param[in] theSketch the feature to create or update workplane
-   *  \return \c true if the workplane cahnged successfully
+   *  \return \c true if the workplane changed successfully
+   *  \remark Type of theSketch is not verified inside
    */
-  bool changeWorkplane(boost::shared_ptr<SketchPlugin_Sketch> theSketch);
+  bool changeWorkplane(boost::shared_ptr<SketchPlugin_Feature> theSketch);
 
-  /** \brief Removes a workplane from the manager. 
+  /** \brief Removes a workplane from the manager.
    *         All groups based on such workplane will be removed too.
    *  \param[in] theSketch the feature to be removed
    *  \return \c true if the workplane removed successfully
@@ -93,14 +94,14 @@ private:
    *  \param[in]  theConstraint constraint to be found
    *  \param[out] theGroups     list of group indexes interacted with constraint
    */
-  void findGroups(boost::shared_ptr<SketchPlugin_Constraint> theConstraint, 
+  void findGroups(boost::shared_ptr<SketchPlugin_Constraint> theConstraint,
                   std::vector<Slvs_hGroup>&                  theGroupIDs) const;
 
   /** \brief Searches in the list of groups the workplane which constains specified constraint
    *  \param[in] theConstraint constraint to be found
-   *  \return workplane contains the constraint
+   *  \return workplane containing the constraint
    */
-  boost::shared_ptr<SketchPlugin_Sketch> findWorkplaneForConstraint(
+  boost::shared_ptr<SketchPlugin_Feature> findWorkplaneForConstraint(
                   boost::shared_ptr<SketchPlugin_Constraint> theConstraint) const;
 
 private:
@@ -116,9 +117,11 @@ private:
 class SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup
 {
 public:
-  /** \brief New group based on specified workplane
+  /** \brief New group based on specified workplane.
+   *         Throws an exception if theWorkplane is not an object of SketchPlugin_Sketch type
+   *  \remark Type of theSketch is not verified inside
    */
-  SketchSolver_ConstraintGroup(boost::shared_ptr<SketchPlugin_Sketch> theWorkplane);
+  SketchSolver_ConstraintGroup(boost::shared_ptr<SketchPlugin_Feature> theWorkplane);
 
   ~SketchSolver_ConstraintGroup();
 
@@ -138,13 +141,13 @@ public:
    */
   bool isInteract(boost::shared_ptr<SketchPlugin_Constraint> theConstraint) const;
 
-  /** \brief Verifies the specified workplane is the same as a base workplane for this group
-   *  \param[in] theWorkplane workplane to be compared
+  /** \brief Verifies the specified feature is equal to the base workplane for this group
+   *  \param[in] theWorkplane the feature to be compared with base workplane
    *  \return \c true if workplanes are the same
    */
-  bool isBaseWorkplane(boost::shared_ptr<SketchPlugin_Sketch> theWorkplane) const;
+  bool isBaseWorkplane(boost::shared_ptr<SketchPlugin_Feature> theWorkplane) const;
 
-  boost::shared_ptr<SketchPlugin_Sketch> getWorkplane() const
+  boost::shared_ptr<SketchPlugin_Feature> getWorkplane() const
   { return mySketch; }
 
   /** \brief Update parameters of workplane. Should be called when Update event is coming.
@@ -179,10 +182,10 @@ protected:
 
   /** \brief Adds or updates a normal in the group
    *
-   *  Normal is a special entity in SolveSpace, which defines a direction in 3D and 
+   *  Normal is a special entity in SolveSpace, which defines a direction in 3D and
    *  a rotation about this direction. So, SolveSpace represents normals as unit quaternions.
    *
-   *  To define a normal there should be specified two coordinate axis 
+   *  To define a normal there should be specified two coordinate axis
    *  on the plane transversed to created normal.
    *
    *  \param[in] theDirX first coordinate axis of the plane
@@ -190,17 +193,17 @@ protected:
    *  \param[in] theNorm attribute for the normal (used to identify newly created entity)
    *  \return identifier of created or updated normal
    */
-  Slvs_hEntity changeNormal(boost::shared_ptr<ModelAPI_Attribute> theDirX, 
-                            boost::shared_ptr<ModelAPI_Attribute> theDirY, 
+  Slvs_hEntity changeNormal(boost::shared_ptr<ModelAPI_Attribute> theDirX,
+                            boost::shared_ptr<ModelAPI_Attribute> theDirY,
                             boost::shared_ptr<ModelAPI_Attribute> theNorm);
 
   /** \brief Adds or updates a parameter in the group
    *  \param[in] theParam   the value of parameter
-   *  \param[in] thePrmIter the cell in the list of parameters which should be changed 
+   *  \param[in] thePrmIter the cell in the list of parameters which should be changed
    *                        (the iterator will be increased if it does not reach the end of the list)
    *  \return identifier of changed parameter; when the parameter cannot be created, returned ID is 0
    */
-  Slvs_hParam changeParameter(const double& theParam, 
+  Slvs_hParam changeParameter(const double& theParam,
                               std::vector<Slvs_Param>::const_iterator& thePrmIter);
 
   /** \brief Compute constraint type according to SolveSpace identifiers
@@ -230,7 +233,7 @@ private:
    *  \param[in] theSketch parameters of workplane are the attributes of this sketch
    *  \return \c true if success, \c false if workplane parameters are not consistent
    */
-  bool addWorkplane(boost::shared_ptr<SketchPlugin_Sketch> theSketch);
+  bool addWorkplane(boost::shared_ptr<SketchPlugin_Feature> theSketch);
 
 private:
   // SolveSpace entities
@@ -247,12 +250,12 @@ private:
   SketchSolver_Solver          myConstrSolver;  ///< Solver for set of equations obtained by constraints
 
   // SketchPlugin entities
-  boost::shared_ptr<SketchPlugin_Sketch> mySketch; ///< Equivalent to workplane
-  std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_hConstraint> 
-                                myConstraintMap;   ///< The map between SketchPlugin and SolveSpace constraints
-  std::list<Slvs_hConstraint> myTempConstraints;   ///< The list of identifiers of temporary constraints
+  boost::shared_ptr<SketchPlugin_Feature> mySketch; ///< Equivalent to workplane
+  std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_hConstraint>
+                                myConstraintMap;    ///< The map between SketchPlugin and SolveSpace constraints
+  std::list<Slvs_hConstraint> myTempConstraints;    ///< The list of identifiers of temporary constraints
   std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>
-                                myEntityMap;       ///< The map between parameters of constraints and their equivalent SolveSpace entities
+                                myEntityMap;        ///< The map between parameters of constraints and their equivalent SolveSpace entities
 };
 
 #endif
index aeb29ef5e44d5753a5febc9cad8baf999f8e97ea..944a58e69354102e1d694b7c6efbb314ea175a5f 100644 (file)
@@ -10,6 +10,8 @@
 // Need to be defined before including SolveSpace to avoid additional dependances on Windows platform
 #if defined(WIN32) && !defined(HAVE_C99_INTEGER_TYPES)
 typedef unsigned int UINT32;
+#else
+#include <stdint.h>
 #endif
 #include <string.h>
 #include <slvs.h>
index f5d55c8dbbf3736bec921f6e69396e2b4d3fb18b..a74824431b559a7be3066491d82b2b33fa344597 100644 (file)
@@ -31,6 +31,9 @@ void XGUI_ContextMenuMgr::createActions()
 
   aAction = new QAction(QIcon(":pictures/assembly.png"), tr("Deactivate"), this);
   addAction("DEACTIVATE_PART_CMD", aAction);
+
+  aAction = new QAction(QIcon(":pictures/delete.png"), tr("Delete"), this);
+  addAction("DELETE_CMD", aAction);
 }
 
 void XGUI_ContextMenuMgr::addAction(const QString& theId, QAction* theAction)
@@ -95,6 +98,7 @@ QMenu* XGUI_ContextMenuMgr::objectBrowserMenu() const
       } else {
         aActions.append(action("EDIT_CMD"));
       }
+      aActions.append(action("DELETE_CMD"));
 
     // Process Root object (document)
     } else { // If feature is 0 the it means that selected root object (document)
@@ -103,6 +107,7 @@ QMenu* XGUI_ContextMenuMgr::objectBrowserMenu() const
       }
     }
   }
+  aActions.append(myWorkshop->objectBrowser()->actions());
   if (aActions.size() > 0) {
     QMenu* aMenu = new QMenu();
     aMenu->addActions(aActions);
index 42c609dac5f2c382b948a2cf30a2a80c7fa411a6..05c5f7e123961d7bea1ebad2ff907413198172eb 100644 (file)
@@ -25,6 +25,10 @@ public:
   //! Returns 0 if the given index is not index of a feature
   virtual FeaturePtr feature(const QModelIndex& theIndex) const = 0;
 
+  //! Returns QModelIndex which corresponds to the given feature
+  //! If the feature is not found then index is not valid
+  virtual QModelIndex featureIndex(const FeaturePtr& theFeature) const = 0;
+
   //! Returns parent index of the given feature
   virtual QModelIndex findParent(const FeaturePtr& theFeature) const = 0;
 
index 2c4470cce95b8d88c0fb3c7dc4d5758499bbbd33..8b42208aee3bd78bacc9ab82b704a7228470b928 100644 (file)
@@ -24,7 +24,7 @@ XGUI_DocumentDataModel::XGUI_DocumentDataModel(QObject* theParent)
   : QAbstractItemModel(theParent), myActivePart(0)
 {
   // Find Document object
-  boost::shared_ptr<ModelAPI_PluginManager> aMgr = ModelAPI_PluginManager::get();
+  PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
   myDocument = aMgr->currentDocument();
 
   // Register in event loop
@@ -49,8 +49,8 @@ void XGUI_DocumentDataModel::processEvent(const Events_Message* theMessage)
   // Created object event *******************
   if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_CREATED)) {
     const Model_FeatureUpdatedMessage* aUpdMsg = dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
-    boost::shared_ptr<ModelAPI_Feature> aFeature = aUpdMsg->feature();
-    boost::shared_ptr<ModelAPI_Document> aDoc = aFeature->document();
+    FeaturePtr aFeature = aUpdMsg->feature();
+    DocumentPtr aDoc = aFeature->document();
 
     if (aDoc == myDocument) {  // If root objects
       if (aFeature->getGroup().compare(PARTS_GROUP) == 0) { // Update only Parts group
@@ -86,12 +86,12 @@ void XGUI_DocumentDataModel::processEvent(const Events_Message* theMessage)
   // Deleted object event ***********************
   } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_DELETED)) {
     const Model_FeatureDeletedMessage* aUpdMsg = dynamic_cast<const Model_FeatureDeletedMessage*>(theMessage);
-    boost::shared_ptr<ModelAPI_Document> aDoc = aUpdMsg->document();
+    DocumentPtr aDoc = aUpdMsg->document();
 
     if (aDoc == myDocument) {  // If root objects
       if (aUpdMsg->group().compare(PARTS_GROUP) == 0) { // Updsate only Parts group
-        int aStart = myPartModels.size();
-        removeSubModel(myPartModels.size() - 1);
+        int aStart = myPartModels.size() - 1;
+        removeSubModel(aStart);
         removeRow(aStart, partFolderNode());
       } else { // Update top groups (other except parts
         QModelIndex aIndex = myModel->findGroup(aUpdMsg->group());
@@ -119,8 +119,8 @@ void XGUI_DocumentDataModel::processEvent(const Events_Message* theMessage)
   // Deleted object event ***********************
   } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED)) {
     //const Model_FeatureUpdatedMessage* aUpdMsg = dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
-    //boost::shared_ptr<ModelAPI_Feature> aFeature = aUpdMsg->feature();
-    //boost::shared_ptr<ModelAPI_Document> aDoc = aFeature->document();
+    //FeaturePtr aFeature = aUpdMsg->feature();
+    //DocumentPtr aDoc = aFeature->document();
     
     // TODO: Identify the necessary index by the modified feature
     QModelIndex aIndex;
@@ -465,3 +465,29 @@ void XGUI_DocumentDataModel::deactivatePart()
   myActivePart = 0;
   myModel->setItemsColor(ACTIVE_COLOR);
 }
+Qt::ItemFlags XGUI_DocumentDataModel::flags(const QModelIndex& theIndex) const
+{
+  Qt::ItemFlags aFlags = QAbstractItemModel::flags(theIndex);
+  if (feature(theIndex)) {
+    aFlags |= Qt::ItemIsEditable;
+  }
+  return aFlags;
+}
+
+QModelIndex XGUI_DocumentDataModel::partIndex(const FeaturePtr& theFeature) const 
+{
+  int aRow = -1;
+  XGUI_PartModel* aModel = 0;
+  foreach (XGUI_PartModel* aPartModel, myPartModels) {
+    aRow++;
+    if (aPartModel->part() == theFeature) {
+      aModel = aPartModel;
+      break;
+    }
+  }
+  if (aModel) {
+    return createIndex(aRow, 0, (void*)getModelIndex(aModel->index(0, 0, QModelIndex())));
+  }
+  return QModelIndex();
+}
index f6ce80eac56ee2efd203ba46d22df6456b9f2b98..c43b99d19c42e5588b0aa859e2bac4e2cf03ed91 100644 (file)
@@ -50,10 +50,16 @@ public:
 
   bool removeRows(int theRow, int theCount, const QModelIndex& theParent = QModelIndex());
 
+  Qt::ItemFlags flags(const QModelIndex& theIndex) const;
+
   //! Returns Feature object by the given Model index.
   //! Returns 0 if the given index is not index of a feature
   FeaturePtr feature(const QModelIndex& theIndex) const;
 
+  //! Returns QModelIndex which corresponds to the given feature if this is a part
+  //! If the feature is not found then index is not valid
+  QModelIndex partIndex(const FeaturePtr& theFeature) const;
+
   //! Activates a part data model if the index is a Part node index. 
   //! Returns true if active part changed.
   bool activatedIndex(const QModelIndex& theIndex);
index dd9706048148cb229bf52fb175284b58833feb2f..352fa4ba8dd1fdf9f0da2b0fdec87c83a2cd8e37 100644 (file)
@@ -2,12 +2,16 @@
 #include "XGUI_DocumentDataModel.h"
 
 #include <ModelAPI_Data.h>
+#include <ModelAPI_PluginManager.h>
+#include <ModelAPI_Document.h>
 
 #include <QLayout>
 #include <QLabel>
+#include <QLineEdit>
 #include <QPixmap>
 #include <QEvent>
 #include <QMouseEvent>
+#include <QAction>
 
 
 
@@ -16,6 +20,7 @@ XGUI_DataTree::XGUI_DataTree(QWidget* theParent)
 {
   setHeaderHidden(true);
   setModel(new XGUI_DocumentDataModel(this));
+  setEditTriggers(QAbstractItemView::NoEditTriggers);
 
   connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), 
           this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
@@ -71,6 +76,16 @@ void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent)
   emit contextMenuRequested(theEvent);
 }
 
+void XGUI_DataTree::commitData(QWidget* theEditor)
+{
+  QLineEdit* aEditor = dynamic_cast<QLineEdit*>(theEditor);
+  if (aEditor) {
+    QString aRes = aEditor->text();
+    FeaturePtr aFeature = mySelectedData.first();
+    aFeature->data()->setName(qPrintable(aRes));
+  }
+}
+
 //********************************************************************
 //********************************************************************
 //********************************************************************
@@ -100,8 +115,14 @@ XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent)
 
   aLabelLay->addWidget(aLbl);
 
-  myActiveDocLbl = new QLabel(tr("Part set"), aLabelWgt);
-  myActiveDocLbl->setMargin(2);
+  PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
+  DocumentPtr aDoc = aMgr->rootDocument();
+  // TODO: Find a name of the root document
+
+  myActiveDocLbl = new QLineEdit(tr("Part set"), aLabelWgt);
+  myActiveDocLbl->setReadOnly(true);
+  myActiveDocLbl->setFrame(false);
+  //myActiveDocLbl->setMargin(2);
   myActiveDocLbl->setContextMenuPolicy(Qt::CustomContextMenu);
 
   myActiveDocLbl->installEventFilter(this);
@@ -127,48 +148,89 @@ XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent)
           this, SLOT(onContextMenuRequested(QContextMenuEvent*)));
   
   onActivePartChanged(FeaturePtr());
-}
 
+  // Create internal actions
+  QAction* aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this);
+  aAction->setData("RENAME_CMD");
+  connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onEditItem()));
+  addAction(aAction);
+}
 
+//***************************************************
 XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser()
 {
 }
 
-
+//***************************************************
 void XGUI_ObjectsBrowser::onActivePartChanged(FeaturePtr thePart)
 {
   QPalette aPalet = myActiveDocLbl->palette();
   if (thePart) {
-    //myActiveDocLbl->setText(tr("Activate Part set"));
-    aPalet.setColor(QPalette::Foreground, Qt::black);
-    //myActiveDocLbl->setCursor(Qt::PointingHandCursor);
+    aPalet.setColor(QPalette::Text, Qt::black);
   }  else {
-    //myActiveDocLbl->setText(tr("Part set is active"));
-    aPalet.setColor(QPalette::Foreground, QColor(0, 72, 140));
-    //myActiveDocLbl->unsetCursor();
+    aPalet.setColor(QPalette::Text, QColor(0, 72, 140));
   }
   myActiveDocLbl->setPalette(aPalet);
 }
 
+//***************************************************
 bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent)
 {
   if (obj == myActiveDocLbl) {
-    if (theEvent->type() == QEvent::MouseButtonDblClick) {
-      if (myDocModel->activePartIndex().isValid()) {
-        myTreeView->setExpanded(myDocModel->activePartIndex(), false);
+    if (myActiveDocLbl->isReadOnly()) {
+      if (theEvent->type() == QEvent::MouseButtonDblClick) {
+        if (myDocModel->activePartIndex().isValid()) {
+          myTreeView->setExpanded(myDocModel->activePartIndex(), false);
+        }
+        myDocModel->deactivatePart();
+        onActivePartChanged(FeaturePtr());
+        emit activePartChanged(FeaturePtr());
+      }
+    } else {
+      // End of editing by mouse click
+      if (theEvent->type() == QEvent::MouseButtonRelease) {
+        QMouseEvent* aEvent = (QMouseEvent*) theEvent;
+        QPoint aPnt = mapFromGlobal(aEvent->globalPos());
+        if (childAt(aPnt) != myActiveDocLbl) {
+          closeDocNameEditing(true);
+        }
+      } else if (theEvent->type() == QEvent::KeyRelease) {
+        QKeyEvent* aEvent = (QKeyEvent*) theEvent;
+        switch (aEvent->key()) {
+        case Qt::Key_Return: // Accept current input
+          closeDocNameEditing(true);
+          break;
+        case Qt::Key_Escape: // Cancel the input
+          closeDocNameEditing(false);
+          break;
+        } 
       }
-      myDocModel->deactivatePart();
-      onActivePartChanged(FeaturePtr());
-      emit activePartChanged(FeaturePtr());
     }
   }
   return QWidget::eventFilter(obj, theEvent);
 }
 
-void XGUI_ObjectsBrowser::activateCurrentPart(bool toActivate)
+//***************************************************
+void XGUI_ObjectsBrowser::closeDocNameEditing(bool toSave)
 {
-  if (toActivate) {
-    QModelIndex aIndex = myTreeView->currentIndex();
+  myActiveDocLbl->deselect();
+  myActiveDocLbl->clearFocus();
+  myActiveDocLbl->releaseMouse();
+  myActiveDocLbl->setReadOnly(true);
+  if (toSave) {
+    // TODO: Save the name of root document
+    PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
+    DocumentPtr aDoc = aMgr->rootDocument();
+  } else {
+    myActiveDocLbl->setText(myActiveDocLbl->property("OldText").toString());
+  }
+}
+
+//***************************************************
+void XGUI_ObjectsBrowser::activatePart(const FeaturePtr& thePart)
+{
+  if (thePart) {
+    QModelIndex aIndex = myDocModel->partIndex(thePart);
 
     if ((myDocModel->activePartIndex() != aIndex) && myDocModel->activePartIndex().isValid()) {
       myTreeView->setExpanded(myDocModel->activePartIndex(), false);
@@ -176,6 +238,7 @@ void XGUI_ObjectsBrowser::activateCurrentPart(bool toActivate)
     bool isChanged = myDocModel->activatedIndex(aIndex);
     if (isChanged) {
       if (myDocModel->activePartIndex().isValid()) {
+        myTreeView->setExpanded(aIndex.parent(), true);
         myTreeView->setExpanded(aIndex, true);
         onActivePartChanged(myDocModel->feature(aIndex));
       } else {
@@ -192,18 +255,55 @@ void XGUI_ObjectsBrowser::activateCurrentPart(bool toActivate)
   }
 }
 
+//***************************************************
 void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent) 
 {
   myFeaturesList = myTreeView->selectedFeatures();
+  bool toEnable = myFeaturesList.size() > 0;
+  foreach(QAction* aCmd, actions()) {
+    aCmd->setEnabled(toEnable);
+  }
   emit contextMenuRequested(theEvent);
 }
 
+//***************************************************
 void XGUI_ObjectsBrowser::onLabelContextMenuRequested(const QPoint& thePnt)
 {
   myFeaturesList.clear();
   //Empty feature pointer means that selected root document
   myFeaturesList.append(FeaturePtr()); 
 
+  foreach(QAction* aCmd, actions()) {
+    aCmd->setEnabled(true);
+  }
   QContextMenuEvent aEvent( QContextMenuEvent::Mouse, thePnt, myActiveDocLbl->mapToGlobal(thePnt) );
   emit contextMenuRequested(&aEvent);
+}
+
+//***************************************************
+void XGUI_ObjectsBrowser::onEditItem()
+{
+  if (myFeaturesList.size() > 0) {
+    FeaturePtr aFeature = myFeaturesList.first();
+    if (aFeature) { // Selection happens in TreeView
+      // Find index which corresponds the feature
+      QModelIndex aIndex;
+      foreach(QModelIndex aIdx, selectedIndexes()) {
+        if (dataModel()->feature(aIdx) == aFeature) {
+          aIndex = aIdx;
+          break;
+        }
+      }
+      if (aIndex.isValid()) {
+        myTreeView->setCurrentIndex(aIndex);
+        myTreeView->edit(aIndex);
+      }
+    } else { //Selection happens in Upper label
+      myActiveDocLbl->setReadOnly(false);
+      myActiveDocLbl->setFocus();
+      myActiveDocLbl->selectAll();
+      myActiveDocLbl->grabMouse();
+      myActiveDocLbl->setProperty("OldText", myActiveDocLbl->text());
+    }
+  }
 }
\ No newline at end of file
index c1907e34d19c9a33a98dc76571e08fa1c8d9e41d..b8e275ae688e3d6f7478bc832ef244377a4eea38 100644 (file)
@@ -9,7 +9,7 @@
 #include <QTreeView>
 
 class XGUI_DocumentDataModel;
-class QLabel;
+class QLineEdit;
 
 
 class XGUI_DataTree: public QTreeView
@@ -32,6 +32,9 @@ signals:
   //! Emited on context menu request
   void contextMenuRequested(QContextMenuEvent* theEvent);
 
+protected slots:
+  virtual void commitData(QWidget* theEditor);
+
 protected:
   virtual void mouseDoubleClickEvent(QMouseEvent* theEvent);
   virtual void contextMenuEvent(QContextMenuEvent* theEvent);
@@ -70,7 +73,7 @@ public:
   XGUI_DataTree* treeView() const { return myTreeView; }
 
   //! Activates currently selected part. Signal activePartChanged will not be sent
-  void activateCurrentPart(bool toActivate);
+  void activatePart(const FeaturePtr& thePart);
 
 signals:
   //! Emited when selection is changed
@@ -90,11 +93,16 @@ private slots:
   void onContextMenuRequested(QContextMenuEvent* theEvent);
   void onLabelContextMenuRequested(const QPoint& thePnt);
 
+  //! Called on Edit command request
+  void onEditItem();
+
 private:
+  void closeDocNameEditing(bool toSave);
+
   //! Internal model
   XGUI_DocumentDataModel* myDocModel;
 
-  QLabel* myActiveDocLbl;
+  QLineEdit* myActiveDocLbl;
   XGUI_DataTree* myTreeView;
 
   QFeatureList myFeaturesList;
index 532d88d787202869ce3140e6f6a22152097cc2e2..6610b64c58ff15dcbbe5b5268c7224188ad021c9 100644 (file)
 #include <QBrush>
 
 
-FeaturePtr featureObj(const FeaturePtr& theFeature)
-{
-  ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(theFeature);
-  if (aObject)
-    return aObject->featureRef();
-  return theFeature;
-}
+//FeaturePtr featureObj(const FeaturePtr& theFeature)
+//{
+//  ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(theFeature);
+//  if (aObject)
+//    return aObject->featureRef();
+//  return theFeature;
+//}
 
 
 XGUI_TopDataModel::XGUI_TopDataModel(const DocumentPtr& theDocument, QObject* theParent)
@@ -41,7 +41,7 @@ QVariant XGUI_TopDataModel::data(const QModelIndex& theIndex, int theRole) const
       return tr("Parameters") + QString(" (%1)").arg(rowCount(theIndex));
     case ParamObject:
       {
-        FeaturePtr aFeature = featureObj(myDocument->feature(PARAMETERS_GROUP, theIndex.row()));
+        FeaturePtr aFeature = myDocument->feature(PARAMETERS_GROUP, theIndex.row(), true);
         if (aFeature)
           return aFeature->data()->getName().c_str();
       } 
@@ -49,7 +49,7 @@ QVariant XGUI_TopDataModel::data(const QModelIndex& theIndex, int theRole) const
         return tr("Constructions") + QString(" (%1)").arg(rowCount(theIndex));
     case ConstructObject:
       {
-        FeaturePtr aFeature = featureObj(myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row()));
+        FeaturePtr aFeature = myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true);
         if (aFeature)
           return aFeature->data()->getName().c_str();
       }
@@ -65,7 +65,7 @@ QVariant XGUI_TopDataModel::data(const QModelIndex& theIndex, int theRole) const
       return QIcon(":pictures/constr_folder.png");
     case ConstructObject:
       {
-        FeaturePtr aFeature = featureObj(myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row()));
+        FeaturePtr aFeature = myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true);
         if (aFeature)
           return QIcon(XGUI_Workshop::featureIcon(aFeature->getKind()));
       }
@@ -152,9 +152,9 @@ FeaturePtr XGUI_TopDataModel::feature(const QModelIndex& theIndex) const
   case ConstructFolder:
     return FeaturePtr();
   case ParamObject:
-    return featureObj(myDocument->feature(PARAMETERS_GROUP, theIndex.row()));
+    return myDocument->feature(PARAMETERS_GROUP, theIndex.row(), true);
   case ConstructObject:
-    return featureObj(myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row()));
+    return myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true);
   }
   return FeaturePtr();
 }
@@ -162,13 +162,7 @@ FeaturePtr XGUI_TopDataModel::feature(const QModelIndex& theIndex) const
 
 QModelIndex XGUI_TopDataModel::findParent(const FeaturePtr& theFeature) const
 {
-  QString aGroup(theFeature->getGroup().c_str());
-
-  if (theFeature->getGroup().compare(PARAMETERS_GROUP) == 0)
-    return createIndex(0, 0, (qint32) ParamsFolder);
-  if (theFeature->getGroup().compare(CONSTRUCTIONS_GROUP) == 0)
-    return createIndex(1, 0, (qint32) ConstructFolder);
-  return QModelIndex();
+  return findGroup(theFeature->getGroup().c_str());
 }
 
 QModelIndex XGUI_TopDataModel::findGroup(const std::string& theGroup) const
@@ -180,6 +174,30 @@ QModelIndex XGUI_TopDataModel::findGroup(const std::string& theGroup) const
   return QModelIndex();
 }
 
+QModelIndex XGUI_TopDataModel::featureIndex(const FeaturePtr& theFeature) const
+{
+  QModelIndex aIndex;
+  if (theFeature) {
+    std::string aGroup = theFeature->getGroup();
+    int aNb = myDocument->size(aGroup);
+    int aRow = -1;
+    for (int i = 0; i < aNb; i++) {
+      if (myDocument->feature(aGroup, i, true) == theFeature) {
+        aRow = i;
+        break;
+      }
+    }
+    if (aRow != -1) {
+      if (aGroup.compare(PARAMETERS_GROUP) == 0)
+        return createIndex(aRow, 0, (qint32) ParamObject);
+      if (aGroup.compare(CONSTRUCTIONS_GROUP) == 0)
+        return createIndex(aRow, 0, (qint32) ConstructObject);
+    }
+  }
+  return aIndex;
+}
+
+
 
 //******************************************************************
 //******************************************************************
@@ -202,7 +220,7 @@ QVariant XGUI_PartDataModel::data(const QModelIndex& theIndex, int theRole) cons
     switch (theIndex.internalId()) {
     case MyRoot:
       {
-        FeaturePtr aFeature = featureObj(myDocument->feature(PARTS_GROUP, myId));
+        FeaturePtr aFeature = myDocument->feature(PARTS_GROUP, myId, true);
         if (aFeature)
           return aFeature->data()->getName().c_str();
       }
@@ -214,19 +232,19 @@ QVariant XGUI_PartDataModel::data(const QModelIndex& theIndex, int theRole) cons
       return tr("Bodies") + QString(" (%1)").arg(rowCount(theIndex));
     case ParamObject:
       {
-        FeaturePtr aFeature = featureObj(featureDocument()->feature(PARAMETERS_GROUP, theIndex.row()));
+        FeaturePtr aFeature = featureDocument()->feature(PARAMETERS_GROUP, theIndex.row(), true);
         if (aFeature)
           return aFeature->data()->getName().c_str();
       }
     case ConstructObject:
       {
-        FeaturePtr aFeature = featureObj(featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row()));
+        FeaturePtr aFeature = featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true);
         if (aFeature)
           return aFeature->data()->getName().c_str();
       }
     case HistoryObject:
       {
-        FeaturePtr aFeature = featureObj(featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3));
+        FeaturePtr aFeature = featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3, true);
         if (aFeature)
           return aFeature->data()->getName().c_str();
       }
@@ -244,13 +262,13 @@ QVariant XGUI_PartDataModel::data(const QModelIndex& theIndex, int theRole) cons
       return QIcon(":pictures/constr_folder.png");
     case ConstructObject:
       {
-        FeaturePtr aFeature = featureObj(featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row()));
+        FeaturePtr aFeature = featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true);
         if (aFeature)
           return QIcon(XGUI_Workshop::featureIcon(aFeature->getKind()));
       }
     case HistoryObject:
       {
-        FeaturePtr aFeature = featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3);
+        FeaturePtr aFeature = featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3, true);
         if (aFeature)
           return QIcon(XGUI_Workshop::featureIcon(aFeature->getKind()));
       }
@@ -274,7 +292,7 @@ QVariant XGUI_PartDataModel::headerData(int section, Qt::Orientation orientation
 int XGUI_PartDataModel::rowCount(const QModelIndex& parent) const
 {
   if (!parent.isValid()) 
-    if (myDocument->feature(PARTS_GROUP, myId))
+    if (myDocument->feature(PARTS_GROUP, myId, true))
       return 1;
     else 
       return 0;
@@ -319,7 +337,7 @@ QModelIndex XGUI_PartDataModel::index(int theRow, int theColumn, const QModelInd
   case ConstructFolder:
     return createIndex(theRow, 0, (qint32) ConstructObject);
   case BodiesFolder:
-    return createIndex(theRow, 0, (qint32) BodieswObject);
+    return createIndex(theRow, 0, (qint32) BodiesObject);
   }
   return QModelIndex();
 }
@@ -350,7 +368,7 @@ bool XGUI_PartDataModel::hasChildren(const QModelIndex& theParent) const
 
 DocumentPtr XGUI_PartDataModel::featureDocument() const
 {
-  FeaturePtr aFeature = featureObj(myDocument->feature(PARTS_GROUP, myId));
+  FeaturePtr aFeature = myDocument->feature(PARTS_GROUP, myId, true);
   return aFeature->data()->docRef("PartDocument")->value();
 }
  
@@ -359,16 +377,19 @@ FeaturePtr XGUI_PartDataModel::feature(const QModelIndex& theIndex) const
   switch (theIndex.internalId()) {
   case MyRoot:
     if (theIndex.row() < 3) {
-      return featureObj(myDocument->feature(PARTS_GROUP, myId));
+      return myDocument->feature(PARTS_GROUP, myId, true);
     } else 
-      return featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3);
+      return featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3, true);
   case ParamsFolder:
   case ConstructFolder:
+  case BodiesFolder:
     return FeaturePtr();
   case ParamObject:
-    return featureObj(featureDocument()->feature(PARAMETERS_GROUP, theIndex.row()));
+    return featureDocument()->feature(PARAMETERS_GROUP, theIndex.row(), true);
   case ConstructObject:
-    return featureObj(featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row()));
+    return featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true);
+  //case BodiesObject:
+  //  return featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true);
   }
   return FeaturePtr();
 }
@@ -381,13 +402,7 @@ bool XGUI_PartDataModel::hasDocument(const DocumentPtr& theDoc) const
 
 QModelIndex XGUI_PartDataModel::findParent(const FeaturePtr& theFeature) const
 {
-  QString aGroup(theFeature->getGroup().c_str());
-
-  if (theFeature->getGroup().compare(PARAMETERS_GROUP) == 0)
-    return createIndex(0, 0, (qint32) ParamsFolder);
-  if (theFeature->getGroup().compare(CONSTRUCTIONS_GROUP) == 0)
-    return createIndex(1, 0, (qint32) ConstructFolder);
-  return QModelIndex();
+  return findGroup(theFeature->getGroup().c_str());
 }
 
 QModelIndex XGUI_PartDataModel::findGroup(const std::string& theGroup) const
@@ -401,5 +416,31 @@ QModelIndex XGUI_PartDataModel::findGroup(const std::string& theGroup) const
 
 FeaturePtr XGUI_PartDataModel::part() const
 {
-  return featureObj(myDocument->feature(PARTS_GROUP, myId));
-}
\ No newline at end of file
+  return myDocument->feature(PARTS_GROUP, myId, true);
+}
+
+QModelIndex XGUI_PartDataModel::featureIndex(const FeaturePtr& theFeature) const
+{
+  QModelIndex aIndex;
+  if (theFeature) {
+    if (part() == theFeature) 
+      return aIndex;
+
+    std::string aGroup = theFeature->getGroup();
+    int aNb = myDocument->size(aGroup);
+    int aRow = -1;
+    for (int i = 0; i < aNb; i++) {
+      if (myDocument->feature(aGroup, i, true) == theFeature) {
+        aRow = i;
+        break;
+      }
+    }
+    if (aRow != -1) {
+      if (aGroup.compare(PARAMETERS_GROUP) == 0)
+        return createIndex(aRow, 0, (qint32) ParamObject);
+      if (aGroup.compare(CONSTRUCTIONS_GROUP) == 0)
+        return createIndex(aRow, 0, (qint32) ConstructObject);
+    }
+  }
+  return aIndex;
+}
index a44dfb03ca5d22f869bdd67f944985816c6ca1ff..e1533ee0bfbd4a14b04628ca438a1715d1f6fa20 100644 (file)
@@ -36,6 +36,10 @@ public:
   //! Returns 0 if the given index is not index of a feature
   virtual FeaturePtr feature(const QModelIndex& theIndex) const;
 
+  //! Returns QModelIndex which corresponds to the given feature
+  //! If the feature is not found then index is not valid
+  virtual QModelIndex featureIndex(const FeaturePtr& theFeature) const;
+
   //! Returns parent index of the given feature
   virtual QModelIndex findParent(const FeaturePtr& theFeature) const;
 
@@ -85,6 +89,10 @@ public:
   //! Returns 0 if the given index is not index of a feature
   virtual FeaturePtr feature(const QModelIndex& theIndex) const;
 
+  //! Returns QModelIndex which corresponds to the given feature
+  //! If the feature is not found then index is not valid
+  virtual QModelIndex featureIndex(const FeaturePtr& theFeature) const;
+
   //! Returns true if the given document is a sub-document of this tree
   virtual bool hasDocument(const DocumentPtr& theDoc) const;
 
@@ -108,7 +116,7 @@ private:
     ConstructFolder,
     ConstructObject,
     BodiesFolder,
-    BodieswObject,
+    BodiesObject,
     HistoryObject
   };
 
index cb7a3c790f8dc44558b5cab53359f64736428bbb..9d064f210bbe9500ad01613bbf22880196a9efcd 100644 (file)
@@ -45,6 +45,7 @@
 #include <QPushButton>
 #include <QDockWidget>
 #include <QLayout>
+#include <QTimer>
 
 #ifdef _DEBUG
 #include <QDebug>
@@ -117,6 +118,9 @@ void XGUI_Workshop::startApplication()
   aLoop->registerListener(this, aPartSetId);
   Events_ID aFeatureUpdatedId = aLoop->eventByName(EVENT_FEATURE_UPDATED);
   aLoop->registerListener(this, aFeatureUpdatedId);
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED));
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_DELETED));
+
   activateModule();
   if (myMainWindow) {
     myMainWindow->show();
@@ -205,6 +209,24 @@ void XGUI_Workshop::processEvent(const Events_Message* theMessage)
     }
     return;
   }
+  // Process creation of Part
+  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_CREATED)) {
+    const Model_FeatureUpdatedMessage* aUpdMsg = dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
+    FeaturePtr aFeature = aUpdMsg->feature();
+    if (aFeature->getKind() == "Part") {
+      //The created part will be created in Object Browser later and we have to activate it
+      // only when it is created everywere
+      QTimer::singleShot(50, this, SLOT(activateLastPart()));
+    }
+  }
+
+  // Process deletion of a part
+  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_DELETED)) {
+    PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
+    if (aMgr->currentDocument() == aMgr->rootDocument())
+      activatePart(FeaturePtr()); // Activate PartSet
+  }
+
   //Update property panel on corresponding message. If there is no current operation (no
   //property panel), or received message has different feature to the current - do nothing.
   static Events_ID aFeatureUpdatedId = Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED);
@@ -298,8 +320,8 @@ void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage)
   QString aWchName = QString::fromStdString(theMessage->workbenchId());
   QString aNestedFeatures = QString::fromStdString(theMessage->nestedFeatures());
   bool isUsePropPanel = theMessage->isUseInput();
+  QString aId = QString::fromStdString(theMessage->id());
   if (isSalomeMode()) {
-    QString aId = QString::fromStdString(theMessage->id());
     QAction* aAction = salomeConnector()->addFeature(aWchName,
                               aId,
                               QString::fromStdString(theMessage->text()),
@@ -323,7 +345,7 @@ void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage)
       aGroup = aPage->addGroup(aGroupName);
     }
     //Create feature...
-    XGUI_Command* aCommand = aGroup->addFeature(QString::fromStdString(theMessage->id()),
+    XGUI_Command* aCommand = aGroup->addFeature(aId,
                                                 QString::fromStdString(theMessage->text()),
                                                 QString::fromStdString(theMessage->tooltip()),
                                                 QIcon(theMessage->icon().c_str()),
@@ -537,7 +559,7 @@ XGUI_Module* XGUI_Workshop::loadModule(const QString& theModule)
     }
   }
 #else
-  void* modLib = dlopen( libName.toLatin1(), RTLD_LAZY );
+  void* modLib = dlopen( libName.toLatin1(), RTLD_LAZY | RTLD_GLOBAL );
   if ( !modLib ) {
     err = QString( "Can not load library %1. %2" ).arg( libName ).arg( dlerror() );
   } else {
@@ -720,25 +742,51 @@ XGUI_SalomeViewer* XGUI_Workshop::salomeViewer() const
 //**************************************************************
 void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
 {
-  if (theId == "ACTIVATE_PART_CMD")
-    activatePart(true);
+  QFeatureList aFeatures = mySelector->selectedFeatures();
+  if ((theId == "ACTIVATE_PART_CMD") && (aFeatures.size() > 0))
+    activatePart(aFeatures.first());
   else if (theId == "DEACTIVATE_PART_CMD") 
-    activatePart(false);
+    activatePart(FeaturePtr());
+  else if (theId == "DELETE_CMD")
+    deleteFeatures(aFeatures);
+}
 
+//**************************************************************
+void XGUI_Workshop::activatePart(FeaturePtr theFeature)
+{
+  changeCurrentDocument(theFeature);
+  myObjectBrowser->activatePart(theFeature);
 }
 
 //**************************************************************
-void XGUI_Workshop::activatePart(bool toActivate)
+void XGUI_Workshop::activateLastPart()
 {
-  if (toActivate) {
-    QFeatureList aFeatures = mySelector->selectedFeatures();
-    if (aFeatures.size() > 0) {
-      changeCurrentDocument(aFeatures.first());
-      myObjectBrowser->activateCurrentPart(true);
+  PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
+  DocumentPtr aDoc = aMgr->rootDocument();
+  FeaturePtr aLastPart = aDoc->feature(PARTS_GROUP, aDoc->size(PARTS_GROUP) - 1, true);
+  activatePart(aLastPart);
+}
+
+//**************************************************************
+void XGUI_Workshop::deleteFeatures(QFeatureList theList)
+{
+  QMainWindow* aDesktop = isSalomeMode()? salomeConnector()->desktop() : myMainWindow;
+  QMessageBox::StandardButton aRes = QMessageBox::warning(aDesktop, tr("Delete features"), 
+                                                          tr("Seleted features will be deleted. Continue?"), 
+                                                          QMessageBox::No | QMessageBox::Yes, QMessageBox::No);
+  if (aRes == QMessageBox::Yes) {
+    PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
+    aMgr->rootDocument()->startOperation();
+    foreach (FeaturePtr aFeature, theList) {
+      if (aFeature->getKind() == "Part") {
+        DocumentPtr aDoc = aFeature->data()->docRef("PartDocument")->value();
+        if (aDoc == aMgr->currentDocument()) {
+          aDoc->close();
+        }
+      } //else
+        //aDoc = aFeature->document();
+      aMgr->rootDocument()->removeFeature(aFeature);
     }
-  } else {
-    changeCurrentDocument(FeaturePtr());
-    myObjectBrowser->activateCurrentPart(false);
+    aMgr->rootDocument()->finishOperation();
   }
 }
-
index 306e6d644b57d3e54cd3778312940e13b5ad445e..8ffb703b82a02815e36e2deeae0e7f1a46cecec6 100644 (file)
@@ -98,9 +98,15 @@ public:
   //! Returns icon name according to feature Id
   static QString featureIcon(const std::string& theId);
 
+  //! Activates or deactivates a part
+  //! If PartPtr is Null pointer then PartSet will be activated
+  void activatePart(FeaturePtr theFeature);
+
+  void deleteFeatures(QFeatureList theList);
 
 signals:
   void salomeViewerSelection();
+  void errorOccurred(const QString&);
 
 public slots:
   void updateCommandStatus();
@@ -121,8 +127,7 @@ public slots:
   void onFeatureTriggered();
   void changeCurrentDocument(FeaturePtr thePart);
 
-signals:
-  void errorOccurred(const QString&);
+  void activateLastPart();
 
 protected:
   //Event-loop processing methods:
@@ -153,10 +158,6 @@ private:
   // Creates Dock widgets: Object browser and Property panel
   void createDockWidgets();
 
-  //! Activates or deactivates currently selected part
-  void activatePart(bool toActivate);
-
-  QString myCurrentDir;
   XGUI_MainWindow* myMainWindow;
   XGUI_Module* myPartSetModule;
   XGUI_ObjectsBrowser* myObjectBrowser;
@@ -170,6 +171,7 @@ private:
   XGUI_ViewerProxy* myViewerProxy;
   XGUI_ContextMenuMgr* myContextMenuMgr;
 
+  QString myCurrentDir;
   static QMap<QString, QString> myIcons;
 
 };
index 30d9ba286de752a09b080113369f1d8334bb21a8..8ae03bf231bcb5beb4553a2de7d2d42247f50015 100644 (file)
@@ -54,5 +54,7 @@
      <file>pictures/edit.png</file>
      <file>pictures/assembly.png</file>
      <file>pictures/activate.png</file>
+     <file>pictures/delete.png</file>
+     <file>pictures/rename_edit.png</file>
  </qresource>
  </RCC>
diff --git a/src/XGUI/pictures/delete.png b/src/XGUI/pictures/delete.png
new file mode 100644 (file)
index 0000000..6c64527
Binary files /dev/null and b/src/XGUI/pictures/delete.png differ
diff --git a/src/XGUI/pictures/rename_edit.png b/src/XGUI/pictures/rename_edit.png
new file mode 100644 (file)
index 0000000..2ba69c3
Binary files /dev/null and b/src/XGUI/pictures/rename_edit.png differ