currentOperation()->postpone();
myOperations.append(theOperation);
+ connect(theOperation, SIGNAL(beforeStarted()), SLOT(onBeforeOperationStarted()));
+ connect(theOperation, SIGNAL(beforeAborted()), SLOT(onBeforeOperationAborted()));
+ connect(theOperation, SIGNAL(beforeCommitted()), SLOT(onBeforeOperationCommitted()));
+
connect(theOperation, SIGNAL(started()), SLOT(onOperationStarted()));
connect(theOperation, SIGNAL(aborted()), SLOT(onOperationAborted()));
connect(theOperation, SIGNAL(committed()), SLOT(onOperationCommitted()));
+
connect(theOperation, SIGNAL(stopped()), SLOT(onOperationStopped()));
connect(theOperation, SIGNAL(resumed()), SLOT(onOperationResumed()));
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
if (theOperation) {
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
if (aFOperation)
- anErrorMgr->updateActions(aFOperation->feature());
+ anErrorMgr->updateAcceptAllAction(aFOperation->feature());
//emit nestedStateChanged(theOperation->getDescription()->operationId().toStdString(),
// theOperation->isValid());
}
bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation)
{
//in case of nested (sketch) operation no confirmation needed
- if (isGrantedOperation(theOperation))
+ if (isGrantedOperation(theOperation->id()))
return true;
if (theOperation && theOperation->isModified()) {
QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());
theOperation->resume();
}
-bool XGUI_OperationMgr::isGrantedOperation(ModuleBase_Operation* theOperation)
+bool XGUI_OperationMgr::isGrantedOperation(const QString& theId)
{
bool isGranted = false;
ModuleBase_Operation* aPreviousOperation = 0;
while (anIt.hasPrevious()) {
ModuleBase_Operation* anOp = anIt.previous();
- if (anOp == theOperation) {
- if (anIt.hasPrevious())
- aPreviousOperation = anIt.previous();
- break;
- }
+ if (anOp)
+ isGranted = anOp->isGranted(theId);
}
- if (aPreviousOperation)
- isGranted = aPreviousOperation->isGranted(theOperation->id());
-
return isGranted;
}
-bool XGUI_OperationMgr::canStartOperation(const QString& theId, const bool isAdditionallyGranted)
+void XGUI_OperationMgr::setCurrentFeature(const FeaturePtr& theFeature)
+{
+ SessionPtr aMgr = ModelAPI_Session::get();
+ DocumentPtr aDoc = aMgr->activeDocument();
+ bool aIsOp = aMgr->isOperation();
+ if (!aIsOp)
+ aMgr->startOperation();
+ aDoc->setCurrentFeature(theFeature, false);
+ if (!aIsOp)
+ aMgr->finishOperation();
+}
+
+bool XGUI_OperationMgr::canStartOperation(const QString& theId)
{
bool aCanStart = true;
ModuleBase_Operation* aCurrentOp = currentOperation();
if (aCurrentOp) {
- bool aGranted = aCurrentOp->isGranted(theId) || isAdditionallyGranted;
- if (!aGranted) {
- if (canStopOperation(aCurrentOp)) {
+ bool aGranted = aCurrentOp->isGranted(theId);
+ // the started operation is granted for the current one,
+ // e.g. current - Sketch, started - Line
+ if (aGranted) {
+ aCanStart = true;
+ }
+ else {
+ if (!isGrantedOperation(theId)) {
+ // the operation is not granted in the current list of operations
+ // e.g. Edit Parameter when Sketch, Line in Sketch is active.
+ aCanStart = abortAllOperations();
+ }
+ else if (canStopOperation(aCurrentOp)) {
+ // the started operation is granted in the parrent operation,
+ // e.g. current - Line in Sketch, started Circle
if (myIsApplyEnabled && aCurrentOp->isModified())
aCurrentOp->commit();
else
}
}
+void XGUI_OperationMgr::onBeforeOperationStarted()
+{
+ ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());
+ if (!aCurrentOperation)
+ return;
+
+ /// Set current feature and remeber old current feature
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(aCurrentOperation);
+ if (aFOperation) {
+ SessionPtr aMgr = ModelAPI_Session::get();
+ DocumentPtr aDoc = aMgr->activeDocument();
+ // the parameter of current feature should be false, we should use all feature, not only visible
+ // in order to correctly save the previous feature of the nested operation, where the
+ // features can be not visible in the tree. The problem case is Edit sketch entitity(line)
+ // in the Sketch, created in ExtrusionCut operation. The entity disappears by commit.
+ // When sketch entity operation started, the sketch should be cashed here as the current.
+ // Otherwise(the flag is true), the ExtrusionCut is cashed, when commit happens, the sketch
+ // is disabled, sketch entity is disabled as extrusion cut is created earliest then sketch.
+ // As a result the sketch disappears from the viewer. However after commit it is displayed back.
+ aFOperation->setPreviousCurrentFeature(aDoc->currentFeature(false));
+ if (aFOperation->isEditOperation()) // it should be performed by the feature edit only
+ // in create operation, the current feature is changed by addFeature()
+ aDoc->setCurrentFeature(aFOperation->feature(), false);
+ }
+}
+
void XGUI_OperationMgr::onOperationStarted()
{
ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
emit operationStarted(aSenderOperation);
}
+void XGUI_OperationMgr::onBeforeOperationAborted()
+{
+ onBeforeOperationCommitted();
+}
+
void XGUI_OperationMgr::onOperationAborted()
{
ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
emit operationAborted(aSenderOperation);
}
+void XGUI_OperationMgr::onBeforeOperationCommitted()
+{
+ ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());
+ if (!aCurrentOperation)
+ return;
+
+ /// Restore the previous current feature
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(aCurrentOperation);
+ if (aFOperation) {
+ if (aFOperation->isEditOperation()) {
+ /// Restore the previous current feature
+ setCurrentFeature(aFOperation->previousCurrentFeature());
+ }
+ else { // create operation
+ // the Top created feature should stays the current. In nested operations, like Line in the Sketch or
+ // Sketch in ExtrusionCut, a previous feature should be restored on commit. It is performed here
+ // in order to perform it in the current transaction without opening a new one.
+ if (myOperations.front() != aFOperation)
+ setCurrentFeature(aFOperation->previousCurrentFeature());
+ }
+ }
+}
+
void XGUI_OperationMgr::onOperationCommitted()
{
// apply state for all features from the stack of operations should be updated
if (noModifiers) {
ModuleBase_IViewer* aViewer = myWorkshop->viewer();
Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
- Handle(V3d_View) aView = aViewer->activeView();
- if ((theEvent->key() == Qt::Key_N))
- aContext->HilightNextDetected(aView);
- else if ((theEvent->key() == Qt::Key_P))
- aContext->HilightPreviousDetected(aView);
+ if (!aContext.IsNull()) {
+ Handle(V3d_View) aView = aViewer->activeView();
+ if ((theEvent->key() == Qt::Key_N))
+ aContext->HilightNextDetected(aView);
+ else if ((theEvent->key() == Qt::Key_P))
+ aContext->HilightPreviousDetected(aView);
+ }
}
}