bool ModuleBase_Operation::isValid() const
{
- if (!myFeature)
+ if (!myFeature || !myFeature->data()->isValid())
return true; // rename operation
if (myFeature->isAction())
return true;
//Get validators for the Id
SessionPtr aMgr = ModelAPI_Session::get();
ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
- return aFactory->validate(myFeature);
+ bool aValid = aFactory->validate(myFeature);
+
+ // the feature exec state should be checked in order to do not apply features, which result can not
+ // be built. E.g. extrusion on sketch, where the "to" is a perpendicular plane to the sketch
+ bool isDone = myFeature->data()->execState() == ModelAPI_StateDone;
+
+ return aValid && isDone;
}
{
QString anId = getDescription()->operationId();
if (myIsEditing) {
- anId = anId.append(EditSuffix());
+ anId = anId.append(EditSuffix());
}
ModelAPI_Session::get()->startOperation(anId.toStdString());
- if (!myIsEditing)
- createFeature();
+ if (!myIsEditing) {
+ FeaturePtr aFeature = createFeature();
+ // if the feature is not created, there is no sense to start the operation
+ if (aFeature.get() == NULL) {
+ // it is necessary to abor the operation in the session and emit the aborted signal
+ // in order to update commands status in the workshop, to be exact the feature action
+ // to be unchecked
+ abort();
+ return;
+ }
+ }
+ /// Set current feature and remeber old current feature
+ if (myIsEditing) {
+ SessionPtr aMgr = ModelAPI_Session::get();
+ DocumentPtr aDoc = aMgr->activeDocument();
+ myCurrentFeature = aDoc->currentFeature(true);
+ aDoc->setCurrentFeature(feature(), false);
+ }
startOperation();
emit started();
void ModuleBase_Operation::abort()
{
+ if (myIsEditing) {
+ SessionPtr aMgr = ModelAPI_Session::get();
+ DocumentPtr aDoc = aMgr->activeDocument();
+ aDoc->setCurrentFeature(myCurrentFeature, true);
+ myCurrentFeature = FeaturePtr();
+ }
abortOperation();
emit aborted();
stopOperation();
+ // is is necessary to deactivate current widgets before the model operation is aborted
+ // because abort removes the feature and activated filters should not check it
+ propertyPanel()->cleanContent();
ModelAPI_Session::get()->abortOperation();
emit stopped();
bool ModuleBase_Operation::commit()
{
if (canBeCommitted()) {
+ SessionPtr aMgr = ModelAPI_Session::get();
+ /// Set current feature and remeber old current feature
+ if (myIsEditing) {
+ DocumentPtr aDoc = aMgr->activeDocument();
+ bool aIsOp = aMgr->isOperation();
+ if (!aIsOp)
+ aMgr->startOperation();
+ aDoc->setCurrentFeature(myCurrentFeature, true);
+ if (!aIsOp)
+ aMgr->finishOperation();
+ myCurrentFeature = FeaturePtr();
+ }
commitOperation();
// check whether there are modifications performed during the current operation
// in the model
// in case if there are no modifications, do not increase the undo/redo stack
- if (ModelAPI_Session::get()->isModified())
- ModelAPI_Session::get()->finishOperation();
+ if (aMgr->isModified())
+ aMgr->finishOperation();
else
- ModelAPI_Session::get()->abortOperation();
+ aMgr->abortOperation();
stopOperation();
emit stopped();
void ModuleBase_Operation::setRunning(bool theState)
{
- if (!theState) {
- abort();
- }
+ emit triggered(theState);
}
void ModuleBase_Operation::activateByPreselection()
ModuleBase_ModelWidget* aWgt, *aFilledWgt = 0;
QList<ModuleBase_ModelWidget*>::const_iterator aWIt;
- QList<ModuleBase_ViewerPrs>::const_iterator aPIt;
bool isSet = false;
- for (aWIt = aWidgets.constBegin(), aPIt = myPreSelection.constBegin();
- (aWIt != aWidgets.constEnd()) && (aPIt != myPreSelection.constEnd());
- ++aWIt) {
+ // 1. apply the selection to controls
+ int aCurrentPosition = 0;
+ for (aWIt = aWidgets.constBegin(); aWIt != aWidgets.constEnd(); ++aWIt) {
aWgt = (*aWIt);
- ModuleBase_ViewerPrs aValue = (*aPIt);
if (!aWgt->canSetValue())
continue;
- ++aPIt;
- if (!aWgt->setSelection(aValue)) {
+ if (!aWgt->setSelection(myPreSelection, aCurrentPosition/*aValue*/)) {
isSet = false;
break;
} else {
aFilledWgt = aWgt;
}
}
+ // 2. ignore not obligatory widgets
+ /*for (; aWIt != aWidgets.constEnd(); ++aWIt) {
+ aWgt = (*aWIt);
+ if (aWgt && aWgt->isObligatory())
+ continue;
+ aFilledWgt = aWgt;
+ }*/
- myPropertyPanel->activateNextWidget(aFilledWgt);
+ // 3. a signal should be emitted before the next widget activation
+ // because, the activation of the next widget will give a focus to the widget. As a result
+ // the value of the widget is initialized. And commit may happens until the value is entered.
if (aFilledWgt)
emit activatedByPreselection();
+ // 4. activate the next obligatory widget
+ myPropertyPanel->activateNextWidget(aFilledWgt);
}
void ModuleBase_Operation::setParentFeature(CompositeFeaturePtr theParent)