Sketcher: Refactor TaskSketcherMessages to move most of the logic into Core to be reused by Assembly

This commit is contained in:
paddle
2025-07-26 08:26:22 +02:00
committed by PaddleStroke
parent ccb28af4a1
commit 35f151d99e
12 changed files with 403 additions and 270 deletions

View File

@@ -23,7 +23,6 @@ set(SketcherGui_UIC_SRCS
TaskSketcherConstraints.ui
TaskSketcherElements.ui
SketcherToolDefaultWidget.ui
TaskSketcherMessages.ui
TaskSketcherSolverAdvanced.ui
TaskSketcherValidation.ui
InsertDatum.ui
@@ -103,7 +102,6 @@ SET(SketcherGui_SRCS
SketcherToolDefaultWidget.h
TaskSketcherTool.cpp
TaskSketcherTool.h
TaskSketcherMessages.ui
TaskSketcherMessages.cpp
TaskSketcherMessages.h
TaskSketcherSolverAdvanced.ui

View File

@@ -1480,7 +1480,7 @@ QWidget* SnapSpaceAction::createWidget(QWidget* parent)
layout->addWidget(snapAngle, 1, 1);
languageChange();
#if QT_VERSION >= QT_VERSION_CHECK(6,7,0)
QObject::connect(snapToObjects, &QCheckBox::checkStateChanged, [this](int state) {
#else
@@ -1925,4 +1925,3 @@ void CreateSketcherCommands()
rcCmdMgr.addCommand(new CmdRenderingOrder());
}
// clang-format on

View File

@@ -24,6 +24,7 @@
#ifndef _PreComp_
#include <QAction>
#include <QMenu>
#include <QCheckBox>
#endif
#include <Gui/Application.h>
@@ -34,7 +35,6 @@
#include "Command.h"
#include "TaskSketcherMessages.h"
#include "ViewProviderSketch.h"
#include "ui_TaskSketcherMessages.h"
// clang-format off
@@ -43,55 +43,15 @@ using namespace Gui::TaskView;
namespace sp = std::placeholders;
TaskSketcherMessages::TaskSketcherMessages(ViewProviderSketch* sketchView)
: TaskBox(Gui::BitmapFactory().pixmap("Sketcher_Sketch"), tr("Sketch Edit"), true, nullptr)
: TaskSolverMessages(Gui::BitmapFactory().pixmap("Sketcher_Sketch"), tr("Sketch Edit"))
, sketchView(sketchView)
, ui(new Ui_TaskSketcherMessages)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
ui->setupUi(proxy);
setupConnections();
this->groupLayout()->addWidget(proxy);
createSettingsButtonActions();
//NOLINTBEGIN
connectionSetUp = sketchView->signalSetUp.connect(std::bind(
&SketcherGui::TaskSketcherMessages::slotSetUp, this, sp::_1, sp::_2, sp::_3, sp::_4));
//NOLINTEND
ui->labelConstrainStatus->setOpenExternalLinks(false);
// Set up the possible state values for the status label
ui->labelConstrainStatus->setParameterGroup(
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");
ui->labelConstrainStatus->registerState(QStringLiteral("empty_sketch"),
palette().windowText().color(),
std::string("EmptySketchMessageColor"));
ui->labelConstrainStatus->registerState(QStringLiteral("under_constrained"),
palette().windowText().color(),
std::string("UnderconstrainedMessageColor"));
ui->labelConstrainStatus->registerState(QStringLiteral("malformed_constraints"),
QColor("red"),
std::string("MalformedConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QStringLiteral("conflicting_constraints"),
QColor("orangered"),
std::string("ConflictingConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QStringLiteral("redundant_constraints"),
QColor("red"),
std::string("RedundantConstraintMessageColor"));
ui->labelConstrainStatus->registerState(
QStringLiteral("partially_redundant_constraints"),
QColor("royalblue"),
std::string("PartiallyRedundantConstraintMessageColor"));
ui->labelConstrainStatus->registerState(
QStringLiteral("solver_failed"), QColor("red"), std::string("SolverFailedMessageColor"));
ui->labelConstrainStatus->registerState(QStringLiteral("fully_constrained"),
QColor("green"),
std::string("FullyConstrainedMessageColor"));
ui->labelConstrainStatusLink->setLaunchExternal(false);
createSettingsButtonActions();
}
TaskSketcherMessages::~TaskSketcherMessages()
@@ -99,121 +59,97 @@ TaskSketcherMessages::~TaskSketcherMessages()
connectionSetUp.disconnect();
}
void TaskSketcherMessages::setupConnections()
{
connect(ui->labelConstrainStatusLink,
&Gui::UrlLabel::linkClicked,
this,
&TaskSketcherMessages::onLabelConstrainStatusLinkClicked);
connect(ui->manualUpdate,
&QToolButton::clicked,
this,
&TaskSketcherMessages::onManualUpdateClicked);
}
void TaskSketcherMessages::slotSetUp(const QString& state, const QString& msg, const QString& link,
const QString& linkText)
{
ui->labelConstrainStatus->setState(state);
ui->labelConstrainStatus->setText(msg);
ui->labelConstrainStatusLink->setUrl(link);
ui->labelConstrainStatusLink->setText(linkText);
updateToolTip(link);
}
void TaskSketcherMessages::updateToolTip(const QString& link)
{
if (link == QStringLiteral("#conflicting"))
ui->labelConstrainStatusLink->setToolTip(
tr("Click to select these conflicting constraints."));
else if (link == QStringLiteral("#redundant"))
ui->labelConstrainStatusLink->setToolTip(tr("Click to select these redundant constraints."));
else if (link == QStringLiteral("#dofs"))
ui->labelConstrainStatusLink->setToolTip(
tr("The sketch has unconstrained elements giving rise to those Degrees Of Freedom. "
"Click to select these unconstrained elements."));
else if (link == QStringLiteral("#malformed"))
ui->labelConstrainStatusLink->setToolTip(tr("Click to select these malformed constraints."));
else if (link == QStringLiteral("#partiallyredundant"))
ui->labelConstrainStatusLink->setToolTip(
if (link == QStringLiteral("#conflicting")) {
setLinkTooltip(tr("Click to select these conflicting constraints."));
}
else if (link == QStringLiteral("#redundant")) {
setLinkTooltip(tr("Click to select these redundant constraints."));
}
else if (link == QStringLiteral("#dofs")) {
setLinkTooltip(tr("The sketch has unconstrained elements giving rise to those "
"Degrees Of Freedom. Click to select these unconstrained elements."));
}
else if (link == QStringLiteral("#malformed")) {
setLinkTooltip(tr("Click to select these malformed constraints."));
}
else if (link == QStringLiteral("#partiallyredundant")) {
setLinkTooltip(
tr("Some constraints in combination are partially redundant. Click to select these "
"partially redundant constraints."));
}
}
void TaskSketcherMessages::onLabelConstrainStatusLinkClicked(const QString& str)
void TaskSketcherMessages::onLabelStatusLinkClicked(const QString& str)
{
if (str == QStringLiteral("#conflicting"))
Gui::Application::Instance->commandManager().runCommandByName(
"Sketcher_SelectConflictingConstraints");
else if (str == QStringLiteral("#redundant"))
Gui::Application::Instance->commandManager().runCommandByName(
"Sketcher_SelectRedundantConstraints");
else if (str == QStringLiteral("#dofs"))
Gui::Application::Instance->commandManager().runCommandByName(
"Sketcher_SelectElementsWithDoFs");
else if (str == QStringLiteral("#malformed"))
Gui::Application::Instance->commandManager().runCommandByName(
"Sketcher_SelectMalformedConstraints");
else if (str == QStringLiteral("#partiallyredundant"))
Gui::Application::Instance->commandManager().runCommandByName(
"Sketcher_SelectPartiallyRedundantConstraints");
}
void TaskSketcherMessages::onAutoUpdateStateChanged()
{
bool state = std::as_const(ui->settingsButton)->actions()[0]->isChecked();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
hGrp->SetBool("AutoRecompute", state);
sketchView->getSketchObject()->noRecomputes = !state;
}
void TaskSketcherMessages::onManualUpdateClicked(bool checked)
{
Q_UNUSED(checked);
Gui::Command::updateActive();
if (str == QStringLiteral("#conflicting")) {
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectConflictingConstraints");
}
else if (str == QStringLiteral("#redundant")) {
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectRedundantConstraints");
}
else if (str == QStringLiteral("#dofs")) {
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectElementsWithDoFs");
}
else if (str == QStringLiteral("#malformed")) {
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectMalformedConstraints");
}
else if (str == QStringLiteral("#partiallyredundant")) {
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectPartiallyRedundantConstraints");
}
}
void TaskSketcherMessages::createSettingsButtonActions()
{
QToolButton* btn = getSettingsButton();
btn->show();
// Set Auto Update in the 'Manual Update' button menu.
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool state = hGrp->GetBool("AutoRecompute", false);
sketchView->getSketchObject()->noRecomputes = !state;
QAction* action = new QAction(tr("Auto-update"), this);
action->setToolTip(tr("Executes a recomputation of active document after every sketch action"));
action->setCheckable(true);
action->setChecked(state);
auto* autoUpdateAction = new QWidgetAction(this);
auto* containerWidget = new QWidget();
auto* layout = new QGridLayout(containerWidget);
auto* checkbox = new QCheckBox(tr("Auto-update"));
checkbox->setToolTip(tr("Executes a recomputation of active document after every sketch action"));
checkbox->setChecked(state);
layout->addWidget(checkbox, 0, 0, 1, 2);
containerWidget->setLayout(layout);
autoUpdateAction->setDefaultWidget(containerWidget);
auto* gsa = new GridSpaceAction(this);
auto* ssa = new SnapSpaceAction(this);
auto* roa = new RenderingOrderAction(this);
QMenu* myMenu = new QMenu(this);
myMenu->addAction(action);
myMenu->addSeparator();
myMenu->addAction(gsa);
myMenu->addSeparator();
myMenu->addAction(ssa);
myMenu->addSeparator();
myMenu->addAction(roa);
ui->settingsButton->setMenu(myMenu);
QObject::connect(myMenu, &QMenu::aboutToShow, [gsa, ssa, roa]() {
gsa->updateWidget();
ssa->updateWidget(true);
roa->updateWidget();
connect(checkbox, &QCheckBox::toggled, this, [this](bool checked) {
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
hGrp->SetBool("AutoRecompute", checked);
sketchView->getSketchObject()->noRecomputes = !checked;
});
QObject::connect(ui->settingsButton, &QToolButton::clicked, ui->settingsButton, &QToolButton::showMenu);
QObject::connect(std::as_const(myMenu)->actions()[0],
&QAction::changed,
this,
&TaskSketcherMessages::onAutoUpdateStateChanged);
auto* gridAction = new GridSpaceAction(this);
auto* snapAction = new SnapSpaceAction(this);
auto* renderingAction = new RenderingOrderAction(this);
QMenu* myMenu = new QMenu(this);
myMenu->addAction(autoUpdateAction);
myMenu->addSeparator();
myMenu->addAction(gridAction);
myMenu->addSeparator();
myMenu->addAction(snapAction);
myMenu->addSeparator();
myMenu->addAction(renderingAction);
btn->setMenu(myMenu);
QObject::connect(myMenu, &QMenu::aboutToShow, [gridAction, snapAction, renderingAction]() {
gridAction->updateWidget();
snapAction->updateWidget(true);
renderingAction->updateWidget();
});
QObject::connect(btn, &QToolButton::clicked, btn, &QToolButton::showMenu);
}
#include "moc_TaskSketcherMessages.cpp"

View File

@@ -23,25 +23,14 @@
#ifndef GUI_TASKVIEW_TaskSketcherMessages_H
#define GUI_TASKVIEW_TaskSketcherMessages_H
#include <boost/signals2.hpp>
#include <Gui/TaskView/TaskView.h>
class Ui_TaskSketcherMessages;
using Connection = boost::signals2::connection;
namespace App
{
class Property;
}
#include <Gui/TaskView/TaskSolverMessages.h>
namespace SketcherGui
{
class ViewProviderSketch;
class TaskSketcherMessages: public Gui::TaskView::TaskBox
class TaskSketcherMessages: public Gui::TaskSolverMessages
{
Q_OBJECT
@@ -49,27 +38,14 @@ public:
explicit TaskSketcherMessages(ViewProviderSketch* sketchView);
~TaskSketcherMessages() override;
void slotSetUp(const QString& state,
const QString& msg,
const QString& link,
const QString& linkText);
private:
void setupConnections();
void createSettingsButtonActions();
void onLabelConstrainStatusLinkClicked(const QString&);
void onAutoUpdateStateChanged();
void onManualUpdateClicked(bool checked);
void createSettingsButtonActions() override;
void onLabelStatusLinkClicked(const QString&) override;
void updateToolTip(const QString& link);
void updateToolTip(const QString& link) override;
protected:
ViewProviderSketch* sketchView;
Connection connectionSetUp;
private:
QWidget* proxy;
std::unique_ptr<Ui_TaskSketcherMessages> ui;
};
} // namespace SketcherGui

View File

@@ -1,96 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskSketcherMessages</class>
<widget class="QWidget" name="TaskSketcherMessages">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>253</width>
<height>48</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="Gui::StatefulLabel" name="labelConstrainStatus">
<property name="text">
<string>DOF</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::UrlLabel" name="labelConstrainStatusLink">
<property name="text">
<string>Link</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="manualUpdate">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Forces the recomputation of the active document</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/icons/view-refresh.svg</normaloff>:/icons/view-refresh.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="settingsButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Sketch edit settings</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="Resources/Sketcher.qrc">
<normaloff>:/icons/dialogs/Sketcher_Settings.svg</normaloff>:/icons/dialogs/Sketcher_Settings.svg</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::StatefulLabel</class>
<extends>QLabel</extends>
<header>Gui/Widgets.h</header>
</customwidget>
<customwidget>
<class>Gui::UrlLabel</class>
<extends>QLabel</extends>
<header>Gui/Widgets.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -3259,7 +3259,7 @@ void ViewProviderSketch::UpdateSolverInformation()
bool hasMalformed = getSketchObject()->getLastHasMalformedConstraints();
if (getSketchObject()->Geometry.getSize() == 0) {
signalSetUp(QStringLiteral("empty_sketch"), tr("Empty sketch"), QString(), QString());
signalSetUp(QStringLiteral("empty"), tr("Empty sketch"), QString(), QString());
}
else if (dofs < 0 || hasConflicts) {// over-constrained sketch
signalSetUp(