From 3876f23f4d26c280f4acb551f00a42b82b3eab25 Mon Sep 17 00:00:00 2001 From: pavltom Date: Thu, 16 Nov 2023 16:43:13 +0100 Subject: [PATCH] [TechDraw] Multiselection mode implementation --- .../TechDraw/Gui/DlgPrefsTechDrawGeneral.ui | 56 +++++++++++++++++++ .../Gui/DlgPrefsTechDrawGeneralImp.cpp | 6 ++ src/Mod/TechDraw/Gui/PreferencesGui.cpp | 5 ++ src/Mod/TechDraw/Gui/PreferencesGui.h | 1 + src/Mod/TechDraw/Gui/QGEPath.h | 1 + src/Mod/TechDraw/Gui/QGIEdge.h | 2 + src/Mod/TechDraw/Gui/QGIFace.h | 2 + src/Mod/TechDraw/Gui/QGIPrimPath.cpp | 49 ++++++++++++++++ src/Mod/TechDraw/Gui/QGIPrimPath.h | 6 ++ src/Mod/TechDraw/Gui/QGIVertex.h | 2 + src/Mod/TechDraw/Gui/QGIView.cpp | 32 ++++++++++- src/Mod/TechDraw/Gui/QGIView.h | 1 + 12 files changed, 162 insertions(+), 1 deletion(-) diff --git a/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneral.ui b/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneral.ui index 5d667e56e6..7d16326e2f 100644 --- a/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneral.ui +++ b/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneral.ui @@ -867,6 +867,62 @@ for ProjectionGroups + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 100 + + + + Selection + + + + + + + + + 0 + 0 + + + + If enabled, clicking without Ctrl does not clear existing vertex/edge/face selection + + + Enable Multiselection Mode + + + false + + + multiSelection + + + Mod/TechDraw/General + + + + + + + + diff --git a/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneralImp.cpp b/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneralImp.cpp index 2c1020e5da..35ffd23d7b 100644 --- a/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneralImp.cpp +++ b/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneralImp.cpp @@ -71,6 +71,8 @@ void DlgPrefsTechDrawGeneralImp::saveSettings() ui->le_NamePattern->onSave(); ui->cb_ShowGrid->onSave(); ui->psb_GridSpacing->onSave(); + + ui->cbMultiSelection->onSave(); } void DlgPrefsTechDrawGeneralImp::loadSettings() @@ -107,6 +109,10 @@ void DlgPrefsTechDrawGeneralImp::loadSettings() double spacingDefault = PreferencesGui::gridSpacing(); ui->psb_GridSpacing->setValue(spacingDefault); ui->psb_GridSpacing->onRestore(); + + bool multiSelectionDefault = PreferencesGui::multiSelection(); + ui->cbMultiSelection->setChecked(multiSelectionDefault); + ui->cbMultiSelection->onRestore(); } /** diff --git a/src/Mod/TechDraw/Gui/PreferencesGui.cpp b/src/Mod/TechDraw/Gui/PreferencesGui.cpp index 43ead436dc..8f106b032c 100644 --- a/src/Mod/TechDraw/Gui/PreferencesGui.cpp +++ b/src/Mod/TechDraw/Gui/PreferencesGui.cpp @@ -206,6 +206,11 @@ bool PreferencesGui::showGrid() return Preferences::getPreferenceGroup("General")->GetBool("showGrid", false); } +bool PreferencesGui::multiSelection() +{ + return Preferences::getPreferenceGroup("General")->GetBool("multiSelection", false); +} + App::Color PreferencesGui::pageColor() { App::Color result; diff --git a/src/Mod/TechDraw/Gui/PreferencesGui.h b/src/Mod/TechDraw/Gui/PreferencesGui.h index b000e4dcce..6c877bc1c7 100644 --- a/src/Mod/TechDraw/Gui/PreferencesGui.h +++ b/src/Mod/TechDraw/Gui/PreferencesGui.h @@ -72,6 +72,7 @@ static bool showGrid(); static App::Color gridColor(); static QColor gridQColor(); static double gridSpacing(); +static bool multiSelection(); static QColor getAccessibleQColor(QColor orig); static QColor lightTextQColor(); diff --git a/src/Mod/TechDraw/Gui/QGEPath.h b/src/Mod/TechDraw/Gui/QGEPath.h index c03298fec0..bc63b4c9d3 100644 --- a/src/Mod/TechDraw/Gui/QGEPath.h +++ b/src/Mod/TechDraw/Gui/QGEPath.h @@ -63,6 +63,7 @@ Q_SIGNALS: void endEdit(); protected: + bool multiselectEligible() override { return false; } void mousePressEvent(QGraphicsSceneMouseEvent *event) override; private: diff --git a/src/Mod/TechDraw/Gui/QGIEdge.h b/src/Mod/TechDraw/Gui/QGIEdge.h index 1bc54dc2bc..4667ce45f9 100644 --- a/src/Mod/TechDraw/Gui/QGIEdge.h +++ b/src/Mod/TechDraw/Gui/QGIEdge.h @@ -57,6 +57,8 @@ protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; + bool multiselectEligible() override { return true; } + int projIndex; //index of edge in Projection. must exist. bool isCosmetic; diff --git a/src/Mod/TechDraw/Gui/QGIFace.h b/src/Mod/TechDraw/Gui/QGIFace.h index 0242025f77..18323799b5 100644 --- a/src/Mod/TechDraw/Gui/QGIFace.h +++ b/src/Mod/TechDraw/Gui/QGIFace.h @@ -150,6 +150,8 @@ protected: bool m_hideSvgTiles; + bool multiselectEligible() override { return true; } + private: QPixmap m_texture; // diff --git a/src/Mod/TechDraw/Gui/QGIPrimPath.cpp b/src/Mod/TechDraw/Gui/QGIPrimPath.cpp index 41fbdeecc2..c7b1d3263a 100644 --- a/src/Mod/TechDraw/Gui/QGIPrimPath.cpp +++ b/src/Mod/TechDraw/Gui/QGIPrimPath.cpp @@ -32,6 +32,10 @@ #include +#include + +#include + #include "QGIPrimPath.h" #include "PreferencesGui.h" #include "QGIView.h" @@ -55,6 +59,7 @@ QGIPrimPath::QGIPrimPath(): setAcceptHoverEvents(true); isHighlighted = false; + multiselectActivated = false; m_colOverride = false; m_colNormal = getNormalColor(); @@ -259,6 +264,50 @@ Qt::PenCapStyle QGIPrimPath::prefCapStyle() return result; } +void QGIPrimPath::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Qt::KeyboardModifiers originalModifiers = event->modifiers(); + if (event->button()&Qt::LeftButton) { + multiselectActivated = false; + } + + if (event->button() == Qt::LeftButton + && multiselectEligible() + && PreferencesGui::multiSelection()) { + + auto parent = dynamic_cast(parentItem()); + if (parent) { + std::vector selection = Gui::Selection().getSelectionEx(); + if (selection.size() == 1 + && selection.front().getObject() == parent->getViewObject()) { + + multiselectActivated = true; + event->setModifiers(originalModifiers | Qt::ControlModifier); + } + } + } + + QGraphicsPathItem::mousePressEvent(event); + + event->setModifiers(originalModifiers); +} + +void QGIPrimPath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Qt::KeyboardModifiers originalModifiers = event->modifiers(); + if ((event->button()&Qt::LeftButton) && multiselectActivated) { + if (PreferencesGui::multiSelection()) { + event->setModifiers(originalModifiers | Qt::ControlModifier); + } + + multiselectActivated = false; + } + + QGraphicsPathItem::mouseReleaseEvent(event); + + event->setModifiers(originalModifiers); +} + void QGIPrimPath::setFill(QColor c, Qt::BrushStyle s) { setFillColor(c); m_fillNormal = s; diff --git a/src/Mod/TechDraw/Gui/QGIPrimPath.h b/src/Mod/TechDraw/Gui/QGIPrimPath.h index 18bb711549..09acc6f03e 100644 --- a/src/Mod/TechDraw/Gui/QGIPrimPath.h +++ b/src/Mod/TechDraw/Gui/QGIPrimPath.h @@ -79,6 +79,11 @@ protected: void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; + virtual bool multiselectEligible() { return false; } + + void mousePressEvent(QGraphicsSceneMouseEvent *event) override; + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + virtual QColor getNormalColor(); virtual QColor getPreColor(); virtual QColor getSelectColor(); @@ -86,6 +91,7 @@ protected: virtual Qt::PenCapStyle prefCapStyle(); bool isHighlighted; + bool multiselectActivated; QPen m_pen; QColor m_colCurrent; diff --git a/src/Mod/TechDraw/Gui/QGIVertex.h b/src/Mod/TechDraw/Gui/QGIVertex.h index 31ed77576c..65fdaa69c6 100644 --- a/src/Mod/TechDraw/Gui/QGIVertex.h +++ b/src/Mod/TechDraw/Gui/QGIVertex.h @@ -46,6 +46,8 @@ public: virtual void setRadius(float r); protected: + bool multiselectEligible() override { return true; } + int projIndex; float m_radius; diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index 6de49b0997..d144e33c6b 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -70,7 +70,8 @@ QGIView::QGIView() :QGraphicsItemGroup(), viewObj(nullptr), m_locked(false), - m_innerView(false) + m_innerView(false), + m_multiselectActivated(false) { setCacheMode(QGraphicsItem::NoCache); setHandlesChildEvents(false); @@ -199,7 +200,25 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value) void QGIView::mousePressEvent(QGraphicsSceneMouseEvent * event) { // Base::Console().Message("QGIV::mousePressEvent() - %s\n", getViewName()); + Qt::KeyboardModifiers originalModifiers = event->modifiers(); + if (event->button()&Qt::LeftButton) { + m_multiselectActivated = false; + } + + if (event->button() == Qt::LeftButton && PreferencesGui::multiSelection()) { + std::vector selection = Gui::Selection().getSelectionEx(); + if (selection.size() == 1 + && selection.front().getObject() == getViewObject() + && selection.front().hasSubNames()) { + + m_multiselectActivated = true; + event->setModifiers(originalModifiers | Qt::ControlModifier); + } + } + QGraphicsItemGroup::mousePressEvent(event); + + event->setModifiers(originalModifiers); } void QGIView::mouseMoveEvent(QGraphicsSceneMouseEvent * event) @@ -210,7 +229,18 @@ void QGIView::mouseMoveEvent(QGraphicsSceneMouseEvent * event) void QGIView::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) { // Base::Console().Message("QGIV::mouseReleaseEvent() - %s\n", getViewName()); + Qt::KeyboardModifiers originalModifiers = event->modifiers(); + if ((event->button()&Qt::LeftButton) && m_multiselectActivated) { + if (PreferencesGui::multiSelection()) { + event->setModifiers(originalModifiers | Qt::ControlModifier); + } + + m_multiselectActivated = false; + } + QGraphicsItemGroup::mouseReleaseEvent(event); + + event->setModifiers(originalModifiers); } void QGIView::hoverEnterEvent(QGraphicsSceneHoverEvent *event) diff --git a/src/Mod/TechDraw/Gui/QGIView.h b/src/Mod/TechDraw/Gui/QGIView.h index 445a18027d..72facfca7d 100644 --- a/src/Mod/TechDraw/Gui/QGIView.h +++ b/src/Mod/TechDraw/Gui/QGIView.h @@ -183,6 +183,7 @@ private: QHash alignHash; bool m_locked; bool m_innerView; //View is inside another View + bool m_multiselectActivated; QPen m_pen; QBrush m_brush;