[TD] Fix win file spec backslash (fix #16646) (#16689)

* [TD]add method to clean win filespecs

- '\' in strings passed to Python as filespecs is interpreted as
  an escape of the following character.
- replace '\' with '/'

* [TD]remove '\' from filespecs before use
This commit is contained in:
WandererFan
2024-09-23 11:40:05 -04:00
committed by GitHub
parent 1ce5fca06b
commit c9beae7ef3
8 changed files with 58 additions and 20 deletions

View File

@@ -1899,6 +1899,18 @@ bool DrawUtil::isCenterLine(App::DocumentObject* owner, std::string element)
return false;
}
//! convert a filespec (string) containing '\' to only use '/'.
//! prevents situation where '\' is interpreted as an escape of the next character in Python
//! commands.
std::string DrawUtil::cleanFilespecBackslash(const std::string& filespec)
{
std::string forwardSlash{"/"};
boost::regex rxBackslash("\\\\"); //this rx really means match to a single '\'
std::string noBackslash = boost::regex_replace(filespec, rxBackslash, forwardSlash);
return noBackslash;
}
//============================
// various debugging routines.
void DrawUtil::dumpVertexes(const char* text, const TopoDS_Shape& s)

View File

@@ -277,6 +277,8 @@ public:
static bool isWithinRange(double actualAngleIn, double targetAngleIn, double allowableError);
static std::string cleanFilespecBackslash(const std::string& filespec);
//debugging routines
static void dumpVertexes(const char* text, const TopoDS_Shape& s);

View File

@@ -94,6 +94,7 @@ std::pair<Base::Vector3d, Base::Vector3d> viewDirection();
class Vertex;
using namespace TechDrawGui;
using namespace TechDraw;
using DU = DrawUtil;
//===========================================================================
// TechDraw_PageDefault
@@ -137,7 +138,8 @@ void CmdTechDrawPageDefault::activated(int iMsg)
svgTemplate->translateLabel("DrawSVGTemplate", "Template", svgTemplate->getNameInDocument());
page->Template.setValue(svgTemplate);
svgTemplate->Template.setValue(templateFileName.toStdString());
auto filespec = DU::cleanFilespecBackslash(Base::Tools::toStdString(templateFileName));
svgTemplate->Template.setValue(filespec);
updateActive();
commitCommand();
@@ -207,7 +209,8 @@ void CmdTechDrawPageTemplate::activated(int iMsg)
svgTemplate->translateLabel("DrawSVGTemplate", "Template", svgTemplate->getNameInDocument());
page->Template.setValue(svgTemplate);
svgTemplate->Template.setValue(templateFileName.toStdString());
auto filespec = DU::cleanFilespecBackslash(Base::Tools::toStdString(templateFileName));
svgTemplate->Template.setValue(filespec);
updateActive();
commitCommand();
@@ -448,8 +451,9 @@ void CmdTechDrawView::activated(int iMsg)
|| filename.endsWith(QString::fromLatin1(".svgz"), Qt::CaseInsensitive)) {
std::string FeatName = getUniqueObjectName("Symbol");
filename = Base::Tools::escapeEncodeFilename(filename);
auto filespec = DU::cleanFilespecBackslash(Base::Tools::toStdString(filename));
openCommand(QT_TRANSLATE_NOOP("Command", "Create Symbol"));
doCommand(Doc, "f = open(\"%s\", 'r')", (const char*)filename.toUtf8());
doCommand(Doc, "f = open(\"%s\", 'r')", filespec.c_str());
doCommand(Doc, "svg = f.read()");
doCommand(Doc, "f.close()");
doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewSymbol', '%s')",
@@ -463,11 +467,12 @@ void CmdTechDrawView::activated(int iMsg)
else {
std::string FeatName = getUniqueObjectName("Image");
filename = Base::Tools::escapeEncodeFilename(filename);
auto filespec = DU::cleanFilespecBackslash(Base::Tools::toStdString(filename));
openCommand(QT_TRANSLATE_NOOP("Command", "Create Image"));
doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewImage', '%s')", FeatName.c_str());
doCommand(Doc, "App.activeDocument().%s.translateLabel('DrawViewImage', 'Image', '%s')",
FeatName.c_str(), FeatName.c_str());
doCommand(Doc, "App.activeDocument().%s.ImageFile = '%s'", FeatName.c_str(), filename.toUtf8().constData());
doCommand(Doc, "App.activeDocument().%s.ImageFile = '%s'", FeatName.c_str(), filespec.c_str());
doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str());
updateActive();
commitCommand();
@@ -1541,8 +1546,9 @@ void CmdTechDrawSymbol::activated(int iMsg)
if (!filename.isEmpty()) {
std::string FeatName = getUniqueObjectName("Symbol");
filename = Base::Tools::escapeEncodeFilename(filename);
auto filespec = DU::cleanFilespecBackslash(Base::Tools::toStdString(filename));
openCommand(QT_TRANSLATE_NOOP("Command", "Create Symbol"));
doCommand(Doc, "f = open(\"%s\", 'r')", (const char*)filename.toUtf8());
doCommand(Doc, "f = open(\"%s\", 'r')", (const char*)filespec.c_str());
doCommand(Doc, "svg = f.read()");
doCommand(Doc, "f.close()");
doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewSymbol', '%s')",
@@ -1853,8 +1859,9 @@ void CmdTechDrawExportPageDXF::activated(int iMsg)
openCommand(QT_TRANSLATE_NOOP("Command", "Save page to DXF"));
doCommand(Doc, "import TechDraw");
fileName = Base::Tools::escapeEncodeFilename(fileName);
auto filespec = DU::cleanFilespecBackslash(Base::Tools::toStdString(fileName));
doCommand(Doc, "TechDraw.writeDXFPage(App.activeDocument().%s, u\"%s\")", PageName.c_str(),
(const char*)fileName.toUtf8());
filespec.c_str());
commitCommand();
}

