From 9938818d82df5efcb347b29615f52d42355b2cc2 Mon Sep 17 00:00:00 2001 From: WandererFan Date: Thu, 8 May 2025 10:18:09 -0400 Subject: [PATCH] [TD]Allow non-shape views to have children (#20768) (#21099) * [TD]Allow non-shape views to have children (#20768) * Update src/Mod/TechDraw/App/DrawView.cpp Review comment Co-authored-by: Benjamin Nauck * Update src/Mod/TechDraw/App/DrawView.cpp review comment Co-authored-by: Benjamin Nauck * Update src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp review comment Co-authored-by: Benjamin Nauck * Update src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp review comment Co-authored-by: Benjamin Nauck --------- Co-authored-by: Benjamin Nauck --- src/Mod/TechDraw/App/DrawView.cpp | 20 +++++++ src/Mod/TechDraw/App/DrawView.h | 1 + .../TechDraw/Gui/ViewProviderDrawingView.cpp | 54 +++++++++++++++++++ .../TechDraw/Gui/ViewProviderDrawingView.h | 4 ++ 4 files changed, 79 insertions(+) diff --git a/src/Mod/TechDraw/App/DrawView.cpp b/src/Mod/TechDraw/App/DrawView.cpp index 2704543c09..4b7f1e7a71 100644 --- a/src/Mod/TechDraw/App/DrawView.cpp +++ b/src/Mod/TechDraw/App/DrawView.cpp @@ -439,6 +439,26 @@ DrawView *DrawView::claimParent() const return getCollection(); } +//! return *unique* list of DrawView derived items which consider this DVP to be their 'owner' +//! if a dimension has two references to this dvp, it will appear twice in the inlist, so we need to +//! pick out duplicates. +std::vector DrawView::getUniqueChildren() const +{ + std::vector result; + auto children = getInList(); + std::sort(children.begin(), children.end(), std::less<>()); + auto newEnd = std::unique(children.begin(), children.end()); + children.erase(newEnd, children.end()); + for (auto& child : children) { + auto* childDV = freecad_cast(child); + if (childDV && childDV->claimParent() == this) { + result.push_back(childDV); + } + } + return result; +} + + DrawViewClip* DrawView::getClipGroup() { for (auto* obj : getInList()) { diff --git a/src/Mod/TechDraw/App/DrawView.h b/src/Mod/TechDraw/App/DrawView.h index 7c261ff819..9adcc33069 100644 --- a/src/Mod/TechDraw/App/DrawView.h +++ b/src/Mod/TechDraw/App/DrawView.h @@ -87,6 +87,7 @@ public: virtual DrawPage* findParentPage() const; virtual std::vector findAllParentPages() const; virtual DrawView *claimParent() const; + std::vector getUniqueChildren() const; virtual int countParentPages() const; virtual QRectF getRect() const; //must be overridden by derived class diff --git a/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp b/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp index 34f54d0729..bf1ecc8af9 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp @@ -39,6 +39,8 @@ #include #include +#include +#include #include #include "ViewProviderDrawingView.h" @@ -477,3 +479,55 @@ TechDraw::DrawView* ViewProviderDrawingView::getViewObject() const { return dynamic_cast(pcObject); } + + +//! it can happen that child graphic items can lose their parent item if the +//! the parent is deleted, then undo is invoked. The linkages on the App side are +//! handled by the undo mechanism, but the QGraphicsScene parentage is not reset. +void ViewProviderDrawingView::fixSceneDependencies() +{ + Base::Console().Message("VPDV::fixSceneDependencies()\n"); + auto page = getViewProviderPage(); + if (!page) { + return; + } + + auto scene = page->getQGSPage(); + auto ourQView = getQView(); + + // this is the logic for items other than Dimensions and Balloons + auto children = getViewObject()->getUniqueChildren(); + for (auto& child : children) { + if (child->isDerivedFrom() || + child->isDerivedFrom() ) { + // these are handled by ViewProviderViewPart + continue; + } + auto* childQView = scene->findQViewForDocObj(child); + auto* childGraphicParent = scene->findParent(childQView); + if (childGraphicParent != ourQView) { + scene->addItemToParent(childQView, ourQView); + } + } +} + + +std::vector ViewProviderDrawingView::claimChildren() const +{ + std::vector temp; + const std::vector &potentialChildren = getViewObject()->getInList(); + try { + for(auto& child : potentialChildren) { + auto* view = freecad_cast(child); + if (view && view->claimParent() == getViewObject()) { + temp.push_back(view); + continue; + } + } + } + catch (...) { + return {}; + } + return temp; +} + diff --git a/src/Mod/TechDraw/Gui/ViewProviderDrawingView.h b/src/Mod/TechDraw/Gui/ViewProviderDrawingView.h index 1ea582d749..195026c57d 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderDrawingView.h +++ b/src/Mod/TechDraw/Gui/ViewProviderDrawingView.h @@ -99,6 +99,10 @@ public: const char* whoAmI() const; + virtual void fixSceneDependencies(); + std::vector claimChildren() const override; + + private: void multiParentPaint(std::vector& pages); void singleParentPaint(const TechDraw::DrawView* dv);