From 55da881bc98f48cab7bc8af94cc280ca77694723 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Wed, 18 Mar 2020 12:27:58 -0400 Subject: [PATCH] [TD]improve selection filtering for DraftView --- src/Mod/TechDraw/Gui/Command.cpp | 34 +++++---- src/Mod/TechDraw/Gui/DrawGuiUtil.cpp | 104 ++++++++++++++++----------- src/Mod/TechDraw/Gui/DrawGuiUtil.h | 3 + 3 files changed, 87 insertions(+), 54 deletions(-) diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 738a7455b3..36d6c9c35e 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -1095,26 +1095,36 @@ void CmdTechDrawDraftView::activated(int iMsg) if (!page) { return; } + std::string PageName = page->getNameInDocument(); + + std::vector objects = getSelection(). + getObjectsOfType(App::DocumentObject::getClassTypeId()); -//TODO: shouldn't this be checking for a Draft object only? -// there is no obvious way of check for a Draft object. Could be App::FeaturePython, Part::Part2DObject, ??? - std::vector objects = getSelection().getObjectsOfType(App::DocumentObject::getClassTypeId()); if (objects.empty()) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Select at least one object.")); return; } - std::string PageName = page->getNameInDocument(); + int draftItemsFound = 0; for (std::vector::iterator it = objects.begin(); it != objects.end(); ++it) { - std::string FeatName = getUniqueObjectName("DraftView"); - std::string SourceName = (*it)->getNameInDocument(); - openCommand("Create DraftView"); - doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDraft','%s')",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(); + if (DrawGuiUtil::isDraftObject((*it))) { + draftItemsFound++; + std::string FeatName = getUniqueObjectName("DraftView"); + std::string SourceName = (*it)->getNameInDocument(); + openCommand("Create DraftView"); + doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDraft','%s')",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(); + } + } + if (draftItemsFound == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("There were no DraftWB objects in the selection.")); } } diff --git a/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp b/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp index 15808e75a5..e14b4a6954 100644 --- a/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp +++ b/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp @@ -48,6 +48,8 @@ #include #include #include +#include +#include #include #include #include @@ -102,34 +104,21 @@ void DrawGuiUtil::loadArrowBox(QComboBox* qcb) //find a page in Selection, Document or CurrentWindow. TechDraw::DrawPage* DrawGuiUtil::findPage(Gui::Command* cmd) { - TechDraw::DrawPage* page; - int failCase = 0; + TechDraw::DrawPage* page = nullptr; - //check Selection and/or Document for a DrawPage - std::vector selPages = cmd->getSelection().getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); - if (selPages.empty()) { //no page in selection + //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 - page = nullptr; - failCase = 1; - } else if (selPages.size() > 1) { //multiple pages in document, but none selected - page = nullptr; - failCase = 2; - } else { //only page in document - use it - page = static_cast(selPages.front()); - } - } else if (selPages.size() > 1) { //multiple pages in selection - page = nullptr; - failCase = 3; - } else { //use only page in selection - page = static_cast(selPages.front()); - } - - //if no page is selected - //default to currently displayed DrawPage is there is one //code moved Coverity CID 174668 - if (page == nullptr) { - if ((failCase == 1) || - (failCase == 2)) { + if (selPages.empty()) { + //no page in document + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No page found"), + QObject::tr("No Drawing Pages in document.")); + } else if (selPages.size() > 1) { + //multiple pages in document, but none selected + //use active page if there is one Gui::MainWindow* w = Gui::getMainWindow(); Gui::MDIView* mv = w->activeWindow(); MDIViewPage* mvp = dynamic_cast(mv); @@ -138,30 +127,61 @@ TechDraw::DrawPage* DrawGuiUtil::findPage(Gui::Command* cmd) QGVPage* qp = mvp->getQGVPage(); page = qp->getDrawPage(); } else { - failCase = 1; - } - } - } - - if (page == nullptr) { - switch(failCase) { - case 1: - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No page found"), - QObject::tr("Create/select a page first.")); - break; - case 2: + // no active page QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Which page?"), QObject::tr("Can not determine correct page.")); - break; - case 3: - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Too many pages"), - QObject::tr("Select exactly 1 page.")); + } + } else { + //only 1 page in document - use it + page = static_cast(selPages.front()); } + } else if (selPages.size() > 1) { + //multiple pages in selection + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Too many pages"), + QObject::tr("Select only 1 page.")); + } else { + //exactly 1 page in selection, use it + page = static_cast(selPages.front()); } return page; } +bool DrawGuiUtil::isDraftObject(App::DocumentObject* obj) +{ + bool result = false; + App::Property* proxy = obj->getPropertyByName("Proxy"); + + if (proxy != nullptr) { + //if no proxy, can not be Draft obj + //if has proxy, might be Draft obj + App::PropertyPythonObject* proxyPy = dynamic_cast(proxy); + std::stringstream ss; + if (proxyPy != nullptr) { + Py::Object proxyObj = proxyPy->getValue(); + std::stringstream ss; + if (proxyPy != nullptr) { + Base::PyGILStateLocker lock; + try { + if (proxyObj.hasAttr("__module__")) { + Py::String mod(proxyObj.getAttr("__module__")); + ss << (std::string)mod; + if (ss.str().find("Draft") != std::string::npos) { + result = true; + } + } + } + catch (Py::Exception&) { + Base::PyException e; // extract the Python error text + e.ReportException(); + result = false; + } + } + } + } + return result; +} + bool DrawGuiUtil::needPage(Gui::Command* cmd) { //need a Document and a Page diff --git a/src/Mod/TechDraw/Gui/DrawGuiUtil.h b/src/Mod/TechDraw/Gui/DrawGuiUtil.h index 0a8c893a52..1829ae1bb7 100644 --- a/src/Mod/TechDraw/Gui/DrawGuiUtil.h +++ b/src/Mod/TechDraw/Gui/DrawGuiUtil.h @@ -30,6 +30,8 @@ #include #include +#include + /*#include */ namespace Part { @@ -51,6 +53,7 @@ class TechDrawGuiExport DrawGuiUtil { Q_DECLARE_TR_FUNCTIONS(TechDrawGui::DrawGuiUtil) public: static TechDraw::DrawPage* findPage(Gui::Command* cmd); + static bool isDraftObject(App::DocumentObject* obj); static bool needPage(Gui::Command* cmd); static bool needView(Gui::Command* cmd, bool partOnly = true); static void dumpRectF(const char* text, const QRectF& r);