View File

@@ -57,6 +57,7 @@
using namespace TechDrawGui;
using namespace TechDraw;
using DU = DrawUtil;
//internal functions
bool _checkSelectionHatch(Gui::Command* cmd);
@@ -266,11 +267,12 @@ void CmdTechDrawImage::activated(int iMsg)
std::string FeatName = getUniqueObjectName("Image");
fileName = Base::Tools::escapeEncodeFilename(fileName);
auto filespec = DU::cleanFilespecBackslash(Base::Tools::toStdString(fileName));
openCommand(QT_TRANSLATE_NOOP("Command", "Create Image"));
doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewImage', '%s')", FeatName.c_str());
doCommand(Doc, "App.activeDocument().%s.translateLabel('DrawViewImage', 'Image', '%s')",
FeatName.c_str(), FeatName.c_str());
doCommand(Doc, "App.activeDocument().%s.ImageFile = '%s'", FeatName.c_str(), fileName.toUtf8().constData());
doCommand(Doc, "App.activeDocument().%s.ImageFile = '%s'", FeatName.c_str(), filespec.c_str());
doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str());
updateActive();
commitCommand();

View File

@@ -49,6 +49,7 @@
#include <Mod/TechDraw/App/DrawPage.h>
#include <Mod/TechDraw/App/DrawPagePy.h>
#include <Mod/TechDraw/App/DrawTemplate.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include <Mod/TechDraw/App/Preferences.h>
#include "PagePrinter.h"
@@ -58,6 +59,7 @@
using namespace TechDrawGui;
using namespace TechDraw;
using DU = DrawUtil;
constexpr double A4Heightmm = 297.0;
constexpr double A4Widthmm = 210.0;
@@ -148,7 +150,9 @@ void PagePrinter::printPdf(std::string file)
}
// set up the pdfwriter
QString outputFile = QString::fromUtf8(file.data(), file.size());
auto filespec = Base::Tools::escapeEncodeFilename(file);
filespec = DU::cleanFilespecBackslash(file);
QString outputFile = Base::Tools::fromStdString(filespec);
QPdfWriter pdfWriter(outputFile);
QPageLayout pageLayout = pdfWriter.pageLayout();
auto marginsdb = pageLayout.margins(QPageLayout::Millimeter);
@@ -375,22 +379,25 @@ void PagePrinter::saveSVG(std::string file)
Base::Console().Warning("PagePrinter - no file specified\n");
return;
}
QString filename = QString::fromUtf8(file.data(), file.size());
auto filespec = Base::Tools::escapeEncodeFilename(file);
filespec = DU::cleanFilespecBackslash(file);
QString filename = Base::Tools::fromStdString(filespec);
if (m_scene) {
m_scene->saveSvg(filename);
}
}
void PagePrinter::saveDXF(std::string fileName)
void PagePrinter::saveDXF(std::string inFileName)
{
TechDraw::DrawPage* page = m_vpPage->getDrawPage();
std::string PageName = page->getNameInDocument();
fileName = Base::Tools::escapeEncodeFilename(fileName);
auto filespec = Base::Tools::escapeEncodeFilename(inFileName);
filespec = DU::cleanFilespecBackslash(filespec);
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Save page to dxf"));
Gui::Command::doCommand(Gui::Command::Doc, "import TechDraw");
Gui::Command::doCommand(Gui::Command::Doc,
"TechDraw.writeDXFPage(App.activeDocument().%s, u\"%s\")",
PageName.c_str(), (const char*)fileName.c_str());
PageName.c_str(), filespec.c_str());
Gui::Command::commitCommand();
}

