diff --git a/src/Mod/TechDraw/App/DrawSVGTemplate.cpp b/src/Mod/TechDraw/App/DrawSVGTemplate.cpp index abd145f84c..f952893be7 100644 --- a/src/Mod/TechDraw/App/DrawSVGTemplate.cpp +++ b/src/Mod/TechDraw/App/DrawSVGTemplate.cpp @@ -96,34 +96,52 @@ void DrawSVGTemplate::onChanged(const App::Property* prop) TechDraw::DrawTemplate::onChanged(prop); } +void DrawSVGTemplate::onSettingDocument() +{ + attachDocument(DocumentObject::getDocument()); + DrawTemplate::onSettingDocument(); +} + +//? should this check for creation of a template or a page? +void DrawSVGTemplate::slotCreatedObject(const App::DocumentObject& obj) +{ + // Base::Console().Message("DSVGT::slotCreatedObject()\n"); + if (!obj.isDerivedFrom(TechDraw::DrawPage::getClassTypeId())) { + // we don't care + return; + } + EditableTexts.touch(); +} + +void DrawSVGTemplate::slotDeletedObject(const App::DocumentObject& obj) +{ + // Base::Console().Message("DSVGT::slotDeletedObject()\n"); + if (!obj.isDerivedFrom(TechDraw::DrawPage::getClassTypeId())) { + // we don't care + return; + } + EditableTexts.touch(); +} + + + + //parse the Svg code, inserting current EditableTexts values, and return the result as a QString. //While parsing, note the Orientation, Width and Height values in the Svg code. QString DrawSVGTemplate::processTemplate() { -// Base::Console().Message("DSVGT::processTemplate() - isRestoring: %d\n", isRestoring()); + // Base::Console().Message("DSVGT::processTemplate() - isRestoring: %d\n", isRestoring()); if (isRestoring()) { //until everything is fully restored, the embedded file is not available, so we //can't do anything return QString(); } + QDomDocument templateDocument; if (!getTemplateDocument(PageResult.getValue(), templateDocument)) { return QString(); } -// QFile templateFile(Base::Tools::fromStdString(PageResult.getValue())); -// if (!templateFile.open(QIODevice::ReadOnly)) { -// Base::Console().Error("DrawSVGTemplate::processTemplate can't read embedded template %s!\n", PageResult.getValue()); -// return QString(); -// } - -// QDomDocument templateDocument; -// if (!templateDocument.setContent(&templateFile)) { -// Base::Console().Error("DrawSVGTemplate::processTemplate - failed to parse file: %s\n", -// PageResult.getValue()); -// return QString(); -// } - XMLQuery query(templateDocument); std::map substitutions = EditableTexts.getValues(); @@ -133,12 +151,23 @@ QString DrawSVGTemplate::processTemplate() "declare default element namespace \"" SVG_NS_URI "\"; " "declare namespace freecad=\"" FREECAD_SVG_NS_URI "\"; " "//text[@" FREECAD_ATTR_EDITABLE "]/tspan"), - [&substitutions, &templateDocument](QDomElement& tspan) -> bool { + [this, &substitutions, &templateDocument](QDomElement& tspan) -> bool { // Replace the editable text spans with new nodes holding actual values QString editableName = tspan.parentNode().toElement().attribute(QString::fromUtf8(FREECAD_ATTR_EDITABLE)); std::map::iterator item = substitutions.find(editableName.toStdString()); if (item != substitutions.end()) { + // we have an editable text, is it autofill? autofill values may have + // changed. + QDomElement parent = tspan.parentNode().toElement(); + QString editableValue = QString::fromUtf8(item->second.c_str()); + if (parent.hasAttribute(QString::fromUtf8(FREECAD_ATTR_AUTOFILL))) { + QString autofillValue = getAutofillValue(parent.attribute(QString::fromUtf8(FREECAD_ATTR_AUTOFILL))); + if (!autofillValue.isNull()) { + editableValue = autofillValue; + } + } + // Keep all spaces in the text node tspan.setAttribute(QString::fromUtf8("xml:space"), QString::fromUtf8("preserve")); @@ -146,34 +175,12 @@ QString DrawSVGTemplate::processTemplate() while (!tspan.lastChild().isNull()) { tspan.removeChild(tspan.lastChild()); } - tspan.appendChild(templateDocument.createTextNode(QString::fromUtf8(item->second.c_str()))); + tspan.appendChild(templateDocument.createTextNode(editableValue)); } return true; }); extractTemplateAttributes(templateDocument); -// // Calculate the dimensions of the page and store for retrieval -// // Obtain the size of the SVG document by reading the document attributes -// QDomElement docElement = templateDocument.documentElement(); -// Base::Quantity quantity; - -// // Obtain the width -// QString str = docElement.attribute(QString::fromLatin1("width")); -// quantity = Base::Quantity::parse(str); -// quantity.setUnit(Base::Unit::Length); - -// Width.setValue(quantity.getValue()); - -// str = docElement.attribute(QString::fromLatin1("height")); -// quantity = Base::Quantity::parse(str); -// quantity.setUnit(Base::Unit::Length); - -// Height.setValue(quantity.getValue()); - -// bool isLandscape = getWidth() / getHeight() >= 1.; - -// Orientation.setValue(isLandscape ? 1 : 0); - //all Qt holds on files should be released on exit #4085 return templateDocument.toString(); } @@ -250,14 +257,9 @@ void DrawSVGTemplate::replaceFileIncluded(std::string newTemplateFileName) std::map DrawSVGTemplate::getEditableTextsFromTemplate() { -// Base::Console().Message("DSVGT::getEditableTextsFromTemplate()\n"); + // Base::Console().Message("DSVGT::getEditableTextsFromTemplate()\n"); std::map editables; -// std::string templateFilename = Template.getValue(); -// if (templateFilename.empty()) { -// return editables; -// } - // if we pass the filename we can reuse getTemplateDocument here QDomDocument templateDocument; if (!getTemplateDocument(Template.getValue(), templateDocument)) { @@ -265,30 +267,6 @@ std::map DrawSVGTemplate::getEditableTextsFromTemplate } -// Base::FileInfo tfi(templateFilename); -// if (!tfi.isReadable()) { -// // if there is an old absolute template file set use a redirect -// tfi.setFile(App::Application::getResourceDir() + "Mod/Drawing/Templates/" + tfi.fileName()); -// // try the redirect -// if (!tfi.isReadable()) { -// Base::Console().Error("DrawSVGTemplate::getEditableTextsFromTemplate() not able to open %s!\n", Template.getValue()); -// return editables; -// } -// } - -// QFile templateFile(QString::fromUtf8(tfi.filePath().c_str())); -// if (!templateFile.open(QIODevice::ReadOnly)) { -// Base::Console().Error("DrawSVGTemplate::getEditableTextsFromTemplate() can't read template %s!\n", Template.getValue()); -// return editables; -// } - -// QDomDocument templateDocument; -// if (!templateDocument.setContent(&templateFile)) { -// Base::Console().Message("DrawSVGTemplate::getEditableTextsFromTemplate() - failed to parse file: %s\n", -// Template.getValue()); -// return editables; -// } - XMLQuery query(templateDocument); // XPath query to select all nodes whose parent @@ -311,7 +289,7 @@ std::map DrawSVGTemplate::getEditableTextsFromTemplate // If the autofill value is not specified or unsupported, use the default text value if (editableValue.isNull()) { - editableValue = tspan.firstChild().nodeValue(); + editableValue = tspan.firstChild().nodeValue(); } editables[std::string(editableName.toUtf8().constData())] = diff --git a/src/Mod/TechDraw/App/DrawSVGTemplate.h b/src/Mod/TechDraw/App/DrawSVGTemplate.h index 4454967e11..b8b662c49f 100644 --- a/src/Mod/TechDraw/App/DrawSVGTemplate.h +++ b/src/Mod/TechDraw/App/DrawSVGTemplate.h @@ -25,6 +25,7 @@ # include +#include #include #include #include @@ -35,7 +36,8 @@ namespace TechDraw { -class TechDrawExport DrawSVGTemplate: public TechDraw::DrawTemplate +class TechDrawExport DrawSVGTemplate: public TechDraw::DrawTemplate, + public App::DocumentObserver { PROPERTY_HEADER_WITH_OVERRIDE(TechDraw::DrawSVGTemplate); @@ -65,9 +67,15 @@ public: protected: + void onSettingDocument() override; + void replaceFileIncluded(std::string newTemplateFileName); std::map getEditableTextsFromTemplate(); +private: + void slotCreatedObject(const App::DocumentObject& obj) override; + void slotDeletedObject(const App::DocumentObject& obj) override; + }; using DrawSVGTemplatePython = App::FeaturePythonT; diff --git a/src/Mod/TechDraw/App/DrawTemplate.cpp b/src/Mod/TechDraw/App/DrawTemplate.cpp index 7ba1cfbe50..527b5a1c44 100644 --- a/src/Mod/TechDraw/App/DrawTemplate.cpp +++ b/src/Mod/TechDraw/App/DrawTemplate.cpp @@ -136,9 +136,11 @@ QString DrawTemplate::getAutofillValue(const QString &id) const std::vector pages = getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId()); std::vector pageNames; for (auto page : pages) { - pageNames.push_back(QString::fromUtf8(page->Label.getValue())); + if (page->isAttachedToDocument() && + !page->testStatus(App::ObjectStatus::Remove)) { + pageNames.push_back(QString::fromUtf8(page->Label.getValue())); + } } - QCollator collator; std::sort(pageNames.begin(), pageNames.end(), collator); diff --git a/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp b/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp index 75492b25e8..6a1993af60 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp @@ -62,8 +62,8 @@ ViewProviderTemplate::ViewProviderTemplate() : m_myName(std::string()) sPixmap = "TechDraw_TreePageTemplate"; - // Do not show in property editor why? wf WF: because DisplayMode applies only to coin and we - // don't use coin. + // Do not show in property editor why? wf WF: because DisplayMode applies only to coin and we + // don't use coin. DisplayMode.setStatus(App::Property::Hidden, true); } @@ -86,7 +86,7 @@ void ViewProviderTemplate::updateData(const App::Property* prop) if (prop == &(t->Template)) { auto page = t->getParentPage(); Gui::ViewProvider* vp = - Gui::Application::Instance->getDocument(t->getDocument())->getViewProvider(page); + Gui::Application::Instance->getDocument(t->DocumentObject::getDocument())->getViewProvider(page); TechDrawGui::ViewProviderPage* vpp = dynamic_cast(vp); if (vpp) { vpp->getQGSPage()->attachTemplate(t);