#include "PartSet_SketcherReetntrantMgr.h"
#include "PartSet_Module.h"
#include "PartSet_SketcherMgr.h"
-#include "PartSet_WidgetPoint2D.h"
+#include "PartSet_WidgetPoint2d.h"
#include "ModelAPI_Session.h"
#include <ModuleBase_ModelWidget.h>
#include <ModuleBase_ViewerPrs.h>
#include <ModuleBase_WidgetSelector.h>
+#include <ModuleBase_PageWidget.h>
+#include <ModuleBase_PageBase.h>
+#include <ModuleBase_WidgetFactory.h>
+#include <ModuleBase_OperationDescription.h>
#include <SketchPlugin_Feature.h>
#include <SketchPlugin_Line.h>
#include <XGUI_Workshop.h>
#include <XGUI_ModuleConnector.h>
#include <XGUI_OperationMgr.h>
+#include <XGUI_PropertyPanel.h>
+
+#include <QToolButton>
PartSet_SketcherReetntrantMgr::PartSet_SketcherReetntrantMgr(ModuleBase_IWorkshop* theWorkshop)
: QObject(theWorkshop),
myWorkshop(theWorkshop),
myRestartingMode(RM_None),
myIsFlagsBlocked(false),
- myIsInternalEditOperation(false)
+ myIsInternalEditOperation(false),
+ myNoMoreWidgetsAttribute("")
{
}
if (aOperation) {
ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
- if (myIsInternalEditOperation && (!anActiveWidget || !anActiveWidget->isViewerSelector())) {
- // finds the first widget which can accept a value
- QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
- ModuleBase_ModelWidget* aFirstWidget = 0;
- ModuleBase_ModelWidget* aWgt;
- QList<ModuleBase_ModelWidget*>::const_iterator aWIt;
- for (aWIt = aWidgets.begin(); aWIt != aWidgets.end() && !aFirstWidget; ++aWIt) {
- aWgt = (*aWIt);
- if (aWgt->canSetValue())
- aFirstWidget = aWgt;
- }
- if (aFirstWidget)
- aWidget = aFirstWidget;
- }
+ if (myIsInternalEditOperation && (!anActiveWidget || !anActiveWidget->isViewerSelector()))
+ aWidget = myInternalActiveWidget;
}
return aWidget;
}
+bool PartSet_SketcherReetntrantMgr::isInternalEditActive() const
+{
+ return myIsInternalEditOperation;
+}
+
bool PartSet_SketcherReetntrantMgr::operationCommitted(ModuleBase_Operation* theOperation)
{
bool aProcessed = false;
if (myIsInternalEditOperation) {
ModuleBase_Operation* anOperation = myWorkshop->currentOperation();
+ ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
- ModuleBase_ModelWidget* anActiveWidget = anOperation->propertyPanel()->activeWidget();
+ ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
if (!anActiveWidget || !anActiveWidget->isViewerSelector()) {
restartOperation();
aProcessed = true;
- // fill the widget by the mouse event point
+ // fill the first widget by the mouse event point
+ // if the active widget is not the first, it means that the restarted operation is filled by
+ // the current preselection.
PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast<PartSet_WidgetPoint2D*>(module()->activeWidget());
- if (aPoint2DWdg) {
+ ModuleBase_ModelWidget* aFirstWidget = aPanel->findFirstAcceptingValueWidget();
+ if (aPoint2DWdg && aPoint2DWdg == aFirstWidget) {
aPoint2DWdg->onMouseRelease(theWnd, theEvent);
}
}
{
if (!isActiveMgr())
return;
- XGUI_OperationMgr* anOpMgr = workshop()->operationMgr();
- if (!anOpMgr->isApplyEnabled())
+
+ // we should avoid processing of the signal about no more widgets attributes and
+ // do this after the restart operaion is finished if it was called
+ // onNoMoreWidgets depends on myIsFlagsBlocked and fill myNoMoreWidgetsAttribute
+ // if it should be called after restart
+ if (myIsFlagsBlocked) {
+ myNoMoreWidgetsAttribute = thePreviousAttributeID;
return;
+ }
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
(myWorkshop->currentOperation());
- if (aFOperation) {
- if (PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) {
- XGUI_OperationMgr* anOpMgr = workshop()->operationMgr();
+ if (!myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty())
+ return;
+
+ if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) {
+ bool isStarted = false;
+ if (!module()->sketchMgr()->sketchSolverError()) {
if (myRestartingMode != RM_Forbided) {
myRestartingMode = RM_LastFeatureUsed;
- startInternalEdit(thePreviousAttributeID);
+ isStarted = startInternalEdit(thePreviousAttributeID);
}
- else
- aFOperation->commit();
}
+ if (!isStarted)
+ aFOperation->commit();
}
}
+bool PartSet_SketcherReetntrantMgr::processEnter(const std::string& thePreviousAttributeID)
+{
+ bool isDone = false;
+
+ if (!isActiveMgr())
+ return isDone;
+
+ // empty previous attribute means that the Apply/Ok button has focus and the enter
+ // should not lead to start edition mode of the previous operation
+ if (thePreviousAttributeID.empty())
+ return isDone;
+
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (myWorkshop->currentOperation());
+ if (!myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty())
+ return isDone;
+
+ bool isSketchSolverError = module()->sketchMgr()->sketchSolverError();
+
+ if (!isSketchSolverError) {
+ myRestartingMode = RM_EmptyFeatureUsed;
+ isDone = startInternalEdit(thePreviousAttributeID);
+ }
+
+ return isDone;
+}
+
void PartSet_SketcherReetntrantMgr::onVertexSelected()
{
if (!isActiveMgr())
}
}
-void PartSet_SketcherReetntrantMgr::onEnterReleased()
+void PartSet_SketcherReetntrantMgr::onBeforeStopped()
{
- if (!isActiveMgr())
+ if (!isActiveMgr() || !myIsInternalEditOperation)
return;
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
- (myWorkshop->currentOperation());
- if (myIsInternalEditOperation)
- myRestartingMode = RM_EmptyFeatureUsed;
+ beforeStopInternalEdit();
}
bool PartSet_SketcherReetntrantMgr::canBeCommittedByPreselection()
bool PartSet_SketcherReetntrantMgr::isActiveMgr() const
{
- PartSet_SketcherMgr* aSketcherMgr = module()->sketchMgr();
ModuleBase_Operation* aCurrentOperation = myWorkshop->currentOperation();
- return PartSet_SketcherMgr::isSketchOperation(aCurrentOperation) ||
- PartSet_SketcherMgr::isNestedSketchOperation(aCurrentOperation);
+
+ bool anActive = PartSet_SketcherMgr::isSketchOperation(aCurrentOperation);
+ if (!anActive) {
+ anActive = PartSet_SketcherMgr::isNestedSketchOperation(aCurrentOperation);
+ if (anActive) { // the manager is not active when the current operation is a usual Edit
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (myWorkshop->currentOperation());
+ if (aFOperation->isEditOperation())
+ anActive = myIsInternalEditOperation;
+ }
+ }
+ return anActive;
}
-void PartSet_SketcherReetntrantMgr::startInternalEdit(const std::string& thePreviousAttributeID)
+bool PartSet_SketcherReetntrantMgr::startInternalEdit(const std::string& thePreviousAttributeID)
{
+ bool isDone = false;
+ /// this is workaround for ModuleBase_WidgetEditor, used in SALOME mode. Sometimes key enter
+ /// event comes two times, so we should not start another internal edit operation
+ /// the Apply button becomes disabled becase the second additional internal feature is created
+ if (myIsInternalEditOperation)
+ return true;
+
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
(myWorkshop->currentOperation());
- aFOperation->setEditOperation();
- FeaturePtr anOperationFeature = aFOperation->feature();
- if (anOperationFeature.get() != NULL) {
+ if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) {
+ aFOperation->setEditOperation(false);
+ workshop()->operationMgr()->updateApplyOfOperations();
+
+ createInternalFeature();
myIsInternalEditOperation = true;
+ isDone = true;
+ connect(aFOperation, SIGNAL(beforeCommitted()), this, SLOT(onBeforeStopped()));
+ connect(aFOperation, SIGNAL(beforeAborted()), this, SLOT(onBeforeStopped()));
+
// activate selection filters of the first widget in the viewer
onWidgetActivated();
aPreviousAttributeWidget = aWidgets[i];
}
// If the current widget is a selector, do nothing, it processes the mouse press
- if (aPreviousAttributeWidget && !aPreviousAttributeWidget->isViewerSelector())
- aPreviousAttributeWidget->focusTo();
+ if (aPreviousAttributeWidget) {
+ if (!aPreviousAttributeWidget->isViewerSelector()) {
+ aPreviousAttributeWidget->focusTo();
+ aPreviousAttributeWidget->selectContent();
+ }
+ else {
+ // in case of shape multi selector, the widget does not lose focus by filling
+ // like it is in shape selector. So, if enter is pressed, the multi shape selector
+ // control should be deactivated. The focus is moved to Apply button and there
+ // should not be active control visualized in property panel
+ if (aPreviousAttributeWidget == aPanel->activeWidget()) {
+ aPanel->activateWidget(NULL, false);
+ }
+ // if there is no the next widget to be automatically activated, the Ok button in property
+ // panel should accept the focus(example is parallel constraint on sketch lines)
+ QToolButton* anOkBtn = aPanel->findChild<QToolButton*>(PROP_PANEL_OK);
+ if (anOkBtn)
+ anOkBtn->setFocus(Qt::TabFocusReason);
+ }
+ }
}
}
}
+ if (isDone)
+ module()->sketchMgr()->clearClickedFlags();
+
+ return isDone;
+}
+
+void PartSet_SketcherReetntrantMgr::beforeStopInternalEdit()
+{
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (myWorkshop->currentOperation());
+ if (aFOperation) {
+ disconnect(aFOperation, SIGNAL(beforeCommitted()), this, SLOT(onBeforeStopped()));
+ disconnect(aFOperation, SIGNAL(beforeAborted()), this, SLOT(onBeforeStopped()));
+ }
+
+ deleteInternalFeature();
}
void PartSet_SketcherReetntrantMgr::restartOperation()
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(
myWorkshop->currentOperation());
if (aFOperation) {
+ myNoMoreWidgetsAttribute = "";
myIsFlagsBlocked = true;
aFOperation->commit();
module()->launchOperation(aFOperation->id());
myIsFlagsBlocked = false;
resetFlags();
+ // we should avoid processing of the signal about no more widgets attributes and
+ // do this after the restart operaion is finished if it was called
+ // onNoMoreWidgets depends on myIsFlagsBlocked and fill myNoMoreWidgetsAttribute
+ // if it should be called after restart
+ if (!myNoMoreWidgetsAttribute.empty()) {
+ onNoMoreWidgets(myNoMoreWidgetsAttribute);
+ myNoMoreWidgetsAttribute = "";
+ }
}
}
}
+void PartSet_SketcherReetntrantMgr::createInternalFeature()
+{
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (myWorkshop->currentOperation());
+
+ if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) {
+ FeaturePtr anOperationFeature = aFOperation->feature();
+
+ CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
+ myInternalFeature = aSketch->addFeature(anOperationFeature->getKind());
+ XGUI_PropertyPanel* aPropertyPanel = dynamic_cast<XGUI_PropertyPanel*>
+ (aFOperation->propertyPanel());
+
+ myInternalWidget = new QWidget(aPropertyPanel->contentWidget()->pageWidget());
+ myInternalWidget->setVisible(false);
+
+ ModuleBase_PageWidget* anInternalPage = new ModuleBase_PageWidget(myInternalWidget);
+
+ QString aXmlRepr = aFOperation->getDescription()->xmlRepresentation();
+ ModuleBase_WidgetFactory aFactory(aXmlRepr.toStdString(), myWorkshop);
+
+ aFactory.createWidget(anInternalPage);
+ QList<ModuleBase_ModelWidget*> aWidgets = aFactory.getModelWidgets();
+
+ foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
+ bool isStoreValue = !aFOperation->isEditOperation() &&
+ !aWidget->getDefaultValue().empty() &&
+ !aWidget->isComputedDefault();
+ aWidget->setFeature(myInternalFeature, isStoreValue);
+ }
+ ModuleBase_ModelWidget* aFirstWidget = ModuleBase_IPropertyPanel::findFirstAcceptingValueWidget
+ (aWidgets);
+ if (aFirstWidget)
+ myInternalActiveWidget = aFirstWidget;
+ }
+}
+
+void PartSet_SketcherReetntrantMgr::deleteInternalFeature()
+{
+ if (myInternalActiveWidget) {
+ ModuleBase_WidgetSelector* aWSelector = dynamic_cast<ModuleBase_WidgetSelector*>(myInternalActiveWidget);
+ if (aWSelector)
+ aWSelector->activateSelectionAndFilters(false);
+ myInternalActiveWidget = 0;
+ }
+ delete myInternalWidget;
+ myInternalWidget = 0;
+
+ QObjectPtrList anObjects;
+ anObjects.append(myInternalFeature);
+ workshop()->deleteFeatures(anObjects);
+}
+
void PartSet_SketcherReetntrantMgr::resetFlags()
{
if (!myIsFlagsBlocked) {
{
return dynamic_cast<PartSet_Module*>(myWorkshop->module());
}
+