Sketcher: Do not allow mouse interruption while entering dimension (#20925)

* Sketcher: Do not allow mouse interruption while entering dimensions

So, currently user has an option to enter dimensions to different
Sketcher elements like circle, line, or hexagon, whatever else. But, if
they move mouse during entering of those parameters, they are gone.

This is because we are currently allowing for constant
`QAbstractSpinBox` value change during mouse move, it stops changing
ONLY AFTER value is being set (user enters number and presses ENTER
or TAB).

So, this patch introduces one more state for `EditableDatumLabel` which
is `hasFinishedEditing` which is being triggered by ENTER or TAB key,
and still keeping old `isSet` state, which disallows mouse movement
disruption and dynamically updates the edited element on viewport.
This means, that all objects now wait for `hasFinishedEditing` state to
actually finish editing.

* Sketcher: Avoid out of boundary access by checking onViewParameters size

* Sketcher: Add missing Qt headers for CI

* Sketcher: Allow using TAB to switch between labels without accepting

* Sketcher: Change to or statement, so enter will accept both labels

* Sketcher: Apply review comments

* used casting directly in if statement and auto to keep linter happy
* added comments for flags used for describing EditableDatumLabel states
This commit is contained in:
tetektoza
2025-06-02 22:18:42 +02:00
committed by GitHub
parent 997d485124
commit 9b40afea7a
17 changed files with 81 additions and 54 deletions

View File

@@ -31,6 +31,9 @@
# include <Inventor/nodes/SoSwitch.h>
#endif // _PreComp_
#include <QEvent>
#include <QKeyEvent>
#include <Gui/Application.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
@@ -52,6 +55,7 @@ EditableDatumLabel::EditableDatumLabel(View3DInventorViewer* view,
bool autoDistance,
bool avoidMouseCursor)
: isSet(false)
, hasFinishedEditing(false)
, autoDistance(autoDistance)
, autoDistanceReverse(false)
, avoidMouseCursor(avoidMouseCursor)
@@ -158,7 +162,8 @@ void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj, bool
spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
spinBox->setFocusPolicy(Qt::ClickFocus); // prevent passing focus with tab.
spinBox->setAutoNormalize(false);
spinBox->setKeyboardTracking(false);
spinBox->setKeyboardTracking(true);
spinBox->installEventFilter(this);
if (eventFilteringObj) {
spinBox->installEventFilter(eventFilteringObj);
@@ -190,6 +195,23 @@ void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj, bool
connect(spinBox, qOverload<double>(&QuantitySpinBox::valueChanged), this, validateAndFinish);
}
bool EditableDatumLabel::eventFilter(QObject* watched, QEvent* event)
{
if (event->type() == QEvent::KeyPress) {
auto* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
if (auto* spinBox = qobject_cast<QAbstractSpinBox*>(watched)) {
this->hasFinishedEditing = true;
Q_EMIT this->valueChanged(this->value);
return false;
}
}
}
return QObject::eventFilter(watched, event);
}
void EditableDatumLabel::stopEdit()
{
if (spinBox) {

View File

@@ -84,7 +84,8 @@ public:
// NOLINTBEGIN
SoDatumLabel* label;
bool isSet;
bool isSet; ///< used to differentiate when user has started typing inside the label
bool hasFinishedEditing; ///< flag to know when user has finished editing, i.e. pressed enter
bool autoDistance;
bool autoDistanceReverse;
bool avoidMouseCursor;
@@ -94,6 +95,9 @@ public:
Q_SIGNALS:
void valueChanged(double val);
protected:
bool eventFilter(QObject* watched, QEvent* event) override;
private:
void positionSpinbox();
SbVec3f getTextCenterPoint() const;

View File

@@ -367,11 +367,6 @@ public:
void tryViewValueChanged(int onviewparameterindex, double value)
{
int nextindex = onviewparameterindex + 1;
if (isOnViewParameterOfCurrentMode(nextindex)) {
setFocusToOnViewParameter(nextindex);
}
/* That is not supported with on-view parameters.
// -> A machine does not forward to a next state when adapting the parameter (though it
// may forward to
@@ -630,6 +625,7 @@ protected:
void unsetOnViewParameter(Gui::EditableDatumLabel* onViewParameter)
{
onViewParameter->isSet = false;
onViewParameter->hasFinishedEditing = false;
onViewParameter->setColor(colorManager.dimConstrDeactivatedColor);
}

View File

@@ -716,22 +716,22 @@ void DSHArcController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
handler->setState(SelectMode::SeekThird);
}
} break;
case SelectMode::SeekThird: {
if (handler->constructionMethod() == DrawSketchHandlerArc::ConstructionMethod::Center) {
if (onViewParameters[OnViewParameter::Fifth]->isSet) {
if (onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}
}
else {
if (onViewParameters[OnViewParameter::Fifth]->isSet
&& onViewParameters[OnViewParameter::Sixth]->isSet) {
if (onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}

View File

@@ -772,20 +772,20 @@ void DSHArcSlotController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
handler->setState(SelectMode::SeekThird);
}
} break;
case SelectMode::SeekThird: {
if (onViewParameters[OnViewParameter::Fifth]->isSet) {
if (onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing) {
handler->setState(SelectMode::SeekFourth);
}
} break;
case SelectMode::SeekFourth: {
if (onViewParameters[OnViewParameter::Sixth]->isSet) {
if (onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}

View File

@@ -1083,8 +1083,8 @@ void DSHBSplineController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
handler->canGoToNextMode(); // its not going to next mode
unsetOnViewParameter(onViewParameters[OnViewParameter::Third].get());

View File

@@ -598,13 +598,13 @@ void DSHCircleController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing
&& handler->constructionMethod()
== DrawSketchHandlerCircle::ConstructionMethod::Center) {
handler->setState(SelectMode::End);
}
else if (onViewParameters[OnViewParameter::Third]->isSet
else if (onViewParameters.size() > 3 && onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet
&& handler->constructionMethod()
== DrawSketchHandlerCircle::ConstructionMethod::ThreeRim) {
@@ -613,8 +613,8 @@ void DSHCircleController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekThird: {
if (onViewParameters[OnViewParameter::Fifth]->isSet
&& onViewParameters[OnViewParameter::Sixth]->isSet) {
if (onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}

View File

@@ -694,8 +694,8 @@ void DSHEllipseController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
handler->setState(SelectMode::SeekThird);
}
@@ -703,14 +703,14 @@ void DSHEllipseController::doChangeDrawSketchHandlerMode()
case SelectMode::SeekThird: {
if (handler->constructionMethod()
== DrawSketchHandlerEllipse::ConstructionMethod::Center) {
if (onViewParameters[OnViewParameter::Fifth]->isSet) {
if (onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}
}
else {
if (onViewParameters[OnViewParameter::Fifth]->isSet
&& onViewParameters[OnViewParameter::Sixth]->isSet) {
if (onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}

View File

@@ -564,8 +564,8 @@ void DSHLineController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}

View File

@@ -1198,7 +1198,7 @@ void DSHOffsetController::doChangeDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
if (onViewParameters[OnViewParameter::First]->isSet) {
if (onViewParameters[OnViewParameter::First]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}
} break;

View File

@@ -237,8 +237,8 @@ void DSHPointController::doChangeDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
if (onViewParameters[OnViewParameter::First]->isSet
&& onViewParameters[OnViewParameter::Second]->isSet) {
if (onViewParameters[OnViewParameter::First]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Second]->hasFinishedEditing) {
handler->setState(SelectMode::End);
// handler->finish(); // Called by the change of mode

View File

@@ -450,8 +450,8 @@ void DSHPolygonController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}

View File

@@ -2346,8 +2346,8 @@ void DSHRectangleController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
if (handler->roundCorners || handler->makeFrame
|| handler->constructionMethod() == ConstructionMethod::ThreePoints
@@ -2363,7 +2363,8 @@ void DSHRectangleController::doChangeDrawSketchHandlerMode()
case SelectMode::SeekThird: {
if (handler->constructionMethod() == ConstructionMethod::Diagonal
|| handler->constructionMethod() == ConstructionMethod::CenterAndCorner) {
if (handler->roundCorners && onViewParameters[OnViewParameter::Fifth]->isSet) {
if (handler->roundCorners
&& onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing) {
if (handler->makeFrame) {
handler->setState(SelectMode::SeekFourth);
@@ -2372,14 +2373,15 @@ void DSHRectangleController::doChangeDrawSketchHandlerMode()
handler->setState(SelectMode::End);
}
}
else if (handler->makeFrame && onViewParameters[OnViewParameter::Sixth]->isSet) {
else if (handler->makeFrame
&& onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}
}
else {
if (onViewParameters[OnViewParameter::Fifth]->isSet
&& onViewParameters[OnViewParameter::Sixth]->isSet) {
if (onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
if (handler->roundCorners || handler->makeFrame) {
handler->setState(SelectMode::SeekFourth);
}
@@ -2392,12 +2394,13 @@ void DSHRectangleController::doChangeDrawSketchHandlerMode()
case SelectMode::SeekFourth: {
if (handler->constructionMethod() == ConstructionMethod::Diagonal
|| handler->constructionMethod() == ConstructionMethod::CenterAndCorner) {
if (onViewParameters[OnViewParameter::Sixth]->isSet) {
if (onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}
}
else {
if (handler->roundCorners && onViewParameters[OnViewParameter::Seventh]->isSet) {
if (handler->roundCorners
&& onViewParameters[OnViewParameter::Seventh]->hasFinishedEditing) {
if (handler->makeFrame) {
handler->setState(SelectMode::SeekFifth);
@@ -2406,13 +2409,15 @@ void DSHRectangleController::doChangeDrawSketchHandlerMode()
handler->setState(SelectMode::End);
}
}
else if (handler->makeFrame && onViewParameters[OnViewParameter::Eighth]->isSet) {
else if (handler->makeFrame
&& onViewParameters[OnViewParameter::Eighth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}
}
} break;
case SelectMode::SeekFifth: {
if (handler->makeFrame && onViewParameters[OnViewParameter::Eighth]->isSet) {
if (handler->makeFrame
&& onViewParameters[OnViewParameter::Eighth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}
} break;

View File

@@ -657,7 +657,7 @@ void DSHRotateController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing) {
handler->totalAngle =
Base::toRadians(onViewParameters[OnViewParameter::Third]->getValue());
@@ -665,7 +665,7 @@ void DSHRotateController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekThird: {
if (onViewParameters[OnViewParameter::Fourth]->isSet) {
if (onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}

View File

@@ -497,7 +497,7 @@ void DSHScaleController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekThird: {
if (onViewParameters[OnViewParameter::Third]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}

View File

@@ -535,14 +535,14 @@ void DSHSlotController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
handler->setState(SelectMode::SeekThird);
}
} break;
case SelectMode::SeekThird: {
if (onViewParameters[OnViewParameter::Fifth]->isSet) {
if (onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}

View File

@@ -703,8 +703,8 @@ void DSHTranslateController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekSecond: {
if (onViewParameters[OnViewParameter::Third]->isSet
&& onViewParameters[OnViewParameter::Fourth]->isSet) {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
if (handler->secondNumberOfCopies == 1) {
handler->setState(SelectMode::End);
@@ -715,8 +715,8 @@ void DSHTranslateController::doChangeDrawSketchHandlerMode()
}
} break;
case SelectMode::SeekThird: {
if (onViewParameters[OnViewParameter::Fifth]->isSet
&& onViewParameters[OnViewParameter::Sixth]->isSet) {
if (onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing
|| onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
}