diff --git a/src/app/valentina/core/vcmdexport.cpp b/src/app/valentina/core/vcmdexport.cpp index 0ec03441a..47fe16429 100644 --- a/src/app/valentina/core/vcmdexport.cpp +++ b/src/app/valentina/core/vcmdexport.cpp @@ -5,8 +5,11 @@ VCommandLinePtr VCommandLine::instance = nullptr; -const static auto LONG_OPTION_OUTFILE = QStringLiteral("outfile"); -const static auto SINGLE_OPTION_OUTFILE = QStringLiteral("o"); +const static auto LONG_OPTION_BASENAME = QStringLiteral("basename"); +const static auto SINGLE_OPTION_BASENAME = QStringLiteral("b"); + +const static auto LONG_OPTION_DESTINATION = QStringLiteral("destination"); +const static auto SINGLE_OPTION_DESTINATION = QStringLiteral("d"); const static auto LONG_OPTION_MEASUREFILE = QStringLiteral("mfile"); const static auto SINGLE_OPTION_MEASUREFILE = QStringLiteral("m"); @@ -62,10 +65,16 @@ VCommandLine::VCommandLine() : parser() //keep in mind order here - that is how user will see it, so group-up for usability //=================================================================================== - {LONG_OPTION_OUTFILE, - new QCommandLineOption(QStringList() << SINGLE_OPTION_OUTFILE << LONG_OPTION_OUTFILE, - tr("Path to output exported layout file. Use it to enable console export mode."), - tr("The exported layout file"))}, + {LONG_OPTION_BASENAME, + new QCommandLineOption(QStringList() << SINGLE_OPTION_BASENAME << LONG_OPTION_BASENAME, + tr("The base filename of exported layout files. Use it to enable console export " + "mode."), + tr("The base filename of layout files"))}, + + {LONG_OPTION_DESTINATION, + new QCommandLineOption(QStringList() << SINGLE_OPTION_DESTINATION << LONG_OPTION_DESTINATION, + tr("The path to output destination folder."), + tr("The destination folder"))}, {LONG_OPTION_MEASUREFILE, new QCommandLineOption(QStringList() << SINGLE_OPTION_MEASUREFILE << LONG_OPTION_MEASUREFILE, @@ -87,18 +96,18 @@ VCommandLine::VCommandLine() : parser() {LONG_OPTION_PAGEW, new QCommandLineOption(QStringList() << SINGLE_OPTION_PAGEW << LONG_OPTION_PAGEW, - tr("Page width in current units like 12.0 (cannot be used with \"") - +LONG_OPTION_PAGETEMPLATE+tr("\", export mode)."), tr("The page width"))}, + tr("Page width in current units like 12.0 (cannot be used with \"%1\", export " + "mode).").arg(LONG_OPTION_PAGETEMPLATE), tr("The page width"))}, {LONG_OPTION_PAGEH, new QCommandLineOption(QStringList() << SINGLE_OPTION_PAGEH << LONG_OPTION_PAGEH, - tr("Page height in current units like 12.0 (cannot be used with \"") - +LONG_OPTION_PAGETEMPLATE+tr("\", export mode)."), ("The page height"))}, + tr("Page height in current units like 12.0 (cannot be used with \"%1\", export " + "mode).").arg(LONG_OPTION_PAGETEMPLATE), ("The page height"))}, {LONG_OPTION_PAGEUNITS, new QCommandLineOption(QStringList() << SINGLE_OPTION_PAGEUNITS << LONG_OPTION_PAGEUNITS, - tr("Page height/width measure units (cannot be used with \"")+ - LONG_OPTION_PAGETEMPLATE+tr("\", export mode): ") + VDomDocument::UnitsHelpString(), + tr("Page height/width measure units (cannot be used with \"%1\", export mode): ") + .arg(LONG_OPTION_PAGETEMPLATE) + VDomDocument::UnitsHelpString(), tr("The measure unit"))}, //=================================================================================== @@ -145,7 +154,7 @@ VCommandLine::VCommandLine() : parser() new QCommandLineOption(QStringList() << SINGLE_OPTION_TEST << LONG_OPTION_TEST, tr("Run the program in a test mode. The program this mode load a single pattern " "file and silently quit without showing the main window. The key have priority " - "before key '%1'.").arg(LONG_OPTION_OUTFILE))} + "before key '%1'.").arg(LONG_OPTION_BASENAME))} }), isGuiEnabled(false) { @@ -327,7 +336,7 @@ bool VCommandLine::IsTestModeEnabled() const //------------------------------------------------------------------------------------------------------ bool VCommandLine::IsExportEnabled() const { - const bool r = parser.isSet(*optionsUsed.value(LONG_OPTION_OUTFILE)); + const bool r = parser.isSet(*optionsUsed.value(LONG_OPTION_BASENAME)); if (r && parser.positionalArguments().size() != 1) { qCritical() << tr("Export options can be used with single input file only.") << "/n"; @@ -384,19 +393,31 @@ QString VCommandLine::OptMeasurePath() const return measure; } -//------------------------------------------------------------------------------------------------------ -QString VCommandLine::OptExportPath() const +//--------------------------------------------------------------------------------------------------------------------- +QString VCommandLine::OptBaseName() const { QString path; if (IsExportEnabled()) { - path = parser.value(*optionsUsed.value(LONG_OPTION_OUTFILE)); + path = parser.value(*optionsUsed.value(LONG_OPTION_BASENAME)); } return path; } -//------------------------------------------------------------------------------------------------------ +//--------------------------------------------------------------------------------------------------------------------- +QString VCommandLine::OptDestinationPath() const +{ + QString path; + if (IsExportEnabled()) + { + path = parser.value(*optionsUsed.value(LONG_OPTION_DESTINATION)); + } + + return path; +} + +//--------------------------------------------------------------------------------------------------------------------- int VCommandLine::OptExportType() const { int r = 0; diff --git a/src/app/valentina/core/vcmdexport.h b/src/app/valentina/core/vcmdexport.h index 69e01738c..908b35efb 100644 --- a/src/app/valentina/core/vcmdexport.h +++ b/src/app/valentina/core/vcmdexport.h @@ -63,8 +63,11 @@ public: //@brief returns path to custom measure file or empty string QString OptMeasurePath() const; - //@brief returns export path or empty string if not set - QString OptExportPath() const; + //@brief returns the base name of layout files or empty string if not set + QString OptBaseName() const; + + //@brief returns the absolute path to output destination directory or path to application's current directory if not set + QString OptDestinationPath() const; //@brief returns export type set, defaults 0 - svg int OptExportType() const; diff --git a/src/app/valentina/dialogs/dialogsavelayout.cpp b/src/app/valentina/dialogs/dialogsavelayout.cpp index c0a7f71ff..f3859f392 100644 --- a/src/app/valentina/dialogs/dialogsavelayout.cpp +++ b/src/app/valentina/dialogs/dialogsavelayout.cpp @@ -40,10 +40,13 @@ using namespace nm_DialogSaveLayout; +const QString baseFilenameRegExp = QStringLiteral("^[\\w\\-. ]+$"); + bool VFrmWithTest::havePdf = false; bool VFrmWithTest::tested = false; -const std::vector DialogSaveLayout::availFormats = { +const std::vector DialogSaveLayout::availFormats = +{ VFrmWithTest(tr("Svg files (*.svg)"), ".svg"), VFrmWithTest(tr("PDF files (*.pdf)"), ".pdf"), VFrmWithTest(tr("Images (*.png)"), ".png"), @@ -55,8 +58,7 @@ const std::vector DialogSaveLayout::availFormats = { //--------------------------------------------------------------------------------------------------------------------- -DialogSaveLayout::DialogSaveLayout(int count, const QString &fileName, - QWidget *parent) +DialogSaveLayout::DialogSaveLayout(int count, const QString &fileName, QWidget *parent) :QDialog(parent), ui(new Ui::DialogSaveLAyout), count(count) { ui->setupUi(this); @@ -67,16 +69,33 @@ DialogSaveLayout::DialogSaveLayout(int count, const QString &fileName, SCASSERT(bOk != nullptr); bOk->setEnabled(false); - QRegularExpressionValidator *validator = new QRegularExpressionValidator(QRegularExpression("^[\\w\\-. ]+$"), this); + QRegularExpressionValidator *validator = new QRegularExpressionValidator(QRegularExpression(baseFilenameRegExp), + this); ui->lineEditFileName->setValidator(validator); - ui->lineEditFileName->setText(fileName+"_"); + const QString mask = fileName+QLatin1Literal("_"); + if (VApplication::CheckGUI()) + { + ui->lineEditFileName->setText(mask); + } + else + { + if (QRegularExpression(baseFilenameRegExp).match(mask).hasMatch()) + { + ui->lineEditFileName->setText(mask); + } + else + { + qCritical() << tr("The base filename has not match regular expression."); + std::exit(V_EX_USAGE); + } + } foreach (auto& v , availFormats) { - if (v.test()) - { - ui->comboBoxFormat->addItem(v.pair.first, QVariant(v.pair.second)); - } + if (v.test()) + { + ui->comboBoxFormat->addItem(v.pair.first, QVariant(v.pair.second)); + } } connect(bOk, &QPushButton::clicked, this, &DialogSaveLayout::Save); connect(ui->lineEditFileName, &QLineEdit::textChanged, this, &DialogSaveLayout::ShowExample); @@ -126,17 +145,30 @@ QString DialogSaveLayout::MakeHelpFormatList() } //--------------------------------------------------------------------------------------------------------------------- -void DialogSaveLayout::SetFullPath(const QString &cmdFileName) +void DialogSaveLayout::SetDestinationPath(const QString &cmdDestinationPath) { - QFileInfo fn(cmdFileName); - fn.makeAbsolute(); - auto p = fn.dir().absolutePath(); - auto n = fn.fileName()+"_"; - QTextStream sout(stdout); + QString path; + if (cmdDestinationPath.isEmpty()) + { + path = QDir::currentPath(); + } + else if (QDir(cmdDestinationPath).isAbsolute()) + { + path = cmdDestinationPath; + } + else + { + QDir dir; + if (not dir.cd(cmdDestinationPath)) + { + qCritical() << tr("The destination directory doesn't exists or is not readable."); + std::exit(V_EX_DATAERR); + } + path = dir.absolutePath(); + } - sout << tr("Output full path: ") << fn.filePath() << "\n"; - ui->lineEditPath->setText(p); - ui->lineEditFileName->setText(n); + qDebug() << "Output full path: " << path << "\n"; + ui->lineEditPath->setText(path); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/valentina/dialogs/dialogsavelayout.h b/src/app/valentina/dialogs/dialogsavelayout.h index 786d34f73..61e64bd0c 100644 --- a/src/app/valentina/dialogs/dialogsavelayout.h +++ b/src/app/valentina/dialogs/dialogsavelayout.h @@ -93,7 +93,7 @@ public: QString Formate() const; void SelectFormate(const size_t formate); static QString MakeHelpFormatList(); - void SetFullPath(const QString& cmdFileName); + void SetDestinationPath(const QString& cmdDestinationPath); public slots: void Save(); void ShowExample(); diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index bd8b36653..2844f8bac 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -3654,8 +3654,8 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams) } PrepareDetailsForLayout(details); LayoutSettings(*settings.get()); - DialogSaveLayout dialog(scenes.size(), expParams->OptExportPath(), this); - dialog.SetFullPath(expParams->OptExportPath()); + DialogSaveLayout dialog(scenes.size(), expParams->OptBaseName(), this); + dialog.SetDestinationPath(expParams->OptDestinationPath()); dialog.SelectFormate(expParams->OptExportType()); ExportLayout(dialog); } diff --git a/src/test/ValentinaTest/tst_valentinacommandline.cpp b/src/test/ValentinaTest/tst_valentinacommandline.cpp index 4bce7a2fa..def027b89 100644 --- a/src/test/ValentinaTest/tst_valentinacommandline.cpp +++ b/src/test/ValentinaTest/tst_valentinacommandline.cpp @@ -98,8 +98,10 @@ void TST_ValentinaCommandLine::ExportMode_data() const QTest::addColumn("result"); QTest::addColumn("exitCode"); + const QString tmp = QApplication::applicationDirPath() + QLatin1Char('/') + tmpTestFolder; + QTest::newRow("Issue #372")<< "issue_372.val" - << "-p;;0;;-o;;output" + << QString("-p;;0;;-d;;%1;;-b;;output").arg(tmp) << true << V_EX_OK; }