[TD]Fix RichText parent in scene (fix #18283) (#18768)

* [TD]allow DrawViewAnno to be attached to another view

* [TD]allow image and spreadsheet attach to view

* [TD]ensure correct parent in scene

* [TD]refactor command helpers to separate file

- gathering the helpers in one place
- helper redundancy to be address in another change

* [TD]create symbol, spreadsheet, image with parent

* [TD]fix claimChildren for some views

- also includes many lint fixes
This commit is contained in:
WandererFan
2025-01-06 12:11:25 -05:00
committed by GitHub
parent f4b1ccdc54
commit 91d7c875a5
25 changed files with 698 additions and 272 deletions

View File

@@ -24,8 +24,6 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <iomanip>
# include <sstream>
#endif
#include "DrawViewAnnotation.h"
@@ -62,6 +60,9 @@ DrawViewAnnotation::DrawViewAnnotation()
TextStyle.setEnums(TextStyleEnums);
ADD_PROPERTY_TYPE(TextStyle, ((long)0), vgroup, App::Prop_None, "Text style");
ADD_PROPERTY_TYPE(Owner, (nullptr), vgroup, (App::PropertyType)(App::Prop_None),
"Feature to which this annotation is attached, if any");
Scale.setStatus(App::Property::Hidden, true);
ScaleType.setStatus(App::Property::Hidden, true);
}
@@ -82,6 +83,20 @@ void DrawViewAnnotation::onChanged(const App::Property* prop)
TechDraw::DrawView::onChanged(prop);
}
short DrawViewAnnotation::mustExecute() const
{
if (!isRestoring()) {
if (Text.isTouched() ||
Owner.isTouched()) {
return 1;
}
}
return DrawView::mustExecute();
}
void DrawViewAnnotation::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop)
// transforms properties that had been changed
{

View File

@@ -51,6 +51,7 @@ public:
App::PropertyInteger LineSpace;
App::PropertyEnumeration TextStyle; // Plain, Bold, Italic, Bold-Italic
App::PropertyFloat MaxWidth;
App::PropertyLink Owner;
QRectF getRect() const override;
@@ -65,6 +66,11 @@ public:
return "TechDrawGui::ViewProviderAnnotation";
}
short mustExecute() const override;
bool checkFit() const override {return true;}
App::PropertyLink *getOwnerProperty() override { return &Owner; }
protected:
void onChanged(const App::Property* prop) override;
void handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property * prop) override;

View File

@@ -52,6 +52,8 @@ DrawViewImage::DrawViewImage()
"Embedded image file. System use only.");// n/a to end users
ADD_PROPERTY_TYPE(Width, (100), vgroup, App::Prop_None, "The width of cropped image");
ADD_PROPERTY_TYPE(Height, (100), vgroup, App::Prop_None, "The height of cropped image");
ADD_PROPERTY_TYPE(Owner, (nullptr), vgroup, (App::PropertyType)(App::Prop_None),
"Feature to which this symbol is attached");
ScaleType.setValue("Custom");
Scale.setStatus(App::Property::Hidden, false);

View File

@@ -47,6 +47,7 @@ public:
App::PropertyFileIncluded ImageIncluded;
App::PropertyFloat Width;
App::PropertyFloat Height;
App::PropertyLink Owner;
/** @name methods override Feature */
//@{
@@ -58,6 +59,9 @@ public:
const char* getViewProviderName() const override {
return "TechDrawGui::ViewProviderImage";
}
App::PropertyLink *getOwnerProperty() override { return &Owner; }
QRectF getRect() const override;
void setupObject() override;

View File

@@ -63,6 +63,9 @@ DrawViewSpreadsheet::DrawViewSpreadsheet()
ADD_PROPERTY_TYPE(TextSize, (12.0), vgroup, App::Prop_None, "The size of the text");
ADD_PROPERTY_TYPE(LineWidth, (0.35), vgroup, App::Prop_None, "The thickness of the cell lines");
ADD_PROPERTY_TYPE(Owner, (nullptr), vgroup, (App::PropertyType)(App::Prop_None),
"Feature to which this sheet is attached");
EditableTexts.setStatus(App::Property::Hidden, true);
}

View File

@@ -49,9 +49,13 @@ public:
App::PropertyFloat LineWidth;
App::PropertyFloat TextSize;
App::PropertyLink Owner;
App::DocumentObjectExecReturn *execute() override;
short mustExecute() const override;
App::PropertyLink *getOwnerProperty() override { return &Owner; }
std::string getSheetImage();
const char* getViewProviderName() const override {

View File

@@ -105,6 +105,8 @@ SET(TechDrawGui_SRCS
CommandExtensionDims.h
CommandExtensionPack.cpp
CommandStack.cpp
CommandHelpers.cpp
CommandHelpers.h
DimensionValidators.cpp
DimensionValidators.h
Resources/TechDraw.qrc

View File

@@ -79,6 +79,7 @@
#include "TaskSectionView.h"
#include "ViewProviderPage.h"
#include "ViewProviderDrawingView.h"
#include "CommandHelpers.h"
void execSimpleSection(Gui::Command* cmd);
void execComplexSection(Gui::Command* cmd);
@@ -1558,8 +1559,17 @@ void CmdTechDrawSymbol::activated(int iMsg)
doCommand(Doc, "App.activeDocument().%s.translateLabel('DrawViewSymbol', 'Symbol', '%s')",
FeatName.c_str(), FeatName.c_str());
doCommand(Doc, "App.activeDocument().%s.Symbol = svg", FeatName.c_str());
auto baseView = CommandHelpers::firstViewInSelection(this);
if (baseView) {
auto baseName = baseView->getNameInDocument();
doCommand(Doc, "App.activeDocument().%s.Owner = App.activeDocument().%s",
FeatName.c_str(), baseName);
}
doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(),
FeatName.c_str());
updateActive();
commitCommand();
}
@@ -1721,6 +1731,12 @@ CmdTechDrawSpreadsheetView::CmdTechDrawSpreadsheetView() : Command("TechDraw_Spr
void CmdTechDrawSpreadsheetView::activated(int iMsg)
{
Q_UNUSED(iMsg);
TechDraw::DrawPage* page = DrawGuiUtil::findPage(this);
if (!page) {
return;
}
std::string PageName = page->getNameInDocument();
const std::vector<App::DocumentObject*> spreads =
getSelection().getObjectsOfType(Spreadsheet::Sheet::getClassTypeId());
if (spreads.size() != 1) {
@@ -1730,12 +1746,6 @@ void CmdTechDrawSpreadsheetView::activated(int iMsg)
}
std::string SpreadName = spreads.front()->getNameInDocument();
TechDraw::DrawPage* page = DrawGuiUtil::findPage(this);
if (!page) {
return;
}
std::string PageName = page->getNameInDocument();
openCommand(QT_TRANSLATE_NOOP("Command", "Create spreadsheet view"));
std::string FeatName = getUniqueObjectName("Sheet");
doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewSpreadsheet', '%s')",
@@ -1744,6 +1754,15 @@ void CmdTechDrawSpreadsheetView::activated(int iMsg)
FeatName.c_str(), FeatName.c_str());
doCommand(Doc, "App.activeDocument().%s.Source = App.activeDocument().%s", FeatName.c_str(),
SpreadName.c_str());
// look for an owner view in the selection
auto baseView = CommandHelpers::firstViewInSelection(this);
if (baseView) {
auto baseName = baseView->getNameInDocument();
doCommand(Doc, "App.activeDocument().%s.Owner = App.activeDocument().%s",
FeatName.c_str(), baseName);
}
doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(),
FeatName.c_str());
updateActive();