View File

@@ -40,6 +40,7 @@
#include <Gui/ViewProvider.h>
#include <Mod/TechDraw/App/DrawPage.h>
#include <Mod/TechDraw/App/DrawViewImage.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include "TaskActiveView.h"
#include "ui_TaskActiveView.h"
@@ -51,6 +52,7 @@
using namespace Gui;
using namespace TechDraw;
using namespace TechDrawGui;
using DU = DrawUtil;
constexpr int SXGAWidth{1280};
constexpr int SXGAHeight{1024};
@@ -207,12 +209,9 @@ TechDraw::DrawViewImage* TaskActiveView::createActiveView()
Base::Console().Error("ActiveView could not save file: %s\n", fileSpec.c_str());
}
//backslashes in windows fileSpec upsets python
std::regex rxBackslash("\\\\"); //this rx really means match to a single '\'
std::string noBackslash = std::regex_replace(tempName, rxBackslash, "/");
tempName = DU::cleanFilespecBackslash(tempName);
Command::doCommand(Command::Doc, "App.getDocument('%s').%s.ImageFile = '%s'",
documentName.c_str(), imageName.c_str(), noBackslash.c_str());
documentName.c_str(), imageName.c_str(), tempName.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(),

View File

@@ -27,12 +27,14 @@
#include <App/Document.h>
#include <Base/Console.h>
#include <Base/Tools.h>
#include <Base/Vector3D.h>
#include <Gui/BitmapFactory.h>
#include <Gui/Command.h>
#include <Gui/ViewProvider.h>
#include <Mod/TechDraw/App/DrawGeomHatch.h>
#include <Mod/TechDraw/App/DrawView.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include "TaskGeomHatch.h"
#include "ui_TaskGeomHatch.h"
@@ -42,6 +44,7 @@
using namespace Gui;
using namespace TechDraw;
using namespace TechDrawGui;
using DU = DrawUtil;
TaskGeomHatch::TaskGeomHatch(TechDraw::DrawGeomHatch* inHatch, TechDrawGui::ViewProviderGeomHatch* inVp, bool mode) :
ui(new Ui_TaskGeomHatch),
@@ -91,7 +94,8 @@ void TaskGeomHatch::initUi()
void TaskGeomHatch::onFileChanged()
{
m_file = ui->fcFile->fileName().toUtf8().constData();
auto filespec = Base::Tools::toStdString(ui->fcFile->fileName());
m_file = DU::cleanFilespecBackslash(filespec);
std::vector<std::string> names = PATLineSpec::getPatternList(m_file);
QStringList qsNames = listToQ(names);
ui->cbName->clear();

View File

@@ -48,6 +48,7 @@
using namespace Gui;
using namespace TechDraw;
using namespace TechDrawGui;
using DU = DrawUtil;
//ctor for creation
TaskHatch::TaskHatch(TechDraw::DrawViewPart* inDvp, std::vector<std::string> subs) :
@@ -208,9 +209,11 @@ void TaskHatch::createHatch()
m_hatch = static_cast<TechDraw::DrawHatch *>(doc->getObject(FeatName.c_str()));
m_hatch->Source.setValue(m_dvp, m_subs);
auto filespec = Base::Tools::toStdString(ui->fcFile->fileName());
filespec = DU::cleanFilespecBackslash(filespec);
Command::doCommand(Command::Doc, "App.activeDocument().%s.HatchPattern = '%s'",
FeatName.c_str(),
Base::Tools::toStdString(ui->fcFile->fileName()).c_str());
filespec.c_str());
//view provider properties
Gui::ViewProvider* vp = Gui::Application::Instance->getDocument(doc)->getViewProvider(m_hatch);
@@ -236,9 +239,11 @@ void TaskHatch::updateHatch()
Command::openCommand(QT_TRANSLATE_NOOP("Command", "Update Hatch"));
auto filespec = Base::Tools::toStdString(ui->fcFile->fileName());
filespec = DU::cleanFilespecBackslash(filespec);
Command::doCommand(Command::Doc, "App.activeDocument().%s.HatchPattern = '%s'",
FeatName.c_str(),
Base::Tools::toStdString(ui->fcFile->fileName()).c_str());
filespec.c_str());
App::Color ac;
ac.setValue<QColor>(ui->ccColor->color());