From be8b2de07d14bc6cb8a040830cafe7f14c410b02 Mon Sep 17 00:00:00 2001 From: Murmele Date: Mon, 9 Dec 2024 18:08:02 +0100 Subject: [PATCH] Add possiblity to autosave current measurement and restarting new measurement (#17717) * initial commit to implement more interactive measurement functionality Files: TaskMeasure.cpp and TaskMeasure.h * Enable artifacts for easy download Files: sub_buildWindows.yml * clearSelection before setting new selection Files: TaskMeasure.cpp * No need for mSkipSelectionChange Reason/Description: Because the next onSelectionChanged will be triggered asynchronly Files: TaskMeasure.cpp and TaskMeasure.h * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * block selection * Block selection must be done on the taskMeasure, because it is the signal observer * Set autosave to false by default Reason/Description: Because the measurement tool is intended to be a temporary tool Files: TaskMeasure.cpp and TaskMeasure.h * Add tooltip Files: TaskMeasure.cpp * No need to set the selection style Reason: Because it was changed to normal, so no need to re set it Files: TaskMeasure.cpp * No need to clear and reset the selection Reason/Description: Because it will be done directly in the application. It was required with greedy selection, but now it is anymore required Files: TaskMeasure.cpp * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Revert "Enable artifacts for easy download" This reverts commit 8118323ab4104ada1fb89eebbe72965c5f2f2b67. * Move autosave and selection mode into a group box and add a possibility to hide those options Files: TaskMeasure.cpp and TaskMeasure.h * Use toolbutton with a normal menu instead of a normal QPushButton Reason/Description: Because it integrates much better Files: TaskMeasure.cpp and TaskMeasure.h * QAction uses a bool for the checkstate Files: TaskMeasure.cpp and TaskMeasure.h * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix compile warnings Reason/Description: cleanup and fix warnings Files: TaskMeasure.cpp and TaskMeasure.h * Add better tool tip * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix typo --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/Mod/Measure/Gui/TaskMeasure.cpp | 106 ++++++++++++++++++++++++++-- src/Mod/Measure/Gui/TaskMeasure.h | 7 ++ 2 files changed, 106 insertions(+), 7 deletions(-) diff --git a/src/Mod/Measure/Gui/TaskMeasure.cpp b/src/Mod/Measure/Gui/TaskMeasure.cpp index e4663bb6f0..0098f1e8be 100644 --- a/src/Mod/Measure/Gui/TaskMeasure.cpp +++ b/src/Mod/Measure/Gui/TaskMeasure.cpp @@ -41,8 +41,12 @@ #include #include +#include #include #include +#include +#include +#include using namespace Gui; @@ -50,6 +54,10 @@ namespace { constexpr auto taskMeasureSettingsGroup = "TaskMeasure"; constexpr auto taskMeasureShowDeltaSettingsName = "ShowDelta"; +constexpr auto taskMeasureAutoSaveSettingsName = "AutoSave"; +constexpr auto taskMeasureGreedySelection = "GreedySelection"; + +using SelectionStyle = Gui::SelectionSingleton::SelectionStyle; } // namespace TaskMeasure::TaskMeasure() @@ -64,13 +72,51 @@ TaskMeasure::TaskMeasure() QSettings settings; settings.beginGroup(QLatin1String(taskMeasureSettingsGroup)); - delta = settings.value(QLatin1String(taskMeasureShowDeltaSettingsName), true).toBool(); + delta = settings.value(QLatin1String(taskMeasureShowDeltaSettingsName), delta).toBool(); + mAutoSave = settings.value(QLatin1String(taskMeasureAutoSaveSettingsName), mAutoSave).toBool(); + if (settings.value(QLatin1String(taskMeasureGreedySelection), false).toBool()) { + Gui::Selection().setSelectionStyle(SelectionStyle::GreedySelection); + } + else { + Gui::Selection().setSelectionStyle(SelectionStyle::NormalSelection); + } showDelta = new QCheckBox(); showDelta->setChecked(delta); showDeltaLabel = new QLabel(tr("Show Delta:")); connect(showDelta, &QCheckBox::stateChanged, this, &TaskMeasure::showDeltaChanged); + autoSaveAction = new QAction(tr("Auto Save")); + autoSaveAction->setCheckable(true); + autoSaveAction->setChecked(mAutoSave); + autoSaveAction->setToolTip(tr("Auto saving of the last measurement when starting a new " + "measurement. Use SHIFT to temporarily invert the behaviour.")); + connect(autoSaveAction, &QAction::triggered, this, &TaskMeasure::autoSaveChanged); + + newMeasurementBehaviourAction = new QAction(tr("Additive Selection")); + newMeasurementBehaviourAction->setCheckable(true); + newMeasurementBehaviourAction->setChecked(Gui::Selection().getSelectionStyle() + == SelectionStyle::GreedySelection); + newMeasurementBehaviourAction->setToolTip( + tr("If checked, new selection will be added to the measurement. If unchecked, CTRL must be " + "pressed to add a " + "selection to the current measurement otherwise a new measurement will be started")); + connect(newMeasurementBehaviourAction, + &QAction::triggered, + this, + &TaskMeasure::newMeasurementBehaviourChanged); + + mSettings = new QToolButton(); + mSettings->setToolTip(tr("Settings")); + mSettings->setIcon(QIcon(QStringLiteral(":/icons/dialogs/Sketcher_Settings.svg"))); + auto* menu = new QMenu(mSettings); + menu->setToolTipsVisible(true); + mSettings->setMenu(menu); + + menu->addAction(autoSaveAction); + menu->addAction(newMeasurementBehaviourAction); + connect(mSettings, &QToolButton::clicked, mSettings, &QToolButton::showMenu); + // Create mode dropdown and add all registered measuretypes modeSwitch = new QComboBox(); modeSwitch->addItem(QString::fromLatin1("Auto")); @@ -98,6 +144,10 @@ TaskMeasure::TaskMeasure() // formLayout->setFieldGrowthPolicy(QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow); formLayout->setFormAlignment(Qt::AlignCenter); + auto* settingsLayout = new QHBoxLayout(); + settingsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding)); + settingsLayout->addWidget(mSettings); + formLayout->addRow(QStringLiteral(), settingsLayout); formLayout->addRow(tr("Mode:"), modeSwitch); formLayout->addRow(showDeltaLabel, showDelta); formLayout->addRow(tr("Result:"), valueResult); @@ -108,9 +158,6 @@ TaskMeasure::TaskMeasure() // engage the selectionObserver attachSelection(); - // Set selection style - Gui::Selection().setSelectionStyle(Gui::SelectionSingleton::SelectionStyle::GreedySelection); - if (!App::GetApplication().getActiveTransaction()) { App::GetApplication().setActiveTransaction("Add Measurement"); } @@ -122,7 +169,7 @@ TaskMeasure::TaskMeasure() TaskMeasure::~TaskMeasure() { - Gui::Selection().setSelectionStyle(Gui::SelectionSingleton::SelectionStyle::NormalSelection); + Gui::Selection().setSelectionStyle(SelectionStyle::NormalSelection); detachSelection(); qApp->removeEventFilter(this); } @@ -134,7 +181,7 @@ void TaskMeasure::modifyStandardButtons(QDialogButtonBox* box) QPushButton* btn = box->button(QDialogButtonBox::Apply); btn->setText(tr("Save")); btn->setToolTip(tr("Save the measurement in the active document.")); - connect(btn, &QPushButton::released, this, &TaskMeasure::apply); + connect(btn, &QPushButton::released, this, qOverload<>(&TaskMeasure::apply)); // Disable button by default btn->setEnabled(false); @@ -342,10 +389,17 @@ void TaskMeasure::invoke() } bool TaskMeasure::apply() +{ + return apply(true); +} + +bool TaskMeasure::apply(bool reset) { ensureGroup(_mMeasureObject); _mMeasureObject = nullptr; - reset(); + if (reset) { + this->reset(); + } // Commit transaction App::GetApplication().closeActiveTransaction(); @@ -409,6 +463,21 @@ void TaskMeasure::onSelectionChanged(const Gui::SelectionChanges& msg) return; } + // If the control modifier is pressed, the object is just added to the current measurement + // If the control modifier is not pressed, a new measurement will be started. If autosave is on, + // the old measurement will be saved otherwise discharded. Shift inverts the autosave behaviour + // temporarly + const auto modifier = QGuiApplication::keyboardModifiers(); + const bool ctrl = (modifier & Qt::ControlModifier) > 0; + const bool shift = (modifier & Qt::ShiftModifier) > 0; + // shift inverts the current state temporarly + const auto autosave = (mAutoSave && !shift) || (!mAutoSave && shift); + if ((!ctrl && Selection().getSelectionStyle() == SelectionStyle::NormalSelection) + || (ctrl && Selection().getSelectionStyle() == SelectionStyle::GreedySelection)) { + if (autosave && this->buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) { + apply(false); + } + } update(); } @@ -465,6 +534,29 @@ void TaskMeasure::showDeltaChanged(int checkState) this->update(); } +void TaskMeasure::autoSaveChanged(bool checked) +{ + mAutoSave = checked; + + QSettings settings; + settings.beginGroup(QLatin1String(taskMeasureSettingsGroup)); + settings.setValue(QLatin1String(taskMeasureAutoSaveSettingsName), mAutoSave); +} + +void TaskMeasure::newMeasurementBehaviourChanged(bool checked) +{ + QSettings settings; + settings.beginGroup(QLatin1String(taskMeasureSettingsGroup)); + if (!checked) { + Gui::Selection().setSelectionStyle(SelectionStyle::NormalSelection); + settings.setValue(QLatin1String(taskMeasureGreedySelection), false); + } + else { + Gui::Selection().setSelectionStyle(SelectionStyle::GreedySelection); + settings.setValue(QLatin1String(taskMeasureGreedySelection), true); + } +} + void TaskMeasure::setModeSilent(App::MeasureType* mode) { modeSwitch->blockSignals(true); diff --git a/src/Mod/Measure/Gui/TaskMeasure.h b/src/Mod/Measure/Gui/TaskMeasure.h index 50d8be4493..88e280317a 100644 --- a/src/Mod/Measure/Gui/TaskMeasure.h +++ b/src/Mod/Measure/Gui/TaskMeasure.h @@ -61,6 +61,7 @@ public: void update(); void close(); bool apply(); + bool apply(bool reset); bool reject() override; void reset(); @@ -77,10 +78,15 @@ private: QComboBox* modeSwitch {nullptr}; QCheckBox* showDelta {nullptr}; QLabel* showDeltaLabel {nullptr}; + QAction* autoSaveAction {nullptr}; + QAction* newMeasurementBehaviourAction {nullptr}; + QToolButton* mSettings {nullptr}; void removeObject(); void onModeChanged(int index); void showDeltaChanged(int checkState); + void autoSaveChanged(bool checked); + void newMeasurementBehaviourChanged(bool checked); void setModeSilent(App::MeasureType* mode); App::MeasureType* getMeasureType(); void enableAnnotateButton(bool state); @@ -94,6 +100,7 @@ private: // Stores if delta measures shall be shown bool delta = true; + bool mAutoSave = false; }; } // namespace Gui