View File

@@ -24,7 +24,6 @@
#ifndef _PreComp_
# include <QApplication>
# include <QMessageBox>
# include <sstream>
#endif
#include <App/DocumentObject.h>
@@ -60,13 +59,15 @@
#include "TaskWeldingSymbol.h"
#include "TaskCosmeticCircle.h"
#include "ViewProviderViewPart.h"
#include "CommandHelpers.h"
using namespace TechDrawGui;
using namespace TechDraw;
using namespace CommandHelpers;
//using CH = CommandHelpers;
//internal functions
bool _checkSelectionHatch(Gui::Command* cmd);
void execCosmeticVertex(Gui::Command* cmd);
void execMidpoints(Gui::Command* cmd);
@@ -76,9 +77,6 @@ void exec2LineCenterLine(Gui::Command* cmd);
void exec2PointCenterLine(Gui::Command* cmd);
void execLine2Points(Gui::Command* cmd);
void execCosmeticCircle(Gui::Command* cmd);
std::vector<std::string> getSelectedSubElements(Gui::Command* cmd,
TechDraw::DrawViewPart* &dvp,
std::string subType = "Edge");
//===========================================================================
// TechDraw_Leader
@@ -333,7 +331,7 @@ void execMidpoints(Gui::Command* cmd)
{
// Base::Console().Message("execMidpoints()\n");
TechDraw::DrawViewPart * dvp = nullptr;
std::vector<std::string> selectedEdges = getSelectedSubElements(cmd, dvp, "Edge");
std::vector<std::string> selectedEdges = CommandHelpers::getSelectedSubElements(cmd, dvp, "Edge");
if (!dvp || selectedEdges.empty())
return;
@@ -360,7 +358,7 @@ void execQuadrants(Gui::Command* cmd)
{
// Base::Console().Message("execQuadrants()\n");
TechDraw::DrawViewPart* dvp = nullptr;
std::vector<std::string> selectedEdges = getSelectedSubElements(cmd, dvp, "Edge");
std::vector<std::string> selectedEdges = CommandHelpers::getSelectedSubElements(cmd, dvp, "Edge");
if (!dvp || selectedEdges.empty())
return;
@@ -553,6 +551,13 @@ void CmdTechDrawAnnotation::activated(int iMsg)
doCommand(Doc, "App.activeDocument().%s.translateLabel('DrawViewAnnotation', 'Annotation', '%s')",
FeatName.c_str(), FeatName.c_str());
auto baseView = CommandHelpers::firstViewInSelection(this);
if (baseView) {
auto baseName = baseView->getNameInDocument();
doCommand(Doc, "App.activeDocument().%s.Owner = App.activeDocument().%s",
FeatName.c_str(), baseName);
}
doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str());
updateActive();
commitCommand();
@@ -823,7 +828,7 @@ void exec2LineCenterLine(Gui::Command* cmd)
return;
}
TechDraw::DrawViewPart* dvp = nullptr;
std::vector<std::string> selectedEdges = getSelectedSubElements(cmd, dvp, "Edge");
std::vector<std::string> selectedEdges = CommandHelpers::getSelectedSubElements(cmd, dvp, "Edge");
if (!dvp || selectedEdges.empty()) {
return;
@@ -1687,46 +1692,3 @@ void CreateTechDrawCommandsAnnotate()
rcCmdMgr.addCommand(new CmdTechDrawSurfaceFinishSymbols());
}
//===========================================================================
// Selection Validation Helpers
//===========================================================================
std::vector<std::string> getSelectedSubElements(Gui::Command* cmd,
TechDraw::DrawViewPart* &dvp,
std::string subType)
{
// Base::Console().Message("getSelectedSubElements() - dvp: %X\n", dvp);
std::vector<std::string> selectedSubs;
std::vector<std::string> subNames;
dvp = nullptr;
std::vector<Gui::SelectionObject> selection = cmd->getSelection().getSelectionEx();
std::vector<Gui::SelectionObject>::iterator itSel = selection.begin();
for (; itSel != selection.end(); itSel++) {
if ((*itSel).getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
dvp = static_cast<TechDraw::DrawViewPart*> ((*itSel).getObject());
subNames = (*itSel).getSubNames();
break;
}
}
if (!dvp) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"),
QObject::tr("No Part View in Selection"));
return selectedSubs;
}
for (auto& s: subNames) {
if (TechDraw::DrawUtil::getGeomTypeFromName(s) == subType) {
selectedSubs.push_back(s);
}
}
if (selectedSubs.empty()) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Wrong Selection"),
QObject::tr("No %1 in Selection")
.arg(QString::fromStdString(subType)));
return selectedSubs;
}
return selectedSubs;
}

View File

@@ -53,6 +53,7 @@
#include "ViewProviderGeomHatch.h"
#include "ViewProviderPage.h"
#include "MDIViewPage.h"
#include "CommandHelpers.h"
using namespace TechDrawGui;
@@ -268,11 +269,20 @@ void CmdTechDrawImage::activated(int iMsg)
std::string FeatName = getUniqueObjectName("Image");
fileName = Base::Tools::escapeEncodeFilename(fileName);
auto filespec = DU::cleanFilespecBackslash(fileName.toStdString());
openCommand(QT_TRANSLATE_NOOP("Command", "Create Image"));
doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewImage', '%s')", FeatName.c_str());
doCommand(Doc, "App.activeDocument().%s.translateLabel('DrawViewImage', 'Image', '%s')",
FeatName.c_str(), FeatName.c_str());
doCommand(Doc, "App.activeDocument().%s.ImageFile = '%s'", FeatName.c_str(), filespec.c_str());
auto baseView = CommandHelpers::firstViewInSelection(this);
if (baseView) {
auto baseName = baseView->getNameInDocument();
doCommand(Doc, "App.activeDocument().%s.Owner = App.activeDocument().%s",
FeatName.c_str(), baseName);
}
doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str());
updateActive();
commitCommand();

View File

