From 5d4495785b727e81c631942f41044c58c33966c1 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Wed, 21 Jan 2026 18:15:45 -0500 Subject: [PATCH 1/5] [TD]more reliable test for DrawProjGroupItem --- src/Mod/TechDraw/App/DrawProjGroupItem.cpp | 1 - src/Mod/TechDraw/App/DrawProjGroupItem.h | 5 +++-- src/Mod/TechDraw/App/DrawView.cpp | 26 +++++++++++++--------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp index 2008547d99..22e8315ca2 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp @@ -152,7 +152,6 @@ void DrawProjGroupItem::autoPosition() if (!pGroup) { return; } -// Base::Console().message("DPGI::autoPosition(%s)\n", Label.getValue()); if (LockPosition.getValue()) { return; } diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.h b/src/Mod/TechDraw/App/DrawProjGroupItem.h index a0199350e8..9c7131fd6b 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.h +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.h @@ -83,11 +83,12 @@ public: DrawPage* findParentPage() const override; std::vector findAllParentPages() const override; -protected: - void onChanged(const App::Property* prop) override; bool isLocked() const override; bool showLock() const override; +protected: + void onChanged(const App::Property* prop) override; + private: static const char* TypeEnums[]; }; diff --git a/src/Mod/TechDraw/App/DrawView.cpp b/src/Mod/TechDraw/App/DrawView.cpp index 19c0a65f75..c6704aa22b 100644 --- a/src/Mod/TechDraw/App/DrawView.cpp +++ b/src/Mod/TechDraw/App/DrawView.cpp @@ -675,21 +675,25 @@ void DrawView::setScaleAttribute() } //! Due to changes made for the "intelligent" view creation tool, testing for a view being an -//! instance of DrawProjGroupItem is no longer reliable, as views not in a group are sometimes -//! created as DrawProjGroupItem without belonging to a group. We now need to test for the -//! existence of the parent DrawProjGroup +//! instance of DrawProjGroupItem is no longer reliable, as views are sometimes +//! created as DrawProjGroupItem without belonging to a group or as a DrawViewPart that does +//! belong to a group. We now need to test for the existence of the parent DrawProjGroup bool DrawView::isProjGroupItem(DrawViewPart* item) { - auto dpgi = freecad_cast(item); - if (!dpgi) { - return false; + // we check if any object that points to us (as in the Views property of a collection) + // is a projection group. + std::vector inlist = item->getInList(); + for (auto& obj : inlist) { + auto* dpg = freecad_cast(obj); + if (dpg) { + // if a dpg points at item, item must be considered a dpgi. Front is sometime a dvp, + // and not a dpgi. + return true; + } } - auto group = dpgi->getPGroup(); - if (!group) { - return false; - } - return true; + return false; } + int DrawView::prefScaleType() { return Preferences::getPreferenceGroup("General")->GetInt("DefaultScaleType", 0); From fd014445fbfbf85ed9f8c652b8bc71dbfe868afc Mon Sep 17 00:00:00 2001 From: wandererfan Date: Thu, 22 Jan 2026 16:13:11 -0500 Subject: [PATCH 2/5] [TD]make QGIProjGroup methods public - also adds a convenience method to return all the views in the group --- src/Mod/TechDraw/Gui/QGIProjGroup.cpp | 42 +++++++++++++++------------ src/Mod/TechDraw/Gui/QGIProjGroup.h | 6 ++-- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/Mod/TechDraw/Gui/QGIProjGroup.cpp b/src/Mod/TechDraw/Gui/QGIProjGroup.cpp index a5023a67d8..291368e355 100644 --- a/src/Mod/TechDraw/Gui/QGIProjGroup.cpp +++ b/src/Mod/TechDraw/Gui/QGIProjGroup.cpp @@ -32,17 +32,15 @@ #include #include "QGIProjGroup.h" -#include "QGIViewDimension.h" #include "QGIViewPart.h" -#include "Rez.h" - +#include "QGSPage.h" using namespace TechDrawGui; using namespace TechDraw; QGIProjGroup::QGIProjGroup() { - m_origin = new QGraphicsItemGroup(); //QGIG added to this QGIG?? + m_origin = new QGraphicsItemGroup(); m_origin->setParentItem(this); setFlag(ItemIsSelectable, false); @@ -50,7 +48,7 @@ QGIProjGroup::QGIProjGroup() setFiltersChildEvents(true); } -TechDraw::DrawProjGroup * QGIProjGroup::getDrawView() const +TechDraw::DrawProjGroup * QGIProjGroup::getPGroupFeature() const { App::DocumentObject *obj = getViewObject(); return dynamic_cast(obj); @@ -58,7 +56,7 @@ TechDraw::DrawProjGroup * QGIProjGroup::getDrawView() const bool QGIProjGroup::autoDistributeEnabled() const { - return getDrawView() && getDrawView()->AutoDistribute.getValue(); + return getPGroupFeature() && getPGroupFeature()->AutoDistribute.getValue(); } @@ -85,13 +83,6 @@ bool QGIProjGroup::sceneEventFilter(QGraphicsItem* watched, QEvent *event) auto *mEvent = dynamic_cast(event); // Disable moves on the view to prevent double drag - std::vector modifiedChildren; - for (auto* child : childItems()) { - if (child->isSelected() && (child->flags() & QGraphicsItem::ItemIsMovable)) { - child->setFlag(QGraphicsItem::ItemIsMovable, false); - modifiedChildren.push_back(child); - } - } switch (event->type()) { case QEvent::GraphicsSceneMousePress: @@ -106,9 +97,6 @@ bool QGIProjGroup::sceneEventFilter(QGraphicsItem* watched, QEvent *event) default: break; } - for (auto* child : modifiedChildren) { - child->setFlag(QGraphicsItem::ItemIsMovable, true); - } return false; } @@ -168,7 +156,6 @@ void QGIProjGroup::mousePressEvent(QGraphicsSceneMouseEvent * event) void QGIProjGroup::mouseMoveEvent(QGraphicsSceneMouseEvent * event) { QGIView *qAnchor = getAnchorQItem(); - // this is obsolete too? if(scene() && qAnchor && (qAnchor == scene()->mouseGrabberItem() || autoDistributeEnabled())) { if((mousePos - event->screenPos()).manhattanLength() > 5) { //if the mouse has moved more than 5, process the mouse event QGIViewCollection::mouseMoveEvent(event); @@ -201,7 +188,7 @@ void QGIProjGroup::mouseReleaseEvent(QGIView* originator, QGraphicsSceneMouseEve QGIView * QGIProjGroup::getAnchorQItem() const { // Get the currently assigned anchor view - App::DocumentObject *anchorObj = getDrawView()->Anchor.getValue(); + App::DocumentObject *anchorObj = getPGroupFeature()->Anchor.getValue(); auto anchorView( dynamic_cast(anchorObj) ); if (!anchorView) { return nullptr; @@ -243,4 +230,23 @@ bool QGIProjGroup::isMember(App::DocumentObject* dvpObj) const return itMatch != groupOutlist.end(); } +QList QGIProjGroup::secondaryQViews() const +{ + auto* qgspage = static_cast(scene()); + if (!qgspage) { + return {}; + } + DrawProjGroup* pgFeature = getPGroupFeature(); + auto pgViewsAll = pgFeature->getViewsAsDPGI(); + QList result; + + for (auto& pgView : pgViewsAll) { + auto* qview = dynamic_cast(qgspage->findQViewForDocObj(pgView)); + if (!qview) { + continue; + } + result.emplace_back(qview); + } + return result; +} diff --git a/src/Mod/TechDraw/Gui/QGIProjGroup.h b/src/Mod/TechDraw/Gui/QGIProjGroup.h index eb78b64258..4d3a3a6a31 100644 --- a/src/Mod/TechDraw/Gui/QGIProjGroup.h +++ b/src/Mod/TechDraw/Gui/QGIProjGroup.h @@ -41,6 +41,7 @@ namespace TechDraw { namespace TechDrawGui { +class QGIViewPart; class TechDrawGuiExport QGIProjGroup : public QGIViewCollection { @@ -60,6 +61,9 @@ public: void drawBorder() override; bool isMember(App::DocumentObject* dvpObj) const; + QGIView* getAnchorQItem() const; + TechDraw::DrawProjGroup* getPGroupFeature() const; + QList secondaryQViews() const; protected: bool sceneEventFilter(QGraphicsItem* watched, QEvent *event) override; @@ -70,11 +74,9 @@ protected: void mouseReleaseEvent(QGraphicsSceneMouseEvent * event) override; void mouseReleaseEvent(QGIView* originator, QGraphicsSceneMouseEvent* event); - QGIView* getAnchorQItem() const; private: /// Convenience function - TechDraw::DrawProjGroup* getDrawView() const; bool autoDistributeEnabled() const; QGraphicsItem* m_origin; From 3fca5d99eea6bd62132f8f2dc9366d6eccc1d3cc Mon Sep 17 00:00:00 2001 From: wandererfan Date: Thu, 22 Jan 2026 16:14:07 -0500 Subject: [PATCH 3/5] [TD]fix secondary view drag goes to origin --- src/Mod/TechDraw/Gui/QGIView.cpp | 16 +++++---- src/Mod/TechDraw/Gui/QGIView.h | 1 + src/Mod/TechDraw/Gui/QGIViewPart.cpp | 53 ++++++++++++++++++++++++---- src/Mod/TechDraw/Gui/QGIViewPart.h | 3 +- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index 7fa224baac..5b9a9ab5da 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -577,12 +577,7 @@ QGIViewClip* QGIView::getClipGroup() void QGIView::updateView(bool forceUpdate) { - //allow/prevent dragging - if (getViewObject()->isLocked()) { - setFlag(QGraphicsItem::ItemIsMovable, false); - } else { - setFlag(QGraphicsItem::ItemIsMovable, true); - } + setMovableFlag(); if (getViewObject() && forceUpdate) { setPosition(Rez::guiX(getViewObject()->X.getValue()), @@ -1140,6 +1135,15 @@ bool QGIView::isExporting() const return scenePage->getExportingAny(); } +void QGIView::setMovableFlag() +{ + if (getViewObject()->isLocked()) { + setFlag(QGraphicsItem::ItemIsMovable, false); + } else { + setFlag(QGraphicsItem::ItemIsMovable, true); + } +} + //! Retrieves objects of type T with given indexes template std::vector QGIView::getObjects(std::vector indexes) diff --git a/src/Mod/TechDraw/Gui/QGIView.h b/src/Mod/TechDraw/Gui/QGIView.h index 1d49cd8d13..f7a62f29dd 100644 --- a/src/Mod/TechDraw/Gui/QGIView.h +++ b/src/Mod/TechDraw/Gui/QGIView.h @@ -187,6 +187,7 @@ public: bool isExporting() const; + virtual void setMovableFlag(); protected: QGIView* getQGIVByName(std::string name) const; diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index eb58261a5d..4d1744be9c 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include "DrawGuiUtil.h" #include "MDIViewPage.h" @@ -65,6 +67,7 @@ #include "PathBuilder.h" #include "QGIBreakLine.h" #include "QGSPage.h" +#include "QGIProjGroup.h" using namespace TechDraw; using namespace TechDrawGui; @@ -220,18 +223,23 @@ QPainterPath QGIViewPart::drawPainterPath(TechDraw::BaseGeomPtr baseGeom) const double rot = getViewObject()->Rotation.getValue(); return m_pathBuilder->geomToPainterPath(baseGeom, rot); } + void QGIViewPart::updateView(bool update) { - // Base::Console().message("QGIVP::updateView() - %s\n", getViewObject()->getNameInDocument()); auto viewPart(dynamic_cast(getViewObject())); - if (!viewPart) - return; - auto vp = static_cast(getViewProvider(getViewObject())); - if (!vp) + if (!viewPart) { return; + } - if (update) + auto vp = static_cast(getViewProvider(getViewObject())); + if (!vp) { + return; + } + + if (update) { draw(); + } + QGIView::updateView(update); } @@ -1427,3 +1435,36 @@ bool QGIViewPart::hideCenterMarks() const return true; } +void QGIViewPart::setMovableFlag() +{ + auto* dvp(dynamic_cast(getViewObject())); + if (TechDraw::DrawView::isProjGroupItem(dvp)) { + setMovableFlagProjGroupItem(); + return; + } + QGIView::setMovableFlag(); +} + +void QGIViewPart::setMovableFlagProjGroupItem() +{ + auto* dpgi(dynamic_cast(getViewObject())); + if (!dpgi) { + return; + } + + if (dpgi->isLocked()) { + setFlag(QGraphicsItem::ItemIsMovable, false); + return; + } + + bool isAutoDist{dpgi->getPGroup()->AutoDistribute.getValue()}; + if (isAutoDist) { + setFlag(QGraphicsItem::ItemIsMovable, false); + return; + } + + // not locked, not autoDistribute + setFlag(QGraphicsItem::ItemIsMovable, true); +} + + diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.h b/src/Mod/TechDraw/Gui/QGIViewPart.h index f243596b8b..191b857985 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.h +++ b/src/Mod/TechDraw/Gui/QGIViewPart.h @@ -129,7 +129,8 @@ public: bool hideCenterMarks() const; - + void setMovableFlag() override; + void setMovableFlagProjGroupItem(); protected: bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override; From bef6aafa73b4ef41f38192d9d19835e60de15f7b Mon Sep 17 00:00:00 2001 From: wandererfan Date: Thu, 22 Jan 2026 16:14:39 -0500 Subject: [PATCH 4/5] [TD]handle AutoDistribute property toggle --- .../TechDraw/Gui/ViewProviderProjGroup.cpp | 31 +++++++++++++++++++ src/Mod/TechDraw/Gui/ViewProviderProjGroup.h | 3 ++ 2 files changed, 34 insertions(+) diff --git a/src/Mod/TechDraw/Gui/ViewProviderProjGroup.cpp b/src/Mod/TechDraw/Gui/ViewProviderProjGroup.cpp index f179f4e6dc..b5554e2d39 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderProjGroup.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderProjGroup.cpp @@ -43,6 +43,7 @@ #include "TaskProjGroup.h" #include "QGIViewPart.h" +#include "QGIProjGroup.h" #include "QGSPage.h" #include "ViewProviderPage.h" #include "ViewProviderProjGroup.h" @@ -240,3 +241,33 @@ void ViewProviderProjGroup::regroupSubViews() } } +void ViewProviderProjGroup::updateData(const App::Property* prop) +{ + TechDraw::DrawProjGroup* group = getViewObject(); + if (prop == &group->AutoDistribute) { + onChangeAutoDistribute(); + return; + } + + ViewProviderDrawingView::updateData(prop); +} + +void ViewProviderProjGroup::onChangeAutoDistribute() +{ + auto* groupQGI = static_cast(getQView()); + if (!groupQGI) { + // our QGItem does not exist yet + return; + } + + QList secondaryQViews = groupQGI->secondaryQViews(); + for (auto& secondary : secondaryQViews) { + if (secondary == groupQGI->getAnchorQItem()) { + // do not touch the anchor + continue; + } + secondary->updateView(false); + } +} + + diff --git a/src/Mod/TechDraw/Gui/ViewProviderProjGroup.h b/src/Mod/TechDraw/Gui/ViewProviderProjGroup.h index 49e837d1be..0e50652312 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderProjGroup.h +++ b/src/Mod/TechDraw/Gui/ViewProviderProjGroup.h @@ -55,6 +55,9 @@ public: bool canDelete(App::DocumentObject* obj) const override; void regroupSubViews(); + void updateData(const App::Property* prop) override; + void onChangeAutoDistribute(); + protected: bool setEdit(int ModNum) override; From ea58456534c50e8db8e54a89d24af58004aa69cb Mon Sep 17 00:00:00 2001 From: wandererfan Date: Thu, 22 Jan 2026 19:29:08 -0500 Subject: [PATCH 5/5] [TD]avoid crash on missing ViewProviderPage --- src/Mod/TechDraw/Gui/QGIView.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index 5b9a9ab5da..4e2c2b5228 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -277,7 +277,7 @@ void QGIView::snapPosition(QPointF& newPosition) return; } - auto feature = getViewObject(); + DrawView* feature = getViewObject(); if (!feature) { return; } @@ -286,14 +286,18 @@ void QGIView::snapPosition(QPointF& newPosition) return; } - auto dvp = freecad_cast(feature); + auto* dvp = freecad_cast(feature); if (dvp && !dvp->hasGeometry()) { // too early. wait for updates to finish. return; } - auto vpPage = getViewProviderPage(feature); + ViewProviderPage* vpPage = getViewProviderPage(feature); + if (!vpPage) { + // too early. not added to page yet? + return; + } QGSPage* scenePage = vpPage->getQGSPage(); if (!scenePage) {