[TD]fix embedded template file handling
This commit is contained in:
@@ -33,11 +33,14 @@
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h> //TODO: should be in DrawTemplate.h??
|
||||
#include <Base/Console.h>
|
||||
#include <Base/FileInfo.h>
|
||||
#include <Base/Quantity.h>
|
||||
#include <Base/Tools.h>
|
||||
|
||||
#include "DrawPage.h"
|
||||
#include "DrawSVGTemplate.h"
|
||||
#include "DrawSVGTemplatePy.h"
|
||||
#include "DrawUtil.h"
|
||||
@@ -51,12 +54,8 @@ DrawSVGTemplate::DrawSVGTemplate()
|
||||
{
|
||||
static const char *group = "Template";
|
||||
|
||||
//TODO: Do we need PageResult anymore? -wf Yes!
|
||||
// PageResult points to a temporary file in tmp/FreeCAD-AB-CD-EF-.../myTemplate.svg
|
||||
// which is really copy of original Template with EditableFields replaced
|
||||
// When restoring saved document, Template is redundant/incorrect/not present - PageResult is the correct info. -wf-
|
||||
ADD_PROPERTY_TYPE(PageResult, (nullptr), group, App::Prop_Output, "Current SVG code for template");
|
||||
ADD_PROPERTY_TYPE(Template, (""), group, App::Prop_Transient, "Template for the page"); //sb TemplateFileName???
|
||||
ADD_PROPERTY_TYPE(PageResult, (nullptr), group, App::Prop_Output, "Embedded SVG code for template. For system use."); //n/a for users
|
||||
ADD_PROPERTY_TYPE(Template, (""), group, App::Prop_None, "Template file name.");
|
||||
|
||||
// Width and Height properties shouldn't be set by the user
|
||||
Height.setStatus(App::Property::ReadOnly, true);
|
||||
@@ -80,103 +79,44 @@ PyObject *DrawSVGTemplate::getPyObject()
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
|
||||
unsigned int DrawSVGTemplate::getMemSize() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
short DrawSVGTemplate::mustExecute() const
|
||||
{
|
||||
return TechDraw::DrawTemplate::mustExecute();
|
||||
}
|
||||
|
||||
void DrawSVGTemplate::onChanged(const App::Property* prop)
|
||||
{
|
||||
bool updatePage = false;
|
||||
|
||||
if (prop == &PageResult) {
|
||||
if (isRestoring()) {
|
||||
|
||||
//original template has been stored in fcstd file
|
||||
Template.setValue(PageResult.getValue());
|
||||
}
|
||||
} else if (prop == &Template) { //fileName has changed
|
||||
if (!isRestoring()) {
|
||||
EditableTexts.setValues(getEditableTextsFromTemplate());
|
||||
updatePage = true;
|
||||
}
|
||||
if (prop == &Template && !isRestoring()) {
|
||||
//if we are restoring an existing file we just want the properties set as they were save,
|
||||
//but if we are not restoring, we need to replace the embedded file and extract the new
|
||||
//EditableTexts.
|
||||
//We could try to find matching field names are preserve the values from
|
||||
//the old template, but there is no guarantee that the same fields will be present.
|
||||
replaceFileIncluded(Template.getValue());
|
||||
EditableTexts.setValues(getEditableTextsFromTemplate());
|
||||
} else if (prop == &EditableTexts) {
|
||||
if (!isRestoring()) {
|
||||
updatePage = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updatePage) {
|
||||
execute();
|
||||
//handled by ViewProvider
|
||||
}
|
||||
|
||||
TechDraw::DrawTemplate::onChanged(prop);
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn * DrawSVGTemplate::execute()
|
||||
//parse the Svg code, inserting current EditableTexts values, and return the result as a QString.
|
||||
//While parsing, not the Orientation, Width and Height values in the Svg code.
|
||||
QString DrawSVGTemplate::processTemplate()
|
||||
{
|
||||
std::string templateFilename = Template.getValue();
|
||||
if (templateFilename.empty())
|
||||
return App::DocumentObject::StdReturn;
|
||||
// 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();
|
||||
}
|
||||
|
||||
Base::FileInfo fi(templateFilename);
|
||||
if (!fi.isReadable()) {
|
||||
// non-empty template value, but can't read file
|
||||
// if there is a old absolute template file set use a redirect
|
||||
fi.setFile(App::Application::getResourceDir() + "Mod/Drawing/Templates/" + fi.fileName());
|
||||
// try the redirect
|
||||
if (!fi.isReadable()) {
|
||||
Base::Console().Log("DrawSVGTemplate::execute() not able to open %s!\n", Template.getValue());
|
||||
std::string error = std::string("Cannot open file ") + Template.getValue();
|
||||
return new App::DocumentObjectExecReturn(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (std::string(PageResult.getValue()).empty()) //first time through?
|
||||
PageResult.setValue(fi.filePath().c_str());
|
||||
|
||||
std::string templateFileSpec = fi.filePath();
|
||||
QString qSpec = Base::Tools::fromStdString(templateFileSpec);
|
||||
std::string documentImage;
|
||||
QString qDocImage;
|
||||
|
||||
qDocImage = processTemplate(qSpec);
|
||||
|
||||
if (!qDocImage.isEmpty()) {
|
||||
// make a temp file for FileIncluded Property
|
||||
std::string tempName = PageResult.getExchangeTempFile();
|
||||
std::ofstream outfinal(tempName.c_str());
|
||||
std::string result = Base::Tools::toStdString(qDocImage);
|
||||
outfinal << result;
|
||||
outfinal.close();
|
||||
PageResult.setValue(tempName.c_str());
|
||||
}
|
||||
else {
|
||||
Base::Console().Error("QSVGT::execute - failed to process Template\n");
|
||||
}
|
||||
|
||||
return TechDraw::DrawTemplate::execute();
|
||||
}
|
||||
|
||||
QString DrawSVGTemplate::processTemplate(QString fileSpec)
|
||||
{
|
||||
QFile templateFile(fileSpec);
|
||||
if (!templateFile.open(QIODevice::ReadOnly)) {
|
||||
Base::Console().Log("DrawSVGTemplate::execute() can't read template %s!\n", Template.getValue());
|
||||
std::string error = std::string("Cannot read file ") + Template.getValue();
|
||||
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().Message("DrawSVGTemplate::execute() - failed to parse file: %s\n",
|
||||
Template.getValue());
|
||||
std::string error = std::string("Cannot parse file ") + Template.getValue();
|
||||
Base::Console().Error("DrawSVGTemplate::processTemplate - failed to parse file: %s\n",
|
||||
PageResult.getValue());
|
||||
return QString();
|
||||
}
|
||||
|
||||
@@ -251,8 +191,24 @@ double DrawSVGTemplate::getHeight() const
|
||||
return Height.getValue();
|
||||
}
|
||||
|
||||
void DrawSVGTemplate::replaceFileIncluded(std::string newTemplateFileName)
|
||||
{
|
||||
// Base::Console().Message("DSVGT::replaceFileIncluded(%s)\n", newTemplateFileName.c_str());
|
||||
if (newTemplateFileName.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Base::FileInfo tfi(newTemplateFileName);
|
||||
if (tfi.isReadable()) {
|
||||
PageResult.setValue(newTemplateFileName.c_str());
|
||||
} else {
|
||||
throw Base::RuntimeError("Could not read the new template file");
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> DrawSVGTemplate::getEditableTextsFromTemplate()
|
||||
{
|
||||
// Base::Console().Message("DSVGT::getEditableTextsFromTemplate()\n");
|
||||
std::map<std::string, std::string> editables;
|
||||
|
||||
std::string templateFilename = Template.getValue();
|
||||
|
||||
Reference in New Issue
Block a user