*/
ModuleBase_DoubleSpinBox::ModuleBase_DoubleSpinBox(QWidget* theParent, int thePrecision)
: QDoubleSpinBox(theParent),
- myCleared(false)
+ myCleared(false),
+ myIsModified(false)
{
// VSR 01/07/2010: Disable thousands separator for spin box
// (to avoid inconsistency of double-2-string and string-2-double conversion)
connect(lineEdit(), SIGNAL(textChanged( const QString& )), this,
SLOT(onTextChanged( const QString& )));
+
+ connect(this, SIGNAL(valueChanged(const QString&)), this, SLOT(onValueChanged(const QString&)));
+ connect(this, SIGNAL(editingFinished()), this, SLOT(onEditingFinished()));
}
/*!
return res;
}
+#include <QKeyEvent>
+void ModuleBase_DoubleSpinBox::keyPressEvent(QKeyEvent *theEvent)
+{
+ myProcessedEvent = 0;
+
+ bool anIsModified = myIsModified;
+ QDoubleSpinBox::keyPressEvent(theEvent);
+
+ switch (theEvent->key()) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return: {
+ if (anIsModified)
+ myProcessedEvent = theEvent;
+ /*qDebug("ModuleBase_DoubleSpinBox::keyPressEvent");
+ if (anIsModified) // we should not perform this event outside
+ theEvent->setAccepted(true);
+ else
+ theEvent->setAccepted(false);*/
+ }
+ break;
+ default:
+ break;
+ }
+}
+
/*!
\brief Perform \a steps increment/decrement steps.
void ModuleBase_DoubleSpinBox::onTextChanged(const QString& )
{
myCleared = false;
+ myIsModified = true;
+}
+
+void ModuleBase_DoubleSpinBox::onValueChanged(const QString& theValue)
+{
+ myIsModified = true;
+}
+
+void ModuleBase_DoubleSpinBox::onEditingFinished()
+{
+ myIsModified = false;
+}
+
+bool ModuleBase_DoubleSpinBox::isEventProcessed(QKeyEvent* theEvent)
+{
+ return myProcessedEvent && myProcessedEvent == theEvent;
}
#include <QDoubleSpinBox>
#include <QValidator>
+class QKeyEvent;
/**
* \ingroup GUI
/// Validate current value
virtual QValidator::State validate(QString&, int&) const;
+ virtual bool isEventProcessed(QKeyEvent* theEvent);
+
protected slots:
/// Called on text changed
virtual void onTextChanged(const QString&);
+ void onValueChanged(const QString& theValue);
+ void onEditingFinished();
protected:
/// Removes extra trailing zero symbols
QString removeTrailingZeroes(const QString&) const;
+ virtual void keyPressEvent(QKeyEvent* theEvent);
private:
/// Is clear flag
/// Precision value
int myPrecision;
+ /// Boolean value whether the spin box content is modified
+ bool myIsModified;
+
+ QKeyEvent* myProcessedEvent;
};
#endif
return aMgr->hasModuleDocument() && aMgr->canRedo() && !aMgr->isOperation();
}
-bool ModuleBase_IModule::canCommitOperation() const
+/*/bool ModuleBase_IModule::canCommitOperation() const
{
return true;
-}
+}*/
void ModuleBase_IModule::onFeatureTriggered()
{
\r
/// Returns True if the current operation can be committed. By default it is true.\r
/// \return a boolean value\r
- virtual bool canCommitOperation() const;\r
+ //virtual bool canCommitOperation() const;\r
\r
/// Returns whether the object can be erased. The default realization returns true.\r
/// \param theObject a model object\r
return isDone;
}
+void ModuleBase_ModelWidget::storeValueByApply()
+{
+ // do not emit signal about update the currenty feature object
+ // in order to do not perform additional redisplay in the viewer.
+ // It should happens by finish operation of the apply action
+ storeValueCustom();
+}
+
void ModuleBase_ModelWidget::updateObject(ObjectPtr theObj)
{
blockUpdateViewer(true);
//blockUpdateViewer(false);
}
+bool ModuleBase_ModelWidget::isEventProcessed(QKeyEvent* theEvent)
+{
+ return false;
+}
+
bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent)
{
QWidget* aWidget = qobject_cast<QWidget*>(theObject);
/// \return True in success
bool restoreValue();
+ /// Saves the internal parameters to the given feature. Emits signals before and after store
+ /// \return True in success
+ void storeValueByApply();
+
/// Set focus to the first control of the current widget. The focus policy of the control is checked.
/// If the widget has the NonFocus focus policy, it is skipped.
/// \return the state whether the widget can accept the focus
/// \return Current Editing mode
bool isEditingMode() const { return myIsEditing; }
+ /// Returns true if the event is processed.
+ virtual bool isEventProcessed(QKeyEvent* theEvent);
+
/// Sends Update and Redisplay for the given object
/// \param theObj is updating object
static void updateObject(ObjectPtr theObj);
void beforeValuesChanged();
/// The signal about widget values changed
void valuesChanged();
+ /// The signal about widget values modified
+ void valuesModified();
/// The signal about widget values are to be changed
void afterValuesChanged();
#include <QDebug>
#endif
+#define APPLY_BY_ENTER_OR_TAB
+
ModuleBase_OperationFeature::ModuleBase_OperationFeature(const QString& theId, QObject* theParent)
: ModuleBase_Operation(theId, theParent),
myIsEditing(false)
ModuleBase_IPropertyPanel* aPropertyPanel = propertyPanel();
if (aPropertyPanel)
aPropertyPanel->cleanContent();
-
+
myFeature->setStable(true);
SessionPtr aMgr = ModelAPI_Session::get();
#include <iostream>
#endif
-//#define APPLY_BY_ENTER_OR_TAB
+#define APPLY_BY_ENTER_OR_TAB
ModuleBase_WidgetDoubleValue::ModuleBase_WidgetDoubleValue(QWidget* theParent,
const Config_WidgetAPI* theData,
#ifdef APPLY_BY_ENTER_OR_TAB
// Apply widget value change by enter/tab event.
connect(mySpinBox, SIGNAL(editingFinished()), this, SIGNAL(valuesChanged()));
+ connect(mySpinBox, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesModified()));
+
#else
connect(mySpinBox, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesChanged()));
#endif
aList.append(mySpinBox);
return aList;
}
+
+bool ModuleBase_WidgetDoubleValue::isEventProcessed(QKeyEvent* theEvent)
+{
+ return mySpinBox->isEventProcessed(theEvent);
+}
/// \return a control list
virtual QList<QWidget*> getControls() const;
+ /// Returns true if the event is processed.
+ virtual bool isEventProcessed(QKeyEvent* theEvent);
+
public slots:
// Delayed value chnged: when user starts typing something,
// it gives him a 0,5 second to finish typing, when sends valueChnaged() signal
#include <iostream>
#endif
-//#define APPLY_BY_ENTER_OR_TAB
+#define APPLY_BY_ENTER_OR_TAB
ModuleBase_WidgetIntValue::ModuleBase_WidgetIntValue(QWidget* theParent,
const Config_WidgetAPI* theData,
#ifdef APPLY_BY_ENTER_OR_TAB
// Apply widget value change by enter/tab event.
connect(mySpinBox, SIGNAL(editingFinished()), this, SIGNAL(valuesChanged()));
+ connect(mySpinBox, SIGNAL(valueChanged(int)), this, SIGNAL(valuesModified()));
#else
connect(mySpinBox, SIGNAL(valueChanged(int)), this, SIGNAL(valuesChanged()));
#endif
return aValid;
}
-bool PartSet_Module::canCommitOperation() const
+/*bool PartSet_Module::canCommitOperation() const
{
return mySketchMgr->canCommitOperation();
-}
+}*/
bool PartSet_Module::canEraseObject(const ObjectPtr& theObject) const
{
/// Returns True if the current operation can be committed. Asks the sketch manager.
/// \return a boolean value
- virtual bool canCommitOperation() const;
+ //virtual bool canCommitOperation() const;
/// Returns whether the object can be erased at the bounds of the active operation.
/// The sub-objects of the current operation can not be erased
PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule)
: QObject(theModule), myModule(theModule), myIsDragging(false), myDragDone(false),
- myIsResetCurrentValue(false), myIsMouseOverWindow(false),
+ myIsResetCurrentValue(false), myIsCurrentValueUnderModification(false), myIsMouseOverWindow(false),
myIsMouseOverViewProcessed(true), myPreviousUpdateViewerEnabled(true),
myIsPopupMenuActive(false), myIsConstraintsShown(true)
{
// redisplayed before this update, the feature presentation jumps from reset value to current.
myIsMouseOverWindow = true;
myIsResetCurrentValue = false;
+ myIsCurrentValueUnderModification = false;
// it is important to validate operation here only if sketch entity create operation is active
// because at this operation we reacts to the mouse leave/enter view port
//operationMgr()->onValidateOperation();
}
}
+void PartSet_SketcherMgr::onValuesModied()
+{
+ myIsCurrentValueUnderModification = true;
+ // update Apply enable state
+ //myIsResetCurrentValue = false;
+ //if (!isNestedCreateOperation(getCurrentOperation()))
+ // return;
+ operationMgr()->onValidateOperation();
+}
+
void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel()
{
myIsResetCurrentValue = false;
+ myIsCurrentValueUnderModification = false;
if (isNestedCreateOperation(getCurrentOperation()))
return;
AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR());
anError = aAttributeString->value().c_str();
}
- else if (myIsResetCurrentValue) { // this flag do not allow commit of the current operation
+ else if (myIsResetCurrentValue || myIsCurrentValueUnderModification) {
+ // this flags do not allow commit of the current operation
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
(getCurrentOperation());
if (aFOperation) {
if (anAttr.get())
anAttributeName = anAttr->id().c_str();
}
- anError = "Attribute \"" + anAttributeName + "\" is not initialized.";
+ if (myIsResetCurrentValue)
+ anError = "Attribute \"" + anAttributeName + "\" is not initialized.";
+ else if (myIsCurrentValueUnderModification) {
+ anError = "Attribute \"" + anAttributeName + "\" modification is not applyed. Please click \"Enter\" or \"Tab\".";
+ }
}
}
}
{
connectToPropertyPanel(false);
myIsResetCurrentValue = false;
+ myIsCurrentValueUnderModification = false;
myIsMouseOverViewProcessed = true;
operationMgr()->onValidateOperation();
if (isNestedCreateOperation(theOp))
return isNestedCreateOperation(getCurrentOperation());
}
-bool PartSet_SketcherMgr::canCommitOperation() const
+/*bool PartSet_SketcherMgr::canCommitOperation() const
{
bool aCanCommit = true;
- if (isNestedCreateOperation(getCurrentOperation()) && myIsResetCurrentValue)
+ if (isNestedCreateOperation(getCurrentOperation()) &&
+ (myIsResetCurrentValue || myIsCurrentValueUnderModification))
aCanCommit = false;
return aCanCommit;
-}
+}*/
bool PartSet_SketcherMgr::canEraseObject(const ObjectPtr& theObject) const
{
bool PartSet_SketcherMgr::canDisplayCurrentCreatedFeature() const
{
- return myIsMouseOverWindow || !myIsResetCurrentValue;
+ return myIsMouseOverWindow || (!myIsResetCurrentValue && !myIsCurrentValueUnderModification);
#ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS
qDebug(QString("canDisplayCurrentCreatedFeature: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str());
#endif
if (isToConnect) {
connect(aWidget, SIGNAL(beforeValuesChanged()),
this, SLOT(onBeforeValuesChangedInPropertyPanel()));
+ connect(aWidget, SIGNAL(valuesModified()),
+ this, SLOT(onValuesModied()));
connect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onValuesChangedInPropertyPanel()));
connect(aWidget, SIGNAL(afterValuesChanged()),
this, SLOT(onAfterValuesChangedInPropertyPanel()));
/// Returns False only if the sketch creating feature can not be visualized.
/// \return a boolean value
- bool canCommitOperation() const;
+ //bool canCommitOperation() const;
/// Returns whether the object can be erased at the bounds of the active operation.
/// Sketch sub-entities can not be erased during the sketch operation
/// Process the leave mouse of the view port. If the current operation is a create of
/// a nested sketch feature, it hides the feature in the viewer
void onLeaveViewPort();
+
+ /// Updates the flag of reset state
+ void onValuesModied();
/// Listens to the value changed signal and display the current operation feature
void onBeforeValuesChangedInPropertyPanel();
/// Listens to the signal about values are to be changed in the property panel
bool myIsDragging;
bool myDragDone;
bool myIsResetCurrentValue; /// the state that value in the property panel is reset
+ bool myIsCurrentValueUnderModification; /// the value is modified in PP but it is not applyed in the model
bool myIsMouseOverWindow; /// the state that the mouse over the view
bool myIsMouseOverViewProcessed; /// the state whether the over view state is processed by mouseMove method
bool myIsPopupMenuActive; /// the state of the popup menu is shown
static QStringList MyFeaturesForCoincedence;
-//#define APPLY_BY_ENTER_OR_TAB
+#define APPLY_BY_ENTER_OR_TAB
PartSet_WidgetPoint2D::PartSet_WidgetPoint2D(QWidget* theParent,
ModuleBase_IWorkshop* theWorkshop,
#ifdef APPLY_BY_ENTER_OR_TAB
// Apply widget value change by enter/tab event.
connect(myXSpin, SIGNAL(editingFinished()), this, SLOT(onValuesChanged()));
+ connect(myXSpin, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesModified()));
#else
connect(myXSpin, SIGNAL(valueChanged(const QString&)), this, SLOT(onValuesChanged()));
#endif
#ifdef APPLY_BY_ENTER_OR_TAB
// Apply widget value change by enter/tab event.
connect(myYSpin, SIGNAL(editingFinished()), this, SLOT(onValuesChanged()));
+ connect(myYSpin, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesModified()));
#else
connect(myYSpin, SIGNAL(valueChanged(const QString&)), this, SLOT(onValuesChanged()));
#endif
myLockApplyMgr->valuesChanged();
emit valuesChanged();
}
+
+bool PartSet_WidgetPoint2D::isEventProcessed(QKeyEvent* theEvent)
+{
+ return myXSpin->isEventProcessed(theEvent) || myXSpin->isEventProcessed(theEvent);
+}
/// Returns coordinate Y currently defined in the control
double y() const;
+ /// Returns true if the event is processed.
+ virtual bool isEventProcessed(QKeyEvent* theEvent);
+
signals:
/// Signal about selection of an existing vertex from an object
void vertexSelected();
#include <QMouseEvent>
-//#define APPLY_BY_ENTER_OR_TAB
+#define APPLY_BY_ENTER_OR_TAB
PartSet_WidgetPoint2dDistance::PartSet_WidgetPoint2dDistance(QWidget* theParent,
ModuleBase_IWorkshop* theWorkshop,
// Apply widget value change by enter/tab event.
disconnect(mySpinBox, SIGNAL(editingFinished()), this, SIGNAL(valuesChanged()));
connect(mySpinBox, SIGNAL(editingFinished()), this, SLOT(onValuesChanged()));
+ connect(mySpinBox, SIGNAL(valueChanged(double)), this, SIGNAL(valuesModified()));
#else
disconnect(mySpinBox, SIGNAL(valueChanged(double)), this, SIGNAL(valuesChanged()));
connect(mySpinBox, SIGNAL(valueChanged(double)), this, SLOT(onValuesChanged()));
emit valuesChanged();
}
+bool PartSet_WidgetPoint2dDistance::isEventProcessed(QKeyEvent* theEvent)
+{
+ return mySpinBox->isEventProcessed(theEvent);
+}
/// Set sketch instance
void setSketch(CompositeFeaturePtr theSketch) { mySketch = theSketch; }
+ /// Returns true if the event is processed.
+ virtual bool isEventProcessed(QKeyEvent* theEvent);
+
public slots:
/// Process of mouse move
/// \param theWnd a pointer to a window
}
}
+#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_ModelWidget.h>
bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
{
+ qDebug("XGUI_OperationMgr::onKeyReleased");
+ QObject* aSender = sender();
+
// Let the manager decide what to do with the given key combination.
ModuleBase_Operation* anOperation = currentOperation();
bool isAccepted = true;
switch (theEvent->key()) {
case Qt::Key_Return:
case Qt::Key_Enter: {
- emit keyEnterReleased();
- commitOperation();
+ ModuleBase_Operation* aOperation = currentOperation();
+ ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+ ModuleBase_ModelWidget* aActiveWgt = aPanel->activeWidget();
+ if (aActiveWgt && !aActiveWgt->isEventProcessed(theEvent)) {
+ qDebug("XGUI_OperationMgr::onKeyReleased accept Enter");
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(currentOperation());
+ if (!aFOperation || myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) {
+ emit keyEnterReleased();
+ commitOperation();
+ }
+ else
+ isAccepted = false;
+ }
+ //else
+ // isAccepted = false;
}
case Qt::Key_N:
case Qt::Key_P: {