From 55fbbb5d6eabe7d3f6b2dd6ced60f7be859a3ef1 Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Fri, 5 Apr 2024 09:42:52 +0200 Subject: [PATCH] TechDraw: Insert tool insert DrawViewProjGroupItem that can then be transfered into groups and back. --- src/Mod/TechDraw/App/DrawProjGroup.cpp | 15 +- src/Mod/TechDraw/App/DrawProjGroupItem.cpp | 134 ++++++-------- src/Mod/TechDraw/App/DrawProjGroupItem.h | 5 - src/Mod/TechDraw/Gui/Command.cpp | 89 +++------- src/Mod/TechDraw/Gui/QGIProjGroup.cpp | 19 +- src/Mod/TechDraw/Gui/TaskProjGroup.cpp | 166 ++++++++++++------ src/Mod/TechDraw/Gui/TaskProjGroup.h | 4 + .../Gui/ViewProviderPageExtension.cpp | 9 +- .../Gui/ViewProviderProjGroupItem.cpp | 35 ++-- .../TechDraw/Gui/ViewProviderProjGroupItem.h | 1 + src/Mod/TechDraw/Gui/ViewProviderViewClip.cpp | 7 +- 11 files changed, 245 insertions(+), 239 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawProjGroup.cpp b/src/Mod/TechDraw/App/DrawProjGroup.cpp index 8cdd49c525..7144b17202 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroup.cpp @@ -542,9 +542,8 @@ int DrawProjGroup::purgeProjections() { while (!Views.getValues().empty()) { std::vector views = Views.getValues(); - DrawProjGroupItem* dpgi; DocumentObject* dObj = views.back(); - dpgi = dynamic_cast(dObj); + auto* dpgi = dynamic_cast(dObj); if (dpgi) { std::string itemName = dpgi->Type.getValueAsString(); removeProjection(itemName.c_str()); @@ -1077,8 +1076,7 @@ TechDraw::DrawProjGroupItem* DrawProjGroup::getAnchor() { App::DocumentObject* docObj = Anchor.getValue(); if (docObj) { - DrawProjGroupItem* result = static_cast(docObj); - return result; + return static_cast(docObj); } return nullptr; } @@ -1086,7 +1084,7 @@ TechDraw::DrawProjGroupItem* DrawProjGroup::getAnchor() void DrawProjGroup::setAnchorDirection(const Base::Vector3d dir) { App::DocumentObject* docObj = Anchor.getValue(); - DrawProjGroupItem* item = static_cast(docObj); + auto* item = static_cast(docObj); item->Direction.setValue(dir); } @@ -1096,7 +1094,7 @@ Base::Vector3d DrawProjGroup::getAnchorDirection() if (!docObj) { return Base::Vector3d(); } - DrawProjGroupItem* item = static_cast(docObj); + auto* item = static_cast(docObj); return item->Direction.getValue(); } @@ -1239,8 +1237,7 @@ std::vector DrawProjGroup::getViewsAsDPGI() std::vector result; auto views = Views.getValues(); for (auto& v : views) { - DrawProjGroupItem* item = static_cast(v); - result.push_back(item); + result.push_back(static_cast(v)); } return result; } @@ -1256,7 +1253,7 @@ void DrawProjGroup::dumpISO(const char* title) for (auto& docObj : Views.getValues()) { Base::Vector3d dir; Base::Vector3d axis; - DrawProjGroupItem* v = static_cast(docObj); + auto* v = static_cast(docObj); std::string t = v->Type.getValueAsString(); dir = v->Direction.getValue(); axis = v->getXDirection(); diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp index 5803e85667..489e72afa3 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp @@ -55,7 +55,7 @@ const char *DrawProjGroupItem::TypeEnums[] = { PROPERTY_SOURCE(TechDraw::DrawProjGroupItem, TechDraw::DrawViewPart) -DrawProjGroupItem::DrawProjGroupItem(void) +DrawProjGroupItem::DrawProjGroupItem() { Type.setEnums(TypeEnums); ADD_PROPERTY(Type, ((long)0)); @@ -65,30 +65,25 @@ DrawProjGroupItem::DrawProjGroupItem(void) //projection group controls these // Direction.setStatus(App::Property::ReadOnly, true); RotationVector.setStatus(App::Property::ReadOnly, true); //Use XDirection - ScaleType.setValue("Custom"); - Scale.setStatus(App::Property::Hidden, true); - ScaleType.setStatus(App::Property::Hidden, true); -} - -short DrawProjGroupItem::mustExecute() const -{ - //there is nothing unique about dpgi vs dvp - return TechDraw::DrawViewPart::mustExecute(); + if (getPGroup()) { + ScaleType.setValue("Custom"); + Scale.setStatus(App::Property::Hidden, true); + ScaleType.setStatus(App::Property::Hidden, true); + } } void DrawProjGroupItem::onChanged(const App::Property *prop) { - if ((prop == &X) || - (prop == &Y)) { - DrawProjGroup* parent = getPGroup(); - if (parent) { - parent->touch(false); + if ((prop == &X) || (prop == &Y)) { + DrawProjGroup* pGroup = getPGroup(); + if (pGroup) { + pGroup->touch(false); } } TechDraw::DrawViewPart::onChanged(prop); } -bool DrawProjGroupItem::isLocked(void) const +bool DrawProjGroupItem::isLocked() const { if (isAnchor()) { //Anchor view is always locked to DPG return true; @@ -96,23 +91,22 @@ bool DrawProjGroupItem::isLocked(void) const return DrawView::isLocked(); } -bool DrawProjGroupItem::showLock(void) const +bool DrawProjGroupItem::showLock() const { DrawProjGroup* parent = getPGroup(); bool parentLock = false; if (parent) { parentLock = parent->LockPosition.getValue(); } - - if (isAnchor() && //don't show lock for Front if DPG is not locked - !parentLock) { + //don't show lock for Front if DPG is not locked + if (isAnchor() && !parentLock) { return false; } return DrawView::showLock(); } -App::DocumentObjectExecReturn *DrawProjGroupItem::execute(void) +App::DocumentObjectExecReturn *DrawProjGroupItem::execute() { // Base::Console().Message("DPGI::execute() - %s / %s\n", getNameInDocument(), Label.getValue()); if (!keepUpdated()) { @@ -132,40 +126,46 @@ App::DocumentObjectExecReturn *DrawProjGroupItem::execute(void) //unblock } - if (DrawUtil::checkParallel(Direction.getValue(), - getXDirection())) { + if (DrawUtil::checkParallel(Direction.getValue(), getXDirection())) { return new App::DocumentObjectExecReturn("DPGI: Direction and XDirection are parallel"); } return DrawViewPart::execute(); } -void DrawProjGroupItem::postHlrTasks(void) +void DrawProjGroupItem::postHlrTasks() { // Base::Console().Message("DPGI::postHlrTasks() - %s\n", getNameInDocument()); DrawViewPart::postHlrTasks(); - //DPGI has no geometry until HLR has finished, and the DPG can not properly - //AutoDistibute until all its items have geometry. - autoPosition(); + DrawProjGroup* pGroup = getPGroup(); + if (pGroup) { + //DPGI has no geometry until HLR has finished, and the DPG can not properly + //AutoDistibute until all its items have geometry. + autoPosition(); - getPGroup()->reportReady(); //tell the parent DPG we are ready + pGroup->reportReady(); //tell the parent DPG we are ready + } } void DrawProjGroupItem::autoPosition() { + DrawProjGroup* pGroup = getPGroup(); + if (!pGroup) { + return; + } // Base::Console().Message("DPGI::autoPosition(%s)\n", Label.getValue()); if (LockPosition.getValue()) { return; } Base::Vector3d newPos; - if (getPGroup() && getPGroup()->AutoDistribute.getValue()) { - newPos = getPGroup()->getXYPosition(Type.getValueAsString()); + if (pGroup && pGroup->AutoDistribute.getValue()) { + newPos = pGroup->getXYPosition(Type.getValueAsString()); X.setValue(newPos.x); Y.setValue(newPos.y); requestPaint(); purgeTouched(); //prevents "still touched after recompute" message - getPGroup()->purgeTouched(); //changing dpgi x, y marks parent dpg as touched + pGroup->purgeTouched(); //changing dpgi x, y marks parent dpg as touched } } @@ -184,49 +184,12 @@ DrawProjGroup* DrawProjGroupItem::getPGroup() const return dynamic_cast(getCollection()); } -bool DrawProjGroupItem::isAnchor(void) const +bool DrawProjGroupItem::isAnchor() const { - if (getPGroup() && (getPGroup()->getAnchor() == this) ) { - return true; - } - return false; + return getPGroup() && (getPGroup()->getAnchor() == this); } -/// get a coord system aligned with Direction and Rotation Vector -gp_Ax2 DrawProjGroupItem::getViewAxis(const Base::Vector3d& pt, - const Base::Vector3d& axis, - const bool flip) const -{ - Base::Console().Message("DPGI::getViewAxis - deprecated. use getProjectionCS\n"); - (void) flip; - gp_Ax2 viewAxis; - Base::Vector3d projDir = Direction.getValue(); - Base::Vector3d rotVec = getXDirection(); - -// mirror projDir through XZ plane - Base::Vector3d yNorm(0.0, 1.0, 0.0); - projDir = projDir - (yNorm * 2.0) * (projDir.Dot(yNorm)); - rotVec = rotVec - (yNorm * 2.0) * (rotVec.Dot(yNorm)); - - if (DrawUtil::checkParallel(projDir, rotVec)) { - Base::Console().Warning("DPGI::getVA - %s - Direction and XDirection parallel. using defaults\n", - getNameInDocument()); - } - try { - viewAxis = gp_Ax2(gp_Pnt(pt.x, pt.y, pt.z), - gp_Dir(projDir.x, projDir.y, projDir.z), - gp_Dir(rotVec.x, rotVec.y, rotVec.z)); - } - catch (Standard_Failure& e4) { - Base::Console().Message("PROBLEM - DPGI (%s) failed to create viewAxis: %s **\n", - getNameInDocument(), e4.GetMessageString()); - return ShapeUtils::getViewAxis(pt, axis, false); - } - - return viewAxis; -} - -Base::Vector3d DrawProjGroupItem::getXDirection(void) const +Base::Vector3d DrawProjGroupItem::getXDirection() const { // Base::Console().Message("DPGI::getXDirection() - %s\n", Label.getValue()); Base::Vector3d result(1.0, 0.0, 0.0); //default X @@ -237,19 +200,23 @@ Base::Vector3d DrawProjGroupItem::getXDirection(void) const prop = getPropertyByName("RotationVector"); if (prop) { result = RotationVector.getValue(); //use RotationVector if we have it - } else { + } + else { result = DrawViewPart::getXDirection(); //over complex. } - } else { + } + else { result = DrawViewPart::getXDirection(); } - } else { //not sure this branch can actually happen + } + else { //not sure this branch can actually happen Base::Console().Message("DPGI::getXDirection - unexpected branch taken!\n"); prop = getPropertyByName("RotationVector"); if (prop) { result = RotationVector.getValue(); - } else { + } + else { Base::Console().Message("DPGI::getXDirection - missing RotationVector and XDirection\n"); } } @@ -309,7 +276,7 @@ double DrawProjGroupItem::getRotateAngle() return angle; } -double DrawProjGroupItem::getScale(void) const +double DrawProjGroupItem::getScale() const { auto pgroup = getPGroup(); if (pgroup) { @@ -319,7 +286,7 @@ double DrawProjGroupItem::getScale(void) const } return result; } - return 1.0; + return Scale.getValue(); } int DrawProjGroupItem::getScaleType() const @@ -339,13 +306,12 @@ void DrawProjGroupItem::unsetupObject() return; } - if (!getPGroup()->hasProjection(Type.getValueAsString()) ) { + if (!getPGroup()->hasProjection(Type.getValueAsString())) { DrawViewPart::unsetupObject(); return; } - if ( getPGroup()->getAnchor() == this && - !getPGroup()->isUnsetting() ) { + if (getPGroup()->getAnchor() == this && !getPGroup()->isUnsetting()) { Base::Console().Warning("Warning - DPG (%s/%s) may be corrupt - Anchor deleted\n", getPGroup()->getNameInDocument(), getPGroup()->Label.getValue()); getPGroup()->Anchor.setValue(nullptr); //this catches situation where DPGI is deleted w/o DPG::removeProjection @@ -361,7 +327,7 @@ int DrawProjGroupItem::countParentPages() const if (dpg) { return dpg->countParentPages(); } - return 0; + return DrawView::countParentPages(); } DrawPage* DrawProjGroupItem::findParentPage() const @@ -370,7 +336,7 @@ DrawPage* DrawProjGroupItem::findParentPage() const if (dpg) { return dpg->findParentPage(); } - return nullptr; + return DrawView::findParentPage(); } std::vector DrawProjGroupItem::findAllParentPages() const @@ -379,10 +345,10 @@ std::vector DrawProjGroupItem::findAllParentPages() const if (dpg) { return dpg->findAllParentPages(); } - return std::vector(); + return DrawView::findAllParentPages(); } -PyObject *DrawProjGroupItem::getPyObject(void) +PyObject *DrawProjGroupItem::getPyObject() { if (PythonObject.is(Py::_None())) { // ref counter is set to 1 diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.h b/src/Mod/TechDraw/App/DrawProjGroupItem.h index 1a15f68241..ea115e0755 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.h +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.h @@ -60,7 +60,6 @@ public: App::PropertyEnumeration Type; App::PropertyVector RotationVector; //this is superseded by dvp xdirection - short mustExecute() const override; void onDocumentRestored() override; void unsetupObject() override; @@ -81,10 +80,6 @@ public: //return PyObject as DrawProjGroupItemPy PyObject *getPyObject() override; - gp_Ax2 getViewAxis(const Base::Vector3d& pt, - const Base::Vector3d& direction, - const bool flip=true) const override; - double getScale() const override; int getScaleType() const override; void autoPosition(); diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 5bb1f6b4fe..76143df922 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -422,7 +422,7 @@ void CmdTechDrawView::activated(int iMsg) bool dontShowAgain = hGrp->GetBool("DontShowInsertFileMessage", false); if (!dontShowAgain) { QMessageBox msgBox; - msgBox.setText(msgBox.tr("Note: If you want to insert a shape you need to select it before starting the tool, else it opens a file browser to insert SVG or Images.")); + msgBox.setText(msgBox.tr("If you want to insert a view from existing objects, please select them before evoking this tool. Without a selection, a file browser will open, to insert a SVG or image file.")); QCheckBox dontShowCheckBox(msgBox.tr("Do not show this message again"), &msgBox); msgBox.setCheckBox(&dontShowCheckBox); QPushButton* okButton = msgBox.addButton(QMessageBox::Ok); @@ -478,71 +478,36 @@ void CmdTechDrawView::activated(int iMsg) } Gui::WaitCursor wc; - bool createProjGroup = hGrp->GetBool("InsertAsProjGroup", true); - if (createProjGroup) { - openCommand(QT_TRANSLATE_NOOP("Command", "Create Projection Group")); + openCommand(QT_TRANSLATE_NOOP("Command", "Create view")); + std::string FeatName = getUniqueObjectName("View"); + doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawProjGroupItem', '%s')", + FeatName.c_str()); + doCommand(Doc, "App.activeDocument().%s.translateLabel('DrawProjGroupItem', 'View', '%s')", + FeatName.c_str(), FeatName.c_str()); + doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), + FeatName.c_str()); - std::string multiViewName = getUniqueObjectName("ProjGroup"); - doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawProjGroup', '%s')", - multiViewName.c_str()); - doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), - multiViewName.c_str()); - - App::DocumentObject* docObj = getDocument()->getObject(multiViewName.c_str()); - auto multiView(static_cast(docObj)); - multiView->Source.setValues(shapes); - multiView->XSource.setValues(xShapes); - doCommand(Doc, "App.activeDocument().%s.addProjection('Front')", multiViewName.c_str()); - - getDocument()->setStatus(App::Document::Status::SkipRecompute, true); - doCommand(Doc, - "App.activeDocument().%s.Anchor.Direction = FreeCAD.Vector(0.0, -1.0, 0.0)", - multiViewName.c_str()); - doCommand(Doc, - "App.activeDocument().%s.Anchor.RotationVector = FreeCAD.Vector(1.0, 0.0, 0.0)", - multiViewName.c_str()); - doCommand(Doc, - "App.activeDocument().%s.Anchor.XDirection = FreeCAD.Vector(1.0, 0.0, 0.0)", - multiViewName.c_str()); - getDocument()->setStatus(App::Document::Status::SkipRecompute, false); - - doCommand(Doc, "App.activeDocument().%s.Anchor.recompute()", multiViewName.c_str()); - commitCommand(); - updateActive(); - - // create the rest of the desired views - Gui::Control().showDialog(new TaskDlgProjGroup(multiView, true)); + App::DocumentObject* docObj = getDocument()->getObject(FeatName.c_str()); + auto* dvp = dynamic_cast(docObj); + if (!dvp) { + throw Base::TypeError("CmdTechDrawView DVP not found\n"); } - else { - openCommand(QT_TRANSLATE_NOOP("Command", "Create view")); - std::string FeatName = getUniqueObjectName("View"); - doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewPart', '%s')", - FeatName.c_str()); - doCommand(Doc, "App.activeDocument().%s.translateLabel('DrawViewPart', 'View', '%s')", - FeatName.c_str(), FeatName.c_str()); - doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), - FeatName.c_str()); + dvp->Source.setValues(shapes); + dvp->XSource.setValues(xShapes); - App::DocumentObject* docObj = getDocument()->getObject(FeatName.c_str()); - auto* dvp = dynamic_cast(docObj); - if (!dvp) { - throw Base::TypeError("CmdTechDrawView DVP not found\n"); - } - dvp->Source.setValues(shapes); - dvp->XSource.setValues(xShapes); + getDocument()->setStatus(App::Document::Status::SkipRecompute, true); + doCommand(Doc, "App.activeDocument().%s.Direction = FreeCAD.Vector(0.0, -1.0, 0.0)", + FeatName.c_str()); + doCommand(Doc, "App.activeDocument().%s.RotationVector = FreeCAD.Vector(1.0, 0.0, 0.0)", + FeatName.c_str()); + doCommand(Doc, "App.activeDocument().%s.XDirection = FreeCAD.Vector(1.0, 0.0, 0.0)", + FeatName.c_str()); + getDocument()->setStatus(App::Document::Status::SkipRecompute, false); + doCommand(Doc, "App.activeDocument().%s.recompute()", FeatName.c_str()); + commitCommand(); - getDocument()->setStatus(App::Document::Status::SkipRecompute, true); - doCommand(Doc, "App.activeDocument().%s.Direction = FreeCAD.Vector(0.0, -1.0, 0.0)", - FeatName.c_str()); - doCommand(Doc, "App.activeDocument().%s.XDirection = FreeCAD.Vector(1.0, 0.0, 0.0)", - FeatName.c_str()); - getDocument()->setStatus(App::Document::Status::SkipRecompute, false); - doCommand(Doc, "App.activeDocument().%s.recompute()", FeatName.c_str()); - commitCommand(); - - // create the rest of the desired views - Gui::Control().showDialog(new TaskDlgProjGroup(dvp, true)); - } + // create the rest of the desired views + Gui::Control().showDialog(new TaskDlgProjGroup(dvp, true)); } bool CmdTechDrawView::isActive() { return DrawGuiUtil::needPage(this); } diff --git a/src/Mod/TechDraw/Gui/QGIProjGroup.cpp b/src/Mod/TechDraw/Gui/QGIProjGroup.cpp index f2e15b2c17..cd55cf93c3 100644 --- a/src/Mod/TechDraw/Gui/QGIProjGroup.cpp +++ b/src/Mod/TechDraw/Gui/QGIProjGroup.cpp @@ -65,7 +65,7 @@ bool QGIProjGroup::sceneEventFilter(QGraphicsItem* watched, QEvent *event) QGIView *qAnchor = getAnchorQItem(); if(qAnchor && watched == qAnchor) { - QGraphicsSceneMouseEvent *mEvent = dynamic_cast(event); + auto *mEvent = dynamic_cast(event); switch(event->type()) { case QEvent::GraphicsSceneMousePress: @@ -99,23 +99,27 @@ QVariant QGIProjGroup::itemChange(GraphicsItemChange change, const QVariant &val if(gView) { TechDraw::DrawView *fView = gView->getViewObject(); if(fView->isDerivedFrom()) { - TechDraw::DrawProjGroupItem *projItemPtr = static_cast(fView); + auto *projItemPtr = static_cast(fView); QString type = QString::fromLatin1(projItemPtr->Type.getValueAsString()); if (type == QString::fromLatin1("Front")) { gView->alignTo(m_origin, QString::fromLatin1("None")); installSceneEventFilter(gView); - } else if ( type == QString::fromLatin1("Top") || + } + else if ( type == QString::fromLatin1("Top") || type == QString::fromLatin1("Bottom")) { gView->alignTo(m_origin, QString::fromLatin1("Vertical")); - } else if ( type == QString::fromLatin1("Left") || + } + else if ( type == QString::fromLatin1("Left") || type == QString::fromLatin1("Right") || type == QString::fromLatin1("Rear") ) { gView->alignTo(m_origin, QString::fromLatin1("Horizontal")); - } else if ( type == QString::fromLatin1("FrontTopRight") || + } + else if ( type == QString::fromLatin1("FrontTopRight") || type == QString::fromLatin1("FrontBottomLeft") ) { gView->alignTo(m_origin, QString::fromLatin1("45slash")); - } else if ( type == QString::fromLatin1("FrontTopLeft") || + } + else if ( type == QString::fromLatin1("FrontTopLeft") || type == QString::fromLatin1("FrontBottomRight") ) { gView->alignTo(m_origin, QString::fromLatin1("45backslash")); } @@ -158,7 +162,8 @@ void QGIProjGroup::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) event->ignore(); qAnchor->mouseReleaseEvent(event); } - } else if(scene() && qAnchor) { + } + else if(scene() && qAnchor) { // End of Drag getViewObject()->setPosition(Rez::appX(x()), Rez::appX(getY())); } diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.cpp b/src/Mod/TechDraw/Gui/TaskProjGroup.cpp index bbd1732e5e..9c9ec75c87 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.cpp +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.cpp @@ -62,6 +62,7 @@ #include "MDIViewPage.h" #include "ViewProviderPage.h" #include "ViewProviderDrawingView.h" +#include "ViewProviderProjGroupItem.h" using namespace Gui; @@ -72,7 +73,8 @@ TaskProjGroup::TaskProjGroup(TechDraw::DrawView* featView, bool mode) : ui(new Ui_TaskProjGroup), view(featView), multiView(nullptr), - m_createMode(mode) + m_createMode(mode), + blockCheckboxes(false) { ui->setupUi(this); @@ -80,6 +82,16 @@ TaskProjGroup::TaskProjGroup(TechDraw::DrawView* featView, bool mode) : multiView = dynamic_cast(view); updateUi(); + if (multiView) { + ui->projection->setCurrentIndex(multiView->ProjectionType.getValue()); + ui->cbAutoDistribute->setChecked(multiView->AutoDistribute.getValue()); + // disable if no AutoDistribute + ui->sbXSpacing->setEnabled(multiView->AutoDistribute.getValue()); + ui->sbYSpacing->setEnabled(multiView->AutoDistribute.getValue()); + ui->sbXSpacing->setValue(multiView->spacingX.getValue()); + ui->sbYSpacing->setValue(multiView->spacingY.getValue()); + } + setFractionalScale(view->getScale()); ui->cmbScaleType->setCurrentIndex(view->ScaleType.getValue()); @@ -157,14 +169,6 @@ void TaskProjGroup::updateUi() ui->label_7->show(); ui->label_10->show(); ui->label_11->show(); - - ui->projection->setCurrentIndex(multiView->ProjectionType.getValue()); - ui->cbAutoDistribute->setChecked(multiView->AutoDistribute.getValue()); - // disable if no AutoDistribute - ui->sbXSpacing->setEnabled(multiView->AutoDistribute.getValue()); - ui->sbYSpacing->setEnabled(multiView->AutoDistribute.getValue()); - ui->sbXSpacing->setValue(multiView->spacingX.getValue()); - ui->sbYSpacing->setValue(multiView->spacingY.getValue()); } else { setWindowTitle(QObject::tr("Part View")); @@ -175,6 +179,12 @@ void TaskProjGroup::updateUi() ui->label_7->hide(); ui->label_10->hide(); ui->label_11->hide(); + + // if the view is not a proj group item, then we disable secondary projs. + auto* dpgi = dynamic_cast(view); + if (!dpgi) { + ui->secondaryProjGroupbox->hide(); + } } } @@ -237,49 +247,20 @@ void TaskProjGroup::viewToggled(bool toggle) int index = sender()->objectName().mid(7).toInt(); const char *viewNameCStr = viewChkIndexToCStr(index); - if (multiView) { - // Check if only front is now available. If so switch to normal view. + if (!blockCheckboxes) { + if (multiView) { + // Check if only front is left. If so switch to normal view. + if (multiView->Views.getValues().size() == 2 && !toggle) { + turnProjGroupToView(); + wc.restoreCursor(); + return; + } + } + else { + // If toggle then we remove the view object and create a proj group instead. + turnViewToProjGroup(); + } } - else { - // If toggle then we remove the view object and create a proj group instead. - - App::Document* doc = view->getDocument(); - - std::string multiViewName = doc->getUniqueObjectName("ProjGroup"); - Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().addObject('TechDraw::DrawProjGroup', '%s')", multiViewName.c_str()); - Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().%s.addView(App.activeDocument().%s)", view->findParentPage()->getNameInDocument(), multiViewName.c_str()); - - auto* viewPart = static_cast(view); - multiView = static_cast(doc->getObject(multiViewName.c_str())); - multiView->Source.setValues(viewPart->Source.getValues()); - multiView->XSource.setValues(viewPart->XSource.getValues()); - multiView->X.setValue(viewPart->X.getValue()); - multiView->Y.setValue(viewPart->Y.getValue()); - Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().%s.addProjection('Front')", multiViewName.c_str()); - - Base::Vector3d dir1 = viewPart->Direction.getValue(); - Base::Vector3d dir2 = viewPart->XDirection.getValue(); - - doc->setStatus(App::Document::Status::SkipRecompute, true); - Gui::Command::doCommand(Gui::Command::Gui, - "App.activeDocument().%s.Anchor.Direction = FreeCAD.Vector(%.12f, %.12f, %.12f)", - multiViewName.c_str(), dir1.x, dir1.y, dir1.z); - Gui::Command::doCommand(Gui::Command::Gui, - "App.activeDocument().%s.Anchor.RotationVector = FreeCAD.Vector(%.12f, %.12f, %.12f)", - multiViewName.c_str(), dir2.x, dir2.y, dir2.z); - Gui::Command::doCommand(Gui::Command::Gui, - "App.activeDocument().%s.Anchor.XDirection = FreeCAD.Vector(%.12f, %.12f, %.12f)", - multiViewName.c_str(), dir2.x, dir2.y, dir2.z); - doc->setStatus(App::Document::Status::SkipRecompute, false); - - Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().%s.Anchor.recompute()", multiViewName.c_str()); - - Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().removeObject('%s')", view->getNameInDocument()); - view = multiView; - - updateUi(); - } - if (toggle && !multiView->hasProjection(viewNameCStr)) { Gui::Command::doCommand(Gui::Command::Doc, @@ -304,6 +285,81 @@ void TaskProjGroup::viewToggled(bool toggle) wc.restoreCursor(); } + +void TaskProjGroup::turnViewToProjGroup() +{ + App::Document* doc = view->getDocument(); + + std::string multiViewName = doc->getUniqueObjectName("ProjGroup"); + Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().addObject('TechDraw::DrawProjGroup', '%s')", multiViewName.c_str()); + Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().%s.addView(App.activeDocument().%s)", view->findParentPage()->getNameInDocument(), multiViewName.c_str()); + + auto* viewPart = static_cast(view); + m_page->removeView(viewPart); + + multiView = static_cast(doc->getObject(multiViewName.c_str())); + multiView->Source.setValues(viewPart->Source.getValues()); + multiView->XSource.setValues(viewPart->XSource.getValues()); + multiView->X.setValue(viewPart->X.getValue()); + multiView->Y.setValue(viewPart->Y.getValue()); + multiView->Scale.setValue(viewPart->Scale.getValue()); + multiView->ScaleType.setValue(viewPart->ScaleType.getValue()); + viewPart->X.setValue(0.0); + viewPart->Y.setValue(0.0); + viewPart->ScaleType.setValue("Custom"); + viewPart->Scale.setStatus(App::Property::Hidden, true); + viewPart->ScaleType.setStatus(App::Property::Hidden, true); + viewPart->Label.setValue("Front"); + + multiView->addView(viewPart); + multiView->Anchor.setValue(view); + multiView->Anchor.purgeTouched(); + + viewPart->LockPosition.setValue(true); + viewPart->LockPosition.setStatus(App::Property::ReadOnly, true); //Front should stay locked. + viewPart->LockPosition.purgeTouched(); + + multiView->requestPaint();//make sure the group object is on the Gui page + view = multiView; + + updateUi(); +} + +void TaskProjGroup::turnProjGroupToView() +{ + TechDraw::DrawViewPart* viewPart = multiView->getAnchor(); + viewPart->Scale.setValue(multiView->Scale.getValue()); + viewPart->ScaleType.setValue(multiView->ScaleType.getValue()); + viewPart->Scale.setStatus(App::Property::Hidden, true); + viewPart->ScaleType.setStatus(App::Property::Hidden, true); + viewPart->Scale.purgeTouched(); + viewPart->ScaleType.purgeTouched(); + viewPart->Label.setValue("View"); + viewPart->LockPosition.setValue(false); + viewPart->LockPosition.setStatus(App::Property::ReadOnly, false); + viewPart->LockPosition.purgeTouched(); + viewPart->X.setValue(multiView->X.getValue()); + viewPart->Y.setValue(multiView->Y.getValue()); + m_page->addView(viewPart); + + // remove viewPart from views before deleting the group. + multiView->removeView(viewPart); + + Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().removeObject('%s')", multiView->getNameInDocument()); + + Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_page->getDocument()); + auto* vp = static_cast(activeGui->getViewProvider(viewPart)); + if (vp) { + vp->updateIcon(); + } + viewPart->recomputeFeature(); + + view = viewPart; + multiView = nullptr; + + updateUi(); +} + void TaskProjGroup::customDirectionClicked() { auto* dirEditDlg = new DirectionEditDialog(); @@ -421,13 +477,16 @@ void TaskProjGroup::projectionTypeChanged(QString qText) if (qText == QString::fromUtf8("Page")) { multiView->ProjectionType.setValue("Default"); - } else { + } + else { std::string text = qText.toStdString(); multiView->ProjectionType.setValue(text.c_str()); } // Update checkboxes so checked state matches the drawing + blockCheckboxes = true; setupViewCheckboxes(); + blockCheckboxes = false; // set the tooltips of the checkboxes ui->chkView0->setToolTip(getToolTipForBox(0)); @@ -630,7 +689,8 @@ void TaskProjGroup::setupViewCheckboxes(bool addConnections) if (!multiView->canDelete(viewStr)) { box->setEnabled(false); } - } else { + } + else { box->setCheckState(Qt::Unchecked); } } diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.h b/src/Mod/TechDraw/Gui/TaskProjGroup.h index 7fa48b70f1..cf2bdc5f7f 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.h +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.h @@ -83,6 +83,9 @@ protected: void restoreGroupState(); void updateUi(); + void turnViewToProjGroup(); + void turnProjGroupToView(); + QString formatVector(Base::Vector3d vec); protected Q_SLOTS: @@ -110,6 +113,7 @@ private: bool m_createMode; bool blockUpdate; + bool blockCheckboxes; /// Translate a view checkbox index into represented view string, depending on projection type const char * viewChkIndexToCStr(int index); QString getToolTipForBox(int boxNumber); diff --git a/src/Mod/TechDraw/Gui/ViewProviderPageExtension.cpp b/src/Mod/TechDraw/Gui/ViewProviderPageExtension.cpp index 1e6ba9b674..f81740d836 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderPageExtension.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderPageExtension.cpp @@ -123,9 +123,12 @@ void ViewProviderPageExtension::extensionDropObject(App::DocumentObject* obj) //this code used to live in ViewProviderPage void ViewProviderPageExtension::dropObject(App::DocumentObject* obj) { - if (obj->isDerivedFrom()) { - //DPGI can not be dropped onto the Page as it belongs to DPG, not Page - return; + if (docObj->isDerivedFrom()) { + //DPGI can not be dropped onto the Page if it belongs to DPG + auto* dpgi = static_cast(docObj); + if (dpgi->getPGroup()) { + return; + } } if (obj->isDerivedFrom()) { auto* link = static_cast(obj); diff --git a/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.cpp b/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.cpp index 488b9c9f32..c7944848f4 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.cpp @@ -54,17 +54,25 @@ ViewProviderProjGroupItem::~ViewProviderProjGroupItem() void ViewProviderProjGroupItem::updateData(const App::Property* prop) { Gui::ViewProviderDocumentObject::updateData(prop); + + //TODO: Once we know that ProjType is valid, sPixMap = "Proj" + projType + + updateIcon(); + } + +void ViewProviderProjGroupItem::updateIcon() +{ TechDraw::DrawProjGroupItem* proj = getObject(); - if(!proj) { + if (!proj) { return; } // Set the icon pixmap depending on the orientation std::string projType = proj->Type.getValueAsString(); - //TODO: Once we know that ProjType is valid, sPixMap = "Proj" + projType - - if(strcmp(projType.c_str(), "Front") == 0) { + if (!getObject()->getPGroup()) { + sPixmap = "TechDraw_TreeView"; + } else if(strcmp(projType.c_str(), "Front") == 0) { sPixmap = "TechDraw_ProjFront"; } else if(strcmp(projType.c_str(), "Rear") == 0) { sPixmap = "TechDraw_ProjRear"; @@ -99,8 +107,9 @@ void ViewProviderProjGroupItem::setupContextMenu(QMenu* menu, QObject* receiver, bool ViewProviderProjGroupItem::setEdit(int ModNum) { - Q_UNUSED(ModNum); - doubleClicked(); + if (!getObject()->getPGroup()) { + return ViewProviderViewPart::setEdit(ModNum); + } return true; } @@ -112,6 +121,7 @@ void ViewProviderProjGroupItem::unsetEdit(int ModNum) bool ViewProviderProjGroupItem::doubleClicked() { + setEdit(ViewProvider::Default); return true; } @@ -125,19 +135,16 @@ bool ViewProviderProjGroupItem::onDelete(const std::vector &) bool isAnchor = false; // get the item and group - TechDraw::DrawProjGroupItem* dpgi = static_cast(getViewObject()); + TechDraw::DrawProjGroupItem* dpgi = getObject(); TechDraw::DrawProjGroup* dpg = dpgi->getPGroup(); - // get the projection - TechDraw::DrawProjGroupItem* proj = getObject(); // check if it is the anchor projection - if (dpg && (dpg->hasProjection(proj->Type.getValueAsString())) - && (dpg->getAnchor() == dpgi)) + if (dpg && (dpg->getAnchor() == dpgi)) isAnchor = true; // get child views - auto viewSection = getObject()->getSectionRefs(); - auto viewDetail = getObject()->getDetailRefs(); - auto viewLeader = getObject()->getLeaders(); + auto viewSection = dpgi->getSectionRefs(); + auto viewDetail = dpgi->getDetailRefs(); + auto viewLeader = dpgi->getLeaders(); if (isAnchor) { diff --git a/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.h b/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.h index b24e88ad43..edc0f683e7 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.h +++ b/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.h @@ -48,6 +48,7 @@ public: bool doubleClicked() override; void setupContextMenu(QMenu*, QObject*, const char*) override; void updateData(const App::Property*) override; + void updateIcon(); TechDraw::DrawProjGroupItem* getViewObject() const override; TechDraw::DrawProjGroupItem* getObject() const; diff --git a/src/Mod/TechDraw/Gui/ViewProviderViewClip.cpp b/src/Mod/TechDraw/Gui/ViewProviderViewClip.cpp index d653b9bb25..7147d67c6e 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderViewClip.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderViewClip.cpp @@ -123,8 +123,11 @@ void ViewProviderViewClip::dragObject(App::DocumentObject* docObj) void ViewProviderViewClip::dropObject(App::DocumentObject* docObj) { if (docObj->isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) { - //DPGI can not be dropped onto the Page as it belongs to DPG, not Page - return; + //DPGI can not be dropped onto the Page if it belongs to DPG + auto* dpgi = static_cast(docObj); + if (dpgi->getPGroup()) { + return; + } } if (!docObj->isDerivedFrom(TechDraw::DrawView::getClassTypeId())) { return;