From e68460017b6943c4f6091a20a7544f48d81edde1 Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Fri, 29 Mar 2024 16:59:57 +0100 Subject: [PATCH 1/8] TechDraw: Insert View : Enable handling of spreadsheet and arch objects. Remove the spreadsheet and arch specific commands from the toolbars --- src/Mod/TechDraw/Gui/Command.cpp | 76 +- .../Resources/icons/actions/TechDraw_View.svg | 837 +++++++++++++++--- src/Mod/TechDraw/Gui/Workbench.cpp | 3 - 3 files changed, 765 insertions(+), 151 deletions(-) diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index b918943a6a..15ef3085c8 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -294,7 +294,7 @@ CmdTechDrawView::CmdTechDrawView() : Command("TechDraw_View") sAppModule = "TechDraw"; sGroup = QT_TR_NOOP("TechDraw"); sMenuText = QT_TR_NOOP("Insert View"); - sToolTipText = QT_TR_NOOP("Insert a View"); + sToolTipText = QT_TR_NOOP("Insert a View in current page. You can select Shapes, SpreadSheets or Section Plane from Arch Workbench objects."); sWhatsThis = "TechDraw_View"; sStatusTip = sToolTipText; sPixmap = "actions/TechDraw_View"; @@ -303,23 +303,62 @@ CmdTechDrawView::CmdTechDrawView() : Command("TechDraw_View") void CmdTechDrawView::activated(int iMsg) { Q_UNUSED(iMsg); + bool viewCreated = false; + TechDraw::DrawPage* page = DrawGuiUtil::findPage(this); + if (!page) { + return; + } + std::string PageName = page->getNameInDocument(); //set projection direction from selected Face //use first object with a face selected - std::vector shapes; - std::vector xShapes; + std::vector shapes, xShapes; App::DocumentObject* partObj = nullptr; std::string faceName; - Gui::ResolveMode resolve = Gui::ResolveMode::OldStyleElement;//mystery - bool single = false; //mystery - auto selection = getSelection().getSelectionEx(nullptr, App::DocumentObject::getClassTypeId(), - resolve, single); + auto selection = getSelection().getSelectionEx(nullptr, App::DocumentObject::getClassTypeId()); for (auto& sel : selection) { bool is_linked = false; auto obj = sel.getObject(); - if (obj->isDerivedFrom(TechDraw::DrawPage::getClassTypeId())) { + if (obj->isDerivedFrom() || obj->isDerivedFrom()) { continue; } + + if (obj->isDerivedFrom()) { + std::string SpreadName = obj->getNameInDocument(); + + openCommand(QT_TRANSLATE_NOOP("Command", "Create spreadsheet view")); + std::string FeatName = getUniqueObjectName("Sheet"); + doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewSpreadsheet', '%s')", + FeatName.c_str()); + doCommand(Doc, "App.activeDocument().%s.translateLabel('DrawViewSpreadsheet', 'Sheet', '%s')", + FeatName.c_str(), FeatName.c_str()); + doCommand(Doc, "App.activeDocument().%s.Source = App.activeDocument().%s", FeatName.c_str(), + SpreadName.c_str()); + doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), + FeatName.c_str()); + updateActive(); + commitCommand(); + viewCreated = true; + continue; + } + else if (DrawGuiUtil::isArchSection(obj)) { + std::string FeatName = getUniqueObjectName("ArchView"); + std::string SourceName = obj->getNameInDocument(); + openCommand(QT_TRANSLATE_NOOP("Command", "Create ArchView")); + doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewArch', '%s')", + FeatName.c_str()); + doCommand(Doc, "App.activeDocument().%s.translateLabel('DrawViewArch', 'ArchView', '%s')", + FeatName.c_str(), FeatName.c_str()); + doCommand(Doc, "App.activeDocument().%s.Source = App.activeDocument().%s", FeatName.c_str(), + SourceName.c_str()); + doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), + FeatName.c_str()); + updateActive(); + commitCommand(); + viewCreated = true; + continue; + } + if (obj->isDerivedFrom(App::LinkElement::getClassTypeId()) || obj->isDerivedFrom(App::LinkGroup::getClassTypeId()) || obj->isDerivedFrom(App::Link::getClassTypeId())) { @@ -365,19 +404,15 @@ void CmdTechDrawView::activated(int iMsg) } if (shapes.empty() && xShapes.empty()) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("No Shapes, Groups or Links in this selection")); + if (!viewCreated) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("No Suitable objects in this selection")); + } return; } - TechDraw::DrawPage* page = DrawGuiUtil::findPage(this); - if (!page) { - return; - } - std::string PageName = page->getNameInDocument(); Base::Vector3d projDir; - Gui::WaitCursor wc; openCommand(QT_TRANSLATE_NOOP("Command", "Create view")); std::string FeatName = getUniqueObjectName("View"); @@ -1493,15 +1528,14 @@ void CmdTechDrawDraftView::activated(int iMsg) std::string PageName = page->getNameInDocument(); std::pair dirs = DrawGuiUtil::get3DDirAndRot(); - for (std::vector::iterator it = objects.begin(); it != objects.end(); - ++it) { - if ((*it)->isDerivedFrom(TechDraw::DrawPage::getClassTypeId()) || - (*it)->isDerivedFrom(TechDraw::DrawView::getClassTypeId())) { + for (auto* obj : objects) { + if (obj->isDerivedFrom(TechDraw::DrawPage::getClassTypeId()) || + obj->isDerivedFrom(TechDraw::DrawView::getClassTypeId())) { // skip over TechDraw objects as they are not valid subjects for a DraftView continue; } std::string FeatName = getUniqueObjectName("DraftView"); - std::string SourceName = (*it)->getNameInDocument(); + std::string SourceName = obj->getNameInDocument(); openCommand(QT_TRANSLATE_NOOP("Command", "Create DraftView")); doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewDraft', '%s')", FeatName.c_str()); diff --git a/src/Mod/TechDraw/Gui/Resources/icons/actions/TechDraw_View.svg b/src/Mod/TechDraw/Gui/Resources/icons/actions/TechDraw_View.svg index 8de5db7f71..1756706e19 100644 --- a/src/Mod/TechDraw/Gui/Resources/icons/actions/TechDraw_View.svg +++ b/src/Mod/TechDraw/Gui/Resources/icons/actions/TechDraw_View.svg @@ -1,146 +1,623 @@ - - - - + + + - - - - + + + + + - - - - + + + + + - - - - - + + + + - - - - + + + + - - - - - - - - + + + - - - + + + - - - + + + - - - + + + - - - - + + + + - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - + + + + + - - - - + + + + + + + + + + + - - - - + - + image/svg+xml - - + [agryson] Alexander Gryson http://agryson.net - + TechDraw_View 2016-01-14 https://www.freecad.org/wiki/index.php?title=Artwork @@ -161,24 +638,130 @@ - - - - - - - + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/TechDraw/Gui/Workbench.cpp b/src/Mod/TechDraw/Gui/Workbench.cpp index 50832dd029..9da46e3014 100644 --- a/src/Mod/TechDraw/Gui/Workbench.cpp +++ b/src/Mod/TechDraw/Gui/Workbench.cpp @@ -298,8 +298,6 @@ Gui::ToolBarItem* Workbench::setupToolBars() const *views << "TechDraw_SectionGroup"; *views << "TechDraw_DetailView"; *views << "TechDraw_DraftView"; - *views << "TechDraw_ArchView"; - *views << "TechDraw_SpreadsheetView"; *views << "TechDraw_ClipGroup"; *views << "TechDraw_ProjectShape"; @@ -405,7 +403,6 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const *views << "TechDraw_SectionGroup"; *views << "TechDraw_DetailView"; *views << "TechDraw_DraftView"; - *views << "TechDraw_SpreadsheetView"; *views << "TechDraw_ClipGroup"; *views << "TechDraw_ProjectShape"; From 3d14c7d0b079074b5818c9d96aa76e86e92208e0 Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Fri, 29 Mar 2024 17:41:48 +0100 Subject: [PATCH 2/8] TechDraw: Insert View : Enable handling of image and SVG if no selection. --- src/Mod/TechDraw/Gui/Command.cpp | 65 +- .../Resources/icons/actions/TechDraw_View.svg | 804 +++--------------- src/Mod/TechDraw/Gui/Workbench.cpp | 4 - 3 files changed, 197 insertions(+), 676 deletions(-) diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 15ef3085c8..0ef6802b3c 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #endif @@ -294,7 +296,9 @@ CmdTechDrawView::CmdTechDrawView() : Command("TechDraw_View") sAppModule = "TechDraw"; sGroup = QT_TR_NOOP("TechDraw"); sMenuText = QT_TR_NOOP("Insert View"); - sToolTipText = QT_TR_NOOP("Insert a View in current page. You can select Shapes, SpreadSheets or Section Plane from Arch Workbench objects."); + sToolTipText = QT_TR_NOOP("Insert a View in current page.\n" + "Selected objects, spreadsheets or Arch WB section planes will be added with the current camera orientation.\n" + "Without a selection, a file browser lets you select a SVG or image file."); sWhatsThis = "TechDraw_View"; sStatusTip = sToolTipText; sPixmap = "actions/TechDraw_View"; @@ -403,15 +407,68 @@ void CmdTechDrawView::activated(int iMsg) } } + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/TechDraw"); if (shapes.empty() && xShapes.empty()) { if (!viewCreated) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("No Suitable objects in this selection")); + // If nothing was selected, then we offer to insert SVG or Images files. + 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.")); + QCheckBox dontShowCheckBox(msgBox.tr("Do not show this message again"), &msgBox); + msgBox.setCheckBox(&dontShowCheckBox); + QPushButton* okButton = msgBox.addButton(QMessageBox::Ok); + + msgBox.exec(); + + if (msgBox.clickedButton() == okButton && dontShowCheckBox.isChecked()) { + // Save the preference to not show the message again + hGrp->SetBool("DontShowInsertFileMessage", true); + } + } + + QString filename = Gui::FileDialog::getOpenFileName(Gui::getMainWindow(), + QObject::tr("Select a SVG or Image file to open"), QString(), + QString::fromLatin1("%1 (*.svg *.svgz *.jpg *.jpeg *.png *.bmp);;%2 (*.*)") + .arg(QObject::tr("SVG or Image files"), QObject::tr("All Files"))); + + if (!filename.isEmpty()) { + if (filename.endsWith(QString::fromLatin1(".svg"), Qt::CaseInsensitive) + || filename.endsWith(QString::fromLatin1(".svgz"), Qt::CaseInsensitive)) { + std::string FeatName = getUniqueObjectName("Symbol"); + filename = Base::Tools::escapeEncodeFilename(filename); + openCommand(QT_TRANSLATE_NOOP("Command", "Create Symbol")); + doCommand(Doc, "f = open(\"%s\", 'r')", (const char*)filename.toUtf8()); + doCommand(Doc, "svg = f.read()"); + doCommand(Doc, "f.close()"); + doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewSymbol', '%s')", + FeatName.c_str()); + 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()); + doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), + FeatName.c_str()); + } + else { + std::string FeatName = getUniqueObjectName("Image"); + filename = Base::Tools::escapeEncodeFilename(filename); + 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(), filename.toUtf8().constData()); + doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str()); + updateActive(); + commitCommand(); + } + + updateActive(); + commitCommand(); + } } return; } - Base::Vector3d projDir; Gui::WaitCursor wc; openCommand(QT_TRANSLATE_NOOP("Command", "Create view")); diff --git a/src/Mod/TechDraw/Gui/Resources/icons/actions/TechDraw_View.svg b/src/Mod/TechDraw/Gui/Resources/icons/actions/TechDraw_View.svg index 1756706e19..598b329cb6 100644 --- a/src/Mod/TechDraw/Gui/Resources/icons/actions/TechDraw_View.svg +++ b/src/Mod/TechDraw/Gui/Resources/icons/actions/TechDraw_View.svg @@ -1,372 +1,68 @@ + + - - - - + id="defs2871"> + id="linearGradient5"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="stop19" /> + id="stop20" /> + + + + + + + + + + + + + + + gradientTransform="matrix(0.86186705,0,0,0.89755344,-75.697779,-13.617255)" /> - - - - - - - - - - - - - - - + gradientTransform="matrix(0.86186705,0,0,0.89755344,-75.697779,-13.617255)" /> + id="linearGradient4029"> - - - - - - - - - - + style="stop-color:#06989a;stop-opacity:1" /> - + style="stop-color:#16d0d2;stop-opacity:1" /> - - - - - - - + id="metadata2874"> @@ -612,156 +133,103 @@ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - [agryson] Alexander Gryson + [maxwxyz] - http://agryson.net - - TechDraw_View - 2016-01-14 https://www.freecad.org/wiki/index.php?title=Artwork FreeCAD - FreeCAD/src/Mod/TechDraw/Gui/Resources/icons/actions/TechDraw_View.svg + FreeCAD/src/ FreeCAD LGPL2+ - - - [agryson] Alexander Gryson - - + 2024 - - - - - - - - - - - - - - - - - - + id="layer3" + style="display:inline"> + style="fill:url(#linearGradient4001);fill-opacity:1;stroke:#042a2a;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-dasharray:none" + d="M 2.7321186,26.119882 V 9.1479626 L 17.58275,13.390943 v 16.971918 z" + id="path3185" /> + style="fill:#34e0e2;stroke:#042a2a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;stroke-dasharray:none" + d="M 2.7321186,9.1479626 15.461232,2.7834937 30.311865,7.0264734 17.58275,13.390943 Z" + id="path3973" /> + style="fill:url(#linearGradient4027);fill-opacity:1;stroke:#042a2a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;stroke-dasharray:none" + d="M 17.58275,13.390943 V 30.362861 L 30.311865,23.998393 V 7.0264734 Z" + id="path3975" /> - - + style="fill:none;stroke:#34e0e2;stroke-width:1.68721;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" + d="M 4.3544558,24.885332 V 11.33044 l 11.5383362,3.245562 0.07098,13.641827 z" + id="path3185-7" /> + style="fill:none;stroke:#16d0d2;stroke-width:1.68721;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 19.190762,14.387266 -0.01437,13.542121 9.51313,-4.666242 -0.03206,-13.4974003 z" + id="path3975-4" /> + + + + + + + + + id="path6" + style="fill:none;stroke:#0b1e23;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.8;stroke-opacity:1" + d="M 23.331615,34.789022 H 17.87336 m 17.458255,0 H 29.87336 M 23.331615,58.69951 H 17.87336 M 42.789873,34.929018 h 4.005096 v 4.26789 m 0,5.078236 v 5.078235 m 0,5.078235 V 58.69951 H 42.78987 m -7.458255,0 H 29.87336 m -19.458255,0 H 6.4100098 v -4.26789 m 0,-5.078235 V 44.27515 m 0,-5.078236 v -4.267896 h 4.0050982" /> + + + + + diff --git a/src/Mod/TechDraw/Gui/Workbench.cpp b/src/Mod/TechDraw/Gui/Workbench.cpp index 9da46e3014..08bb9fd11c 100644 --- a/src/Mod/TechDraw/Gui/Workbench.cpp +++ b/src/Mod/TechDraw/Gui/Workbench.cpp @@ -362,8 +362,6 @@ Gui::ToolBarItem* Workbench::setupToolBars() const decor->setCommand("TechDraw Decoration"); *decor << "TechDraw_Hatch"; *decor << "TechDraw_GeometricHatch"; - *decor << "TechDraw_Symbol"; - *decor << "TechDraw_Image"; *decor << "TechDraw_ToggleFrame"; Gui::ToolBarItem* anno = new Gui::ToolBarItem(root); @@ -467,8 +465,6 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const decor->setCommand("TechDraw Decoration"); *decor << "TechDraw_Hatch"; *decor << "TechDraw_GeometricHatch"; - *decor << "TechDraw_Symbol"; - *decor << "TechDraw_Image"; *decor << "TechDraw_ToggleFrame"; Gui::ToolBarItem* anno = new Gui::ToolBarItem(root); From 246496eed170afc28023ca46206a77142f1593e6 Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Sat, 30 Mar 2024 22:02:41 +0100 Subject: [PATCH 3/8] TechDraw: Add taskbox to Part View. Removes Projection Group from toolbar. --- src/Mod/TechDraw/App/DrawProjGroup.cpp | 69 +--- src/Mod/TechDraw/App/DrawViewPart.cpp | 118 ++++++ src/Mod/TechDraw/App/DrawViewPart.h | 5 + src/Mod/TechDraw/Gui/Command.cpp | 139 ++++--- src/Mod/TechDraw/Gui/Resources/TechDraw.qrc | 1 + .../icons/TechDraw_CameraOrientation.svg | 195 +++++++++ src/Mod/TechDraw/Gui/TaskProjGroup.cpp | 388 +++++++++++++----- src/Mod/TechDraw/Gui/TaskProjGroup.h | 17 +- src/Mod/TechDraw/Gui/TaskProjGroup.ui | 212 +++++----- src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp | 11 +- src/Mod/TechDraw/Gui/Workbench.cpp | 2 - 11 files changed, 784 insertions(+), 373 deletions(-) create mode 100644 src/Mod/TechDraw/Gui/Resources/icons/TechDraw_CameraOrientation.svg diff --git a/src/Mod/TechDraw/App/DrawProjGroup.cpp b/src/Mod/TechDraw/App/DrawProjGroup.cpp index 0a7fcf49ea..679772ffa7 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroup.cpp @@ -583,74 +583,7 @@ std::pair DrawProjGroup::getDirsFromFront(std::s throw Base::RuntimeError("Project Group missing Anchor projection item"); } - Base::Vector3d org(0.0, 0.0, 0.0); - gp_Ax2 anchorCS = anch->getProjectionCS(org); - gp_Pnt gOrg(0.0, 0.0, 0.0); - gp_Dir gDir = anchorCS.Direction(); - gp_Dir gXDir = anchorCS.XDirection(); - gp_Dir gYDir = anchorCS.YDirection(); - gp_Ax1 gUpAxis(gOrg, gYDir); - gp_Ax2 newCS; - gp_Dir gNewDir; - gp_Dir gNewXDir; - - double angle = M_PI / 2.0;//90* - - if (viewType == "Right") { - newCS = anchorCS.Rotated(gUpAxis, angle); - projDir = dir2vec(newCS.Direction()); - rotVec = dir2vec(newCS.XDirection()); - } - else if (viewType == "Left") { - newCS = anchorCS.Rotated(gUpAxis, -angle); - projDir = dir2vec(newCS.Direction()); - rotVec = dir2vec(newCS.XDirection()); - } - else if (viewType == "Top") { - projDir = dir2vec(gYDir); - rotVec = dir2vec(gXDir); - } - else if (viewType == "Bottom") { - projDir = dir2vec(gYDir.Reversed()); - rotVec = dir2vec(gXDir); - } - else if (viewType == "Rear") { - projDir = dir2vec(gDir.Reversed()); - rotVec = dir2vec(gXDir.Reversed()); - } - else if (viewType == "FrontTopLeft") { - gp_Dir newDir = gp_Dir(gp_Vec(gDir) - gp_Vec(gXDir) + gp_Vec(gYDir)); - projDir = dir2vec(newDir); - gp_Dir newXDir = gp_Dir(gp_Vec(gXDir) + gp_Vec(gDir)); - rotVec = dir2vec(newXDir); - } - else if (viewType == "FrontTopRight") { - gp_Dir newDir = gp_Dir(gp_Vec(gDir) + gp_Vec(gXDir) + gp_Vec(gYDir)); - projDir = dir2vec(newDir); - gp_Dir newXDir = gp_Dir(gp_Vec(gXDir) - gp_Vec(gDir)); - rotVec = dir2vec(newXDir); - } - else if (viewType == "FrontBottomLeft") { - gp_Dir newDir = gp_Dir(gp_Vec(gDir) - gp_Vec(gXDir) - gp_Vec(gYDir)); - projDir = dir2vec(newDir); - gp_Dir newXDir = gp_Dir(gp_Vec(gXDir) + gp_Vec(gDir)); - rotVec = dir2vec(newXDir); - } - else if (viewType == "FrontBottomRight") { - gp_Dir newDir = gp_Dir(gp_Vec(gDir) + gp_Vec(gXDir) - gp_Vec(gYDir)); - projDir = dir2vec(newDir); - gp_Dir newXDir = gp_Dir(gp_Vec(gXDir) - gp_Vec(gDir)); - rotVec = dir2vec(newXDir); - } else { - // not one of the standard view directions, so complain and use the values for "Front" - Base::Console().Error("DrawProjGroup - %s unknown projection: %s\n", getNameInDocument(), - viewType.c_str()); - Base::Vector3d dirAnch = anch->Direction.getValue(); - Base::Vector3d rotAnch = anch->getXDirection(); - return std::make_pair(dirAnch, rotAnch); - } - - return std::make_pair(projDir, rotVec); + return anch->getDirsFromFront(viewType); } Base::Vector3d DrawProjGroup::dir2vec(gp_Dir d) diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index f2876419bb..07f43c5d4e 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -1263,6 +1263,124 @@ Base::Vector3d DrawViewPart::getXDirection() const return result; } + +void DrawViewPart::rotate(const std::string& rotationdirection) +{ + std::pair newDirs; + if (rotationdirection == "Right") + newDirs = getDirsFromFront("Left");// Front -> Right -> Rear -> Left -> Front + else if (rotationdirection == "Left") + newDirs = getDirsFromFront("Right");// Front -> Left -> Rear -> Right -> Front + else if (rotationdirection == "Up") + newDirs = getDirsFromFront("Bottom");// Front -> Top -> Rear -> Bottom -> Front + else if (rotationdirection == "Down") + newDirs = getDirsFromFront("Top");// Front -> Bottom -> Rear -> Top -> Front + + Direction.setValue(newDirs.first); + XDirection.setValue(newDirs.second); + recompute(); +} + +void DrawViewPart::spin(const std::string& spindirection) +{ + double angle; + if (spindirection == "CW") + angle = M_PI / 2.0;// Top -> Right -> Bottom -> Left -> Top + if (spindirection == "CCW") + angle = -M_PI / 2.0;// Top -> Left -> Bottom -> Right -> Top + + Base::Vector3d org(0.0, 0.0, 0.0); + Base::Vector3d curRot = getXDirection(); + Base::Vector3d curDir = Direction.getValue(); + Base::Vector3d newRot = DrawUtil::vecRotate(curRot, angle, curDir, org); + + XDirection.setValue(newRot); + recompute(); +} + +std::pair DrawViewPart::getDirsFromFront(std::string viewType) +{ + // Base::Console().Message("DVP::getDirsFromFront(%s)\n", viewType.c_str()); + std::pair result; + + Base::Vector3d projDir, rotVec; + + Base::Vector3d org(0.0, 0.0, 0.0); + gp_Ax2 anchorCS = getProjectionCS(org); + gp_Pnt gOrg(0.0, 0.0, 0.0); + gp_Dir gDir = anchorCS.Direction(); + gp_Dir gXDir = anchorCS.XDirection(); + gp_Dir gYDir = anchorCS.YDirection(); + gp_Ax1 gUpAxis(gOrg, gYDir); + gp_Ax2 newCS; + gp_Dir gNewDir; + gp_Dir gNewXDir; + + double angle = M_PI / 2.0;//90* + + if (viewType == "Right") { + newCS = anchorCS.Rotated(gUpAxis, angle); + projDir = dir2vec(newCS.Direction()); + rotVec = dir2vec(newCS.XDirection()); + } + else if (viewType == "Left") { + newCS = anchorCS.Rotated(gUpAxis, -angle); + projDir = dir2vec(newCS.Direction()); + rotVec = dir2vec(newCS.XDirection()); + } + else if (viewType == "Top") { + projDir = dir2vec(gYDir); + rotVec = dir2vec(gXDir); + } + else if (viewType == "Bottom") { + projDir = dir2vec(gYDir.Reversed()); + rotVec = dir2vec(gXDir); + } + else if (viewType == "Rear") { + projDir = dir2vec(gDir.Reversed()); + rotVec = dir2vec(gXDir.Reversed()); + } + else if (viewType == "FrontTopLeft") { + gp_Dir newDir = gp_Dir(gp_Vec(gDir) - gp_Vec(gXDir) + gp_Vec(gYDir)); + projDir = dir2vec(newDir); + gp_Dir newXDir = gp_Dir(gp_Vec(gXDir) + gp_Vec(gDir)); + rotVec = dir2vec(newXDir); + } + else if (viewType == "FrontTopRight") { + gp_Dir newDir = gp_Dir(gp_Vec(gDir) + gp_Vec(gXDir) + gp_Vec(gYDir)); + projDir = dir2vec(newDir); + gp_Dir newXDir = gp_Dir(gp_Vec(gXDir) - gp_Vec(gDir)); + rotVec = dir2vec(newXDir); + } + else if (viewType == "FrontBottomLeft") { + gp_Dir newDir = gp_Dir(gp_Vec(gDir) - gp_Vec(gXDir) - gp_Vec(gYDir)); + projDir = dir2vec(newDir); + gp_Dir newXDir = gp_Dir(gp_Vec(gXDir) + gp_Vec(gDir)); + rotVec = dir2vec(newXDir); + } + else if (viewType == "FrontBottomRight") { + gp_Dir newDir = gp_Dir(gp_Vec(gDir) + gp_Vec(gXDir) - gp_Vec(gYDir)); + projDir = dir2vec(newDir); + gp_Dir newXDir = gp_Dir(gp_Vec(gXDir) - gp_Vec(gDir)); + rotVec = dir2vec(newXDir); + } + else { + // not one of the standard view directions, so complain and use the values for "Front" + Base::Console().Error("DrawViewPart - %s unknown projection: %s\n", getNameInDocument(), + viewType.c_str()); + Base::Vector3d dirAnch = Direction.getValue(); + Base::Vector3d rotAnch = getXDirection(); + return std::make_pair(dirAnch, rotAnch); + } + + return std::make_pair(projDir, rotVec); +} + +Base::Vector3d DrawViewPart::dir2vec(gp_Dir d) +{ + return Base::Vector3d(d.X(), d.Y(), d.Z()); +} + Base::Vector3d DrawViewPart::getLegacyX(const Base::Vector3d& pt, const Base::Vector3d& axis, const bool flip) const { diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 896261665b..32b321bfca 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -172,6 +172,11 @@ public: virtual Base::Vector3d getLegacyX(const Base::Vector3d& pt, const Base::Vector3d& axis, const bool flip = true) const; + void rotate(const std::string& rotationdirection); + void spin(const std::string& spindirection); + std::pair getDirsFromFront(std::string viewType); + Base::Vector3d dir2vec(gp_Dir d); + gp_Ax2 localVectorToCS(const Base::Vector3d localUnit) const; Base::Vector3d localVectorToDirection(const Base::Vector3d localUnit) const; diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 0ef6802b3c..a14044c6e9 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -297,7 +297,7 @@ CmdTechDrawView::CmdTechDrawView() : Command("TechDraw_View") sGroup = QT_TR_NOOP("TechDraw"); sMenuText = QT_TR_NOOP("Insert View"); sToolTipText = QT_TR_NOOP("Insert a View in current page.\n" - "Selected objects, spreadsheets or Arch WB section planes will be added with the current camera orientation.\n" + "Selected objects, spreadsheets or Arch WB section planes will be added.\n" "Without a selection, a file browser lets you select a SVG or image file."); sWhatsThis = "TechDraw_View"; sStatusTip = sToolTipText; @@ -469,51 +469,72 @@ void CmdTechDrawView::activated(int iMsg) return; } - Base::Vector3d projDir; Gui::WaitCursor wc; - 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()); + bool createProjGroup = hGrp->GetBool("InsertAsProjGroup", true); + if (createProjGroup) { + openCommand(QT_TRANSLATE_NOOP("Command", "Create Projection Group")); + + 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()); - App::DocumentObject* docObj = getDocument()->getObject(FeatName.c_str()); - TechDraw::DrawViewPart* dvp = dynamic_cast(docObj); - if (!dvp) { - throw Base::TypeError("CmdTechDrawView DVP not found\n"); - } - dvp->Source.setValues(shapes); - dvp->XSource.setValues(xShapes); - if (!faceName.empty()) { - std::pair dirs = - DrawGuiUtil::getProjDirFromFace(partObj, faceName); - projDir = dirs.first; getDocument()->setStatus(App::Document::Status::SkipRecompute, true); - doCommand(Doc, "App.activeDocument().%s.Direction = FreeCAD.Vector(%.12f, %.12f, %.12f)", - FeatName.c_str(), projDir.x, projDir.y, projDir.z); - //do something clever with dirs.second; - // dvp->setXDir(dirs.second); - doCommand(Doc, "App.activeDocument().%s.XDirection = FreeCAD.Vector(%.12f, %.12f, %.12f)", - FeatName.c_str(), dirs.second.x, dirs.second.y, dirs.second.z); - doCommand(Doc, "App.activeDocument().%s.recompute()", FeatName.c_str()); + 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)); } else { - std::pair dirs = DrawGuiUtil::get3DDirAndRot(); - projDir = dirs.first; + 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()); + + 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(%.12f, %.12f, %.12f)", - FeatName.c_str(), projDir.x, projDir.y, projDir.z); - doCommand(Doc, "App.activeDocument().%s.XDirection = FreeCAD.Vector(%.12f, %.12f, %.12f)", - FeatName.c_str(), dirs.second.x, dirs.second.y, dirs.second.z); - // dvp->setXDir(dirs.second); + 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)); } - commitCommand(); } bool CmdTechDrawView::isActive() { return DrawGuiUtil::needPage(this); } @@ -1106,37 +1127,21 @@ void CmdTechDrawProjectionGroup::activated(int iMsg) multiView->XSource.setValues(xShapes); doCommand(Doc, "App.activeDocument().%s.addProjection('Front')", multiViewName.c_str()); - if (!faceName.empty()) { - std::pair dirs = - DrawGuiUtil::getProjDirFromFace(partObj, faceName); - getDocument()->setStatus(App::Document::Status::SkipRecompute, true); - doCommand(Doc, - "App.activeDocument().%s.Anchor.Direction = FreeCAD.Vector(%.12f, %.12f, %.12f)", - multiViewName.c_str(), dirs.first.x, dirs.first.y, dirs.first.z); - doCommand( - Doc, - "App.activeDocument().%s.Anchor.RotationVector = FreeCAD.Vector(%.12f, %.12f, %.12f)", - multiViewName.c_str(), dirs.second.x, dirs.second.y, dirs.second.z); - doCommand(Doc, - "App.activeDocument().%s.Anchor.XDirection = FreeCAD.Vector(%.12f, %.12f, %.12f)", - multiViewName.c_str(), dirs.second.x, dirs.second.y, dirs.second.z); - getDocument()->setStatus(App::Document::Status::SkipRecompute, false); - } - else { - std::pair dirs = DrawGuiUtil::get3DDirAndRot(); - getDocument()->setStatus(App::Document::Status::SkipRecompute, true); - doCommand(Doc, - "App.activeDocument().%s.Anchor.Direction = FreeCAD.Vector(%.12f, %.12f, %.12f)", - multiViewName.c_str(), dirs.first.x, dirs.first.y, dirs.first.z); - doCommand( - Doc, - "App.activeDocument().%s.Anchor.RotationVector = FreeCAD.Vector(%.12f, %.12f, %.12f)", - multiViewName.c_str(), dirs.second.x, dirs.second.y, dirs.second.z); - doCommand(Doc, - "App.activeDocument().%s.Anchor.XDirection = FreeCAD.Vector(%.12f, %.12f, %.12f)", - multiViewName.c_str(), dirs.second.x, dirs.second.y, dirs.second.z); - getDocument()->setStatus(App::Document::Status::SkipRecompute, false); - } + std::pair dirs = !faceName.empty() ? + DrawGuiUtil::getProjDirFromFace(partObj, faceName) + : DrawGuiUtil::get3DDirAndRot(); + + getDocument()->setStatus(App::Document::Status::SkipRecompute, true); + doCommand(Doc, + "App.activeDocument().%s.Anchor.Direction = FreeCAD.Vector(%.12f, %.12f, %.12f)", + multiViewName.c_str(), dirs.first.x, dirs.first.y, dirs.first.z); + doCommand(Doc, + "App.activeDocument().%s.Anchor.RotationVector = FreeCAD.Vector(%.12f, %.12f, %.12f)", + multiViewName.c_str(), dirs.second.x, dirs.second.y, dirs.second.z); + doCommand(Doc, + "App.activeDocument().%s.Anchor.XDirection = FreeCAD.Vector(%.12f, %.12f, %.12f)", + multiViewName.c_str(), dirs.second.x, dirs.second.y, dirs.second.z); + getDocument()->setStatus(App::Document::Status::SkipRecompute, false); doCommand(Doc, "App.activeDocument().%s.Anchor.recompute()", multiViewName.c_str()); commitCommand(); diff --git a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc index df640134ff..82812f4187 100644 --- a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc +++ b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc @@ -87,6 +87,7 @@ icons/TechDraw_3PtAngleDimension.svg icons/TechDraw_AngleDimension.svg icons/TechDraw_Balloon.svg + icons/TechDraw_CameraOrientation.svg icons/TechDraw_DiameterDimension.svg icons/TechDraw_Dimension.svg icons/TechDraw_DimensionRepair.svg diff --git a/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_CameraOrientation.svg b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_CameraOrientation.svg new file mode 100644 index 0000000000..1c103f40dc --- /dev/null +++ b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_CameraOrientation.svg @@ -0,0 +1,195 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.cpp b/src/Mod/TechDraw/Gui/TaskProjGroup.cpp index 043810c0f7..8b285dc2b5 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.cpp +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.cpp @@ -27,6 +27,7 @@ # include #endif // #ifndef _PreComp_ +#include #include #include #include @@ -36,37 +37,41 @@ #include #include -#include +#include +#include #include +#include #include +#include "DrawGuiUtil.h" #include "TaskProjGroup.h" #include "ui_TaskProjGroup.h" #include "MDIViewPage.h" #include "ViewProviderPage.h" -#include "ViewProviderProjGroup.h" +#include "ViewProviderDrawingView.h" using namespace Gui; using namespace TechDraw; using namespace TechDrawGui; -TaskProjGroup::TaskProjGroup(TechDraw::DrawProjGroup* featView, bool mode) : +TaskProjGroup::TaskProjGroup(TechDraw::DrawView* featView, bool mode) : ui(new Ui_TaskProjGroup), - multiView(featView), + view(featView), + multiView(nullptr), m_createMode(mode) { ui->setupUi(this); blockUpdate = true; + multiView = dynamic_cast(view); + updateUi(); - ui->projection->setCurrentIndex(multiView->ProjectionType.getValue()); - - setFractionalScale(multiView->getScale()); - ui->cmbScaleType->setCurrentIndex(multiView->ScaleType.getValue()); + setFractionalScale(view->getScale()); + ui->cmbScaleType->setCurrentIndex(view->ScaleType.getValue()); //Allow or prevent scale changing initially - if (multiView->ScaleType.isValue("Custom")) { + if (view->ScaleType.isValue("Custom")) { ui->sbScaleNum->setEnabled(true); ui->sbScaleDen->setEnabled(true); } @@ -75,12 +80,6 @@ TaskProjGroup::TaskProjGroup(TechDraw::DrawProjGroup* featView, bool mode) : ui->sbScaleDen->setEnabled(false); } - 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()); // Initially toggle view checkboxes if needed setupViewCheckboxes(true); @@ -95,6 +94,8 @@ TaskProjGroup::TaskProjGroup(TechDraw::DrawProjGroup* featView, bool mode) : connect(ui->butDownRotate, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked); connect(ui->butLeftRotate, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked); connect(ui->butCCWRotate, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked); + connect(ui->butFront, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked); + connect(ui->butCam, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked); // //Reset button // connect(ui->butReset, SIGNAL(clicked()), this, SLOT(onResetClicked())); @@ -120,36 +121,71 @@ TaskProjGroup::TaskProjGroup(TechDraw::DrawProjGroup* featView, bool mode) : ui->sbXSpacing->setUnit(Base::Unit::Length); ui->sbYSpacing->setUnit(Base::Unit::Length); - m_page = multiView->findParentPage(); + m_page = view->findParentPage(); Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_page->getDocument()); Gui::ViewProvider* vp = activeGui->getViewProvider(m_page); - ViewProviderPage* dvp = static_cast(vp); + auto* dvp = static_cast(vp); m_mdi = dvp->getMDIViewPage(); setUiPrimary(); saveGroupState(); } +void TaskProjGroup::updateUi() +{ + if (multiView) { + setWindowTitle(QObject::tr("Projection Group")); + ui->projection->show(); + ui->cbAutoDistribute->show(); + ui->sbXSpacing->show(); + ui->sbYSpacing->show(); + 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")); + ui->projection->hide(); + ui->cbAutoDistribute->hide(); + ui->sbXSpacing->hide(); + ui->sbYSpacing->hide(); + ui->label_7->hide(); + ui->label_10->hide(); + ui->label_11->hide(); + } +} + void TaskProjGroup::saveGroupState() { // Base::Console().Message("TPG::saveGroupState()\n"); - if (!multiView) + if (!view) return; - m_saveSource = multiView->Source.getValues(); - m_saveProjType = multiView->ProjectionType.getValueAsString(); - m_saveScaleType = multiView->ScaleType.getValueAsString(); - m_saveScale = multiView->Scale.getValue(); - m_saveAutoDistribute = multiView->AutoDistribute.getValue(); - m_saveSpacingX = multiView->spacingX.getValue(); - m_saveSpacingY = multiView->spacingY.getValue(); - DrawProjGroupItem* anchor = multiView->getAnchor(); - m_saveDirection = anchor->Direction.getValue(); + m_saveScaleType = view->ScaleType.getValueAsString(); + m_saveScale = view->Scale.getValue(); - for( const auto it : multiView->Views.getValues() ) { - auto view( dynamic_cast(it) ); - if (view) { - m_saveViewNames.emplace_back(view->Type.getValueAsString()); + if (multiView) { + m_saveSource = multiView->Source.getValues(); + m_saveProjType = multiView->ProjectionType.getValueAsString(); + m_saveAutoDistribute = multiView->AutoDistribute.getValue(); + m_saveSpacingX = multiView->spacingX.getValue(); + m_saveSpacingY = multiView->spacingY.getValue(); + DrawProjGroupItem* anchor = multiView->getAnchor(); + m_saveDirection = anchor->Direction.getValue(); + + for( const auto it : multiView->Views.getValues() ) { + auto view( dynamic_cast(it) ); + if (view) { + m_saveViewNames.emplace_back(view->Type.getValueAsString()); + } } } } @@ -158,19 +194,22 @@ void TaskProjGroup::saveGroupState() void TaskProjGroup::restoreGroupState() { Base::Console().Message("TPG::restoreGroupState()\n"); - if (!multiView) + if (!view) return; - multiView->ProjectionType.setValue(m_saveProjType.c_str()); - multiView->ScaleType.setValue(m_saveScaleType.c_str()); - multiView->Scale.setValue(m_saveScale); - multiView->AutoDistribute.setValue(m_saveAutoDistribute); - multiView->spacingX.setValue(m_saveSpacingX); - multiView->spacingY.setValue(m_saveSpacingY); - multiView->purgeProjections(); - for(auto & sv : m_saveViewNames) { - if (sv != "Front") { - multiView->addProjection(sv.c_str()); + view->ScaleType.setValue(m_saveScaleType.c_str()); + view->Scale.setValue(m_saveScale); + + if (multiView) { + multiView->ProjectionType.setValue(m_saveProjType.c_str()); + multiView->AutoDistribute.setValue(m_saveAutoDistribute); + multiView->spacingX.setValue(m_saveSpacingX); + multiView->spacingY.setValue(m_saveSpacingY); + multiView->purgeProjections(); + for(auto & sv : m_saveViewNames) { + if (sv != "Front") { + multiView->addProjection(sv.c_str()); + } } } } @@ -180,42 +219,147 @@ void TaskProjGroup::viewToggled(bool toggle) Gui::WaitCursor wc; bool changed = false; // Obtain name of checkbox - QString viewName = sender()->objectName(); - int index = viewName.mid(7).toInt(); + int index = sender()->objectName().mid(7).toInt(); const char *viewNameCStr = viewChkIndexToCStr(index); - if ( toggle && !multiView->hasProjection( viewNameCStr ) ) { + + if (multiView) { + // Check if only front is now available. If so switch to normal view. + } + 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, "App.activeDocument().%s.addProjection('%s')", multiView->getNameInDocument(), viewNameCStr); changed = true; - } else if ( !toggle && multiView->hasProjection( viewNameCStr ) ) { + } + else if (!toggle && multiView->hasProjection(viewNameCStr)) { if (multiView->canDelete(viewNameCStr)) { multiView->removeProjection( viewNameCStr ); changed = true; } } + if (changed) { - if (multiView->ScaleType.isValue("Automatic")) { - double scale = multiView->getScale(); + if (view->ScaleType.isValue("Automatic")) { + double scale = view->getScale(); setFractionalScale(scale); } - multiView->recomputeFeature(); + view->recomputeFeature(); } wc.restoreCursor(); } void TaskProjGroup::rotateButtonClicked() { - if ( multiView && ui ) { + if ( view && ui ) { const QObject *clicked = sender(); - //change Front View Dir by 90 - if ( clicked == ui->butTopRotate ) multiView->rotate("Up"); - else if (clicked == ui->butDownRotate) multiView->rotate("Down"); - else if (clicked == ui->butRightRotate) multiView->rotate("Right"); - else if (clicked == ui->butLeftRotate) multiView->rotate("Left"); - else if (clicked == ui->butCWRotate ) multiView->spin("CW"); - else if (clicked == ui->butCCWRotate) multiView->spin("CCW"); + auto handleCameraButton = [&]() { + std::string faceName; + App::DocumentObject* obj = nullptr; + auto selection = Gui::Command::getSelection().getSelectionEx(); + for (auto& sel : selection) { + for (auto& sub : sel.getSubNames()) { + if (TechDraw::DrawUtil::getGeomTypeFromName(sub) == "Face") { + obj = sel.getObject(); + faceName = sub; + break; + } + } + if (!faceName.empty()) { + break; + } + } + + std::pair dirs = !faceName.empty() ? + DrawGuiUtil::getProjDirFromFace(obj, faceName) + : DrawGuiUtil::get3DDirAndRot(); + return dirs; + }; + + if (multiView) { + //change Front View Dir by 90 + if (clicked == ui->butTopRotate) multiView->rotate("Up"); + else if (clicked == ui->butDownRotate) multiView->rotate("Down"); + else if (clicked == ui->butRightRotate) multiView->rotate("Right"); + else if (clicked == ui->butLeftRotate) multiView->rotate("Left"); + else if (clicked == ui->butCWRotate) multiView->spin("CW"); + else if (clicked == ui->butCCWRotate) multiView->spin("CCW"); + else if (clicked == ui->butFront) { + multiView->getAnchor()->Direction.setValue(Base::Vector3d(0.0, -1.0, 0.0)); + multiView->getAnchor()->RotationVector.setValue(Base::Vector3d(1.0, 0.0, 0.0)); + multiView->getAnchor()->XDirection.setValue(Base::Vector3d(1.0, 0.0, 0.0)); + multiView->updateSecondaryDirs(); + } + else if (clicked == ui->butCam) { + std::pair dirs = handleCameraButton(); + multiView->getAnchor()->Direction.setValue(dirs.first); + multiView->getAnchor()->RotationVector.setValue(dirs.second); + multiView->getAnchor()->XDirection.setValue(dirs.second); + multiView->updateSecondaryDirs(); + } + } + else { + auto* viewPart = static_cast(view); + if (clicked == ui->butTopRotate) viewPart->rotate("Up"); + else if (clicked == ui->butDownRotate) viewPart->rotate("Down"); + else if (clicked == ui->butRightRotate) viewPart->rotate("Right"); + else if (clicked == ui->butLeftRotate) viewPart->rotate("Left"); + else if (clicked == ui->butCWRotate) viewPart->spin("CW"); + else if (clicked == ui->butCCWRotate) viewPart->spin("CCW"); + else if (clicked == ui->butFront) { + viewPart->Direction.setValue(Base::Vector3d(0.0,-1.0,0.0)); + viewPart->XDirection.setValue(Base::Vector3d(1.0, 0.0, 0.0)); + viewPart->recomputeFeature(); + } + else if (clicked == ui->butCam) { + std::pair dirs = handleCameraButton(); + + viewPart->Direction.setValue(dirs.first); + viewPart->XDirection.setValue(dirs.second); + viewPart->recomputeFeature(); + } + } setUiPrimary(); } @@ -224,7 +368,7 @@ void TaskProjGroup::rotateButtonClicked() //void TaskProjGroup::projectionTypeChanged(int index) void TaskProjGroup::projectionTypeChanged(QString qText) { - if(blockUpdate) { + if(blockUpdate || !multiView) { return; } @@ -250,7 +394,7 @@ void TaskProjGroup::projectionTypeChanged(QString qText) ui->chkView8->setToolTip(getToolTipForBox(8)); ui->chkView9->setToolTip(getToolTipForBox(9)); - multiView->recomputeFeature(); + view->recomputeFeature(); } void TaskProjGroup::scaleTypeChanged(int index) @@ -264,33 +408,35 @@ void TaskProjGroup::scaleTypeChanged(int index) if (index == 0) { // Document Scale Type - multiView->ScaleType.setValue("Page"); - } else if (index == 1) { + view->ScaleType.setValue("Page"); + } + else if (index == 1) { // Automatic Scale Type //block recompute - multiView->ScaleType.setValue("Automatic"); - double autoScale = multiView->autoScale(); - multiView->Scale.setValue(autoScale); + view->ScaleType.setValue("Automatic"); + double autoScale = view->autoScale(); + view->Scale.setValue(autoScale); //unblock recompute - } else if (index == 2) { + } + else if (index == 2) { // Custom Scale Type //block recompute - multiView->ScaleType.setValue("Custom"); + view->ScaleType.setValue("Custom"); ui->sbScaleNum->setEnabled(true); ui->sbScaleDen->setEnabled(true); int a = ui->sbScaleNum->value(); int b = ui->sbScaleDen->value(); double scale = (double) a / (double) b; - multiView->Scale.setValue(scale); + view->Scale.setValue(scale); //unblock recompute } } void TaskProjGroup::AutoDistributeClicked(bool clicked) { - if (blockUpdate) { + if (blockUpdate || !multiView) { return; } multiView->AutoDistribute.setValue(clicked); @@ -299,7 +445,7 @@ void TaskProjGroup::AutoDistributeClicked(bool clicked) void TaskProjGroup::spacingChanged() { - if (blockUpdate) { + if (blockUpdate || !multiView) { return; } multiView->spacingX.setValue(ui->sbXSpacing->value().getValue()); @@ -311,10 +457,10 @@ void TaskProjGroup::updateTask() { // Update the scale type blockUpdate = true; - ui->cmbScaleType->setCurrentIndex(multiView->ScaleType.getValue()); + ui->cmbScaleType->setCurrentIndex(view->ScaleType.getValue()); // Update the scale value - setFractionalScale(multiView->getScale()); + setFractionalScale(view->getScale()); blockUpdate = false; } @@ -336,7 +482,7 @@ void TaskProjGroup::scaleManuallyChanged(int unused) Q_UNUSED(unused); if(blockUpdate) return; - if (!multiView->ScaleType.isValue("Custom")) { //ignore if not custom! + if (!view->ScaleType.isValue("Custom")) { //ignore if not custom! return; } @@ -345,9 +491,9 @@ void TaskProjGroup::scaleManuallyChanged(int unused) double scale = (double) a / (double) b; - Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.Scale = %f", multiView->getNameInDocument() + Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.Scale = %f", view->getNameInDocument() , scale); - multiView->recomputeFeature(); + view->recomputeFeature(); } void TaskProjGroup::changeEvent(QEvent *event) @@ -366,9 +512,8 @@ const char * TaskProjGroup::viewChkIndexToCStr(int index) // First Angle: FBRight B FBL // Right F L Rear // FTRight T FTL - assert (multiView); - bool thirdAngle = multiView->usedProjectionType().isValue("Third Angle"); + bool thirdAngle = multiView ? multiView->usedProjectionType().isValue("Third Angle") : false; switch(index) { case 0: return (thirdAngle ? "FrontTopLeft" : "FrontBottomRight"); case 1: return (thirdAngle ? "Top" : "Bottom"); @@ -386,7 +531,7 @@ const char * TaskProjGroup::viewChkIndexToCStr(int index) QString TaskProjGroup::getToolTipForBox(int boxNumber) { - bool thirdAngle = multiView->usedProjectionType().isValue("Third Angle"); + bool thirdAngle = multiView ? multiView->usedProjectionType().isValue("Third Angle") : false; switch(boxNumber) { case 0: {return (thirdAngle ? tr("FrontTopLeft") : tr("FrontBottomRight")); break;} case 1: {return (thirdAngle ? tr("Top") : tr("Bottom")); break;} @@ -404,7 +549,7 @@ QString TaskProjGroup::getToolTipForBox(int boxNumber) void TaskProjGroup::setupViewCheckboxes(bool addConnections) { - if (!multiView) + if (!view) return; // There must be a better way to construct this list... @@ -419,29 +564,44 @@ void TaskProjGroup::setupViewCheckboxes(bool addConnections) ui->chkView8, ui->chkView9 }; - for (int i = 0; i < 10; ++i) { QCheckBox *box = viewCheckboxes[i]; + box->setToolTip(getToolTipForBox(i)); + const char *viewStr = viewChkIndexToCStr(i); + + if (!multiView) { + box->setCheckState(viewStr == "Front" ? Qt::Checked : Qt::Unchecked); + } + if (addConnections) { connect(box, &QCheckBox::toggled, this, &TaskProjGroup::viewToggled); } - const char *viewStr = viewChkIndexToCStr(i); - if (viewStr && multiView->hasProjection(viewStr)) { - box->setCheckState(Qt::Checked); - if (!multiView->canDelete(viewStr)) { - box->setEnabled(false); + if (multiView) { + if (viewStr && multiView->hasProjection(viewStr)) { + box->setCheckState(Qt::Checked); + if (!multiView->canDelete(viewStr)) { + box->setEnabled(false); + } + } else { + box->setCheckState(Qt::Unchecked); } - } else { - box->setCheckState(Qt::Unchecked); } - box->setToolTip(getToolTipForBox(i)); } } void TaskProjGroup::setUiPrimary() { - Base::Vector3d frontDir = multiView->getAnchorDirection(); + Base::Vector3d frontDir; + if (multiView) { + frontDir = multiView->getAnchorDirection(); + } + else { + auto* viewPart = static_cast(view); + if (viewPart) { + frontDir = viewPart->Direction.getValue(); + } + } ui->lePrimary->setText(formatVector(frontDir)); } @@ -467,8 +627,10 @@ void TaskProjGroup::saveButtons(QPushButton* btnOK, bool TaskProjGroup::apply() { // Base::Console().Message("TPG::apply()\n"); - multiView->recomputeChildren(); - multiView->recomputeFeature(); + if (multiView) { + multiView->recomputeChildren(); + } + view->recomputeFeature(); return true; } @@ -476,12 +638,14 @@ bool TaskProjGroup::apply() bool TaskProjGroup::accept() { // Base::Console().Message("TPG::accept()\n"); - Gui::Document* doc = Gui::Application::Instance->getDocument(multiView->getDocument()); + Gui::Document* doc = Gui::Application::Instance->getDocument(view->getDocument()); if (!doc) return false; - multiView->recomputeChildren(); - multiView->recomputeFeature(); + if (multiView) { + multiView->recomputeChildren(); + } + view->recomputeFeature(); Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()"); @@ -490,28 +654,31 @@ bool TaskProjGroup::accept() bool TaskProjGroup::reject() { - Gui::Document* doc = Gui::Application::Instance->getDocument(multiView->getDocument()); + Gui::Document* doc = Gui::Application::Instance->getDocument(view->getDocument()); if (!doc) return false; if (getCreateMode()) { //remove the object completely from the document - std::string multiViewName = multiView->getNameInDocument(); - std::string PageName = multiView->findParentPage()->getNameInDocument(); + const char* viewName = view->getNameInDocument(); + const char* PageName = view->findParentPage()->getNameInDocument(); - Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().%s.purgeProjections()", - multiViewName.c_str()); - Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().%s.removeView(App.activeDocument().%s)", - PageName.c_str(), multiViewName.c_str()); - Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().removeObject('%s')", multiViewName.c_str()); + if (multiView) { + Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().%s.purgeProjections()", + viewName); + Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().%s.removeView(App.activeDocument().%s)", + PageName, viewName); + } + Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().removeObject('%s')", viewName); Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()"); - } else { + } + else { //set the DPG and its views back to entry state. if (Gui::Command::hasPendingCommand()) { Gui::Command::abortCommand(); // std::vector undos = Gui::Application::Instance->activeDocument()->getUndoVector(); // Gui::Application::Instance->activeDocument()->undo(1); -// multiView->rebuildViewList(); +// view->rebuildViewList(); // apply(); } } @@ -521,12 +688,12 @@ bool TaskProjGroup::reject() ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TODO: Do we really need to hang on to the TaskDlgProjGroup in this class? IR -TaskDlgProjGroup::TaskDlgProjGroup(TechDraw::DrawProjGroup* featView, bool mode) +TaskDlgProjGroup::TaskDlgProjGroup(TechDraw::DrawView* featView, bool mode) : TaskDialog() , viewProvider(nullptr) - , multiView(featView) + , view(featView) { - //viewProvider = dynamic_cast(featView); + //viewProvider = dynamic_cast(featView); widget = new TaskProjGroup(featView, mode); taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("actions/TechDraw_ProjectionGroup"), widget->windowTitle(), true, nullptr); @@ -559,8 +726,13 @@ void TaskDlgProjGroup::modifyStandardButtons(QDialogButtonBox* box) //==== calls from the TaskView =============================================================== void TaskDlgProjGroup::open() { - if (!widget->getCreateMode()) { //this is an edit session, start a transaction - App::GetApplication().setActiveTransaction("Edit Projection Group", true); + if (!widget->getCreateMode()) { //this is an edit session, start a transaction + if (dynamic_cast(view)) { + App::GetApplication().setActiveTransaction("Edit Projection Group", true); + } + else { + App::GetApplication().setActiveTransaction("Edit Part View", true); + } } } diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.h b/src/Mod/TechDraw/Gui/TaskProjGroup.h index 7a3062443c..663974e7ec 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.h +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.h @@ -33,6 +33,7 @@ namespace TechDraw { +class DrawView; class DrawProjGroup; class DrawPage; } @@ -41,14 +42,14 @@ namespace TechDrawGui { class MDIViewPage; class Ui_TaskProjGroup; -class ViewProviderProjGroup; +class ViewProviderDrawingView; class TaskProjGroup : public QWidget { Q_OBJECT public: - TaskProjGroup(TechDraw::DrawProjGroup* featView, bool mode); + TaskProjGroup(TechDraw::DrawView* featView, bool mode); ~TaskProjGroup() override = default; virtual bool accept(); @@ -77,6 +78,7 @@ protected: void setUiPrimary(); void saveGroupState(); void restoreGroupState(); + void updateUi(); QString formatVector(Base::Vector3d vec); @@ -98,6 +100,7 @@ private: MDIViewPage* m_mdi; std::unique_ptr ui; + TechDraw::DrawView* view; TechDraw::DrawProjGroup* multiView; bool m_createMode; @@ -126,11 +129,11 @@ class TaskDlgProjGroup : public Gui::TaskView::TaskDialog Q_OBJECT public: - TaskDlgProjGroup(TechDraw::DrawProjGroup* featView, bool mode); + TaskDlgProjGroup(TechDraw::DrawView* featView, bool mode); ~TaskDlgProjGroup() override; - const ViewProviderProjGroup * getViewProvider() const { return viewProvider; } - TechDraw::DrawProjGroup * getMultiView() const { return multiView; } + const ViewProviderDrawingView* getViewProvider() const { return viewProvider; } + TechDraw::DrawView* getView() const { return view; } QDialogButtonBox::StandardButtons getStandardButtons() const override { return QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel; } @@ -152,8 +155,8 @@ public: void update(); protected: - const ViewProviderProjGroup *viewProvider; - TechDraw::DrawProjGroup *multiView; + const ViewProviderDrawingView *viewProvider; + TechDraw::DrawView* view; private: TaskProjGroup * widget; diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.ui b/src/Mod/TechDraw/Gui/TaskProjGroup.ui index c644fe3e4f..481b26ecf4 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.ui +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.ui @@ -26,39 +26,6 @@ Projection Group - - - - - - Projection - - - - - - - First or Third Angle - - - - First Angle - - - - - Third Angle - - - - - Page - - - - - - @@ -90,17 +57,6 @@ - - - - - - - - Custom Scale - - - @@ -176,7 +132,7 @@ - Adjust Primary Direction + Adjust Direction true @@ -193,6 +149,27 @@ + + + + Spin clock wise + + + + + + + :/icons/arrow-cw.svg + + + + + 24 + 24 + + + + @@ -220,6 +197,27 @@ + + + + Spin counter clock wise + + + + + + + :/icons/arrow-ccw.svg + + + + + 24 + 24 + + + + @@ -290,17 +288,25 @@ - - - Qt::Horizontal + + + Set document front view as primary direction. - + + + + + + :/icons/view-front.svg + + + - 40 - 20 + 24 + 24 - + @@ -324,17 +330,25 @@ - - - Qt::Horizontal + + + Set direction of the camera, or selected face if any, as primary direction. - + + + + + + :/icons/TechDraw_CameraOrientation.svg + + + - 40 - 20 + 24 + 24 - + @@ -575,76 +589,36 @@ height: 24px; - + - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Spin CW - + - - - - - :/icons/arrow-cw.svg - + Projection - - - Qt::Horizontal - - - - 40 - 20 - - - - - - + - Spin CCW - - - - - - - :/icons/arrow-ccw.svg - + First or Third Angle + + + First Angle + + + + + Third Angle + + + + + Page + + - - - - Qt::Horizontal - - - - 40 - 20 - - - - diff --git a/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp b/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp index 9575d0ca97..488ff1bff3 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp @@ -56,6 +56,7 @@ #include "PreferencesGui.h" #include "QGIView.h" #include "TaskDetail.h" +#include "TaskProjGroup.h" #include "ViewProviderViewPart.h" #include "ViewProviderPage.h" #include "QGIViewDimension.h" @@ -264,6 +265,10 @@ bool ViewProviderViewPart::setEdit(int ModNum) if (Gui::Control().activeDialog()) { //TaskPanel already open! return false; } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + TechDraw::DrawViewPart* dvp = getViewObject(); TechDraw::DrawViewDetail* dvd = dynamic_cast(dvp); if (dvd) { @@ -271,13 +276,15 @@ bool ViewProviderViewPart::setEdit(int ModNum) Base::Console().Error("DrawViewDetail - %s - has no BaseView!\n", dvd->getNameInDocument()); return false; } - // clear the selection (convenience) - Gui::Selection().clearSelection(); Gui::Control().showDialog(new TaskDlgDetail(dvd)); Gui::Selection().clearSelection(); Gui::Selection().addSelection(dvd->getDocument()->getName(), dvd->getNameInDocument()); } + else { + auto* view = dynamic_cast(getObject()); + Gui::Control().showDialog(new TaskDlgProjGroup(view, false)); + } return true; } diff --git a/src/Mod/TechDraw/Gui/Workbench.cpp b/src/Mod/TechDraw/Gui/Workbench.cpp index 08bb9fd11c..d5dd37fbae 100644 --- a/src/Mod/TechDraw/Gui/Workbench.cpp +++ b/src/Mod/TechDraw/Gui/Workbench.cpp @@ -294,7 +294,6 @@ Gui::ToolBarItem* Workbench::setupToolBars() const *views << "TechDraw_View"; *views << "TechDraw_BrokenView"; *views << "TechDraw_ActiveView"; - *views << "TechDraw_ProjectionGroup"; *views << "TechDraw_SectionGroup"; *views << "TechDraw_DetailView"; *views << "TechDraw_DraftView"; @@ -397,7 +396,6 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const views->setCommand("Views"); *views << "TechDraw_View"; *views << "TechDraw_ActiveView"; - *views << "TechDraw_ProjectionGroup"; *views << "TechDraw_SectionGroup"; *views << "TechDraw_DetailView"; *views << "TechDraw_DraftView"; From b6d8bb094ab4331f9323b6577907e50cf89ddd68 Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Tue, 2 Apr 2024 13:58:56 +0200 Subject: [PATCH 4/8] TechDraw: InsertView switch the MDI to page when triggered. --- src/Mod/TechDraw/Gui/Command.cpp | 8 ++++++++ src/Mod/TechDraw/Gui/ViewProviderPage.cpp | 7 ++++++- src/Mod/TechDraw/Gui/ViewProviderPage.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index a14044c6e9..5bb1f6b4fe 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -314,6 +314,14 @@ void CmdTechDrawView::activated(int iMsg) } std::string PageName = page->getNameInDocument(); + // switch to the page if it's not current active window + auto* vpp = dynamic_cast + (Gui::Application::Instance->getViewProvider(page)); + if (vpp) { + vpp->switchToMdiViewPage(); + } + + //set projection direction from selected Face //use first object with a face selected std::vector shapes, xShapes; diff --git a/src/Mod/TechDraw/Gui/ViewProviderPage.cpp b/src/Mod/TechDraw/Gui/ViewProviderPage.cpp index c78b9cfa8f..fae8b1a27b 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderPage.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderPage.cpp @@ -275,7 +275,7 @@ bool ViewProviderPage::doubleClicked(void) show(); if (m_mdiView) { - Gui::getMainWindow()->setActiveWindow(m_mdiView); + switchToMdiViewPage(); } return true; } @@ -339,6 +339,11 @@ void ViewProviderPage::createMDIViewPage() m_mdiView->setWindowTitle(tabTitle + QString::fromLatin1("[*]")); m_mdiView->setWindowIcon(Gui::BitmapFactory().pixmap("TechDraw_TreePage")); Gui::getMainWindow()->addWindow(m_mdiView); + switchToMdiViewPage(); +} + +void ViewProviderPage::switchToMdiViewPage() +{ Gui::getMainWindow()->setActiveWindow(m_mdiView); m_graphicsView->setFocus(); } diff --git a/src/Mod/TechDraw/Gui/ViewProviderPage.h b/src/Mod/TechDraw/Gui/ViewProviderPage.h index 34dbb27d42..b23d666c5f 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderPage.h +++ b/src/Mod/TechDraw/Gui/ViewProviderPage.h @@ -107,6 +107,7 @@ public: MDIViewPage* getMDIViewPage() const; bool showMDIViewPage(); void removeMDIView(); + void switchToMdiViewPage(); Gui::MDIView* getMDIView() const override; From 5eb73cf949639a8008dd4bb753149d61157219c6 Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Tue, 2 Apr 2024 14:01:07 +0200 Subject: [PATCH 5/8] TechDraw: Enable setting a custom direction. Fixes #5821 --- src/Mod/TechDraw/App/DrawProjGroup.cpp | 5 + src/Mod/TechDraw/App/DrawProjGroup.h | 1 + src/Mod/TechDraw/App/DrawViewPart.cpp | 5 + src/Mod/TechDraw/App/DrawViewPart.h | 1 + src/Mod/TechDraw/Gui/TaskProjGroup.cpp | 149 +++++++++++++++++++++++++ src/Mod/TechDraw/Gui/TaskProjGroup.h | 30 +++++ src/Mod/TechDraw/Gui/TaskProjGroup.ui | 14 +-- 7 files changed, 192 insertions(+), 13 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawProjGroup.cpp b/src/Mod/TechDraw/App/DrawProjGroup.cpp index 679772ffa7..8cdd49c525 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroup.cpp @@ -1219,6 +1219,11 @@ void DrawProjGroup::spin(const std::string& spindirection) if (spindirection == "CCW") angle = -M_PI / 2.0;// Top -> Left -> Bottom -> Right -> Top + spin(angle); +} + +void DrawProjGroup::spin(double angle) +{ DrawProjGroupItem* anchor = getAnchor(); Base::Vector3d org(0.0, 0.0, 0.0); Base::Vector3d curRot = anchor->getXDirection(); diff --git a/src/Mod/TechDraw/App/DrawProjGroup.h b/src/Mod/TechDraw/App/DrawProjGroup.h index 3bb4f863ea..05c0934cc8 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.h +++ b/src/Mod/TechDraw/App/DrawProjGroup.h @@ -129,6 +129,7 @@ public: void rotate(const std::string &rotationdirection); void spin(const std::string &spindirection); + void spin(double angle); void dumpISO(const char * title); std::vector getViewsAsDPGI(); diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index 07f43c5d4e..a1d129129f 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -1289,6 +1289,11 @@ void DrawViewPart::spin(const std::string& spindirection) if (spindirection == "CCW") angle = -M_PI / 2.0;// Top -> Left -> Bottom -> Right -> Top + spin(angle); +} + +void DrawViewPart::spin(double angle) +{ Base::Vector3d org(0.0, 0.0, 0.0); Base::Vector3d curRot = getXDirection(); Base::Vector3d curDir = Direction.getValue(); diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 32b321bfca..e5d772097e 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -174,6 +174,7 @@ public: void rotate(const std::string& rotationdirection); void spin(const std::string& spindirection); + void spin(double val); std::pair getDirsFromFront(std::string viewType); Base::Vector3d dir2vec(gp_Dir d); diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.cpp b/src/Mod/TechDraw/Gui/TaskProjGroup.cpp index 8b285dc2b5..bbd1732e5e 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.cpp +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.cpp @@ -25,8 +25,20 @@ #ifndef _PreComp_ # include # include +# include +# include +# include +# include +# include +# include +# include #endif // #ifndef _PreComp_ +#include +#include +#include +#include + #include #include #include @@ -35,6 +47,7 @@ #include #include #include +#include #include #include @@ -97,6 +110,8 @@ TaskProjGroup::TaskProjGroup(TechDraw::DrawView* featView, bool mode) : connect(ui->butFront, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked); connect(ui->butCam, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked); + connect(ui->lePrimary, &QPushButton::clicked, this, &TaskProjGroup::customDirectionClicked); + // //Reset button // connect(ui->butReset, SIGNAL(clicked()), this, SLOT(onResetClicked())); @@ -289,6 +304,38 @@ void TaskProjGroup::viewToggled(bool toggle) wc.restoreCursor(); } +void TaskProjGroup::customDirectionClicked() +{ + auto* dirEditDlg = new DirectionEditDialog(); + + if (multiView) { + dirEditDlg->setDirection(multiView->getAnchor()->Direction.getValue()); + dirEditDlg->setAngle(0.0); + } + else { + auto* viewPart = static_cast(view); + dirEditDlg->setDirection(viewPart->Direction.getValue()); + dirEditDlg->setAngle(0.0); + } + + if (dirEditDlg->exec() == QDialog::Accepted) { + if (multiView) { + multiView->getAnchor()->Direction.setValue(dirEditDlg->getDirection()); + multiView->spin(Base::toRadians(dirEditDlg->getAngle())); + } + else { + auto* viewPart = static_cast(view); + viewPart->Direction.setValue(dirEditDlg->getDirection()); + viewPart->spin(Base::toRadians(dirEditDlg->getAngle())); + } + + setUiPrimary(); + } + + + delete dirEditDlg; +} + void TaskProjGroup::rotateButtonClicked() { if ( view && ui ) { @@ -758,4 +805,106 @@ bool TaskDlgProjGroup::reject() } +DirectionEditDialog::DirectionEditDialog(QWidget* parent) : QDialog(parent) { + setWindowFlags(Qt::Popup); // Make the dialog non-intrusive + createUI(); +} + +void DirectionEditDialog::setDirection(const Base::Vector3d& pos) { + xSpinBox->setValue(pos.x); + ySpinBox->setValue(pos.y); + zSpinBox->setValue(pos.z); +} + +Base::Vector3d DirectionEditDialog::getDirection() const { + return Base::Vector3d(xSpinBox->value().getValue(), ySpinBox->value().getValue(), zSpinBox->value().getValue()); +} + +void DirectionEditDialog::setAngle(double val) { + angleSpinBox->setValue(val); +} + +double DirectionEditDialog::getAngle() const { + return angleSpinBox->value().getValue(); +} + +void DirectionEditDialog::showEvent(QShowEvent* event) { + QDialog::showEvent(event); + + // Calculate the position to ensure the dialog appears within the screen boundaries + QPoint cursorPos = QCursor::pos(); + QSize screenSize = QApplication::primaryScreen()->size(); // Get the size of the primary screen + int x = cursorPos.x(); + int y = cursorPos.y(); + int dialogWidth = this->width(); + int dialogHeight = this->height(); + + // Check if the dialog goes beyond the right edge of the screen + if (x + dialogWidth > screenSize.width()) { + x = screenSize.width() - dialogWidth; + } + + // Check if the dialog goes beyond the bottom edge of the screen + if (y + dialogHeight > screenSize.height()) { + y = screenSize.height() - dialogHeight; + } + + // Move the dialog to the calculated position + this->move(x, y); +} + +void DirectionEditDialog::createUI() { + auto* directionGroup = new QGroupBox(tr("Direction")); + auto* directionLayout = new QVBoxLayout; // Use QVBoxLayout for vertical alignment + + // Create layout and widgets for X + auto* xLayout = new QHBoxLayout; + auto* xLabel = new QLabel(tr("X: ")); + xSpinBox = new Gui::QuantitySpinBox; + xSpinBox->setUnit(Base::Unit::Length); + xLayout->addWidget(xLabel); + xLayout->addWidget(xSpinBox); + + // Create layout and widgets for Y + auto* yLayout = new QHBoxLayout; + auto* yLabel = new QLabel(tr("Y: ")); + ySpinBox = new Gui::QuantitySpinBox; + ySpinBox->setUnit(Base::Unit::Length); + yLayout->addWidget(yLabel); + yLayout->addWidget(ySpinBox); + + // Create layout and widgets for Z + auto* zLayout = new QHBoxLayout; + auto* zLabel = new QLabel(tr("Z: ")); + zSpinBox = new Gui::QuantitySpinBox; + zSpinBox->setUnit(Base::Unit::Length); + zLayout->addWidget(zLabel); + zLayout->addWidget(zSpinBox); + + // Add the layouts to the direction group + directionLayout->addLayout(xLayout); + directionLayout->addLayout(yLayout); + directionLayout->addLayout(zLayout); + directionGroup->setLayout(directionLayout); + + angleSpinBox = new Gui::QuantitySpinBox; + angleSpinBox->setUnit(Base::Unit::Angle); + + auto* buttonsLayout = new QHBoxLayout; + auto* okButton = new QPushButton(tr("OK")); + auto* cancelButton = new QPushButton(tr("Cancel")); + buttonsLayout->addWidget(okButton); + buttonsLayout->addWidget(cancelButton); + + auto* mainLayout = new QVBoxLayout; + mainLayout->addWidget(directionGroup); + mainLayout->addWidget(new QLabel(tr("Rotate by"))); + mainLayout->addWidget(angleSpinBox); + mainLayout->addLayout(buttonsLayout); + setLayout(mainLayout); + + connect(okButton, &QPushButton::clicked, this, &QDialog::accept); + connect(cancelButton, &QPushButton::clicked, this, &QDialog::reject); +} + #include diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.h b/src/Mod/TechDraw/Gui/TaskProjGroup.h index 663974e7ec..7fa48b70f1 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.h +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.h @@ -31,6 +31,9 @@ #include #include +namespace Gui { + class QuantitySpinBox; +} namespace TechDraw { class DrawView; @@ -88,6 +91,8 @@ protected Q_SLOTS: /// Requests appropriate rotation of our DrawProjGroup void rotateButtonClicked(); + void customDirectionClicked(); + void projectionTypeChanged(QString qText); void scaleTypeChanged(int index); void AutoDistributeClicked(bool clicked); @@ -163,6 +168,31 @@ private: Gui::TaskView::TaskBox* taskbox; }; + +class DirectionEditDialog : public QDialog { + Q_OBJECT + +public: + explicit DirectionEditDialog(QWidget* parent = nullptr); + + void setDirection(const Base::Vector3d& pos); + Base::Vector3d getDirection() const; + + void setAngle(double val); + double getAngle() const; + +protected: + void showEvent(QShowEvent* event) override; + +private: + Gui::QuantitySpinBox* xSpinBox; + Gui::QuantitySpinBox* ySpinBox; + Gui::QuantitySpinBox* zSpinBox; + Gui::QuantitySpinBox* angleSpinBox; + + void createUI(); +}; + } //namespace TechDrawGui #endif // #ifndef GUI_TASKVIEW_TASKVIEWGROUP_H diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.ui b/src/Mod/TechDraw/Gui/TaskProjGroup.ui index 481b26ecf4..93f18106a9 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.ui +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.ui @@ -240,10 +240,7 @@ - - - false - + 11 @@ -252,18 +249,9 @@ false - - Qt::NoFocus - Current primary view direction - - Qt::AlignCenter - - - true - From 2b0403dc27ee3a20a34d5c2dbaa0216035e03d1e Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Fri, 5 Apr 2024 09:42:52 +0200 Subject: [PATCH 6/8] 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; From e0e0a91046a3365b8ffed41fecaa0793016774ea Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Fri, 5 Apr 2024 14:12:33 +0200 Subject: [PATCH 7/8] TechDraw: TaskProjGroup.ui : use QGroupBox instead of lines for app consistency. --- src/Mod/TechDraw/Gui/TaskProjGroup.ui | 1164 ++++++++++++------------- 1 file changed, 560 insertions(+), 604 deletions(-) diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.ui b/src/Mod/TechDraw/Gui/TaskProjGroup.ui index 93f18106a9..5ebbf221cd 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.ui +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.ui @@ -115,622 +115,578 @@ - - - Qt::Horizontal + + + Direction + + + + + Spin clock wise + + + + + + + :/icons/arrow-cw.svg + + + + + 24 + 24 + + + + + + + + + 0 + 0 + + + + Rotate up + + + + + + + :/icons/arrow-up.svg + + + + + 24 + 24 + + + + + + + + Spin counter clock wise + + + + + + + :/icons/arrow-ccw.svg + + + + + 24 + 24 + + + + + + + + Rotate left + + + + + + + :/icons/arrow-left.svg + + + + + 24 + 24 + + + + + + + + + 11 + 50 + false + false + + + + Current primary view direction + + + + + + + Rotate right + + + + + + + :/icons/arrow-right.svg + + + + + 24 + 24 + + + + + + + + Set document front view as primary direction. + + + + + + + :/icons/view-front.svg + + + + + 24 + 24 + + + + + + + + Rotate down + + + + + + + :/icons/arrow-down.svg + + + + + 24 + 24 + + + + + + + + Set direction of the camera, or selected face if any, as primary direction. + + + + + + + :/icons/TechDraw_CameraOrientation.svg + + + + + 24 + 24 + + + + + - - - - - - 0 - 0 - - - - Adjust Direction - - - true - - - Qt::AlignCenter - - - 0 - - - - - - - - - - - Spin clock wise - - - - - - - :/icons/arrow-cw.svg - - - - - 24 - 24 - - - - - - - - - 0 - 0 - - - - Rotate up - - - - - - - :/icons/arrow-up.svg - - - - - 24 - 24 - - - - - - - - Spin counter clock wise - - - - - - - :/icons/arrow-ccw.svg - - - - - 24 - 24 - - - - - - - - Rotate left - - - - - - - :/icons/arrow-left.svg - - - - - 24 - 24 - - - - - - - - - 11 - 50 - false - false - - - - Current primary view direction - - - - - - - Rotate right - - - - - - - :/icons/arrow-right.svg - - - - - 24 - 24 - - - - - - - - Set document front view as primary direction. - - - - - - - :/icons/view-front.svg - - - - - 24 - 24 - - - - - - - - Rotate down - - - - - - - :/icons/arrow-down.svg - - - - - 24 - 24 - - - - - - - - Set direction of the camera, or selected face if any, as primary direction. - - - - - - - :/icons/TechDraw_CameraOrientation.svg - - - - - 24 - 24 - - - - - - - - - - Qt::Horizontal + + + Secondary Projections - - - - - - - - Secondary Projections - - - Qt::AlignCenter - - - - - - - - - - - LeftFrontTop - - - QCheckBox::indicator { -width: 24px; -height: 24px; -} - - - - - - - - 24 - 24 - - - - - - - - Top - - - QCheckBox::indicator { -width: 24px; -height: 24px; -} - - - - - - - - - - - RightFrontTop - - - QCheckBox::indicator { -width: 24px; -height: 24px; -} - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Left - - - QCheckBox::indicator { -width: 24px; -height: 24px; -} - - - - - - - - - - - false - - - Primary - - - QCheckBox::indicator { -width: 24px; -height: 24px; -} - - - - - - - true - - - - - - - Right - - - QCheckBox::indicator { -width: 24px; -height: 24px; -} - - - - - - - - - - - Rear - - - QCheckBox::indicator { -width: 24px; -height: 24px; -} - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - LeftFrontBottom - - - QCheckBox::indicator { -width: 24px; -height: 24px; -} - - - - - - - - - - - true - - - Bottom - - - QCheckBox::indicator { -width: 24px; -height: 24px; -} - - - - - - - - - - - RightFrontBottom - - - QCheckBox::indicator { -width: 24px; -height: 24px; -} - - - - - - - - - - - - - - - Projection - - - - - - - First or Third Angle - - - - First Angle + + + + + LeftFrontTop - - - - Third Angle + + QCheckBox::indicator { +width: 24px; +height: 24px; +} + - - - Page + - - - - - - - - - Distributes projections automatically + + + 24 + 24 + + + + + + + + Top + + + QCheckBox::indicator { +width: 24px; +height: 24px; +} + + + + + + + + + + + RightFrontTop + + + QCheckBox::indicator { +width: 24px; +height: 24px; +} + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Left + + + QCheckBox::indicator { +width: 24px; +height: 24px; +} + + + + + + + + + + + false + + + Primary + + + QCheckBox::indicator { +width: 24px; +height: 24px; +} + + + + + + + true + + + + + + + Right + + + QCheckBox::indicator { +width: 24px; +height: 24px; +} + + + + + + + + + + + Rear + + + QCheckBox::indicator { +width: 24px; +height: 24px; +} + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + LeftFrontBottom + + + QCheckBox::indicator { +width: 24px; +height: 24px; +} + + + + + + + + + + + true + + + Bottom + + + QCheckBox::indicator { +width: 24px; +height: 24px; +} + + + + + + + + + + + RightFrontBottom + + + QCheckBox::indicator { +width: 24px; +height: 24px; +} + + + + + + + + + + + + + Projection + + + + + + + First or Third Angle + + + + First Angle + + + + + Third Angle + + + + + Page + + + + + + + + + + Distributes projections automatically using the given X/Y Spacing - - - Auto Distribute - + + + Auto Distribute + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + X Spacing + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 150 + 22 + + + + Horizontal space between border of projections + + + false + + + + + + 0.000000000000000 + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Y Spacing + + + + + + + + 0 + 0 + + + + + 150 + 22 + + + + Vertical space between border of projections + + + false + + + + + + 0.000000000000000 + + + + + + - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - X Spacing - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 150 - 22 - - - - Horizontal space between border of projections - - - false - - - - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Y Spacing - - - - - - - - 0 - 0 - - - - - 150 - 22 - - - - Vertical space between border of projections - - - false - - - - - - 0.000000000000000 - - - - - From ddd35aeefaf1dd32af3c5c195dc24cb725d2c0ad Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Mon, 22 Apr 2024 15:12:24 +0200 Subject: [PATCH 8/8] Fix typo introduced by solving conflict. --- src/Mod/TechDraw/Gui/Command.cpp | 2 +- src/Mod/TechDraw/Gui/ViewProviderPageExtension.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 76143df922..3c953b72b6 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("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.")); + msgBox.setText(msgBox.tr("If you want to insert a view from existing objects, please select them before invoking 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); diff --git a/src/Mod/TechDraw/Gui/ViewProviderPageExtension.cpp b/src/Mod/TechDraw/Gui/ViewProviderPageExtension.cpp index f81740d836..bc5c7e6ee9 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderPageExtension.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderPageExtension.cpp @@ -123,9 +123,9 @@ void ViewProviderPageExtension::extensionDropObject(App::DocumentObject* obj) //this code used to live in ViewProviderPage void ViewProviderPageExtension::dropObject(App::DocumentObject* obj) { - if (docObj->isDerivedFrom()) { + if (obj->isDerivedFrom()) { //DPGI can not be dropped onto the Page if it belongs to DPG - auto* dpgi = static_cast(docObj); + auto* dpgi = static_cast(obj); if (dpgi->getPGroup()) { return; }