boost::shared_ptr<Model_Document> aNew(new Model_Document(theDocID));
myDocs[theDocID] = aNew;
+ // load it if it must be loaded by demand
+ if (myLoadedByDemand.find(theDocID) != myLoadedByDemand.end() && !myPath.empty()) {
+ aNew->load(myPath.c_str());
+ myLoadedByDemand.erase(theDocID); // done, don't do it anymore
+ }
+
return myDocs[theDocID];
}
return myDocs.find(theDocID) != myDocs.end();
}
+//=======================================================================
+void Model_Application::setLoadPath(std::string thePath)
+{
+ myPath = thePath;
+}
+
+//=======================================================================
+void Model_Application::setLoadByDemand(std::string theID)
+{
+ myLoadedByDemand.insert(theID);
+}
+
//=======================================================================
Model_Application::Model_Application()
{
//! Deletes the document from the application
MODEL_EXPORT void deleteDocument(std::string theDocID);
+ //! Set path for the loaded by demand documents
+ void setLoadPath(std::string thePath);
+ //! Defines that specified document must be loaded by demand
+ void setLoadByDemand(std::string theID);
+
public:
// Redefined OCAF methods
//! Return name of resource (i.e. "Standard")
private:
/// Map from string identifiers to created documents of an application
std::map<std::string, boost::shared_ptr<Model_Document> > myDocs;
+ /// Path for the loaded by demand documents
+ std::string myPath;
+ /// Path for the loaded by demand documents
+ std::set<std::string> myLoadedByDemand;
};
#endif
if (!theLabel.FindAttribute(TDataStd_Comment::GetID(), myComment)) {
// create attribute: not initialized by value yet, just empty string
myComment = TDataStd_Comment::Set(theLabel, "");
+ } else { // document was already referenced: try to set it as loaded by demand
+ Handle(Model_Application) anApp = Model_Application::getApplication();
+ string anID(TCollection_AsciiString(myComment->Get()).ToCString());
+ if (!anApp->hasDocument(anID)) {
+ anApp->setLoadByDemand(anID);
+ }
}
}
static string anEmpty;
return anEmpty;
}
+
+bool Model_Data::isEqual(const boost::shared_ptr<ModelAPI_Data> theData)
+{
+ boost::shared_ptr<Model_Data> aData = boost::dynamic_pointer_cast<Model_Data>(theData);
+ if (aData)
+ return myLab.IsEqual(aData->myLab) == Standard_True;
+ return false;
+}
+
+bool Model_Data::isValid()
+{
+ return !myLab.IsNull() && myLab.HasAttribute();
+}
/// Identifier by the id (not fast, iteration by map)
/// \param theAttr attribute already created in this data
MODEL_EXPORT virtual const std::string& id(const boost::shared_ptr<ModelAPI_Attribute> theAttr);
+ /// Returns true if data belongs to same features
+ MODEL_EXPORT virtual bool isEqual(const boost::shared_ptr<ModelAPI_Data> theData);
+ /// Returns true if it is correctly connected t othe data model
+ MODEL_EXPORT virtual bool isValid();
/// Initializes object by the attributes: must be called just after the object is created
/// for each attribute of the object
#include <Model_PluginManager.h>
#include <Model_Events.h>
#include <Events_Loop.h>
+#include <Events_Error.h>
#include <TDataStd_Integer.hxx>
#include <TDataStd_Comment.hxx>
#include <climits>
+#ifdef WIN32
+# define _separator_ '\\'
+#else
+# define _separator_ '/'
+#endif
+
static const int UNDO_LIMIT = 10; // number of possible undo operations
static const int TAG_GENERAL = 1; // general properties tag
using namespace std;
+/// Returns the file name of this document by the nameof directory and identifuer of a document
+static TCollection_ExtendedString DocFileName(const char* theFileName, const string& theID)
+{
+ TCollection_ExtendedString aPath ((const Standard_CString)theFileName);
+ aPath += _separator_;
+ aPath += theID.c_str();
+ aPath += ".cbf"; // standard binary file extension
+ return aPath;
+}
+
bool Model_Document::load(const char* theFileName)
{
- bool myIsError = Standard_False;
- /*
- TCollection_ExtendedString aPath ((const Standard_CString)theFileName);
- PCDM_ReaderStatus aStatus = (PCDM_ReaderStatus) -1;
- try
- {
- Handle(TDocStd_Document) aDoc = this;
- aStatus = Model_Application::GetApplication()->Open(aPath, aDoc);
- }
- catch (Standard_Failure)
- {}
- myIsError = aStatus != PCDM_RS_OK;
- if (myIsError)
- {
- switch (aStatus)
- {
- case PCDM_RS_UnknownDocument: cout<<"OCAFApp_Appl_RUnknownDocument"<<endl; break;
- case PCDM_RS_AlreadyRetrieved: cout<<"OCAFApp_Appl_RAlreadyRetrieved"<<endl; break;
- case PCDM_RS_AlreadyRetrievedAndModified: cout<<"OCAFApp_Appl_RAlreadyRetrievedAndModified"<<endl; break;
- case PCDM_RS_NoDriver: cout<<"OCAFApp_Appl_RNoDriver"<<endl; break;
- case PCDM_RS_UnknownFileDriver: cout<<"OCAFApp_Appl_RNoDriver"<<endl; break;
- case PCDM_RS_OpenError: cout<<"OCAFApp_Appl_ROpenError"<<endl; break;
- case PCDM_RS_NoVersion: cout<<"OCAFApp_Appl_RNoVersion"<<endl; break;
- case PCDM_RS_NoModel: cout<<"OCAFApp_Appl_RNoModel"<<endl; break;
- case PCDM_RS_NoDocument: cout<<"OCAFApp_Appl_RNoDocument"<<endl; break;
- case PCDM_RS_FormatFailure: cout<<"OCAFApp_Appl_RFormatFailure"<<endl; break;
- case PCDM_RS_TypeNotFoundInSchema: cout<<"OCAFApp_Appl_RTypeNotFound"<<endl; break;
- case PCDM_RS_UnrecognizedFileFormat: cout<<"OCAFApp_Appl_RBadFileFormat"<<endl; break;
- case PCDM_RS_MakeFailure: cout<<"OCAFApp_Appl_RMakeFailure"<<endl; break;
- case PCDM_RS_PermissionDenied: cout<<"OCAFApp_Appl_RPermissionDenied"<<endl; break;
- case PCDM_RS_DriverFailure: cout<<"OCAFApp_Appl_RDriverFailure"<<endl; break;
- default: cout<<"OCAFApp_Appl_RUnknownFail"<<endl; break;
- }
- }
- SetUndoLimit(UNDO_LIMIT);
- */
- return !myIsError;
+ Handle(Model_Application) anApp = Model_Application::getApplication();
+ if (this == Model_PluginManager::get()->rootDocument().get()) {
+ anApp->setLoadPath(theFileName);
+ }
+ TCollection_ExtendedString aPath (DocFileName(theFileName, myID));
+ PCDM_ReaderStatus aStatus = (PCDM_ReaderStatus) -1;
+ try
+ {
+ aStatus = anApp->Open(aPath, myDoc);
+ }
+ catch (Standard_Failure)
+ {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ Events_Error::send(string("Exception in opening of document: ") + aFail->GetMessageString());
+ return false;
+ }
+ bool isError = aStatus != PCDM_RS_OK;
+ if (isError)
+ {
+ switch (aStatus)
+ {
+ case PCDM_RS_UnknownDocument:
+ Events_Error::send(string("Can not open document: PCDM_RS_UnknownDocument")); break;
+ case PCDM_RS_AlreadyRetrieved:
+ Events_Error::send(string("Can not open document: PCDM_RS_AlreadyRetrieved")); break;
+ case PCDM_RS_AlreadyRetrievedAndModified:
+ Events_Error::send(string("Can not open document: PCDM_RS_AlreadyRetrievedAndModified")); break;
+ case PCDM_RS_NoDriver:
+ Events_Error::send(string("Can not open document: PCDM_RS_NoDriver")); break;
+ case PCDM_RS_UnknownFileDriver:
+ Events_Error::send(string("Can not open document: PCDM_RS_UnknownFileDriver")); break;
+ case PCDM_RS_OpenError:
+ Events_Error::send(string("Can not open document: PCDM_RS_OpenError")); break;
+ case PCDM_RS_NoVersion:
+ Events_Error::send(string("Can not open document: PCDM_RS_NoVersion")); break;
+ case PCDM_RS_NoModel:
+ Events_Error::send(string("Can not open document: PCDM_RS_NoModel")); break;
+ case PCDM_RS_NoDocument:
+ Events_Error::send(string("Can not open document: PCDM_RS_NoDocument")); break;
+ case PCDM_RS_FormatFailure:
+ Events_Error::send(string("Can not open document: PCDM_RS_FormatFailure")); break;
+ case PCDM_RS_TypeNotFoundInSchema:
+ Events_Error::send(string("Can not open document: PCDM_RS_TypeNotFoundInSchema")); break;
+ case PCDM_RS_UnrecognizedFileFormat:
+ Events_Error::send(string("Can not open document: PCDM_RS_UnrecognizedFileFormat")); break;
+ case PCDM_RS_MakeFailure:
+ Events_Error::send(string("Can not open document: PCDM_RS_MakeFailure")); break;
+ case PCDM_RS_PermissionDenied:
+ Events_Error::send(string("Can not open document: PCDM_RS_PermissionDenied")); break;
+ case PCDM_RS_DriverFailure:
+ Events_Error::send(string("Can not open document: PCDM_RS_DriverFailure")); break;
+ default:
+ Events_Error::send(string("Can not open document: unknown error")); break;
+ }
+ }
+ if (!isError) {
+ myDoc->SetUndoLimit(UNDO_LIMIT);
+ synchronizeFeatures();
+ }
+ return !isError;
}
bool Model_Document::save(const char* theFileName)
{
- bool myIsError = true;
- /*
- TCollection_ExtendedString aPath ((const Standard_CString)theFileName);
- PCDM_StoreStatus aStatus;
- try {
- Handle(TDocStd_Document) aDoc = this;
- aStatus = Model_Application::GetApplication()->SaveAs (aDoc, aPath);
- }
- catch (Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
- cout<<"OCAFApp_Engine:save Error: "<<aFail->GetMessageString()<<endl;
- return false;
- }
- myIsError = aStatus != PCDM_SS_OK;
- if (myIsError)
- {
- switch (aStatus)
- {
- case PCDM_SS_DriverFailure:
- cout<<"OCAFApp_Appl_SDriverFailure"<<endl;
- break;
- case PCDM_SS_WriteFailure:
- cout<<"OCAFApp_Appl_SWriteFailure"<<endl;
- break;
- case PCDM_SS_Failure:
- default:
- cout<<"OCAFApp_Appl_SUnknownFailure"<<endl;
- break;
- }
- }
- myTransactionsAfterSave = 0;
- Standard::Purge(); // Release free memory
- */
- return !myIsError;
+ // create a directory in the root document if it is not yet exist
+ if (this == Model_PluginManager::get()->rootDocument().get()) {
+#ifdef WIN32
+ CreateDirectory(theFileName, NULL);
+#else
+ mkdir(theFileName, 0x1ff);
+#endif
+ }
+ // filename in the dir is id of document inside of the given directory
+ TCollection_ExtendedString aPath(DocFileName(theFileName, myID));
+ PCDM_StoreStatus aStatus;
+ try {
+ aStatus = Model_Application::getApplication()->SaveAs(myDoc, aPath);
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ Events_Error::send(string("Exception in saving of document: ") + aFail->GetMessageString());
+ return false;
+ }
+ bool isDone = aStatus == PCDM_SS_OK || aStatus == PCDM_SS_No_Obj;
+ if (!isDone)
+ {
+ switch (aStatus)
+ {
+ case PCDM_SS_DriverFailure:
+ Events_Error::send(string("Can not save document: PCDM_SS_DriverFailure"));
+ break;
+ case PCDM_SS_WriteFailure:
+ Events_Error::send(string("Can not save document: PCDM_SS_WriteFailure"));
+ break;
+ case PCDM_SS_Failure:
+ default:
+ Events_Error::send(string("Can not save document: PCDM_SS_Failure"));
+ break;
+ }
+ }
+ myTransactionsAfterSave = 0;
+ if (isDone) { // save also sub-documents if any
+ set<string>::iterator aSubIter = mySubs.begin();
+ for(; aSubIter != mySubs.end() && isDone; aSubIter++)
+ isDone = subDocument(*aSubIter)->save(theFileName);
+ }
+ return isDone;
}
void Model_Document::close()
void Model_Document::startOperation()
{
+ // check is it nested or not
+ if (myDoc->HasOpenCommand()) {
+ myNestedStart = myTransactionsAfterSave;
+ }
// new command for this
myDoc->NewCommand();
// new command for all subs
void Model_Document::finishOperation()
{
+ if (myNestedStart > myTransactionsAfterSave) // this nested transaction is owervritten
+ myNestedStart = 0;
// returns false if delta is empty and no transaction was made
myIsEmptyTr[myTransactionsAfterSave] = !myDoc->CommitCommand();
myTransactionsAfterSave++;
bool Model_Document::canUndo()
{
- if (myDoc->GetAvailableUndos() > 0)
+ if (myDoc->GetAvailableUndos() > 0 && myNestedStart != myTransactionsAfterSave)
return true;
// check other subs contains operation that can be undoed
set<string>::iterator aSubIter = mySubs.begin();
aData->setLabel(anObjLab);
boost::shared_ptr<ModelAPI_Document> aThis =
Model_Application::getApplication()->getDocument(myID);
- theFeature->setData(aData);
theFeature->setDoc(aThis);
+ theFeature->setData(aData);
setUniqueName(theFeature);
theFeature->initAttributes();
// keep the feature ID to restore document later correctly
{
myDoc->SetUndoLimit(UNDO_LIMIT);
myTransactionsAfterSave = 0;
+ myNestedStart = 0;
+ myDoc->SetNestedTransactionMode();
+ // to have something in the document and avoid empty doc open/save problem
+ TDataStd_Integer::Set(myDoc->Main().Father(), 0);
}
TDF_Label Model_Document::groupLabel(const string theGroup)
TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(
aFLabIter.Value())->Get()).ToCString());
+ if (aFIter == aFeatures.end()) { // must be before "setData" to redo the sketch line correctly
+ aFeatures.push_back(aFeature);
+ aFIter = aFeatures.end();
+ } else {
+ aFIter++;
+ aFeatures.insert(aFIter, aFeature);
+ }
boost::shared_ptr<Model_Data> aData(new Model_Data);
TDF_Label aLab = aFLabIter.Value()->Label();
aData->setLabel(aLab);
aFeature->setDoc(aThis);
aFeature->setData(aData);
aFeature->initAttributes();
+
// event: model is updated
static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_CREATED);
Model_FeatureUpdatedMessage aMsg(aFeature, anEvent);
Events_Loop::loop()->send(aMsg);
- if (aFIter == aFeatures.end()) {
- aFeatures.push_back(aFeature);
- aFIter = aFeatures.end();
- } else {
- aFIter++;
- aFeatures.insert(aFIter, aFeature);
- }
// feature for this label is added, so go to the next label
aFLabIter.Next();
} else { // nothing is changed, both iterators are incremented
Handle_TDocStd_Document myDoc; ///< OCAF document
/// number of transactions after the last "save" call, used for "IsModified" method
int myTransactionsAfterSave;
+ /// number of myTransactionsAfterSave for the nested transaction start
+ int myNestedStart;
/// root labels of the features groups identified by names
std::map<std::string, TDF_Label> myGroups;
std::vector<std::string> myGroupsNames; ///< names of added groups to the document
/// Identifier by the id (not fast, iteration by map)
/// \param theAttr attribute already created in this data
virtual const std::string& id(const boost::shared_ptr<ModelAPI_Attribute> theAttr) = 0;
+ /// Returns true if data belongs to same features
+ virtual bool isEqual(const boost::shared_ptr<ModelAPI_Data> theData) = 0;
+ /// Returns true if it is correctly connected t othe data model
+ virtual bool isValid() = 0;
/// Initializes object by the attributes: must be called just after the object is created
/// for each attribute of the object
{}
/// Sets the data manager of an object (document does)
- MODELAPI_EXPORT void setData(boost::shared_ptr<ModelAPI_Data> theData) {myData = theData;}
+ MODELAPI_EXPORT virtual void setData(boost::shared_ptr<ModelAPI_Data> theData)
+ {myData = theData;}
/// Sets the data manager of an object (document does)
MODELAPI_EXPORT void setDoc(boost::shared_ptr<ModelAPI_Document> theDoc) {myDoc = theDoc;}
: myModule(theModule)
{
Events_Loop* aLoop = Events_Loop::loop();
- Events_ID aFeatureUpdatedId = aLoop->eventByName(EVENT_FEATURE_UPDATED);
- aLoop->registerListener(this, aFeatureUpdatedId);
+ aLoop->registerListener(this, aLoop->eventByName(EVENT_FEATURE_UPDATED));
+ aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED));
+ aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_DELETED));
}
PartSet_Listener::~PartSet_Listener()
//******************************************************
void PartSet_Listener::processEvent(const Events_Message* theMessage)
{
- if (QString(theMessage->eventID().eventText()) == EVENT_FEATURE_UPDATED)
+ QString aType = QString(theMessage->eventID().eventText());
+ if (aType == EVENT_FEATURE_UPDATED ||
+ aType == EVENT_FEATURE_CREATED)
{
const Model_FeatureUpdatedMessage* aUpdMsg = dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
boost::shared_ptr<ModelAPI_Feature> aFeature = aUpdMsg->feature();
- if (myModule->workshop()->displayer()->IsVisible(aFeature))
+ if (myModule->workshop()->displayer()->IsVisible(aFeature) ||
+ aType == EVENT_FEATURE_CREATED)
myModule->visualizePreview(aFeature, true);
}
+ if (aType == EVENT_FEATURE_DELETED)
+ {
+ const Model_FeatureDeletedMessage* aDelMsg = dynamic_cast<const Model_FeatureDeletedMessage*>(theMessage);
+ boost::shared_ptr<ModelAPI_Document> aDoc = aDelMsg->document();
+
+ std::string aGroup = aDelMsg->group();
+ if (aDelMsg->group().compare("Sketch") == 0) { // Update only Sketch group
+ myModule->updateCurrentPreview(aGroup);
+ }
+ }
}
aDisplayer->Erase(anOperation->feature());
}
}
+
+void PartSet_Module::updateCurrentPreview(const std::string& theCmdId)
+{
+ ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
+ if (!anOperation)
+ return;
+
+ PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
+ if (!aPreviewOp)
+ return;
+
+ boost::shared_ptr<ModelAPI_Feature> aFeature = aPreviewOp->feature();
+ if (!aFeature || aFeature->getKind() != theCmdId)
+ return;
+
+ std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
+ aList = aPreviewOp->preview();
+ XGUI_Displayer* aDisplayer = myWorkshop->displayer();
+ std::list<int> aModes = aPreviewOp->getSelectionModes(aPreviewOp->feature());
+
+ std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >::const_iterator
+ anIt = aList.begin(), aLast = aList.end();
+ aDisplayer->EraseAll(false);
+ for (; anIt != aLast; anIt++) {
+ boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).first;
+ boost::shared_ptr<GeomAPI_Shape> aPreview = (*anIt).second;
+ aDisplayer->RedisplayInLocalContext(aFeature,
+ aPreview ? aPreview->impl<TopoDS_Shape>() : TopoDS_Shape(),
+ aModes, false);
+ }
+ aDisplayer->UpdateViewer();
+}
+
/// \param isDisplay the state whether the presentation should be displayed or erased
void visualizePreview(boost::shared_ptr<ModelAPI_Feature> theFeature, bool isDisplay);
+ /// Updates current operation preview, if it has it.
+ /// \param theCmdId the operation name
+ void updateCurrentPreview(const std::string& theCmdId);
+
public slots:
void onFeatureTriggered();
/// SLOT, that is called after the operation is stopped. Switched off the modfications performed
#include <ModelAPI_Data.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeRefList.h>
+
#include <GeomAlgoAPI_FaceBuilder.h>
#include <GeomDataAPI_Point.h>
#include <GeomDataAPI_Dir.h>
emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
}
+std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
+ PartSet_OperationSketch::preview() const
+{
+ std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> > aPreviewMap;
+
+ boost::shared_ptr<SketchPlugin_Feature> aFeature;
+
+ boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
+ boost::shared_ptr<ModelAPI_AttributeRefList> aRefList =
+ boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(aData->attribute(SKETCH_ATTR_FEATURES));
+
+ std::list<boost::shared_ptr<ModelAPI_Feature> > aFeatures = aRefList->list();
+ std::list<boost::shared_ptr<ModelAPI_Feature> >::const_iterator anIt = aFeatures.begin(),
+ aLast = aFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ aFeature = boost::dynamic_pointer_cast<SketchPlugin_Feature>(*anIt);
+ boost::shared_ptr<GeomAPI_Shape> aPreview = aFeature->preview();
+ if (aPreview)
+ aPreviewMap[aFeature] = aPreview;
+ }
+ return aPreviewMap;
+}
+
void PartSet_OperationSketch::setSketchPlane(const TopoDS_Shape& theShape)
{
if (theShape.IsNull())
virtual void mouseMoved(QMouseEvent* theEvent, Handle_V3d_View theView,
const std::list<XGUI_ViewerPrs>& theSelected);
+ /// 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;
signals:
/// signal about the sketch plane is selected
/// \param theX the value in the X direction of the plane
return aFeature->preview();
}
+std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
+ PartSet_OperationSketchBase::preview() 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();
#include <ModuleBase_Operation.h>
#include <QObject>
+#include <map>
+
class Handle_V3d_View;
class QMouseEvent;
class GeomAPI_Shape;
/// \param theFeature the feature object to obtain the preview
boost::shared_ptr<GeomAPI_Shape> preview(boost::shared_ptr<ModelAPI_Feature> theFeature) const;
+ /// 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;
+
/// Returns the operation local selection mode
/// \param theFeature the feature object to get the selection mode
/// \return the selection mode
PARTSETPLUGIN_EXPORT virtual boost::shared_ptr<ModelAPI_Document> documentToAdd();
+ /// Returns true if this feature must be displayed in the history (top level of Part tree)
+ PARTSETPLUGIN_EXPORT virtual bool isInHistory() {return false;}
+
/// Use plugin manager for features creation
PartSetPlugin_Part();
};
#include "SketchPlugin_Feature.h"
+#include "SketchPlugin_Sketch.h"
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_AttributeRefList.h>
+
+SketchPlugin_Feature::SketchPlugin_Feature()
+{
+ mySketch = 0;
+}
+
+void SketchPlugin_Feature::setData(boost::shared_ptr<ModelAPI_Data> theData)
+{
+ ModelAPI_Feature::setData(theData);
+
+ // find sketch that references to this feature
+ int aSketches = document()->size("Construction");
+ for(int a = 0; a < aSketches && !mySketch; a++) {
+ boost::shared_ptr<SketchPlugin_Sketch> aSketch =
+ boost::dynamic_pointer_cast<SketchPlugin_Sketch>(document()->feature("Construction", a));
+ std::list<boost::shared_ptr<ModelAPI_Feature> > aList =
+ aSketch->data()->reflist(SKETCH_ATTR_FEATURES)->list();
+ std::list<boost::shared_ptr<ModelAPI_Feature> >::iterator aSub = aList.begin();
+ for(; aSub != aList.end(); aSub++) {
+ if ((*aSub)->data()->isEqual(theData)) {
+ mySketch = aSketch.get();
+ break;
+ }
+ }
+ }
+}
void SketchPlugin_Feature::setPreview(const boost::shared_ptr<GeomAPI_Shape>& theShape)
{
void setSketch(SketchPlugin_Sketch* theSketch) {mySketch = theSketch;}
/// Returns the sketch of this feature
SketchPlugin_Sketch* sketch() {return mySketch;}
+ /// initializes mySketch
+ SketchPlugin_Feature();
+ /// Sets the data manager of an object and here initializes mySketch field
+ SKETCHPLUGIN_EXPORT virtual void setData(boost::shared_ptr<ModelAPI_Data> theData);
friend class SketchPlugin_Sketch;
const double PLANE_SIZE = 200;
SketchPlugin_Line::SketchPlugin_Line()
+ : SketchPlugin_Feature()
{
+ setSketch(0);
}
void SketchPlugin_Line::initAttributes()
const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_Line::preview()
{
SketchPlugin_Sketch* aSketch = sketch();
- // compute a start point in 3D view
- boost::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
- boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(LINE_ATTR_START));
- boost::shared_ptr<GeomAPI_Pnt> aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
- // compute an end point in 3D view
- boost::shared_ptr<GeomDataAPI_Point2D> anEndAttr =
- boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(LINE_ATTR_END));
- boost::shared_ptr<GeomAPI_Pnt> anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
- // make linear edge
- boost::shared_ptr<GeomAPI_Shape> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
- setPreview(anEdge);
-
+ if (aSketch) {
+ // compute a start point in 3D view
+ boost::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(LINE_ATTR_START));
+ boost::shared_ptr<GeomAPI_Pnt> aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
+ // compute an end point in 3D view
+ boost::shared_ptr<GeomDataAPI_Point2D> anEndAttr =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(LINE_ATTR_END));
+ boost::shared_ptr<GeomAPI_Pnt> anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
+ // make linear edge
+ boost::shared_ptr<GeomAPI_Shape> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
+ setPreview(anEdge);
+ }
return getPreview();
}
XGUI_ViewerProxy.h
XGUI_ViewerPrs.h
XGUI_PropertyPanel.h
+ XGUI_ContextMenuMgr.h
)
SET(PROJECT_AUTOMOC
XGUI_ViewerProxy.cpp
XGUI_ViewerPrs.cpp
XGUI_PropertyPanel.cpp
+ XGUI_ContextMenuMgr.cpp
)
SET(PROJECT_RESOURCES
--- /dev/null
+
+#include "XGUI_ContextMenuMgr.h"
+#include "XGUI_Workshop.h"
+#include "XGUI_ObjectsBrowser.h"
+#include "XGUI_SelectionMgr.h"
+
+#include <QAction>
+#include <QContextMenuEvent>
+#include <QMenu>
+
+XGUI_ContextMenuMgr::XGUI_ContextMenuMgr(XGUI_Workshop* theParent) :
+QObject(theParent), myWorkshop(theParent)
+{
+
+}
+
+XGUI_ContextMenuMgr::~XGUI_ContextMenuMgr()
+{
+}
+
+void XGUI_ContextMenuMgr::createActions()
+{
+ QAction* aAction = new QAction(QIcon(":pictures/edit.png"), tr("Edit..."), this);
+ addAction("EDIT_CMD", aAction);
+}
+
+void XGUI_ContextMenuMgr::addAction(const QString& theId, QAction* theAction)
+{
+ if (myActions.contains(theId))
+ qCritical("A command with Id = '%s' already defined!", qPrintable(theId));
+ theAction->setData(theId);
+ connect(theAction, SIGNAL(triggered(bool)), this, SLOT(onAction(bool)));
+ myActions[theId] = theAction;
+}
+
+QAction* XGUI_ContextMenuMgr::action(const QString& theId) const
+{
+ if (myActions.contains(theId))
+ return myActions[theId];
+ return 0;
+}
+
+QStringList XGUI_ContextMenuMgr::actionIds() const
+{
+ return myActions.keys();
+}
+
+void XGUI_ContextMenuMgr::onAction(bool isChecked)
+{
+ QAction* aAction = static_cast<QAction*>(sender());
+ emit actionTriggered(aAction->data().toString(), isChecked);
+}
+
+void XGUI_ContextMenuMgr::updateCommandsStatus()
+{
+}
+
+void XGUI_ContextMenuMgr::onContextMenuRequest(QContextMenuEvent* theEvent)
+{
+ QMenu* aMenu = 0;
+ if (sender() == myWorkshop->objectBrowser())
+ aMenu = objectBrowserMenu();
+
+ if (aMenu) {
+ aMenu->exec(theEvent->globalPos());
+ delete aMenu;
+ }
+}
+
+QMenu* XGUI_ContextMenuMgr::objectBrowserMenu() const
+{
+ XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
+ QFeatureList aFeatures = aSelMgr->selectedFeatures();
+ if (aFeatures.size() == 1) {
+ FeaturePtr aFeature = aFeatures.first();
+ if (aFeature->getKind() != "Part") {
+ QMenu* aMenu = new QMenu();
+ aMenu->addAction(action("EDIT_CMD"));
+ return aMenu;
+ }
+ }
+ return 0;
+}
+
+void XGUI_ContextMenuMgr::connectObjectBrowser() const
+{
+ connect(myWorkshop->objectBrowser(), SIGNAL(contextMenuRequested(QContextMenuEvent*)),
+ this, SLOT(onContextMenuRequest(QContextMenuEvent*)));
+}
\ No newline at end of file
--- /dev/null
+
+#ifndef XGUI_ContextMenuMgr_H
+#define XGUI_ContextMenuMgr_H
+
+#include "XGUI.h"
+
+#include <QObject>
+#include <QMap>
+
+class XGUI_Workshop;
+class QAction;
+class QContextMenuEvent;
+class QMenu;
+
+class XGUI_EXPORT XGUI_ContextMenuMgr: public QObject
+{
+Q_OBJECT
+public:
+ XGUI_ContextMenuMgr(XGUI_Workshop* theParent);
+ virtual ~XGUI_ContextMenuMgr();
+
+ void createActions();
+
+ void addAction(const QString& theId, QAction* theAction);
+
+ QAction* action(const QString& theId) const;
+
+ QStringList actionIds() const;
+
+ void updateCommandsStatus();
+
+ void connectObjectBrowser() const;
+
+signals:
+ void actionTriggered(const QString& theId, bool isChecked);
+
+private slots:
+ void onAction(bool isChecked);
+
+ void onContextMenuRequest(QContextMenuEvent* theEvent);
+
+private:
+ QMenu* objectBrowserMenu() const;
+
+ QMap<QString, QAction*> myActions;
+
+ XGUI_Workshop* myWorkshop;
+};
+
+#endif
\ No newline at end of file
#include <ModelAPI_Document.h>
#include <QAbstractItemModel>
+#include <QColor>
/**\class XGUI_FeaturesModel
* \ingroup GUI
{
public:
XGUI_FeaturesModel(const boost::shared_ptr<ModelAPI_Document>& theDocument, QObject* theParent):
- QAbstractItemModel(theParent), myDocument(theDocument) {}
+ QAbstractItemModel(theParent), myDocument(theDocument), myItemsColor(Qt::black) {}
//! Returns Feature object by the given Model index.
//! Returns 0 if the given index is not index of a feature
//! Returns index corresponded to the group
virtual QModelIndex findGroup(const std::string& theGroup) const = 0;
+ void setItemsColor(const QColor& theColor) { myItemsColor = theColor; }
+
+ QColor itemsColor() const { return myItemsColor; }
+
protected:
boost::shared_ptr<ModelAPI_Document> myDocument;
+ QColor myItemsColor;
};
//! Returns true if the given document is a sub-document of this tree
virtual bool hasDocument(const boost::shared_ptr<ModelAPI_Document>& theDoc) const = 0;
+ //! Return a Part object
+ virtual FeaturePtr part() const = 0;
+
protected:
//! Id of the current part object in the document
int myId;
aContext->UpdateCurrentViewer();
}
+void XGUI_Displayer::EraseAll(const bool isUpdateViewer)
+{
+ Handle(AIS_InteractiveContext) ic = AISContext();
+
+ AIS_ListOfInteractive aList;
+ ic->DisplayedObjects(aList);
+ AIS_ListIteratorOfListOfInteractive anIter(aList);
+ for (; anIter.More(); anIter.Next()) {
+ if ((anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron)))
+ continue;
+
+ // erase an object
+ Handle(AIS_InteractiveObject) anIO = anIter.Value();
+ ic->Erase(anIO, false);
+ }
+ myFeature2AISObjectMap.clear();
+ if (isUpdateViewer)
+ ic->UpdateCurrentViewer();
+}
+
void XGUI_Displayer::CloseLocalContexts(const bool isUpdateViewer)
{
closeAllContexts(true);
}
}
+void XGUI_Displayer::UpdateViewer()
+{
+ Handle(AIS_InteractiveContext) ic = AISContext();
+ if (!ic.IsNull())
+ ic->UpdateCurrentViewer();
+}
+
Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
{
return myWorkshop->viewer()->AISContext();
/// \param isUpdateViewer the parameter whether the viewer should be update immediatelly
void Erase(boost::shared_ptr<ModelAPI_Feature> theFeature, const bool isUpdateViewer = true);
+ /// Erase all presentations
+ /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly
+ void EraseAll(const bool isUpdateViewer = true);
+
/// Deactivates selection of sub-shapes
/// \param isUpdateViewer the parameter whether the viewer should be update immediatelly
void CloseLocalContexts(const bool isUpdateViewer = true);
+ /// Updates the viewer
+ void UpdateViewer();
+
protected:
/// Deactivate local selection
/// \param isUpdateViewer the state wether the viewer should be updated immediatelly
#include <QIcon>
#include <QString>
+#include <QBrush>
+#define ACTIVE_COLOR QColor(0,72,140)
+#define PASSIVE_COLOR Qt::black
+
XGUI_DocumentDataModel::XGUI_DocumentDataModel(QObject* theParent)
- : QAbstractItemModel(theParent)
+ : QAbstractItemModel(theParent), myActivePart(0)
{
// Find Document object
boost::shared_ptr<ModelAPI_PluginManager> aMgr = ModelAPI_PluginManager::get();
// Create a top part of data tree model
myModel = new XGUI_TopDataModel(myDocument, this);
+ myModel->setItemsColor(ACTIVE_COLOR);
}
return QIcon(":pictures/constr_folder.png");
case Qt::ToolTipRole:
return tr("Parts folder");
+ case Qt::ForegroundRole:
+ if (myActivePart)
+ return QBrush(PASSIVE_COLOR);
+ else
+ return QBrush(ACTIVE_COLOR);
default:
return QVariant();
}
return QIcon(XGUI_Workshop::featureIcon(aFeature->getKind()));
case Qt::ToolTipRole:
return tr("Feature object");
+ case Qt::ForegroundRole:
+ if (myActivePart)
+ return QBrush(PASSIVE_COLOR);
+ else
+ return QBrush(ACTIVE_COLOR);
default:
return QVariant();
}
if (aParent.isValid() && (aParent.internalId() == PartsFolder)) {
return myPartModels.at(theIndex.row())->data(QModelIndex(), theRole);
}
- return toSourceModelIndex(theIndex).data(theRole);
+ return toSourceModelIndex(theIndex)->data(theRole);
}
if (theParent.internalId() == HistoryNode) {
return 0;
}
- QModelIndex aParent = toSourceModelIndex(theParent);
- if (!isSubModel(aParent.model()))
+ QModelIndex* aParent = toSourceModelIndex(theParent);
+ const QAbstractItemModel* aModel = aParent->model();
+ if (!isSubModel(aModel))
return 0;
- return aParent.model()->rowCount(aParent);
+ /*if (isPartSubModel(aModel)) {
+ if (aModel != myActivePart)
+ return 0;
+ }*/
+ return aModel->rowCount(*aParent);
}
int XGUI_DocumentDataModel::columnCount(const QModelIndex& theParent) const
if ((theIndex.internalId() == PartsFolder) || (theIndex.internalId() == HistoryNode))
return QModelIndex();
- QModelIndex aIndex = toSourceModelIndex(theIndex);
- const QAbstractItemModel* aModel = aIndex.model();
+ QModelIndex* aIndex = toSourceModelIndex(theIndex);
+ const QAbstractItemModel* aModel = aIndex->model();
if (!isSubModel(aModel))
return QModelIndex();
if (isPartSubModel(aModel)) {
- if (!aModel->parent(aIndex).isValid()) {
+ if (!aModel->parent(*aIndex).isValid()) {
return partFolderNode();
}
}
- aIndex = aModel->parent(aIndex);
- if (aIndex.isValid())
- return createIndex(aIndex.row(), aIndex.column(), (void*)getModelIndex(aIndex));
- return aIndex;
+ QModelIndex aIndex1 = aModel->parent(*aIndex);
+ if (aIndex1.isValid())
+ return createIndex(aIndex1.row(), aIndex1.column(), (void*)getModelIndex(aIndex1));
+ return aIndex1;
}
}
-QModelIndex XGUI_DocumentDataModel::toSourceModelIndex(const QModelIndex& theProxy) const
+QModelIndex* XGUI_DocumentDataModel::toSourceModelIndex(const QModelIndex& theProxy) const
{
QModelIndex* aIndexPtr = static_cast<QModelIndex*>(theProxy.internalPointer());
- return (*aIndexPtr);
+ return aIndexPtr;
}
int aOffset = historyOffset();
return myDocument->feature(FEATURES_GROUP, theIndex.row() - aOffset);
}
- QModelIndex aIndex = toSourceModelIndex(theIndex);
- if (!isSubModel(aIndex.model()))
+ QModelIndex* aIndex = toSourceModelIndex(theIndex);
+ if (!isSubModel(aIndex->model()))
return FeaturePtr();
- const XGUI_FeaturesModel* aModel = dynamic_cast<const XGUI_FeaturesModel*>(aIndex.model());
- return aModel->feature(aIndex);
+ const XGUI_FeaturesModel* aModel = dynamic_cast<const XGUI_FeaturesModel*>(aIndex->model());
+ return aModel->feature(*aIndex);
}
bool XGUI_DocumentDataModel::insertRows(int theRow, int theCount, const QModelIndex& theParent)
{
// Nb of rows of top model + Parts folder
return myModel->rowCount(QModelIndex()) + 1;
+}
+
+bool XGUI_DocumentDataModel::activatedIndex(const QModelIndex& theIndex)
+{
+ if ((theIndex.internalId() == PartsFolder) || (theIndex.internalId() == HistoryNode))
+ return false;
+
+ QModelIndex* aIndex = toSourceModelIndex(theIndex);
+ if (!aIndex)
+ return false;
+
+ const QAbstractItemModel* aModel = aIndex->model();
+
+ if (isPartSubModel(aModel)) {
+ // if this is root node (Part item index)
+ if (!aIndex->parent().isValid()) {
+ if (myActivePart) myActivePart->setItemsColor(PASSIVE_COLOR);
+ myActivePart = (myActivePart == aModel)? 0 : (XGUI_PartModel*)aModel;
+ if (myActivePart) {
+ myActivePart->setItemsColor(ACTIVE_COLOR);
+ myModel->setItemsColor(PASSIVE_COLOR);
+ } else
+ myModel->setItemsColor(ACTIVE_COLOR);
+ return true;
+ }
+ }
+ return false;
+}
+
+FeaturePtr XGUI_DocumentDataModel::activePart() const
+{
+ if (myActivePart)
+ return myActivePart->part();
+ return FeaturePtr();
}
\ No newline at end of file
//! Returns 0 if the given index is not index of a feature
FeaturePtr feature(const QModelIndex& theIndex) 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);
+
+ FeaturePtr activePart() const;
+
private:
enum {PartsFolder, HistoryNode};
//! Converts QModelIndex of this model to QModelIndex of a one of sub-models.
- QModelIndex toSourceModelIndex(const QModelIndex& theProxy) const;
+ QModelIndex* toSourceModelIndex(const QModelIndex& theProxy) const;
//! Finds a pointer on QModelIndex which is equal to the given one
QModelIndex* findModelIndex(const QModelIndex& theIndex) const;
//! Data models for Parts data tree representation (one data model per a one part)
QList<XGUI_PartModel*> myPartModels;
+ //! Active part in part editing mode
+ XGUI_PartModel* myActivePart;
+
//! List of saved QModelIndexes created by sub-models
QList<QModelIndex*> myIndexes;
mySelectedData.append(aFeature);
}
emit selectionChanged();
+}
+
+void XGUI_ObjectsBrowser::mouseDoubleClickEvent(QMouseEvent* theEvent)
+{
+ QModelIndex aIndex = currentIndex();
+ bool isChanged = myDocModel->activatedIndex(aIndex);
+ QTreeView::mouseDoubleClickEvent(theEvent);
+ if (isChanged) {
+ emit activePartChanged(myDocModel->activePart());
+ }
+}
+
+void XGUI_ObjectsBrowser::contextMenuEvent(QContextMenuEvent* theEvent)
+{
+ emit contextMenuRequested(theEvent);
}
\ No newline at end of file
signals:
//! Emited when selection is changed
void selectionChanged();
+ void activePartChanged(FeaturePtr thePart);
+
+ //! Emited on context menu request
+ void contextMenuRequested(QContextMenuEvent* theEvent);
+protected:
+ virtual void mouseDoubleClickEvent(QMouseEvent* theEvent);
+ virtual void contextMenuEvent(QContextMenuEvent* theEvent);
private slots:
//! Called when selection in Data Tree is changed
//! List of currently selected data
QFeatureList mySelectedData;
+
+ //QModelIndex myActivePartIndex;
};
#endif
\ No newline at end of file
return true;
}
+bool XGUI_OperationMgr::abortOperation()
+{
+ ModuleBase_Operation* aCurrentOp = currentOperation();
+ if (!aCurrentOp || !canStopOperation())
+ return false;
+
+ aCurrentOp->abort();
+ return true;
+}
+
void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
{
connect(theOperation, SIGNAL(stopped()), this, SLOT(onOperationStopped()));
ModuleBase_Operation* aCurrentOp = currentOperation();
if (aCurrentOp && !theOperation->isGranted())
{
- int anAnswer = QMessageBox::question(0, tr("Operation launch"),
- tr("Previous operation is not finished and will be aborted"),
- QMessageBox::Ok, QMessageBox::Cancel);
- if (anAnswer == QMessageBox::Ok) {
+ if (canStopOperation()) {
aCurrentOp->abort();
} else {
aCanStart = false;
return aCanStart;
}
+bool XGUI_OperationMgr::canStopOperation()
+{
+ int anAnswer = QMessageBox::question(0, tr("Operation launch"),
+ tr("Previous operation is not finished and will be aborted"),
+ QMessageBox::Ok, QMessageBox::Cancel);
+ return anAnswer == QMessageBox::Ok;
+}
+
void XGUI_OperationMgr::onOperationStopped()
{
ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
/// \return the state whether the current operation is started
bool startOperation(ModuleBase_Operation* theOperation);
+ /// Abort the operation and append it to the stack of operations
+ /// \return the state whether the current operation is aborted
+ bool abortOperation();
+
signals:
/// Signal about an operation is started. It is emitted after the start() of operation is done.
void operationStarted();
/// \param theOperation an operation to check
bool canStartOperation(ModuleBase_Operation* theOperation);
+ /// Returns whether the operation can be stopped.
+ bool canStopOperation();
+
protected slots:
/// Slot that is called by an operation stop. Removes the stopped operation form the stack.
/// If there is a suspended operation, restart it.
#include <ModelAPI_AttributeDocRef.h>
#include <QIcon>
+#include <QBrush>
XGUI_TopDataModel::XGUI_TopDataModel(const boost::shared_ptr<ModelAPI_Document>& theDocument, QObject* theParent)
: XGUI_FeaturesModel(theDocument, theParent)
case Qt::ToolTipRole:
// return Tooltip
break;
+ case Qt::ForegroundRole:
+ return QBrush(myItemsColor);
+ break;
}
return QVariant();
}
case Qt::ToolTipRole:
// return Tooltip
break;
+ case Qt::ForegroundRole:
+ return QBrush(myItemsColor);
+ break;
}
return QVariant();
}
return createIndex(1, 0, (qint32) ConstructFolder);
return QModelIndex();
}
+
+FeaturePtr XGUI_PartDataModel::part() const
+{
+ return myDocument->feature(PARTS_GROUP, myId);
+}
\ No newline at end of file
//! Returns index corresponded to the group
virtual QModelIndex findGroup(const std::string& theGroup) const;
+ //! Return a Part object
+ virtual FeaturePtr part() const;
+
private:
boost::shared_ptr<ModelAPI_Document> featureDocument() const;
void XGUI_ViewWindow::contextMenuEvent(QContextMenuEvent* theEvent)
{
if (theEvent->modifiers() == Qt::NoModifier) {
- QFrame::contextMenuEvent(theEvent);
+ // Temporary: has to be removed when viewer popup will be defined
+ //QFrame::contextMenuEvent(theEvent);
emit contextMenuRequested(theEvent);
}
}
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QApplication>
+#include <QMouseEvent>
+#include <QMenu>
#include <V3d_View.hxx>
#include <AIS_ListIteratorOfListOfInteractive.hxx>
#include <AIS_Shape.hxx>
-#include <QMouseEvent>
#ifdef WIN32
#include <WNT_Window.hxx>
connect(aWindow, SIGNAL(keyReleased(XGUI_ViewWindow*, QKeyEvent*)),
this, SIGNAL(keyRelease(XGUI_ViewWindow*, QKeyEvent*)));
- //connect(aWindow, SIGNAL(contextMenuRequested( QContextMenuEvent* )),
- // this, SLOT (onContextMenuRequested( QContextMenuEvent* )));
+ connect(aWindow, SIGNAL(contextMenuRequested( QContextMenuEvent* )),
+ this, SLOT (onContextMenuRequested( QContextMenuEvent* )));
//connect(aWindow, SIGNAL( contextMenuRequested(QContextMenuEvent*) ),
// this, SIGNAL( contextMenuRequested(QContextMenuEvent*) ) );
aView->updateEnabledDrawMode();
}
}
+
+//******************************************************
+void XGUI_Viewer::onContextMenuRequested(QContextMenuEvent* theEvent)
+{
+ XGUI_ViewWindow* aWnd = dynamic_cast<XGUI_ViewWindow*>(sender());
+ if (!aWnd) return;
+
+ QMenu aMenu;
+
+ // Include Viewer actions
+ if (myActions.size() > 0) {
+ aMenu.addActions(myActions);
+ aMenu.addSeparator();
+ }
+ if (aWnd->actions().size() > 0) {
+ aMenu.addActions(aWnd->actions());
+ aMenu.addSeparator();
+ }
+
+ QMdiArea* aMDI = myMainWindow->mdiArea();
+ if (aMenu.actions().size() > 0) {
+ QMenu* aSubMenu = aMenu.addMenu(tr("Windows"));
+ aSubMenu->addActions(aMDI->actions());
+ } else {
+ aMenu.addActions(aMDI->actions());
+ }
+ aMenu.exec(theEvent->globalPos());
+}
\ No newline at end of file
#include <QObject>
#include <QMap>
#include <QList>
+#include <QPoint>
+#include <QAction>
#include <V3d_Viewer.hxx>
#include <AIS_InteractiveContext.hxx>
#include <NCollection_List.hxx>
#include <TopoDS_Shape.hxx>
-#include <QPoint>
class XGUI_MainWindow;
class QMdiSubWindow;
//! Compute trihedron size dependent on 3d scene size
bool computeTrihedronSize(double& theNewSize, double& theSize);
+ //! Add action to the viewer
+ void addAction(QAction* theAction) { myActions.append(theAction); }
+
+
static void setHotButton(XGUI::InteractionStyle theInteractionStyle, XGUI::HotOperation theOper,
Qt::KeyboardModifiers theState, Qt::MouseButtons theButton);
static void getHotButton(XGUI::InteractionStyle theInteractionStyle, XGUI::HotOperation theOper,
void onMouseMove(XGUI_ViewWindow* theWindow, QMouseEvent* theEvent);
void onMouseReleased(XGUI_ViewWindow* theWindow, QMouseEvent* theEvent);
void onMousePressed(XGUI_ViewWindow* theWindow, QMouseEvent* theEvent);
+ void onContextMenuRequested(QContextMenuEvent* theEvent);
private:
void addView(QMdiSubWindow* theView);
/// Points used for selection management
QPoint myStartPnt, myEndPnt, myCurPnt;
- // A counter of created windows
+ /// A counter of created windows
int myWndIdCount;
+
+ /// List of Viewer actions
+ QList<QAction*> myActions;
};
#endif
#include "XGUI_ErrorDialog.h"
#include "XGUI_ViewerProxy.h"
#include "XGUI_PropertyPanel.h"
+#include "XGUI_ContextMenuMgr.h"
#include <Model_Events.h>
#include <ModelAPI_PluginManager.h>
myDisplayer = new XGUI_Displayer(this);
mySelector = new XGUI_SelectionMgr(this);
- connect(mySelector, SIGNAL(selectionChanged()), this, SLOT(changeCurrentDocument()));
myOperationMgr = new XGUI_OperationMgr(this);
myActionsMgr = new XGUI_ActionsMgr(this);
myErrorDlg = new XGUI_ErrorDialog(myMainWindow);
+ myContextMenuMgr = new XGUI_ContextMenuMgr(this);
myViewerProxy = new XGUI_ViewerProxy(this);
QIcon(":pictures/close.png"), QKeySequence::Close);
aCommand->connectTo(this, SLOT(onExit()));
+ myContextMenuMgr->createActions();
}
//******************************************************
}
//show file dialog, check if readable and open
- myCurrentFile = QFileDialog::getOpenFileName(mainWindow());
+ myCurrentFile = QFileDialog::getExistingDirectory(mainWindow());
if(myCurrentFile.isEmpty())
return;
QFileInfo aFileInfo(myCurrentFile);
objectBrowser()->setCurrentIndex(QModelIndex());
boost::shared_ptr<ModelAPI_PluginManager> aMgr = ModelAPI_PluginManager::get();
boost::shared_ptr<ModelAPI_Document> aDoc = aMgr->rootDocument();
+ //if (!operationMgr()->abortOperation())
+ // return;
+ operationMgr()->abortOperation();
aDoc->undo();
updateCommandStatus();
}
if (aMgr->hasRootDocument()) {
XGUI_Command* aUndoCmd;
XGUI_Command* aRedoCmd;
- for (aIt = aCommands.constBegin(); aIt != aCommands.constEnd(); ++aIt) {
- if ((*aIt)->id() == "UNDO_CMD")
- aUndoCmd = (*aIt);
- else if ((*aIt)->id() == "REDO_CMD")
- aRedoCmd = (*aIt);
+ foreach(XGUI_Command* aCmd, aCommands) {
+ if (aCmd->id() == "UNDO_CMD")
+ aUndoCmd = aCmd;
+ else if (aCmd->id() == "REDO_CMD")
+ aRedoCmd = aCmd;
else // Enable all commands
- (*aIt)->enable();
+ aCmd->enable();
}
boost::shared_ptr<ModelAPI_Document> aDoc = aMgr->rootDocument();
aUndoCmd->setEnabled(aDoc->canUndo());
aRedoCmd->setEnabled(aDoc->canRedo());
} else {
- for (aIt = aCommands.constBegin(); aIt != aCommands.constEnd(); ++aIt) {
- if ((*aIt)->id() == "NEW_CMD")
- (*aIt)->enable();
- else if ((*aIt)->id() == "EXIT_CMD")
- (*aIt)->enable();
+ foreach(XGUI_Command* aCmd, aCommands) {
+ if (aCmd->id() == "NEW_CMD")
+ aCmd->enable();
+ else if (aCmd->id() == "EXIT_CMD")
+ aCmd->enable();
else
- (*aIt)->disable();
+ aCmd->disable();
}
}
}
aObjDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
aObjDock->setWindowTitle(tr("Object browser"));
myObjectBrowser = new XGUI_ObjectsBrowser(aObjDock);
+ connect(myObjectBrowser, SIGNAL(activePartChanged(FeaturePtr)), this, SLOT(changeCurrentDocument(FeaturePtr)));
aObjDock->setWidget(myObjectBrowser);
+
+ myContextMenuMgr->connectObjectBrowser();
return aObjDock;
}
}
//******************************************************
-void XGUI_Workshop::changeCurrentDocument()
+void XGUI_Workshop::changeCurrentDocument(FeaturePtr thePart)
{
- QFeatureList aFeatures = objectBrowser()->selectedFeatures();
-
- // Set current document
- if (aFeatures.size() > 0) {
- FeaturePtr aFeature = aFeatures.first();
-
- boost::shared_ptr<ModelAPI_PluginManager> aMgr = ModelAPI_PluginManager::get();
- boost::shared_ptr<ModelAPI_AttributeDocRef> aDocRef = aFeature->data()->docRef("PartDocument");
+ boost::shared_ptr<ModelAPI_PluginManager> aMgr = ModelAPI_PluginManager::get();
+ if (thePart) {
+ boost::shared_ptr<ModelAPI_AttributeDocRef> aDocRef = thePart->data()->docRef("PartDocument");
if (aDocRef)
aMgr->setCurrentDocument(aDocRef->value());
+ } else {
+ aMgr->setCurrentDocument(aMgr->rootDocument());
}
}
#define XGUI_WORKSHOP_H
#include "XGUI.h"
+#include "XGUI_Constants.h"
#include <Events_Listener.h>
#include <QObject>
class XGUI_SalomeViewer;
class XGUI_ViewerProxy;
class XGUI_PropertyPanel;
+class XGUI_ContextMenuMgr;
class ModuleBase_Operation;
//! Returns property panel widget
XGUI_PropertyPanel* propertyPanel() const { return myPropertyPanel; }
+ //! Returns context menu manager object
+ XGUI_ContextMenuMgr* contextMenuMgr() const { return myContextMenuMgr; }
+
//! Creates and adds a new workbench (menu group) with the given name and returns it
XGUI_Workbench* addWorkbench(const QString& theName);
void hideObjectBrowser();
void onFeatureTriggered();
- void changeCurrentDocument();
+ void changeCurrentDocument(FeaturePtr thePart);
signals:
void errorOccurred(const QString&);
XGUI_SalomeConnector* mySalomeConnector;
XGUI_ErrorDialog* myErrorDlg;
XGUI_ViewerProxy* myViewerProxy;
+ XGUI_ContextMenuMgr* myContextMenuMgr;
static QMap<QString, QString> myIcons;
<file>pictures/redo.png</file>
<file>pictures/undo.png</file>
<file>pictures/rebuild.png</file>
- <!--For test purposes-->
<file>pictures/occ_view_back.png</file>
<file>pictures/occ_view_bottom.png</file>
<file>pictures/cascade_views.png</file>
<file>pictures/tile_views.png</file>
<file>pictures/new_view.png</file>
+ <file>pictures/edit.png</file>
</qresource>
</RCC>