From 51184b99d535d201e27f2a0bea6f36a1fb0fe902 Mon Sep 17 00:00:00 2001 From: WandererFan Date: Mon, 23 Jun 2025 12:13:27 -0400 Subject: [PATCH] [TechDraw]Detail highlight drag (fix #21828) (#22036) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [TD]add preferences for detail highlight snapping * [TD]fix highlight drag issues * Update src/Mod/TechDraw/Gui/TaskDetail.cpp minor format change from benj5378. Co-authored-by: Benjamin Bræstrup Sayoc --------- Co-authored-by: Benjamin Bræstrup Sayoc --- src/Mod/TechDraw/App/DrawViewDetail.cpp | 7 + src/Mod/TechDraw/App/DrawViewPart.cpp | 32 +++++ src/Mod/TechDraw/App/DrawViewPart.h | 3 + src/Mod/TechDraw/App/Preferences.cpp | 12 ++ src/Mod/TechDraw/App/Preferences.h | 3 + .../TechDraw/Gui/DlgPrefsTechDrawGeneral.ui | 103 ++++++++----- .../Gui/DlgPrefsTechDrawGeneralImp.cpp | 5 + src/Mod/TechDraw/Gui/QGIHighlight.cpp | 2 + src/Mod/TechDraw/Gui/QGIViewPart.cpp | 18 ++- src/Mod/TechDraw/Gui/TaskDetail.cpp | 136 +++++++++--------- src/Mod/TechDraw/Gui/TaskDetail.h | 1 + src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp | 32 +++-- src/Mod/TechDraw/Gui/ViewProviderViewPart.h | 1 + 13 files changed, 230 insertions(+), 125 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawViewDetail.cpp b/src/Mod/TechDraw/App/DrawViewDetail.cpp index 4e7f322d0e..3a9d0a67e3 100644 --- a/src/Mod/TechDraw/App/DrawViewDetail.cpp +++ b/src/Mod/TechDraw/App/DrawViewDetail.cpp @@ -400,6 +400,13 @@ void DrawViewDetail::postHlrTasks(void) Scale.purgeTouched(); detailExec(m_saveShape, m_saveDvp, m_saveDvs); } + + auto* baseView = freecad_cast(BaseView.getValue()); + if (!baseView) { + throw Base::RuntimeError("Detail has no base view!"); + } + baseView->requestPaint(); // repaint the highlight on the base view. + overrideKeepUpdated(false); } diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index abc3157730..1b866a095b 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -718,6 +718,38 @@ void DrawViewPart::onFacesFinished() requestPaint(); } + +//! returns the position of the first visible vertex within snap radius of newAnchorPoint. newAnchorPoint +//! should be unscaled in conventional coordinates. if no suitable vertex is found, newAnchorPoint +//! is returned. the result is unscaled and inverted? +Base::Vector3d DrawViewPart::snapHighlightToVertex(Base::Vector3d newAnchorPoint, + double radius) const +{ + if (!Preferences::snapDetailHighlights()) { + return newAnchorPoint; + } + + double snapRadius = radius * Preferences::detailSnapRadius(); + double dvpScale = getScale(); + std::vector vertexPoints; + auto vertsAll = getVertexGeometry(); + double nearDistance{std::numeric_limits::max()}; + Base::Vector3d nearPoint{newAnchorPoint}; + for (auto& vert: vertsAll) { + if (vert->getHlrVisible()) { + Base::Vector3d vertPointUnscaled = DU::invertY(vert->point()) / dvpScale; + double distanceToVertex = (vertPointUnscaled - newAnchorPoint).Length(); + if (distanceToVertex < snapRadius && + distanceToVertex < nearDistance) { + nearDistance = distanceToVertex; + nearPoint = vertPointUnscaled; + } + } + } + return nearPoint; +} + + //retrieve all the face hatches associated with this dvp std::vector DrawViewPart::getHatches() const { diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 4b29b9db30..c4a971781d 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -243,6 +243,9 @@ public: bool isCosmeticEdge(const std::string& element); bool isCenterLine(const std::string& element); + Base::Vector3d snapHighlightToVertex(Base::Vector3d newAnchorPoint, double radius) const; + + public Q_SLOTS: void onHlrFinished(void); void onFacesFinished(void); diff --git a/src/Mod/TechDraw/App/Preferences.cpp b/src/Mod/TechDraw/App/Preferences.cpp index f65a583042..c8dcee130b 100644 --- a/src/Mod/TechDraw/App/Preferences.cpp +++ b/src/Mod/TechDraw/App/Preferences.cpp @@ -693,3 +693,15 @@ bool Preferences::showUnits() } +bool Preferences::snapDetailHighlights() +{ + return Preferences::getPreferenceGroup("General")->GetBool("SnapHighlights", true); +} + + +//! distance within which we should snap a highlight to a vertex +double Preferences::detailSnapRadius() +{ + return getPreferenceGroup("General")->GetFloat("DetailSnapRadius", 0.6); +} + diff --git a/src/Mod/TechDraw/App/Preferences.h b/src/Mod/TechDraw/App/Preferences.h index 09689d6994..ea823bbb83 100644 --- a/src/Mod/TechDraw/App/Preferences.h +++ b/src/Mod/TechDraw/App/Preferences.h @@ -163,6 +163,9 @@ public: static bool showUnits(); + static bool snapDetailHighlights(); + static double detailSnapRadius(); + }; diff --git a/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneral.ui b/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneral.ui index 8df8ba9242..fb821d651e 100644 --- a/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneral.ui +++ b/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneral.ui @@ -6,8 +6,8 @@ 0 0 - 578 - 1073 + 676 + 1200 @@ -254,7 +254,7 @@ for ProjectionGroups - + 0 @@ -264,10 +264,7 @@ for ProjectionGroups Label size - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + 8.000000000000000 @@ -449,7 +446,7 @@ for ProjectionGroups - + 1 @@ -468,7 +465,7 @@ for ProjectionGroups - + 1 @@ -487,7 +484,7 @@ for ProjectionGroups - + 1 @@ -518,7 +515,7 @@ for ProjectionGroups - + 1 @@ -537,7 +534,7 @@ for ProjectionGroups - + 1 @@ -547,9 +544,6 @@ for ProjectionGroups Default directory for welding symbols - - Gui::FileChooser::Directory - WeldingDir @@ -559,7 +553,7 @@ for ProjectionGroups - + 1 @@ -569,9 +563,6 @@ for ProjectionGroups Starting directory for menu 'Insert Page using Template' - - Gui::FileChooser::Directory - TemplateDir @@ -588,7 +579,7 @@ for ProjectionGroups - + 1 @@ -598,9 +589,6 @@ for ProjectionGroups Alternate directory to search for SVG symbol files. - - Gui::FileChooser::Directory - DirSymbol @@ -752,14 +740,11 @@ for ProjectionGroups - + Distance between Page grid lines. - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + 10.000000000000000 @@ -899,7 +884,7 @@ for ProjectionGroups - + @@ -919,6 +904,44 @@ for ProjectionGroups + + + + Check this box if you want detail view highlights to snap to the nearest vertex when dragging in TaskDetail. + + + Snap Detail Highlights + + + true + + + SnapHighlights + + + /Mod/TechDraw/General + + + + + + + When dragging a view, if it is within this fraction of view size of the correct alignment, it will snap into alignment. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0.050000000000000 + + + SnapLimitFactor + + + /Mod/TechDraw/General + + + @@ -939,23 +962,31 @@ for ProjectionGroups - - + + + + Highlight SnappingFactor + + + + + - When dragging a view, if it is within this fraction of view size of the correct alignment, it will snap into alignment. + Controls the snap radius for highlights. Vertex must be within this factor times the highlight size to be a snap target. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - 0.050000000000000 + 0.600000000000000 - SnapLimitFactor + DetailSnapRadius /Mod/TechDraw/General + @@ -1046,8 +1077,6 @@ for ProjectionGroups
Gui/PrefWidgets.h
- - - + diff --git a/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneralImp.cpp b/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneralImp.cpp index 30f04ee679..6cc3c89269 100644 --- a/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneralImp.cpp +++ b/src/Mod/TechDraw/Gui/DlgPrefsTechDrawGeneralImp.cpp @@ -81,6 +81,8 @@ void DlgPrefsTechDrawGeneralImp::saveSettings() ui->cb_alwaysShowLabel->onSave(); ui->cb_SnapViews->onSave(); ui->psb_SnapFactor->onSave(); + ui->cb_SnapHighlights->onSave(); + ui->psb_HighlightSnapFactor->onSave(); } void DlgPrefsTechDrawGeneralImp::loadSettings() @@ -129,6 +131,9 @@ void DlgPrefsTechDrawGeneralImp::loadSettings() ui->cb_SnapViews->onRestore(); ui->psb_SnapFactor->onRestore(); + + ui->cb_SnapHighlights->onRestore(); + ui->psb_HighlightSnapFactor->onRestore(); } /** diff --git a/src/Mod/TechDraw/Gui/QGIHighlight.cpp b/src/Mod/TechDraw/Gui/QGIHighlight.cpp index a2886b657c..9fb0bc2e32 100644 --- a/src/Mod/TechDraw/Gui/QGIHighlight.cpp +++ b/src/Mod/TechDraw/Gui/QGIHighlight.cpp @@ -64,6 +64,8 @@ QGIHighlight::~QGIHighlight() } + +// QGIHighlight is no longer dragged except through TaskDetail. void QGIHighlight::onDragFinished() { // Base::Console().message("QGIH::onDragFinished - pos: %s\n", diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index 095fa93f14..8f2a7cafc3 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -930,7 +930,7 @@ void QGIViewPart::drawAllHighlights() void QGIViewPart::drawHighlight(TechDraw::DrawViewDetail* viewDetail, bool b) { - TechDraw::DrawViewPart* viewPart = static_cast(getViewObject()); + auto* viewPart = static_cast(getViewObject()); if (!viewPart || !viewDetail) { return; } @@ -950,14 +950,16 @@ void QGIViewPart::drawHighlight(TechDraw::DrawViewDetail* viewDetail, bool b) if (b) { double fontSize = Preferences::labelFontSizeMM(); - QGIHighlight* highlight = new QGIHighlight(); + auto* highlight = new QGIHighlight(); + scene()->addItem(highlight); highlight->setReference(viewDetail->Reference.getValue()); Base::Color color = Preferences::getAccessibleColor(vp->HighlightLineColor.getValue()); highlight->setColor(color.asValue()); highlight->setFeatureName(viewDetail->getNameInDocument()); - highlight->setInteractive(true); + + highlight->setInteractive(false); addToGroup(highlight); highlight->setPos(0.0, 0.0);//sb setPos(center.x, center.y)? @@ -986,20 +988,26 @@ void QGIViewPart::drawHighlight(TechDraw::DrawViewDetail* viewDetail, bool b) } } +//! this method is no longer used due to conflicts with TaskDetail dialog highlight drag void QGIViewPart::highlightMoved(QGIHighlight* highlight, QPointF newPos) { std::string highlightName = highlight->getFeatureName(); App::Document* doc = getViewObject()->getDocument(); App::DocumentObject* docObj = doc->getObject(highlightName.c_str()); auto detail = freecad_cast(docObj); - if (detail) { + auto baseView = freecad_cast(getViewObject()); + if (detail && baseView) { auto oldAnchor = detail->AnchorPoint.getValue(); Base::Vector3d delta = Rez::appX(DrawUtil::toVector3d(newPos)) / getViewObject()->getScale(); delta = DrawUtil::invertY(delta); - detail->AnchorPoint.setValue(oldAnchor + delta); + Base::Vector3d newAnchorPoint = oldAnchor + delta; + newAnchorPoint = baseView->snapHighlightToVertex(newAnchorPoint, + detail->Radius.getValue()); + detail->AnchorPoint.setValue(newAnchorPoint); } } + void QGIViewPart::drawMatting() { auto viewPart(dynamic_cast(getViewObject())); diff --git a/src/Mod/TechDraw/Gui/TaskDetail.cpp b/src/Mod/TechDraw/Gui/TaskDetail.cpp index 473674a785..f4a3776a16 100644 --- a/src/Mod/TechDraw/Gui/TaskDetail.cpp +++ b/src/Mod/TechDraw/Gui/TaskDetail.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include "ui_TaskDetail.h" #include "TaskDetail.h" @@ -59,7 +60,7 @@ TaskDetail::TaskDetail(TechDraw::DrawViewPart* baseFeat): m_ghost(nullptr), m_detailFeat(nullptr), m_baseFeat(baseFeat), - m_basePage(nullptr), + m_basePage(m_baseFeat->findParentPage()), m_qgParent(nullptr), m_inProgressLock(false), m_btnOK(nullptr), @@ -67,9 +68,6 @@ TaskDetail::TaskDetail(TechDraw::DrawViewPart* baseFeat): m_saveAnchor(Base::Vector3d(0.0, 0.0, 0.0)), m_saveRadius(0.0), m_saved(false), - m_baseName(std::string()), - m_pageName(std::string()), - m_detailName(std::string()), m_doc(nullptr), m_mode(CREATEMODE), m_created(false) @@ -137,9 +135,6 @@ TaskDetail::TaskDetail(TechDraw::DrawViewDetail* detailFeat): m_saveAnchor(Base::Vector3d(0.0, 0.0, 0.0)), m_saveRadius(0.0), m_saved(false), - m_baseName(std::string()), - m_pageName(std::string()), - m_detailName(std::string()), m_doc(nullptr), m_mode(EDITMODE), m_created(false) @@ -160,12 +155,13 @@ TaskDetail::TaskDetail(TechDraw::DrawViewDetail* detailFeat): App::DocumentObject* baseObj = m_detailFeat->BaseView.getValue(); m_baseFeat = dynamic_cast(baseObj); - if (m_baseFeat) { - m_baseName = m_baseFeat->getNameInDocument(); - } else { + if (!m_baseFeat) { Base::Console().error("TaskDetail - no BaseView. Can not proceed.\n"); return; } + m_baseName = m_baseFeat->getNameInDocument(); + // repaint baseObj here to make highlight inactive. + m_baseFeat->requestPaint(); ui->setupUi(this); @@ -219,7 +215,6 @@ void TaskDetail::changeEvent(QEvent *e) //save the start conditions void TaskDetail::saveDetailState() { -// Base::Console().message("TD::saveDetailState()\n"); TechDraw::DrawViewDetail* dvd = getDetailFeat(); m_saveAnchor = dvd->AnchorPoint.getValue(); m_saveRadius = dvd->Radius.getValue(); @@ -228,7 +223,6 @@ void TaskDetail::saveDetailState() void TaskDetail::restoreDetailState() { -// Base::Console().message("TD::restoreDetailState()\n"); TechDraw::DrawViewDetail* dvd = getDetailFeat(); dvd->AnchorPoint.setValue(m_saveAnchor); dvd->Radius.setValue(m_saveRadius); @@ -238,7 +232,6 @@ void TaskDetail::restoreDetailState() void TaskDetail::setUiFromFeat() { -// Base::Console().message("TD::setUIFromFeat()\n"); if (m_baseFeat) { std::string baseName = getBaseFeat()->getNameInDocument(); ui->leBaseView->setText(QString::fromStdString(baseName)); @@ -271,10 +264,12 @@ void TaskDetail::setUiFromFeat() ui->qsbRadius->setValue(radius); ui->qsbScale->setDecimals(decimals); ui->cbScaleType->setCurrentIndex(ScaleType); - if (ui->cbScaleType->currentIndex() == 2) // only if custom scale + if (ui->cbScaleType->currentIndex() == 2) { // only if custom scale ui->qsbScale->setEnabled(true); - else + } + else { ui->qsbScale->setEnabled(false); + } ui->qsbScale->setValue(scale); ui->leReference->setText(ref); } @@ -282,16 +277,23 @@ void TaskDetail::setUiFromFeat() //update ui point fields after tracker finishes void TaskDetail::updateUi(QPointF pos) { + ui->qsbX->blockSignals(true); + ui->qsbY->blockSignals(true); + ui->qsbX->setValue(pos.x()); - ui->qsbY->setValue(- pos.y()); + ui->qsbY->setValue(pos.y()); + + ui->qsbX->blockSignals(false); + ui->qsbY->blockSignals(false); } void TaskDetail::enableInputFields(bool isEnabled) { ui->qsbX->setEnabled(isEnabled); ui->qsbY->setEnabled(isEnabled); - if (ui->cbScaleType->currentIndex() == 2) // only if custom scale + if (ui->cbScaleType->currentIndex() == 2) { // only if custom scale ui->qsbScale->setEnabled(isEnabled); + } ui->qsbRadius->setEnabled(isEnabled); ui->leReference->setEnabled(isEnabled); } @@ -315,10 +317,10 @@ void TaskDetail::onScaleTypeEdit() { TechDraw::DrawViewDetail* detailFeat = getDetailFeat(); - if (ui->cbScaleType->currentIndex() == 0) { + detailFeat->ScaleType.setValue(ui->cbScaleType->currentIndex()); + if (ui->cbScaleType->currentIndex() == 0) { // page scale ui->qsbScale->setEnabled(false); - detailFeat->ScaleType.setValue(0.0); // set the page scale if there is a valid page if (m_basePage) { // set the page scale @@ -331,15 +333,12 @@ void TaskDetail::onScaleTypeEdit() else if (ui->cbScaleType->currentIndex() == 1) { // automatic scale (if view is too large to fit into page, it will be scaled down) ui->qsbScale->setEnabled(false); - detailFeat->ScaleType.setValue(1.0); // updating the feature will trigger the rescaling updateDetail(); } else if (ui->cbScaleType->currentIndex() == 2) { // custom scale ui->qsbScale->setEnabled(true); - detailFeat->ScaleType.setValue(2.0); - // no updateDetail() necessary since nothing visibly was changed } } @@ -359,12 +358,10 @@ void TaskDetail::onDraggerClicked(bool clicked) ui->pbDragger->setEnabled(false); enableInputFields(false); editByHighlight(); - return; } void TaskDetail::editByHighlight() { -// Base::Console().message("TD::editByHighlight()\n"); if (!m_ghost) { Base::Console().error("TaskDetail::editByHighlight - no ghost object\n"); return; @@ -382,34 +379,38 @@ void TaskDetail::editByHighlight() //dragEnd is in scene coords. void TaskDetail::onHighlightMoved(QPointF dragEnd) { -// Base::Console().message("TD::onHighlightMoved(%s) - highlight: %X\n", -// DrawUtil::formatVector(dragEnd).c_str(), m_ghost); ui->pbDragger->setEnabled(true); + double radius = m_detailFeat->Radius.getValue(); double scale = getBaseFeat()->getScale(); double x = Rez::guiX(getBaseFeat()->X.getValue()); double y = Rez::guiX(getBaseFeat()->Y.getValue()); DrawViewPart* dvp = getBaseFeat(); - DrawProjGroupItem* dpgi = freecad_cast(dvp); - if (dpgi) { - DrawProjGroup* dpg = dpgi->getPGroup(); - if (!dpg) { - Base::Console().message("TD::getAnchorScene - projection group is confused\n"); - //TODO::throw something. - return; - } + auto* dpgi = freecad_cast(dvp); + DrawProjGroup* dpg{nullptr}; + if (dpgi && DrawView::isProjGroupItem(dpgi)) { + dpg = dpgi->getPGroup(); + } + + if (dpg) { x += Rez::guiX(dpg->X.getValue()); y += Rez::guiX(dpg->Y.getValue()); } QPointF basePosScene(x, -y); //base position in scene coords QPointF anchorDisplace = dragEnd - basePosScene; - QPointF newAnchorPos = Rez::appX(anchorDisplace / scale); + QPointF newAnchorPosScene = Rez::appX(anchorDisplace / scale); - updateUi(newAnchorPos); + + Base::Vector3d newAnchorPosPage = DrawUtil::toVector3d(newAnchorPosScene); + newAnchorPosPage = DrawUtil::invertY(newAnchorPosPage); + Base::Vector3d snappedPos = dvp->snapHighlightToVertex(newAnchorPosPage, radius); + + updateUi(DrawUtil::toQPointF(snappedPos)); updateDetail(); enableInputFields(true); + m_ghost->setSelected(false); m_ghost->hide(); } @@ -430,7 +431,6 @@ void TaskDetail::enableTaskButtons(bool button) //***** Feature create & edit stuff ******************************************* void TaskDetail::createDetail() { -// Base::Console().message("TD::createDetail()\n"); Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create Detail View")); const std::string objectName{"Detail"}; @@ -471,14 +471,15 @@ void TaskDetail::createDetail() void TaskDetail::updateDetail() { -// Base::Console().message("TD::updateDetail()\n"); + TechDraw::DrawViewDetail* detailFeat = getDetailFeat(); try { Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Update Detail")); double x = ui->qsbX->rawValue(); double y = ui->qsbY->rawValue(); Base::Vector3d temp(x, y, 0.0); - TechDraw::DrawViewDetail* detailFeat = getDetailFeat(); - detailFeat->AnchorPoint.setValue(temp); + + detailFeat->AnchorPoint.setValue(temp); // point2d + double scale = ui->qsbScale->rawValue(); detailFeat->Scale.setValue(scale); double radius = ui->qsbRadius->rawValue(); @@ -487,8 +488,6 @@ void TaskDetail::updateDetail() std::string ref = qRef.toStdString(); detailFeat->Reference.setValue(ref); - detailFeat->recomputeFeature(); - getBaseFeat()->requestPaint(); Gui::Command::updateActive(); Gui::Command::commitCommand(); } @@ -496,6 +495,8 @@ void TaskDetail::updateDetail() //this is probably due to appl closing while dialog is still open Base::Console().error("Task Detail - detail feature update failed.\n"); } + + detailFeat->recomputeFeature(); } //***** Getters **************************************************************** @@ -504,45 +505,42 @@ void TaskDetail::updateDetail() QPointF TaskDetail::getAnchorScene() { DrawViewPart* dvp = getBaseFeat(); - DrawProjGroupItem* dpgi = freecad_cast(dvp); + auto* dpgi = freecad_cast(dvp); DrawViewDetail* dvd = getDetailFeat(); Base::Vector3d anchorPos = dvd->AnchorPoint.getValue(); anchorPos.y = -anchorPos.y; Base::Vector3d basePos; double scale = 1; - if (!dpgi) { //base is normal view - double x = dvp->X.getValue(); - double y = dvp->Y.getValue(); - basePos = Base::Vector3d (x, -y, 0.0); - scale = dvp->getScale(); - } else { //part of projection group + double x = dvp->X.getValue(); + double y = dvp->Y.getValue(); + scale = dvp->getScale(); - DrawProjGroup* dpg = dpgi->getPGroup(); - if (!dpg) { - Base::Console().message("TD::getAnchorScene - projection group is confused\n"); - //TODO::throw something. - return QPointF(0.0, 0.0); - } - double x = dpg->X.getValue(); + DrawProjGroup* dpg{nullptr}; + if (dpgi && DrawProjGroup::isProjGroupItem(dpgi)) { + dpg = dpgi->getPGroup(); + } + + if (dpg) { + // part of a projection group + x = dpg->X.getValue(); x += dpgi->X.getValue(); - double y = dpg->Y.getValue(); + y = dpg->Y.getValue(); y += dpgi->Y.getValue(); - basePos = Base::Vector3d(x, -y, 0.0); scale = dpgi->getScale(); } + basePos = Base::Vector3d (x, -y, 0.0); + Base::Vector3d xyScene = Rez::guiX(basePos); Base::Vector3d anchorOffsetScene = Rez::guiX(anchorPos) * scale; Base::Vector3d netPos = xyScene + anchorOffsetScene; - return QPointF(netPos.x, netPos.y); + return {netPos.x, netPos.y}; } // protects against stale pointers DrawViewPart* TaskDetail::getBaseFeat() { -// Base::Console().message("TD::getBaseFeat()\n"); - if (m_doc) { App::DocumentObject* baseObj = m_doc->getObject(m_baseName.c_str()); if (baseObj) { @@ -560,8 +558,6 @@ DrawViewPart* TaskDetail::getBaseFeat() // protects against stale pointers DrawViewDetail* TaskDetail::getDetailFeat() { -// Base::Console().message("TD::getDetailFeat()\n"); - if (m_baseFeat) { App::DocumentObject* detailObj = m_baseFeat->getDocument()->getObject(m_detailName.c_str()); if (detailObj) { @@ -572,7 +568,6 @@ DrawViewDetail* TaskDetail::getDetailFeat() std::string msg = "TaskDetail - detail feature " + m_detailName + " not found \n"; -// throw Base::TypeError("TaskDetail - detail feature not found\n"); throw Base::TypeError(msg); return nullptr; } @@ -581,15 +576,14 @@ DrawViewDetail* TaskDetail::getDetailFeat() bool TaskDetail::accept() { -// Base::Console().message("TD::accept()\n"); - Gui::Document* doc = Gui::Application::Instance->getDocument(m_basePage->getDocument()); - if (!doc) + if (!doc) { return false; + } m_ghost->hide(); - getDetailFeat()->requestPaint(); - getBaseFeat()->requestPaint(); + getDetailFeat()->recomputeFeature(); + Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()"); return true; @@ -597,10 +591,10 @@ bool TaskDetail::accept() bool TaskDetail::reject() { -// Base::Console().message("TD::reject()\n"); Gui::Document* doc = Gui::Application::Instance->getDocument(m_basePage->getDocument()); - if (!doc) + if (!doc) { return false; + } m_ghost->hide(); if (m_mode == CREATEMODE) { diff --git a/src/Mod/TechDraw/Gui/TaskDetail.h b/src/Mod/TechDraw/Gui/TaskDetail.h index 8a9cbd71b5..5c1ae309fc 100644 --- a/src/Mod/TechDraw/Gui/TaskDetail.h +++ b/src/Mod/TechDraw/Gui/TaskDetail.h @@ -28,6 +28,7 @@ #include #include +#include "QGIGhostHighlight.h" namespace TechDraw { diff --git a/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp b/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp index 10e6d080c2..a3696d81ff 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp @@ -60,6 +60,7 @@ #include "TaskProjGroup.h" #include "ViewProviderViewPart.h" #include "ViewProviderPage.h" +#include "QGIViewPart.h" #include "QGIViewDimension.h" #include "QGIViewBalloon.h" #include "QGSPage.h" @@ -213,8 +214,8 @@ void ViewProviderViewPart::onChanged(const App::Property* prop) void ViewProviderViewPart::attach(App::DocumentObject *pcFeat) { // Base::Console().message("VPVP::attach(%s)\n", pcFeat->getNameInDocument()); - TechDraw::DrawViewMulti* dvm = dynamic_cast(pcFeat); - TechDraw::DrawViewDetail* dvd = dynamic_cast(pcFeat); + auto* dvm = dynamic_cast(pcFeat); + auto* dvd = dynamic_cast(pcFeat); if (dvm) { sPixmap = "TechDraw_TreeMulti"; } else if (dvd) { @@ -269,7 +270,7 @@ std::vector ViewProviderViewPart::claimChildren() const } return temp; } catch (...) { - return std::vector(); + return {}; } } @@ -287,25 +288,32 @@ bool ViewProviderViewPart::setEdit(int ModNum) Gui::Selection().clearSelection(); TechDraw::DrawViewPart* dvp = getViewObject(); - TechDraw::DrawViewDetail* dvd = dynamic_cast(dvp); + auto* dvd = dynamic_cast(dvp); if (dvd) { if (!dvd->BaseView.getValue()) { Base::Console().error("DrawViewDetail - %s - has no BaseView!\n", dvd->getNameInDocument()); return false; } - Gui::Control().showDialog(new TaskDlgDetail(dvd)); - Gui::Selection().clearSelection(); - Gui::Selection().addSelection(dvd->getDocument()->getName(), - dvd->getNameInDocument()); - } - else { - auto* view = getObject(); - Gui::Control().showDialog(new TaskDlgProjGroup(view, false)); + return setDetailEdit(ModNum, dvd); } + auto* view = getObject(); + Gui::Control().showDialog(new TaskDlgProjGroup(view, false)); return true; } +bool ViewProviderViewPart::setDetailEdit(int ModNum, DrawViewDetail* dvd) +{ + Q_UNUSED(ModNum); + + Gui::Control().showDialog(new TaskDlgDetail(dvd)); + Gui::Selection().clearSelection(); + Gui::Selection().addSelection(dvd->getDocument()->getName(), + dvd->getNameInDocument()); + return true; +} + + bool ViewProviderViewPart::doubleClicked() { setEdit(ViewProvider::Default); diff --git a/src/Mod/TechDraw/Gui/ViewProviderViewPart.h b/src/Mod/TechDraw/Gui/ViewProviderViewPart.h index d19137e349..2d9b89ab0c 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderViewPart.h +++ b/src/Mod/TechDraw/Gui/ViewProviderViewPart.h @@ -71,6 +71,7 @@ public: bool onDelete(const std::vector &) override; bool canDelete(App::DocumentObject* obj) const override; bool setEdit(int ModNum) override; + bool setDetailEdit(int ModNum, TechDraw::DrawViewDetail* dvd); bool doubleClicked(void) override; void onChanged(const App::Property *prop) override; void handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property * prop) override;