[TD]Fix #4085 Win File Rename Fail
This commit is contained in:
@@ -133,128 +133,125 @@ void DrawSVGTemplate::onChanged(const App::Property* prop)
|
||||
|
||||
App::DocumentObjectExecReturn * DrawSVGTemplate::execute(void)
|
||||
{
|
||||
std::string templateFilename = Template.getValue();
|
||||
if (templateFilename.empty())
|
||||
return App::DocumentObject::StdReturn;
|
||||
std::string templateFilename = Template.getValue();
|
||||
if (templateFilename.empty())
|
||||
return App::DocumentObject::StdReturn;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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());
|
||||
if (std::string(PageResult.getValue()).empty()) //first time through?
|
||||
PageResult.setValue(fi.filePath().c_str());
|
||||
|
||||
QFile templateFile(QString::fromUtf8(fi.filePath().c_str()));
|
||||
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 new App::DocumentObjectExecReturn(error);
|
||||
}
|
||||
std::string templateFileSpec = fi.filePath();
|
||||
QString qSpec = Base::Tools::fromStdString(templateFileSpec);
|
||||
std::string documentImage;
|
||||
QString qDocImage;
|
||||
|
||||
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();
|
||||
return new App::DocumentObjectExecReturn(error);
|
||||
}
|
||||
qDocImage = processTemplate(qSpec);
|
||||
|
||||
QXmlQuery query(QXmlQuery::XQuery10);
|
||||
QDomNodeModel model(query.namePool(), templateDocument);
|
||||
query.setFocus(QXmlItem(model.fromDomNode(templateDocument.documentElement())));
|
||||
if (!qDocImage.isEmpty()) {
|
||||
// make a temp file for FileIncluded Property
|
||||
string tempName = PageResult.getExchangeTempFile();
|
||||
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");
|
||||
}
|
||||
|
||||
// XPath query to select all <tspan> nodes whose <text> parent
|
||||
// has "freecad:editable" attribute
|
||||
query.setQuery(QString::fromUtf8(
|
||||
"declare default element namespace \"" SVG_NS_URI "\"; "
|
||||
"declare namespace freecad=\"" FREECAD_SVG_NS_URI "\"; "
|
||||
"//text[@freecad:editable]/tspan"));
|
||||
|
||||
QXmlResultItems queryResult;
|
||||
query.evaluateTo(&queryResult);
|
||||
|
||||
std::map<std::string, std::string> substitutions = EditableTexts.getValues();
|
||||
while (!queryResult.next().isNull())
|
||||
{
|
||||
QDomElement tspan = model.toDomNode(queryResult.current().toNodeModelIndex()).toElement();
|
||||
|
||||
// Replace the editable text spans with new nodes holding actual values
|
||||
QString editableName = tspan.parentNode().toElement().attribute(QString::fromUtf8("freecad:editable"));
|
||||
std::map<std::string, std::string>::iterator item =
|
||||
substitutions.find(std::string(editableName.toUtf8().constData()));
|
||||
if (item != substitutions.end()) {
|
||||
// Keep all spaces in the text node
|
||||
tspan.setAttribute(QString::fromUtf8("xml:space"), QString::fromUtf8("preserve"));
|
||||
|
||||
// Remove all child nodes and append text node with editable replacement as the only descendant
|
||||
while (!tspan.lastChild().isNull()) {
|
||||
tspan.removeChild(tspan.lastChild());
|
||||
}
|
||||
tspan.appendChild(templateDocument.createTextNode(QString::fromUtf8(item->second.c_str())));
|
||||
}
|
||||
}
|
||||
|
||||
//re #4085 -
|
||||
std::string ssExchangeName = PageResult.getExchangeTempFile();
|
||||
QString qExchangeName = Base::Tools::fromStdString(ssExchangeName);
|
||||
bool rc = writeExchangeFile(qExchangeName, templateDocument.toString());
|
||||
if (rc) {
|
||||
PageResult.setValue(ssExchangeName.c_str());
|
||||
} else {
|
||||
Base::Console().Error("DrawSVGTemplate::execute - failed to exchange temp file: %s\n",
|
||||
ssExchangeName.c_str());
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
return TechDraw::DrawTemplate::execute();
|
||||
return TechDraw::DrawTemplate::execute();
|
||||
}
|
||||
|
||||
bool DrawSVGTemplate::writeExchangeFile(QString exchangeName, QString fileContent)
|
||||
QString DrawSVGTemplate::processTemplate(QString fileSpec)
|
||||
{
|
||||
// Base::Console().Message("DSVGT::writeExchangeFile(%s)\n", qPrintable(exchangeName));
|
||||
bool rc = true;
|
||||
QFile newTempFile(exchangeName);
|
||||
if (newTempFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream stream(&newTempFile);
|
||||
stream << fileContent;
|
||||
newTempFile.close();
|
||||
}
|
||||
else {
|
||||
Base::Console().Message("DrawSVGT:writeExchangeFile - failed to open temp file for writing: %s\n",
|
||||
qPrintable(exchangeName));
|
||||
rc = false;
|
||||
}
|
||||
return rc;
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
return QString();
|
||||
}
|
||||
|
||||
QXmlQuery query(QXmlQuery::XQuery10);
|
||||
QDomNodeModel model(query.namePool(), templateDocument);
|
||||
query.setFocus(QXmlItem(model.fromDomNode(templateDocument.documentElement())));
|
||||
|
||||
// XPath query to select all <tspan> nodes whose <text> parent
|
||||
// has "freecad:editable" attribute
|
||||
query.setQuery(QString::fromUtf8(
|
||||
"declare default element namespace \"" SVG_NS_URI "\"; "
|
||||
"declare namespace freecad=\"" FREECAD_SVG_NS_URI "\"; "
|
||||
"//text[@freecad:editable]/tspan"));
|
||||
|
||||
QXmlResultItems queryResult;
|
||||
query.evaluateTo(&queryResult);
|
||||
|
||||
std::map<std::string, std::string> substitutions = EditableTexts.getValues();
|
||||
while (!queryResult.next().isNull())
|
||||
{
|
||||
QDomElement tspan = model.toDomNode(queryResult.current().toNodeModelIndex()).toElement();
|
||||
|
||||
// Replace the editable text spans with new nodes holding actual values
|
||||
QString editableName = tspan.parentNode().toElement().attribute(QString::fromUtf8("freecad:editable"));
|
||||
std::map<std::string, std::string>::iterator item =
|
||||
substitutions.find(std::string(editableName.toUtf8().constData()));
|
||||
if (item != substitutions.end()) {
|
||||
// Keep all spaces in the text node
|
||||
tspan.setAttribute(QString::fromUtf8("xml:space"), QString::fromUtf8("preserve"));
|
||||
|
||||
// Remove all child nodes and append text node with editable replacement as the only descendant
|
||||
while (!tspan.lastChild().isNull()) {
|
||||
tspan.removeChild(tspan.lastChild());
|
||||
}
|
||||
tspan.appendChild(templateDocument.createTextNode(QString::fromUtf8(item->second.c_str())));
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
double DrawSVGTemplate::getWidth() const
|
||||
@@ -308,7 +305,7 @@ std::map<std::string, std::string> DrawSVGTemplate::getEditableTextsFromTemplate
|
||||
// XPath query to select all <tspan> nodes whose <text> parent
|
||||
// has "freecad:editable" attribute
|
||||
query.setQuery(QString::fromUtf8(
|
||||
"declare default element namespace \"" SVG_NS_URI "\"; "
|
||||
"declare default element namespace \"" SVG_NS_URI "\"; "
|
||||
"declare namespace freecad=\"" FREECAD_SVG_NS_URI "\"; "
|
||||
"//text[@freecad:editable]/tspan"));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user