Undo/Redo for a line under sketch.
: 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
SketchPlugin_Line::SketchPlugin_Line()
{
+ 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();
}
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
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.
objectBrowser()->setCurrentIndex(QModelIndex());
boost::shared_ptr<ModelAPI_PluginManager> aMgr = ModelAPI_PluginManager::get();
boost::shared_ptr<ModelAPI_Document> aDoc = aMgr->rootDocument();
+ if (!operationMgr()->abortOperation())
+ return;
aDoc->undo();
updateCommandStatus();
}