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)
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)
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
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;
}
#include <TDataStd_Name.hxx>
#include <climits>
+#ifndef WIN32
+#include <sys/stat.h>
+#endif
#ifdef WIN32
# define _separator_ '\\'
subDocument(*aSubIter)->close();
mySubs.clear();
// close this
- myDoc->Close();
+ if (myDoc->CanClose() == CDM_CCS_OK)
+ myDoc->Close();
Model_Application::getApplication()->deleteDocument(myID);
}
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);
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);
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
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++;
//! \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);
//! 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
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;
+}
+
#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;
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 {
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
#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();
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 + "'");
}
}
boost::shared_ptr<ModelAPI_Document> Model_PluginManager::currentDocument()
{
- if (!myCurrentDoc)
+ if (!myCurrentDoc || !Model_Application::getApplication()->hasDocument(myCurrentDoc->id()))
myCurrentDoc = rootDocument();
return myCurrentDoc;
}
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;
/// 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();
//! \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;
/// 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;}
/// 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();
)
# 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)
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);
}
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)
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)),
aPreview ? aPreview->impl<TopoDS_Shape>() : TopoDS_Shape(), false);
}
else
- aDisplayer->Erase(anOperation->feature(), false);
+ aDisplayer->Erase(theFeature, false);
if (isUpdateViewer)
aDisplayer->UpdateViewer();
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());
/// \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
#include <ModelAPI_Data.h>
#include <ModelAPI_Document.h>
+#include <Model_Events.h>
+
+#include <Events_Loop.h>
+
#include <SketchPlugin_Line.h>
#include <V3d_View.hxx>
moveLinePoint(aFeature, aDeltaX, aDeltaY, LINE_ATTR_END);
}
}
+ sendFeatures();
+
myCurPoint.setPoint(aPoint);
}
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)
{
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);
+}
+
\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
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
}
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;
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())
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());
}
/// 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
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> >();
}
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;
}
{
Q_OBJECT
public:
- enum FeatureActionMode { FM_Activation, FM_Deactivation, FM_Abort };
+ enum FeatureActionMode { FM_Activation, FM_Deactivation, FM_Hide };
public:
/// Constructor
/// 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
/// \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
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:
{
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;
}
{
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;
void PartSet_OperationSketchLine::abortOperation()
{
- emit featureConstructed(feature(), FM_Abort);
+ emit featureConstructed(feature(), FM_Hide);
PartSet_OperationSketchBase::abortOperation();
}
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
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})
--- /dev/null
+// 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);
+ }
+ }
+}
--- /dev/null
+// 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
#include "PartSetPlugin_Plugin.h"
#include "PartSetPlugin_Part.h"
+#include "PartSetPlugin_Duplicate.h"
+#include "PartSetPlugin_Remove.h"
#include <ModelAPI_PluginManager.h>
#include <ModelAPI_Document.h>
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>();
}
--- /dev/null
+// 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);
+ }
+ }
+ }
+}
--- /dev/null
+// 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
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
{
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)
SKETCHPLUGIN_EXPORT virtual const void addSub(
const boost::shared_ptr<ModelAPI_Feature>& theFeature) {}
+protected:
/// \brief Use plugin manager for features creation
SketchPlugin_Constraint() {}
};
/** \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
*/
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;
SET(PROJECT_LIBRARIES
${SLVS_LIBRARIES}
- SketchPlugin
Events
+ ModelAPI
+ Model
)
INCLUDE_DIRECTORIES(
ADD_DEFINITIONS(-DSKETCHSOLVER_EXPORTS ${BOOST_DEFINITIONS})
-ADD_LIBRARY(SketchSolver SHARED
+ADD_LIBRARY(SketchSolver MODULE
${PROJECT_SOURCES}
${PROJECT_HEADERS}
)
#include <SketchPlugin_Sketch.h>
#include <math.h>
+#include <assert.h>
/// Tolerance for value of parameters
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
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()
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))
}
}
}
+ 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;
// 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))
{
// 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);
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);
}
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++)
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;
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();
}
// ========================================================
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),
// Initialize workplane
myWorkplane.h = SLVS_E_UNKNOWN;
- addWorkplane(theWorkplane);
+ assert(addWorkplane(theWorkplane));
}
SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::~SketchSolver_ConstraintGroup()
}
bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::isBaseWorkplane(
- boost::shared_ptr<SketchPlugin_Sketch> theWorkplane) const
+ boost::shared_ptr<SketchPlugin_Feature> theWorkplane) const
{
return theWorkplane == mySketch;
}
// 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;
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])
);
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;
// 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)
{
}
// Point in 2D
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(theEntity);
if (aPoint2D)
{
}
/// \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};
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;
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()
Slvs_hParam SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeParameter(
- const double& theParam,
+ const double& theParam,
std::vector<Slvs_Param>::const_iterator& thePrmIter)
{
if (thePrmIter != myParams.end())
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)
{
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)
{
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)
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
}
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
// 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)
{
}
// Point in 2D
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
if (aPoint2D)
{
{
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;
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);
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);
/** \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.
/** \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
* \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:
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();
*/
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.
/** \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
* \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
* \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
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
// 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>
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)
} 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)
}
}
}
+ aActions.append(myWorkshop->objectBrowser()->actions());
if (aActions.size() > 0) {
QMenu* aMenu = new QMenu();
aMenu->addActions(aActions);
//! 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;
: 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
// 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
// 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());
// 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;
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();
+}
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);
#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>
{
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&)));
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));
+ }
+}
+
//********************************************************************
//********************************************************************
//********************************************************************
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);
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);
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 {
}
}
+//***************************************************
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
#include <QTreeView>
class XGUI_DocumentDataModel;
-class QLabel;
+class QLineEdit;
class XGUI_DataTree: public QTreeView
//! 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);
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
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;
#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)
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();
}
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();
}
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()));
}
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();
}
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
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;
+}
+
+
//******************************************************************
//******************************************************************
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();
}
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();
}
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()));
}
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;
case ConstructFolder:
return createIndex(theRow, 0, (qint32) ConstructObject);
case BodiesFolder:
- return createIndex(theRow, 0, (qint32) BodieswObject);
+ return createIndex(theRow, 0, (qint32) BodiesObject);
}
return QModelIndex();
}
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();
}
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();
}
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
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;
+}
//! 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;
//! 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;
ConstructFolder,
ConstructObject,
BodiesFolder,
- BodieswObject,
+ BodiesObject,
HistoryObject
};
#include <QPushButton>
#include <QDockWidget>
#include <QLayout>
+#include <QTimer>
#ifdef _DEBUG
#include <QDebug>
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();
}
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);
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()),
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()),
}
}
#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 {
//**************************************************************
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();
}
}
-
//! 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();
void onFeatureTriggered();
void changeCurrentDocument(FeaturePtr thePart);
-signals:
- void errorOccurred(const QString&);
+ void activateLastPart();
protected:
//Event-loop processing methods:
// 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;
XGUI_ViewerProxy* myViewerProxy;
XGUI_ContextMenuMgr* myContextMenuMgr;
+ QString myCurrentDir;
static QMap<QString, QString> myIcons;
};
<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>