From ce4ba703d9ed367668cd0d1cf6210a118f024d8e Mon Sep 17 00:00:00 2001 From: wandererfan Date: Sun, 16 Oct 2022 13:40:21 -0400 Subject: [PATCH] [TD]ActiveView from different document --- src/Mod/TechDraw/Gui/Command.cpp | 4 +- src/Mod/TechDraw/Gui/DrawGuiUtil.cpp | 104 ++++++++++++++++++------ src/Mod/TechDraw/Gui/DrawGuiUtil.h | 4 +- src/Mod/TechDraw/Gui/Grabber3d.cpp | 21 +---- src/Mod/TechDraw/Gui/Grabber3d.h | 7 +- src/Mod/TechDraw/Gui/TaskActiveView.cpp | 60 ++++++++++---- 6 files changed, 138 insertions(+), 62 deletions(-) diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 5d8004b218..c880df5c6e 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -449,7 +449,7 @@ CmdTechDrawActiveView::CmdTechDrawActiveView() void CmdTechDrawActiveView::activated(int iMsg) { Q_UNUSED(iMsg); - TechDraw::DrawPage* page = DrawGuiUtil::findPage(this); + TechDraw::DrawPage* page = DrawGuiUtil::findPage(this, true); if (!page) { return; } @@ -459,7 +459,7 @@ void CmdTechDrawActiveView::activated(int iMsg) bool CmdTechDrawActiveView::isActive() { - return DrawGuiUtil::needPage(this); + return DrawGuiUtil::needPage(this, true); } //=========================================================================== diff --git a/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp b/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp index 732211d568..f6d9c7ee1a 100644 --- a/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp +++ b/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp @@ -36,6 +36,7 @@ # include #endif +#include #include #include #include @@ -83,35 +84,75 @@ void DrawGuiUtil::loadArrowBox(QComboBox* qcb) //=========================================================================== //find a page in Selection, Document or CurrentWindow. -TechDraw::DrawPage* DrawGuiUtil::findPage(Gui::Command* cmd) +TechDraw::DrawPage* DrawGuiUtil::findPage(Gui::Command* cmd, + bool findAny) { - TechDraw::DrawPage* page = nullptr; +// Base::Console().Message("DGU::findPage()\n"); std::vector names; std::vector labels; + auto docs = App::GetApplication().getDocuments(); + + if (findAny) { + //find a page in any open document + std::vector foundPageObjects; + //no page found in the usual places, but we have been asked to search all + //open documents for a page. + auto docsAll = App::GetApplication().getDocuments(); + for (auto& doc : docsAll) { + auto docPages = doc->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); + if (docPages.empty()) { + //this open document has no TD pages + continue; + } + foundPageObjects.insert(foundPageObjects.end(), docPages.begin(), docPages.end()); + } + if (foundPageObjects.empty()) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No page found"), + QObject::tr("No Drawing Pages available.")); + return nullptr; + } else if (foundPageObjects.size() > 1) { + //multiple pages available, ask for help + for (auto obj : foundPageObjects) { + std::string name = obj->getNameInDocument(); + names.push_back(name); + std::string label = obj->Label.getValue(); + labels.push_back(label); + } + DlgPageChooser dlg(labels, names, Gui::getMainWindow()); + if (dlg.exec() == QDialog::Accepted) { + std::string selName = dlg.getSelection(); + App::Document* doc = cmd->getDocument(); + return static_cast(doc->getObject(selName.c_str())); + } + } else { + //only 1 page found + return static_cast (foundPageObjects.front()); + } + } //check Selection for a page std::vector selPages = cmd->getSelection(). getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); if (selPages.empty()) { - //no page in selection, try document - selPages = cmd->getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); - if (selPages.empty()) { - //no page in document + //no page in selection, try this document + auto docPages = cmd->getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); + if (docPages.empty()) { + //we are only to look in this document, and there is no page in this document QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No page found"), QObject::tr("No Drawing Pages in document.")); + return nullptr; } - else if (selPages.size() > 1) { - //multiple pages in document, but none selected - //use active page if there is one + if (docPages.size() > 1) { + //multiple pages in document, use active page if there is one Gui::MainWindow* w = Gui::getMainWindow(); Gui::MDIView* mv = w->activeWindow(); MDIViewPage* mvp = dynamic_cast(mv); if (mvp) { QGSPage* qp = mvp->getViewProviderPage()->getQGSPage(); - page = qp->getDrawPage(); + return qp->getDrawPage(); } else { - // no active page + // none of pages in document is active, ask for help for (auto obj : selPages) { std::string name = obj->getNameInDocument(); names.push_back(name); @@ -122,13 +163,12 @@ TechDraw::DrawPage* DrawGuiUtil::findPage(Gui::Command* cmd) if (dlg.exec() == QDialog::Accepted) { std::string selName = dlg.getSelection(); App::Document* doc = cmd->getDocument(); - page = static_cast(doc->getObject(selName.c_str())); + return static_cast(doc->getObject(selName.c_str())); } } - } - else { + } else { //only 1 page in document - use it - page = static_cast(selPages.front()); + return static_cast(docPages.front()); } } else if (selPages.size() > 1) { @@ -143,15 +183,16 @@ TechDraw::DrawPage* DrawGuiUtil::findPage(Gui::Command* cmd) if (dlg.exec() == QDialog::Accepted) { std::string selName = dlg.getSelection(); App::Document* doc = cmd->getDocument(); - page = static_cast(doc->getObject(selName.c_str())); + return static_cast(doc->getObject(selName.c_str())); } } else { //exactly 1 page in selection, use it - page = static_cast(selPages.front()); + return static_cast(selPages.front()); } - return page; + //we can not actually reach this point. + return nullptr; } bool DrawGuiUtil::isDraftObject(App::DocumentObject* obj) @@ -246,18 +287,33 @@ bool DrawGuiUtil::isArchSection(App::DocumentObject* obj) return result; } -bool DrawGuiUtil::needPage(Gui::Command* cmd) +bool DrawGuiUtil::needPage(Gui::Command* cmd, + bool findAny) { + if (findAny) { + //look for any page in any open document + auto docsAll = App::GetApplication().getDocuments(); + for (auto& doc : docsAll) { + auto docPages = doc->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); + if (docPages.empty()) { + //this open document has no TD pages + continue; + } else { + //found at least 1 page + return true; + } + } + //did not find any pages + return false; + } + //need a Document and a Page - bool active = false; if (cmd->hasActiveDocument()) { auto drawPageType(TechDraw::DrawPage::getClassTypeId()); auto selPages = cmd->getDocument()->getObjectsOfType(drawPageType); - if (!selPages.empty()) { - active = true; - } + return !selPages.empty(); } - return active; + return false; } bool DrawGuiUtil::needView(Gui::Command* cmd, bool partOnly) diff --git a/src/Mod/TechDraw/Gui/DrawGuiUtil.h b/src/Mod/TechDraw/Gui/DrawGuiUtil.h index dd0ec46888..ec8e06db31 100644 --- a/src/Mod/TechDraw/Gui/DrawGuiUtil.h +++ b/src/Mod/TechDraw/Gui/DrawGuiUtil.h @@ -56,13 +56,13 @@ namespace TechDrawGui class TechDrawGuiExport DrawGuiUtil { Q_DECLARE_TR_FUNCTIONS(TechDrawGui::DrawGuiUtil) public: - static TechDraw::DrawPage* findPage(Gui::Command* cmd); + static TechDraw::DrawPage* findPage(Gui::Command* cmd, bool findAny = false); static bool isDraftObject(App::DocumentObject* obj); static bool isArchObject(App::DocumentObject* obj); static bool isArchSection(App::DocumentObject* obj); - static bool needPage(Gui::Command* cmd); + static bool needPage(Gui::Command* cmd, bool findAny = false); static bool needView(Gui::Command* cmd, bool partOnly = true); static void dumpRectF(const char* text, const QRectF& r); static void dumpPointF(const char* text, const QPointF& p); diff --git a/src/Mod/TechDraw/Gui/Grabber3d.cpp b/src/Mod/TechDraw/Gui/Grabber3d.cpp index a56fa60bf2..85c8139352 100644 --- a/src/Mod/TechDraw/Gui/Grabber3d.cpp +++ b/src/Mod/TechDraw/Gui/Grabber3d.cpp @@ -30,35 +30,22 @@ #include "Grabber3d.h" - using namespace TechDrawGui; using namespace Gui; -void Grabber3d::quickView(const QColor bgColor, +void Grabber3d::quickView(View3DInventor* view3d, + const QColor bgColor, QImage &image) { // Base::Console().Message("G3d::quickView()); - //get a 3d view if (!Gui::getMainWindow()) { + //this should already be checked in the caller Base::Console().Warning("G3d::quickView - no Main Window - returning\n"); return; } - Gui::MainWindow* mainWindow = Gui::getMainWindow(); - Gui::MDIView* mdiView = Gui::getMainWindow()->activeWindow(); - View3DInventor* view3d = qobject_cast(mdiView); - if (!view3d) { - //the active window is not a 3D view, so try to find one - auto mdiWindows = mainWindow->windows(); - for (auto& mdi : mdiWindows) { - auto mdiView = qobject_cast(mdi); - if (mdiView) { - view3d = mdiView; - break; - } - } - } if (!view3d) { + //this should also already be checked in the caller Base::Console().Warning("G3d::quickView - no 3D view for ActiveView - returning\n"); return; } diff --git a/src/Mod/TechDraw/Gui/Grabber3d.h b/src/Mod/TechDraw/Gui/Grabber3d.h index 715a7d3016..e1edc5fc3c 100644 --- a/src/Mod/TechDraw/Gui/Grabber3d.h +++ b/src/Mod/TechDraw/Gui/Grabber3d.h @@ -28,6 +28,10 @@ #include #include +namespace Gui { +class View3DInventor; +} + namespace App { class Document; } @@ -38,7 +42,8 @@ namespace TechDrawGui /// Utility functions for obtaining 3d window image class TechDrawGuiExport Grabber3d { public: - static void quickView(const QColor bgColor, + static void quickView(Gui::View3DInventor* view3d, + const QColor bgColor, QImage &image); }; diff --git a/src/Mod/TechDraw/Gui/TaskActiveView.cpp b/src/Mod/TechDraw/Gui/TaskActiveView.cpp index 1912262fab..4fe60103d2 100644 --- a/src/Mod/TechDraw/Gui/TaskActiveView.cpp +++ b/src/Mod/TechDraw/Gui/TaskActiveView.cpp @@ -122,15 +122,31 @@ TechDraw::DrawViewImage* TaskActiveView::createActiveView() QObject::tr("Can not find the main window")); return nullptr; } + + App::Document* pageDocument = m_pageFeat->getDocument(); + std::string documentName = m_pageFeat->getDocument()->getName(); + Gui::Document* pageGuiDocument = Gui::Application::Instance->getDocument(pageDocument->getName()); + + //if the active view is a 3d window, use that. View3DInventor* view3d = qobject_cast(Gui::getMainWindow()->activeWindow()); if (!view3d) { - //the active window is not a 3D view, so try to find one - auto mdiWindows = Gui::getMainWindow()->windows(); - for (auto& mdi : mdiWindows) { - auto mdiView = qobject_cast(mdi); - if (mdiView) { - view3d = mdiView; - break; + // active view is not a 3D view, try to find one in the current document + auto views3dAll = pageGuiDocument->getMDIViewsOfType(Gui::View3DInventor::getClassTypeId()); + if (!views3dAll.empty()) { + view3d = qobject_cast(views3dAll.front()); + } else { + //this code is only for the rare case where the page's document does not have a + //3D window. It might occur if the user closes the 3D window, but leaves, for + //example, a DrawPage window open. + //the active window is not a 3D view, and the page's document does not have a + //3D view, so try to find one somewhere among the open windows. + auto mdiWindows = Gui::getMainWindow()->windows(); + for (auto& mdi : mdiWindows) { + auto mdiView = qobject_cast(mdi); + if (mdiView) { + view3d = mdiView; + break; + } } } } @@ -140,15 +156,20 @@ TechDraw::DrawViewImage* TaskActiveView::createActiveView() return nullptr; } + //we are sure we have a 3D window! std::string imageName = m_pageFeat->getDocument()->getUniqueObjectName("ActiveView"); std::string imageType = "TechDraw::DrawViewImage"; std::string pageName = m_pageFeat->getNameInDocument(); - Command::doCommand(Command::Doc,"App.activeDocument().addObject('%s','%s')", - imageType.c_str(),imageName.c_str()); - Command::doCommand(Command::Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)", - pageName.c_str(), imageName.c_str()); + //the Page's document may not be the active one, so we need to get the right + //document by name instead of using ActiveDocument + Command::doCommand(Command::Doc,"App.getDocument('%s').addObject('%s','%s')", + documentName.c_str(), + imageType.c_str(), imageName.c_str()); + Command::doCommand(Command::Doc,"App.getDocument('%s').%s.addView(App.getDocument('%s').%s)", + documentName.c_str(), pageName.c_str(), + documentName.c_str(), imageName.c_str()); App::Document* doc = m_pageFeat->getDocument(); std::string special = "/" + imageName + "image.png"; @@ -165,7 +186,7 @@ TechDraw::DrawViewImage* TaskActiveView::createActiveView() QImage image(100, 100, QImage::Format_RGB32); //arbitrary initial image size. quickView will use //MdiView size in pixels image.fill(QColor(Qt::transparent)); - Grabber3d:: quickView(bg, image); + Grabber3d:: quickView(view3d, bg, image); bool success = image.save(Base::Tools::fromStdString(fileSpec)); if (!success) { @@ -174,9 +195,17 @@ TechDraw::DrawViewImage* TaskActiveView::createActiveView() //backslashes in windows fileSpec upsets python std::regex rxBackslash("\\\\"); std::string noBackslash = std::regex_replace(fileSpec, rxBackslash, "/"); - Command::doCommand(Command::Doc,"App.activeDocument().%s.ImageFile = '%s'",imageName.c_str(), noBackslash.c_str()); - Command::doCommand(Command::Doc,"App.activeDocument().%s.Width = %.5f",imageName.c_str(), ui->qsbWidth->rawValue()); - Command::doCommand(Command::Doc,"App.activeDocument().%s.Height = %.5f",imageName.c_str(), ui->qsbHeight->rawValue()); + Command::doCommand(Command::Doc,"App.getDocument('%s').%s.ImageFile = '%s'", + documentName.c_str(), + imageName.c_str(), noBackslash.c_str()); + Command::doCommand(Command::Doc,"App.getDocument('%s').%s.Width = %.5f", + documentName.c_str(), + imageName.c_str(), + ui->qsbWidth->rawValue()); + Command::doCommand(Command::Doc,"App.getDocument('%s').%s.Height = %.5f", + documentName.c_str(), + imageName.c_str(), + ui->qsbHeight->rawValue()); App::DocumentObject* newObj = m_pageFeat->getDocument()->getObject(imageName.c_str()); TechDraw::DrawViewImage* newImg = dynamic_cast(newObj); @@ -193,7 +222,6 @@ TechDraw::DrawViewImage* TaskActiveView::createActiveView() } } - return newImg; }