@@ -0,0 +1,228 @@
// SPDX-License-Identifier: LGPL-2.0-or-later
/***************************************************************************
* Copyright (c) 2024 WandererFan <wandererfan@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
//! CommandHelpers is a collection of methods for common actions in commands
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include <QMessageBox>
#include <App/DocumentObject.h>
#include <App/Link.h>
#include <Gui/Command.h>
#include <Gui/MainWindow.h>
#include <Gui/Selection.h>
#include <Gui/SelectionObject.h>
#include <Mod/TechDraw/App/DrawPage.h>
#include <Mod/TechDraw/App/DrawView.h>
#include <Mod/TechDraw/App/DrawViewPart.h>
#include <Mod/TechDraw/App/DrawViewSpreadsheet.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include <Mod/TechDraw/App/Preferences.h>
#include <Mod/TechDraw/Gui/PreferencesGui.h>
#include <Mod/TechDraw/Gui/DrawGuiUtil.h>
#include "CommandHelpers.h"
using namespace TechDraw;
using namespace TechDrawGui;
//! find the first DrawView in the current selection for use as a base view (owner)
TechDraw::DrawView* CommandHelpers::firstViewInSelection(Gui::Command* cmd)
{
std::vector<Gui::SelectionObject> selection = cmd->getSelection().getSelectionEx();
TechDraw::DrawView* baseView{nullptr};
if (!selection.empty()) {
for (auto& selobj : selection) {
if (selobj.getObject()->isDerivedFrom<DrawView>()) {
auto docobj = selobj.getObject();
baseView = dynamic_cast<TechDraw::DrawView *>(docobj);
break;
}
}
}
return baseView;
}
//! find the first DrawView in the current selection for use as a base view (owner)
TechDraw::DrawView* CommandHelpers::firstNonSpreadsheetInSelection(Gui::Command* cmd)
{
std::vector<Gui::SelectionObject> selection = cmd->getSelection().getSelectionEx();
TechDraw::DrawView* baseView{nullptr};
if (!selection.empty()) {
for (auto& selobj : selection) {
if (selobj.getObject()->isDerivedFrom<DrawViewSpreadsheet>()) {
continue;
} else {
auto docobj = selobj.getObject();
baseView = dynamic_cast<TechDraw::DrawView *>(docobj);
break;
}
}
}
return baseView;
}
std::vector<std::string> CommandHelpers::getSelectedSubElements(Gui::Command* cmd,
TechDraw::DrawViewPart* &dvp,
std::string subType)
{
std::vector<std::string> selectedSubs;
std::vector<std::string> subNames;
dvp = nullptr;
std::vector<Gui::SelectionObject> selection = cmd->getSelection().getSelectionEx();
std::vector<Gui::SelectionObject>::iterator itSel = selection.begin();
for (; itSel != selection.end(); itSel++) {
if ((*itSel).getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
dvp = static_cast<TechDraw::DrawViewPart*> ((*itSel).getObject());
subNames = (*itSel).getSubNames();
break;
}
}
if (!dvp) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"),
QObject::tr("No Part View in Selection"));
return selectedSubs;
}
for (auto& s: subNames) {
if (TechDraw::DrawUtil::getGeomTypeFromName(s) == subType) {
selectedSubs.push_back(s);
}
}
if (selectedSubs.empty()) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Wrong Selection"),
QObject::tr("No %1 in Selection")
.arg(QString::fromStdString(subType)));
return selectedSubs;
}
return selectedSubs;
}
//! extract the selected shapes and xShapes and determine if a face has been
//! selected to define the projection direction
void CommandHelpers::getSelectedShapes(Gui::Command* cmd,
std::vector<App::DocumentObject*>& shapes,
std::vector<App::DocumentObject*>& xShapes,
App::DocumentObject* faceObj,
std::string& faceName)
{
Gui::ResolveMode resolve = Gui::ResolveMode::OldStyleElement;//mystery
bool single = false; //mystery
auto selection = cmd->getSelection().getSelectionEx(nullptr, App::DocumentObject::getClassTypeId(),
resolve, single);
for (auto& sel : selection) {
bool is_linked = false;
auto obj = sel.getObject();
if (obj->isDerivedFrom(TechDraw::DrawPage::getClassTypeId())) {
continue;
}
if (obj->isDerivedFrom(App::LinkElement::getClassTypeId())
|| obj->isDerivedFrom(App::LinkGroup::getClassTypeId())
|| obj->isDerivedFrom(App::Link::getClassTypeId())) {
is_linked = true;
}
// If parent of the obj is a link to another document, we possibly need to treat non-link obj as linked, too
// 1st, is obj in another document?
if (obj->getDocument() != cmd->getDocument()) {
std::set<App::DocumentObject*> parents = obj->getInListEx(true);
for (auto& parent : parents) {
// Only consider parents in the current document, i.e. possible links in this View's document
if (parent->getDocument() != cmd->getDocument()) {
continue;
}
// 2nd, do we really have a link to obj?
if (parent->isDerivedFrom(App::LinkElement::getClassTypeId())
|| parent->isDerivedFrom(App::LinkGroup::getClassTypeId())
|| parent->isDerivedFrom(App::Link::getClassTypeId())) {
// We have a link chain from this document to obj, and obj is in another document -> it is an XLink target
is_linked = true;
}
}
}
if (is_linked) {
xShapes.push_back(obj);
continue;
}
//not a Link and not null. assume to be drawable. Undrawables will be
// skipped later.
shapes.push_back(obj);
if (faceObj) {
continue;
}
//don't know if this works for an XLink
for (auto& sub : sel.getSubNames()) {
if (TechDraw::DrawUtil::getGeomTypeFromName(sub) == "Face") {
faceName = sub;
//
faceObj = obj;
break;
}
}
}
}
std::pair<Base::Vector3d, Base::Vector3d> CommandHelpers::viewDirection()
{
if (!Preferences::useCameraDirection()) {
return { Base::Vector3d(0, -1, 0), Base::Vector3d(1, 0, 0) };
}
auto faceInfo = faceFromSelection();
if (faceInfo.first) {
return DrawGuiUtil::getProjDirFromFace(faceInfo.first, faceInfo.second);
}
return DrawGuiUtil::get3DDirAndRot();
}
std::pair<App::DocumentObject*, std::string> CommandHelpers::faceFromSelection()
{
auto selection = Gui::Selection().getSelectionEx(
nullptr, App::DocumentObject::getClassTypeId(), Gui::ResolveMode::NoResolve);
if (selection.empty()) {
return { nullptr, "" };
}
for (auto& sel : selection) {
for (auto& sub : sel.getSubNames()) {
if (TechDraw::DrawUtil::getGeomTypeFromName(sub) == "Face") {
return { sel.getObject(), sub };
}
}
}
return { nullptr, "" };
}

View File

@@ -0,0 +1,71 @@
// SPDX-License-Identifier: LGPL-2.0-or-later
/***************************************************************************
* Copyright (c) 2024 WandererFan <wandererfan@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
//! CommandHelpers is a collection of methods for common actions in commands
#ifndef COMMANDHELPERS_H
#define COMMANDHELPERS_H
#include <string>
#include <vector>
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <Base/Vector3D.h>
namespace App {
class DocumentObject;
}
namespace Gui {
class Command;
}
namespace TechDraw {
class DrawView;
class DrawViewPart;
namespace CommandHelpers {
TechDraw::DrawView* firstViewInSelection(Gui::Command* cmd);
TechDraw::DrawView* firstNonSpreadsheetInSelection(Gui::Command* cmd);
std::vector<std::string> getSelectedSubElements(Gui::Command* cmd,
TechDraw::DrawViewPart* &dvp,
std::string subType = "Edge");
void getSelectedShapes(Gui::Command* cmd,
std::vector<App::DocumentObject*>& shapes,
std::vector<App::DocumentObject*>& xShapes,
App::DocumentObject* faceObj,
std::string& faceName);
std::pair<App::DocumentObject*, std::string> faceFromSelection();
std::pair<Base::Vector3d, Base::Vector3d> viewDirection();
} // end namespace CommandHelpers
} // end namespace TechDraw
#endif

View File

@@ -277,7 +277,7 @@ QGIViewBalloon::QGIViewBalloon()
arrow->setPrettyNormal();
arrow->setStyle(prefDefaultArrow());
balloonLabel->setZValue(ZVALUE::LABEL);
balloonLabel->setZValue(ZVALUE::BALLOON);
arrow->setZValue(ZVALUE::DIMENSION);
balloonLines->setZValue(ZVALUE::DIMENSION);

View File

@@ -175,7 +175,6 @@ Qt::KeyboardModifiers QGSPage::cleanModifierList(Qt::KeyboardModifiers mods)
void QGSPage::addChildrenToPage()
{
// Base::Console().Message("QGSP::addChildrenToPage()\n");
// A fresh page is added and we iterate through its collected children and add these to Canvas View -MLP
// if docobj is a featureviewcollection (ex orthogroup), add its child views. if there are ever children that have children,
// we'll have to make this recursive. -WF
@@ -188,11 +187,11 @@ void QGSPage::addChildrenToPage()
}
}
}
//when restoring, it is possible for a Dimension to be loaded before the ViewPart it applies to
//therefore we need to make sure parentage of the graphics representation is set properly. bit of a kludge.
setDimensionGroups();
setBalloonGroups();
setLeaderParentage();
// when restoring, it is possible for an item (ex a Dimension) to be loaded before the ViewPart
// it applies to therefore we need to make sure parentage of the graphics representation is set
// properly. bit of a kludge.
//
setViewParents();
App::DocumentObject* obj = m_vpPage->getDrawPage()->Template.getValue();
auto pageTemplate(dynamic_cast<TechDraw::DrawTemplate*>(obj));
@@ -329,6 +328,8 @@ int QGSPage::addQView(QGIView* view)
}
view->updateView(true);
} else {
Base::Console().Message("QGSP::addQView - qview already exists\n");
}
return 0;
}
@@ -416,7 +417,7 @@ bool QGSPage::attachView(App::DocumentObject* obj)
qview = addViewBalloon(static_cast<TechDraw::DrawViewBalloon*>(obj));
}
else if (typeId.isDerivedFrom(TechDraw::DrawViewAnnotation::getClassTypeId())) {
qview = addDrawViewAnnotation(static_cast<TechDraw::DrawViewAnnotation*>(obj));
qview = addAnnotation(static_cast<TechDraw::DrawViewAnnotation*>(obj));
}
else if (typeId.isDerivedFrom(TechDraw::DrawViewSymbol::getClassTypeId())) {
qview = addDrawViewSymbol(static_cast<TechDraw::DrawViewSymbol*>(obj));
@@ -447,37 +448,85 @@ bool QGSPage::attachView(App::DocumentObject* obj)
return (qview != nullptr);
}
void QGSPage::addItemToScene(QGIView* item)
{
addItem(item);
// Does item belong to a parent?
QGIView* parent = nullptr;
parent = findParent(item);
if (parent) {
addItemToParent(item, parent);
}
}
//! adds item to parent's group with position adjustments if required.
void QGSPage::addItemToParent(QGIView* item, QGIView* parent)
{
// not every view uses the same remapping?? spreadsheets, image, RTA, anno?
// anything that was originally designed to have its position
// defined relative to the Page should not use the dimension/balloon mapping.
assert(item);
assert(parent);
// TODO: make custom user types retrievable by name (see QGIUserTypes.h)
constexpr int QGIVDimensionType {QGraphicsItem::UserType + 106};
constexpr int QGIVBalloonType {QGraphicsItem::UserType + 140};
constexpr int QGIWeldSymbolType {QGraphicsItem::UserType + 340};
// constexpr int QGIViewAnnotationType {QGraphicsItem::UserType + 120};
if (item->type() == QGIWeldSymbolType) {
// don't touch these
return;
}
// original parenting logic here
QPointF posRef(0., 0.);
if (item->type() == QGIVDimensionType || item->type() == QGIVBalloonType) {
QPointF mapPos = item->mapToItem(parent, posRef);
item->moveBy(-mapPos.x(), -mapPos.y());
parent->addToGroup(item);
return;
}
// positioning logic for objects (leader/rta/etc) that normally draw relative to the page goes
// here
//
QPointF itemPosition {item->getViewObject()->X.getValue(), // millimetres on page
-item->getViewObject()->Y.getValue()};
parent->addToGroup(item);
item->setPos(Rez::guiX(itemPosition));
item->setZValue(ZVALUE::DIMENSION);
}
QGIView* QGSPage::addViewPart(TechDraw::DrawViewPart* partFeat)
{
// Base::Console().Message("QGSP::addViewPart(%s)\n", partFeat->Label.getValue());
auto viewPart(new QGIViewPart);
addItem(viewPart);
viewPart->setViewPartFeature(partFeat);
addQView(viewPart);
// we need to install an event filter for any views derived from DrawViewPart
viewPart->installSceneEventFilter(viewPart);
return viewPart;
}
QGIView* QGSPage::addViewSection(DrawViewSection* sectionFeat)
{
auto viewSection(new QGIViewSection);
addItem(viewSection);
viewSection->setViewPartFeature(sectionFeat);
addQView(viewSection);
viewSection->installSceneEventFilter(viewSection);
return viewSection;
}
QGIView* QGSPage::addProjectionGroup(TechDraw::DrawProjGroup* projGroupFeat)
{
// Base::Console().Message("QGSP::addprojectionGroup(%s)\n", projGroupFeat->Label.getValue());
auto qview(new QGIProjGroup);
addItem(qview);
qview->setViewFeature(projGroupFeat);
addQView(qview);
qview->installSceneEventFilter(qview);
return qview;
@@ -486,85 +535,72 @@ QGIView* QGSPage::addProjectionGroup(TechDraw::DrawProjGroup* projGroupFeat)
QGIView* QGSPage::addDrawView(TechDraw::DrawView* view)
{
auto qview(new QGIView);
addItem(qview);
qview->setViewFeature(view);
addQView(qview);
return qview;
}
QGIView* QGSPage::addDrawViewCollection(TechDraw::DrawViewCollection* collectionFeat)
{
auto qview(new QGIViewCollection);
addItem(qview);
qview->setViewFeature(collectionFeat);
addQView(qview);
return qview;
}
QGIView* QGSPage::addDrawViewAnnotation(TechDraw::DrawViewAnnotation* annoFeat)
QGIView* QGSPage::addAnnotation(TechDraw::DrawViewAnnotation* annoFeat)
{
auto qview(new QGIViewAnnotation);
auto annoView{new QGIViewAnnotation};
annoView->setViewFeature(annoFeat);
annoView->setZValue(ZVALUE::ANNOTATION);
addItemToScene(annoView);
qview->setViewAnnoFeature(annoFeat);
addQView(qview);
return qview;
return annoView;
}
QGIView* QGSPage::addDrawViewSymbol(TechDraw::DrawViewSymbol* symbolFeat)
{
QGIViewSymbol *symbolView = new QGIViewSymbol;
symbolView->setViewFeature(symbolFeat);
addItemToScene(symbolView);
addQView(symbolView);
return symbolView;
}
QGIView* QGSPage::addDrawViewClip(TechDraw::DrawViewClip* view)
{
auto qview(new QGIViewClip);
qview->setPosition(Rez::guiX(view->X.getValue()), Rez::guiX(view->Y.getValue()));
qview->setViewFeature(view);
addItemToScene(qview);
qview->setPosition(Rez::guiX(view->X.getValue()), Rez::guiX(view->Y.getValue()));
addQView(qview);
return qview;
}
QGIView* QGSPage::addDrawViewSpreadsheet(TechDraw::DrawViewSpreadsheet* sheetFeat)
{
auto qview(new QGIViewSpreadsheet);
qview->setViewFeature(sheetFeat);
addItemToScene(qview);
addQView(qview);
return qview;
}
QGIView* QGSPage::addDrawViewImage(TechDraw::DrawViewImage* imageFeat)
{
auto qview(new QGIViewImage);
qview->setViewFeature(imageFeat);
addItemToScene(qview);
addQView(qview);
return qview;
}
QGIView* QGSPage::addViewBalloon(TechDraw::DrawViewBalloon* balloonFeat)
{
auto vBalloon(new QGIViewBalloon);
addItem(vBalloon);
vBalloon->setViewPartFeature(balloonFeat);
QGIView* parent = nullptr;
parent = findParent(vBalloon);
if (parent) {
addBalloonToParent(vBalloon, parent);
}
addItemToScene(vBalloon);
return vBalloon;
}
@@ -631,18 +667,8 @@ void QGSPage::createBalloon(QPointF origin, DrawView* parent)
QGIView* QGSPage::addViewDimension(TechDraw::DrawViewDimension* dimFeat)
{
auto dimGroup(new QGIViewDimension);
addItem(dimGroup);
dimGroup->setViewPartFeature(dimFeat);
// Find if it belongs to a parent
QGIView* parent = nullptr;
parent = findParent(dimGroup);
if (parent) {
addDimToParent(dimGroup, parent);
}
addItemToScene(dimGroup);
return dimGroup;
}
@@ -662,16 +688,9 @@ void QGSPage::addDimToParent(QGIViewDimension* dim, QGIView* parent)
QGIView* QGSPage::addViewLeader(TechDraw::DrawLeaderLine* leaderFeat)
{
QGILeaderLine *leaderItem = new QGILeaderLine;
addItem(leaderItem);
leaderItem->setViewFeature(leaderFeat);
addItemToScene(leaderItem);
// Find if it belongs to a parent
QGIView* parent = nullptr;
parent = findParent(leaderItem);
if (parent) {
addLeaderToParent(leaderItem, parent);
}
return leaderItem;
}
@@ -693,67 +712,67 @@ void QGSPage::addLeaderToParent(QGILeaderLine* leader, QGIView* parent)
QGIView* QGSPage::addRichAnno(TechDraw::DrawRichAnno* richFeat)
{
QGIRichAnno *richView = new QGIRichAnno;
auto richView = new QGIRichAnno;
richView->setViewFeature(richFeat);
addItemToScene(richView);
// Find if it belongs to a parent
QGIView* parent = nullptr;
parent = findParent(richView);
if (parent) {
addRichAnnoToParent(richView, parent);
}
addQView(richView);
return richView;
}
void QGSPage::addRichAnnoToParent(QGIRichAnno* anno, QGIView* parent)
{
assert(anno);
assert(parent);//blow up if we don't have Anno or Parent
QPointF posRef(0., 0.);
QPointF parentOrigin = anno->mapToItem(parent, posRef);
// this is not right for a DPGI? Needs the usual calculation??
QPointF annoPositionInParent{ anno->getViewObject()->X.getValue(),
anno->getViewObject()->Y.getValue()};
QPointF moveToPosition = parentOrigin + annoPositionInParent;
anno->moveBy(-moveToPosition.x(), -moveToPosition.y());
parent->addToGroup(anno);
anno->setZValue(ZVALUE::DIMENSION);
}
// ?? why does this not get parented to its leader here??
// the taskdialog sets the Leader property in the weld feature.
// the weld symbol draws itself based on the leader's geometry, but is not added to the leader's
// group(?why?)
QGIView* QGSPage::addWeldSymbol(TechDraw::DrawWeldSymbol* weldFeat)
{
QGIWeldSymbol *weldView = new QGIWeldSymbol;
weldView->setViewFeature(weldFeat);
addItem(weldView);
addQView(weldView);
return weldView;
}
void QGSPage::setDimensionGroups()
//! ensure that all QGIViews are parented correctly in the scene
void QGSPage::setViewParents()
{
const std::vector<QGIView*>& allItems = getViews();
int dimItemType = QGraphicsItem::UserType + 106;
for (auto& item : allItems) {
if (item->type() == dimItemType && !item->group()) {
QGIView* parent = findParent(item);
if (parent) {
QGIViewDimension* dim = dynamic_cast<QGIViewDimension*>(item);
addDimToParent(dim, parent);
}
if (item->group()) {
// this item already has a parent in the scene. probably should check if it is the
// correct parent
continue;
}
}
}
void QGSPage::setBalloonGroups()
{
const std::vector<QGIView*>& allItems = getViews();
int balloonItemType = QGraphicsItem::UserType + 140;
for (auto& item : allItems) {
if (item->type() == balloonItemType && !item->group()) {
QGIView* parent = findParent(item);
if (parent) {
QGIViewBalloon* balloon = dynamic_cast<QGIViewBalloon*>(item);
addBalloonToParent(balloon, parent);
}
}
}
}
//! ensure that all Leader QGItems are parented correctly
void QGSPage::setLeaderParentage()
{
const std::vector<QGIView*>& allItems = getViews();
int LeaderItemType = QGraphicsItem::UserType + 232;
for (auto& item : allItems) {
if (item->type() == LeaderItemType && !item->group()) {
QGIView* parent = findParent(item);
if (parent) {
QGILeaderLine* leader = dynamic_cast<QGILeaderLine*>(item);
addLeaderToParent(leader, parent);
}
QGIView* parent = findParent(item);
if (parent) {
// item has a parent, so make sure it belongs to parent's group
addItemToParent(item, parent);
}
}
}
@@ -792,7 +811,6 @@ QGIView* QGSPage::getQGIVByName(std::string name) const
//find the parent of a QGIV based on the corresponding feature's parentage
QGIView* QGSPage::findParent(QGIView* view) const
{
// Base::Console().Message("QGSP::findParent(%s)\n", view->getViewName());
const std::vector<QGIView*> qviews = getViews();
TechDraw::DrawView* myFeat = view->getViewObject();

View File

@@ -67,6 +67,7 @@ class ViewProviderPage;
class QGIViewBalloon;
class QGITile;
class QGILeaderLine;
class QGIRichAnno;
class TechDrawGuiExport QGSPage: public QGraphicsScene
{
@@ -85,7 +86,7 @@ public:
QGIView* addViewSection(TechDraw::DrawViewSection* sectionFeat);
QGIView* addDrawView(TechDraw::DrawView* viewFeat);
QGIView* addDrawViewCollection(TechDraw::DrawViewCollection* collectionFeat);
QGIView* addDrawViewAnnotation(TechDraw::DrawViewAnnotation* annoFeat);
QGIView* addAnnotation(TechDraw::DrawViewAnnotation* annoFeat);
QGIView* addDrawViewSymbol(TechDraw::DrawViewSymbol* symbolFeat);
QGIView* addDrawViewClip(TechDraw::DrawViewClip* clipFeat);
QGIView* addDrawViewSpreadsheet(TechDraw::DrawViewSpreadsheet* sheetFeat);
@@ -112,6 +113,10 @@ public:
void addDimToParent(QGIViewDimension* dim, QGIView* parent);
void addLeaderToParent(QGILeaderLine* leader, QGIView* parent);
void addRichAnnoToParent(QGIRichAnno* anno, QGIView* parent);
void addItemToScene(QGIView* item);
void addItemToParent(QGIView* item, QGIView* parent);
std::vector<QGIView*> getViews() const;
@@ -143,9 +148,7 @@ public:
void postProcessXml(QTemporaryFile& temporaryFile, QString filename, QString pagename);
// scene parentage fixups
void setDimensionGroups();
void setBalloonGroups();
void setLeaderParentage();
void setViewParents();
static bool itemClearsSelection(int itemTypeIn);
static Qt::KeyboardModifiers cleanModifierList(Qt::KeyboardModifiers mods);

View File

@@ -40,6 +40,8 @@
#include <Gui/ViewProviderDocumentObject.h>
#include <Mod/TechDraw/App/LineGroup.h>
#include <Mod/TechDraw/App/DrawRichAnno.h>
#include <Mod/TechDraw/App/DrawLeaderLine.h>
#include "PreferencesGui.h"
#include "ZVALUE.h"
@@ -72,9 +74,6 @@ ViewProviderBalloon::ViewProviderBalloon()
StackOrder.setValue(ZVALUE::DIMENSION);
}
ViewProviderBalloon::~ViewProviderBalloon()
{
}
bool ViewProviderBalloon::doubleClicked()
{
@@ -84,7 +83,7 @@ bool ViewProviderBalloon::doubleClicked()
void ViewProviderBalloon::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
Gui::ActionFunction* func = new Gui::ActionFunction(menu);
auto* func = new Gui::ActionFunction(menu);
QAction* act = menu->addAction(QObject::tr("Edit %1").arg(QString::fromUtf8(getObject()->Label.getValue())));
act->setData(QVariant((int)ViewProvider::Default));
func->trigger(act, [this]() {
@@ -111,12 +110,12 @@ bool ViewProviderBalloon::setEdit(int ModNum)
return true;
}
void ViewProviderBalloon::updateData(const App::Property* p)
void ViewProviderBalloon::updateData(const App::Property* prop)
{
//Balloon handles X, Y updates differently that other QGIView
//call QGIViewBalloon::updateView
if (p == &(getViewObject()->X) ||
p == &(getViewObject()->Y) ){
if (prop == &(getViewObject()->X) ||
prop == &(getViewObject()->Y) ){
QGIView* qgiv = getQView();
if (qgiv) {
qgiv->updateView(true);
@@ -124,22 +123,22 @@ void ViewProviderBalloon::updateData(const App::Property* p)
}
//Skip QGIView X, Y processing - do not call ViewProviderDrawingView
Gui::ViewProviderDocumentObject::updateData(p);
Gui::ViewProviderDocumentObject::updateData(prop);
}
void ViewProviderBalloon::onChanged(const App::Property* p)
void ViewProviderBalloon::onChanged(const App::Property* prop)
{
if ((p == &Font) ||
(p == &Fontsize) ||
(p == &Color) ||
(p == &LineWidth) ||
(p == &LineVisible)) {
if ((prop == &Font) ||
(prop == &Fontsize) ||
(prop == &Color) ||
(prop == &LineWidth) ||
(prop == &LineVisible)) {
QGIView* qgiv = getQView();
if (qgiv) {
qgiv->updateView(true);
}
}
Gui::ViewProviderDocumentObject::onChanged(p);
Gui::ViewProviderDocumentObject::onChanged(prop);
}
TechDraw::DrawViewBalloon* ViewProviderBalloon::getViewObject() const
@@ -189,3 +188,24 @@ bool ViewProviderBalloon::onDelete(const std::vector<std::string> & parms)
}
return true;
}
std::vector<App::DocumentObject*> ViewProviderBalloon::claimChildren() const
{
// What can reasonably have a Balloon as a parent? A leader? a bit unconventional, but not forbidden.
// A RichAnno? Maybe? Another Balloon? Maybe?
std::vector<App::DocumentObject*> temp;
const std::vector<App::DocumentObject*>& candidates = getViewObject()->getInList();
for (auto& obj : candidates) {
if (obj->isDerivedFrom<TechDraw::DrawViewBalloon>() ||
obj->isDerivedFrom<TechDraw::DrawLeaderLine>() ||
obj->isDerivedFrom<TechDraw::DrawRichAnno>() ) {
temp.push_back(obj);
}
}
return temp;
}

View File

@@ -44,7 +44,7 @@ public:
/// constructor
ViewProviderBalloon();
/// destructor
~ViewProviderBalloon() override;
~ViewProviderBalloon() override = default;
App::PropertyFont Font;
App::PropertyLength Fontsize;
@@ -53,9 +53,9 @@ public:
App::PropertyColor Color;
bool useNewSelectionModel() const override {return false;}
void updateData(const App::Property*) override;
void onChanged(const App::Property* p) override;
void setupContextMenu(QMenu*, QObject*, const char*) override;
void updateData(const App::Property* prop) override;
void onChanged(const App::Property* prop) override;
void setupContextMenu(QMenu* menu, QObject* receiver, const char* member) override;
bool setEdit(int ModNum) override;
bool doubleClicked() override;
bool canDelete(App::DocumentObject* obj) const override;
@@ -63,6 +63,8 @@ public:
TechDraw::DrawViewBalloon* getViewObject() const override;
std::vector<App::DocumentObject*> claimChildren() const override;
protected:
void handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property * prop) override;
};

View File

@@ -41,6 +41,10 @@
#include <Mod/TechDraw/App/LineGroup.h>
#include <Mod/TechDraw/App/LandmarkDimension.h>
#include <Mod/TechDraw/App/DrawLeaderLine.h>
#include <Mod/TechDraw/App/DrawRichAnno.h>
#include <Mod/TechDraw/App/DrawViewBalloon.h>
#include "PreferencesGui.h"
#include "ZVALUE.h"
@@ -98,9 +102,6 @@ ViewProviderDimension::ViewProviderDimension()
StackOrder.setValue(ZVALUE::DIMENSION);
}
ViewProviderDimension::~ViewProviderDimension()
{
}
void ViewProviderDimension::attach(App::DocumentObject *pcFeat)
{
@@ -122,7 +123,7 @@ bool ViewProviderDimension::doubleClicked()
void ViewProviderDimension::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
Gui::ActionFunction* func = new Gui::ActionFunction(menu);
auto* func = new Gui::ActionFunction(menu);
QAction* act = menu->addAction(QObject::tr("Edit %1").arg(QString::fromUtf8(getObject()->Label.getValue())));
act->setData(QVariant((int)ViewProvider::Default));
func->trigger(act, [this](){
@@ -201,34 +202,34 @@ void ViewProviderDimension::setPixmapForType()
}
}
void ViewProviderDimension::onChanged(const App::Property* p)
void ViewProviderDimension::onChanged(const App::Property* prop)
{
if ((p == &Font) ||
(p == &Fontsize) ||
(p == &Arrowsize) ||
(p == &LineWidth) ||
(p == &StandardAndStyle) ||
(p == &RenderingExtent) ||
(p == &FlipArrowheads) ||
(p == &GapFactorASME) ||
(p == &GapFactorISO) ||
p == &LineSpacingFactorISO) {
QGIView* qgiv = getQView();
if ((prop == &Font) ||
(prop == &Fontsize) ||
(prop == &Arrowsize) ||
(prop == &LineWidth) ||
(prop == &StandardAndStyle) ||
(prop == &RenderingExtent) ||
(prop == &FlipArrowheads) ||
(prop == &GapFactorASME) ||
(prop == &GapFactorISO) ||
prop == &LineSpacingFactorISO) {
auto* qgiv = getQView();
if (qgiv) {
qgiv->updateView(true);
}
}
if (p == &Color) {
QGIView* qgiv = getQView();
if (prop == &Color) {
auto* qgiv = getQView();
if (qgiv) {
QGIViewDimension* qgivd = dynamic_cast<QGIViewDimension*>(qgiv);
auto* qgivd = dynamic_cast<QGIViewDimension*>(qgiv);
if (qgivd) {
qgivd->setNormalColorAll();
}
}
}
ViewProviderDrawingView::onChanged(p);
ViewProviderDrawingView::onChanged(prop);
}
TechDraw::DrawViewDimension* ViewProviderDimension::getViewObject() const
@@ -292,7 +293,6 @@ bool ViewProviderDimension::canDelete(App::DocumentObject *obj) const
bool ViewProviderDimension::onDelete(const std::vector<std::string> & parms)
{
Q_UNUSED(parms)
// Base::Console().Message("VPB::onDelete() - parms: %d\n", parms.size());
auto dlg = Gui::Control().activeDialog();
auto ourDlg = dynamic_cast<TaskDlgDimension*>(dlg);
if (ourDlg) {
@@ -308,3 +308,23 @@ bool ViewProviderDimension::onDelete(const std::vector<std::string> & parms)
return true;
}
std::vector<App::DocumentObject*> ViewProviderDimension::claimChildren() const
{
// What can reasonably have a Dimension as a parent? A leader? a bit unconventional, but not forbidden.
// A RichAnno? Maybe? Balloons? This is a bit of a corner case. Typically, a
// Dimension would belong to something rather than owning something.
// Pages will appear in the inList, but should not be treated as a child of the dimension!
std::vector<App::DocumentObject*> temp;
const std::vector<App::DocumentObject*>& candidates = getViewObject()->getInList();
for (auto& obj : candidates) {
if (obj->isDerivedFrom<TechDraw::DrawViewBalloon>() ||
obj->isDerivedFrom<TechDraw::DrawLeaderLine>() ||
obj->isDerivedFrom<TechDraw::DrawRichAnno>() ) {
temp.push_back(obj);
}
}
return temp;
}

View File

@@ -41,7 +41,7 @@ public:
/// constructor
ViewProviderDimension();
/// destructor
~ViewProviderDimension() override;
~ViewProviderDimension() override = default;
App::PropertyFont Font;
App::PropertyLength Fontsize;
@@ -90,6 +90,9 @@ public:
bool canDelete(App::DocumentObject* obj) const override;
void setPixmapForType();
std::vector<App::DocumentObject*> claimChildren() const override;
protected:
void handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property * prop) override;

View File

@@ -100,18 +100,18 @@ bool ViewProviderLeader::doubleClicked()
return true;
}
void ViewProviderLeader::onChanged(const App::Property* p)
void ViewProviderLeader::onChanged(const App::Property* prop)
{
if ((p == &Color) ||
(p == &LineWidth) ||
(p == &LineStyle) ||
(p == &UseOldCoords)) {
QGIView* qgiv = getQView();
if ((prop == &Color) ||
(prop == &LineWidth) ||
(prop == &LineStyle) ||
(prop == &UseOldCoords)) {
auto* qgiv = getQView();
if (qgiv) {
qgiv->updateView(true);
}
}
ViewProviderDrawingView::onChanged(p);
ViewProviderDrawingView::onChanged(prop);
}
std::vector<App::DocumentObject*> ViewProviderLeader::claimChildren() const

View File

@@ -35,7 +35,9 @@
#include <Gui/MainWindow.h>
#include <Gui/Selection.h>
#include <Mod/TechDraw/App/DrawViewBalloon.h>
#include <Mod/TechDraw/App/DrawLeaderLine.h>
#include <Mod/TechDraw/App/DrawRichAnno.h>
#include <Mod/TechDraw/App/DrawProjGroupItem.h>
#include <Mod/TechDraw/App/DrawViewDetail.h>
#include <Mod/TechDraw/App/DrawViewSection.h>
@@ -55,16 +57,6 @@ ViewProviderProjGroup::ViewProviderProjGroup()
sPixmap = "TechDraw_TreeProjGroup";
}
ViewProviderProjGroup::~ViewProviderProjGroup()
{
}
void ViewProviderProjGroup::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
Q_UNUSED(menu);
Q_UNUSED(receiver);
Q_UNUSED(member);
}
bool ViewProviderProjGroup::setEdit(int ModNum)
{
@@ -72,10 +64,11 @@ bool ViewProviderProjGroup::setEdit(int ModNum)
// When double-clicking on the item for this sketch the
// object unsets and sets its edit mode without closing
// the task panel
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
TaskDlgProjGroup *projDlg = qobject_cast<TaskDlgProjGroup *>(dlg);
if (projDlg && projDlg->getViewProvider() != this)
auto* dlg = Gui::Control().activeDialog();
auto* projDlg = qobject_cast<TaskDlgProjGroup *>(dlg);
if (projDlg && projDlg->getViewProvider() != this) {
projDlg = nullptr; // another sketch left open its task panel
}
// clear the selection (convenience)
Gui::Selection().clearSelection();
@@ -97,8 +90,9 @@ bool ViewProviderProjGroup::doubleClicked()
return true;
}
bool ViewProviderProjGroup::onDelete(const std::vector<std::string> &)
bool ViewProviderProjGroup::onDelete(const std::vector<std::string> & parms)
{
Q_UNUSED(parms)
// warn the user if the ProjGroup is not empty
QString bodyMessage;
@@ -142,8 +136,9 @@ bool ViewProviderProjGroup::onDelete(const std::vector<std::string> &)
bodyMessageStream << qApp->translate("Std_Delete",
"The group cannot be deleted because its items have the following\nsection or detail views, or leader lines that would get broken:");
bodyMessageStream << '\n';
for (const auto& ListIterator : ViewList)
for (const auto& ListIterator : ViewList) {
bodyMessageStream << '\n' << QString::fromUtf8(ListIterator.c_str());
}
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("Std_Delete", "Object dependencies"), bodyMessage,
QMessageBox::Ok);
@@ -156,20 +151,17 @@ bool ViewProviderProjGroup::onDelete(const std::vector<std::string> &)
bodyMessageStream << qApp->translate("Std_Delete",
"The projection group is not empty, therefore\nthe following referencing objects might be lost:");
bodyMessageStream << '\n';
for (auto ObjIterator : objs)
for (auto ObjIterator : objs) {
bodyMessageStream << '\n' << QString::fromUtf8(ObjIterator->Label.getValue());
}
bodyMessageStream << "\n\n" << QObject::tr("Are you sure you want to continue?");
// show and evaluate dialog
int DialogResult = QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("Std_Delete", "Object dependencies"), bodyMessage,
QMessageBox::Yes, QMessageBox::No);
if (DialogResult == QMessageBox::Yes)
return true;
else
return false;
return (DialogResult == QMessageBox::Yes);
}
else
return true;
return true;
}
bool ViewProviderProjGroup::canDelete(App::DocumentObject *obj) const
@@ -183,17 +175,36 @@ bool ViewProviderProjGroup::canDelete(App::DocumentObject *obj) const
std::vector<App::DocumentObject*> ViewProviderProjGroup::claimChildren() const
{
// Collect any child fields
// Collect any child Document Objects and put them in the right place in the Feature tree
// valid children of an ProjGroup are:
// - Balloons
// - Leaders
// - RichAnno
std::vector<App::DocumentObject*> temp;
const std::vector<App::DocumentObject*>& candidates = getViewObject()->getInList();
// DPGI's do not point at the DPG, the DPG/DVC maintains links to the items
// why does this need a try/catch??
try {
for (auto* view : getObject()->Views.getValues()) {
temp.push_back(view);
}
return temp;
} catch (...) {
std::vector<App::DocumentObject*> tmp;
return tmp;
for (auto& obj : candidates) {
if (obj->isDerivedFrom<TechDraw::DrawViewBalloon>() ||
obj->isDerivedFrom<TechDraw::DrawLeaderLine>() ||
obj->isDerivedFrom<TechDraw::DrawRichAnno>()) {
temp.push_back(obj);
}
}
// return temp;
}
catch (...) {
return {};
}
// plus the individual ProjGroupItems
for (auto& view : getViewObject()->Views.getValues()) {
temp.push_back(view);
}
return temp;
}
TechDraw::DrawProjGroup* ViewProviderProjGroup::getViewObject() const

View File

@@ -22,8 +22,8 @@
#ifndef DRAWINGGUI_VIEWPROVIDERVIEWGROUP_H
#define DRAWINGGUI_VIEWPROVIDERVIEWGROUP_H
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <Mod/TechDraw/App/DrawProjGroup.h>
@@ -39,20 +39,19 @@ class TechDrawGuiExport ViewProviderProjGroup : public ViewProviderDrawingView
public:
ViewProviderProjGroup(); /// constructor
~ViewProviderProjGroup() override; /// destructor
~ViewProviderProjGroup() override = default; /// destructor
bool useNewSelectionModel() const override {return false;}
/// Claim all the views for the page
/// Claim all the views for the group
std::vector<App::DocumentObject*> claimChildren() const override;
/// Is called by the tree if the user double click on the object
bool doubleClicked() override;
void setupContextMenu(QMenu*, QObject*, const char*) override;
TechDraw::DrawProjGroup* getObject() const;
TechDraw::DrawProjGroup* getViewObject() const override;
bool onDelete(const std::vector<std::string> &) override;
bool onDelete(const std::vector<std::string> &parms) override;
bool canDelete(App::DocumentObject* obj) const override;
protected:

View File

@@ -28,14 +28,16 @@
#include <Gui/Selection.h>
#include <Mod/TechDraw/App/DrawRichAnno.h>
#include <Mod/TechDraw/App/LineGroup.h>
#include <Mod/TechDraw/App/DrawLeaderLine.h>
#include <Mod/TechDraw/App/DrawViewBalloon.h>
#include <Mod/TechDraw/App/DrawViewDimension.h>
#include <Mod/TechDraw/App/LineGroup.h>
#include "PreferencesGui.h"
#include "ZVALUE.h"
#include "QGIView.h"
#include "TaskRichAnno.h"
#include "QGSPage.h"
#include "ViewProviderPage.h"
#include "ViewProviderRichAnno.h"
using namespace TechDrawGui;
@@ -68,9 +70,6 @@ ViewProviderRichAnno::ViewProviderRichAnno()
StackOrder.setValue(ZVALUE::DIMENSION);
}
ViewProviderRichAnno::~ViewProviderRichAnno()
{
}
bool ViewProviderRichAnno::doubleClicked()
{
@@ -79,7 +78,7 @@ bool ViewProviderRichAnno::doubleClicked()
return true;
}
void ViewProviderRichAnno::updateData(const App::Property* p)
void ViewProviderRichAnno::updateData(const App::Property* prop)
{
// only if there is a frame we can enable the frame line parameters
if (getViewObject()) {
@@ -95,21 +94,21 @@ void ViewProviderRichAnno::updateData(const App::Property* p)
}
}
ViewProviderDrawingView::updateData(p);
ViewProviderDrawingView::updateData(prop);
}
void ViewProviderRichAnno::onChanged(const App::Property* p)
void ViewProviderRichAnno::onChanged(const App::Property* prop)
{
if ((p == &LineColor) ||
(p == &LineWidth) ||
(p == &LineStyle)) {
QGIView* qgiv = getQView();
if ((prop == &LineColor) ||
(prop == &LineWidth) ||
(prop == &LineStyle)) {
auto* qgiv = getQView();
if (qgiv) {
qgiv->updateView(true);
}
}
ViewProviderDrawingView::onChanged(p);
ViewProviderDrawingView::onChanged(prop);
}
TechDraw::DrawRichAnno* ViewProviderRichAnno::getViewObject() const
@@ -183,3 +182,23 @@ bool ViewProviderRichAnno::canDelete(App::DocumentObject *obj) const
Q_UNUSED(obj)
return true;
}
std::vector<App::DocumentObject*> ViewProviderRichAnno::claimChildren() const
{
// What can reasonably have a RichAnno as a parent? A leader? a bit unconventional, but not forbidden.
// Another RichAnno? Maybe? Balloons? Dimensions? This is a bit of a corner case. Typically, a
// RichAnno would belong to something rather than owning something.
std::vector<App::DocumentObject*> temp;
const std::vector<App::DocumentObject*>& candidates = getViewObject()->getInList();
for (auto& obj : candidates) {
if (obj->isDerivedFrom<TechDraw::DrawViewBalloon>() ||
obj->isDerivedFrom<TechDraw::DrawLeaderLine>() ||
obj->isDerivedFrom<TechDraw::DrawRichAnno>() ||
obj->isDerivedFrom<TechDraw::DrawViewDimension>() ) {
temp.push_back(obj);
}
}
return temp;
}

View File

@@ -46,15 +46,15 @@ public:
/// constructor
ViewProviderRichAnno();
/// destructor
~ViewProviderRichAnno() override;
~ViewProviderRichAnno() override = default;
App::PropertyLength LineWidth;
App::PropertyEnumeration LineStyle;
App::PropertyColor LineColor;
bool useNewSelectionModel() const override {return false;}
void updateData(const App::Property*) override;
void onChanged(const App::Property* p) override;
void updateData(const App::Property* prop) override;
void onChanged(const App::Property* prop) override;
bool doubleClicked() override;
bool canDelete(App::DocumentObject* obj) const override;
@@ -63,6 +63,10 @@ public:
TechDraw::DrawRichAnno* getViewObject() const override;
TechDraw::DrawRichAnno* getFeature() const;
/// Claim any views that have this as a parent
std::vector<App::DocumentObject*> claimChildren() const override;
protected:
App::Color getDefLineColor();
std::string getDefFont();

View File

@@ -16,7 +16,8 @@ namespace ZVALUE {
const int SECTIONLINE = 90;
const int MATTING = 100;
const int DIMENSION = 110;
const int LABEL = 120;
const int BALLOON = 120;
const int ANNOTATION = 120;
const int TRACKER = 125;
const int LOCK = 200;
}