diff --git a/src/app/puzzle/puzzle.pri b/src/app/puzzle/puzzle.pri index c05dc0d69..66396d8cc 100644 --- a/src/app/puzzle/puzzle.pri +++ b/src/app/puzzle/puzzle.pri @@ -2,21 +2,25 @@ # This need for corect working file translations.pro SOURCES += \ - $$PWD/main.cpp \ - $$PWD/puzzlemainwindow.cpp \ + $$PWD/main.cpp \ + $$PWD/puzzlecommands.cpp \ + $$PWD/puzzlemainwindow.cpp \ $$PWD/puzzleapplication.cpp \ + $$PWD/vpuzzlecommandline.cpp \ $$PWD/dialogs/dialogaboutpuzzle.cpp \ $$PWD/vpiececarrousel.cpp *msvc*:SOURCES += $$PWD/stable.cpp HEADERS += \ - $$PWD/puzzlemainwindow.h \ - $$PWD/stable.h \ + $$PWD/puzzlecommands.h \ + $$PWD/puzzlemainwindow.h \ + $$PWD/stable.h \ $$PWD/puzzleapplication.h \ + $$PWD/vpuzzlecommandline.h \ $$PWD/dialogs/dialogaboutpuzzle.h \ $$PWD/vpiececarrousel.h FORMS += \ - $$PWD/puzzlemainwindow.ui \ + $$PWD/puzzlemainwindow.ui \ $$PWD/dialogs/dialogaboutpuzzle.ui diff --git a/src/app/puzzle/puzzleapplication.cpp b/src/app/puzzle/puzzleapplication.cpp index 9cb624b52..b7ca164c9 100644 --- a/src/app/puzzle/puzzleapplication.cpp +++ b/src/app/puzzle/puzzleapplication.cpp @@ -387,6 +387,8 @@ void PuzzleApplication::InitOptions() LoadTranslation(QLocale().name());// By default the console version uses system locale + VPuzzleCommandLine::Instance(*this); + static const char * GENERIC_ICON_TO_CHECK = "document-open"; if (QIcon::hasThemeIcon(GENERIC_ICON_TO_CHECK) == false) { @@ -442,24 +444,8 @@ void PuzzleApplication::ActivateDarkMode() //--------------------------------------------------------------------------------------------------------------------- void PuzzleApplication::ParseCommandLine(const SocketConnection &connection, const QStringList &arguments) { - QCommandLineParser parser; - parser.setApplicationDescription(tr("Valentina's manual layout editor.")); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addPositionalArgument("filename", tr("The raw layout file.")); - //----- - QCommandLineOption testOption(QStringList() << "test", - tr("Use for unit testing. Run the program and open a file without showing the main window.")); - parser.addOption(testOption); - //----- - QCommandLineOption scalingOption(QStringList() << LONG_OPTION_NO_HDPI_SCALING, - tr("Disable high dpi scaling. Call this option if has problem with scaling (by default scaling enabled). " - "Alternatively you can use the %1 environment variable.").arg("QT_AUTO_SCREEN_SCALE_FACTOR=0")); - parser.addOption(scalingOption); - //----- - parser.process(arguments); - - testMode = parser.isSet(testOption); + VPuzzleCommandLinePtr cmd = CommandLine(); + testMode = cmd->IsTestModeEnabled(); if (not testMode && connection == SocketConnection::Client) { @@ -499,13 +485,13 @@ void PuzzleApplication::ParseCommandLine(const SocketConnection &connection, con LoadTranslation(PuzzleSettings()->GetLocale()); } - const QStringList args = parser.positionalArguments(); + const QStringList args = cmd->OptionFileNames(); if (args.count() > 0) { if (testMode && args.count() > 1) { qCCritical(mApp, "%s\n", qPrintable(tr("Test mode doesn't support openning several files."))); - parser.showHelp(V_EX_USAGE); + cmd.get()->parser.showHelp(V_EX_USAGE); } for (auto &arg : args) @@ -531,7 +517,7 @@ void PuzzleApplication::ParseCommandLine(const SocketConnection &connection, con else { qCCritical(mApp, "%s\n", qPrintable(tr("Please, provide one input file."))); - parser.showHelp(V_EX_USAGE); + cmd.get()->parser.showHelp(V_EX_USAGE); } } @@ -634,3 +620,9 @@ void PuzzleApplication::Clean() } } } + +//-------------------------------------------------------------------------------------------- +const VPuzzleCommandLinePtr PuzzleApplication::CommandLine() +{ + return VPuzzleCommandLine::instance; +} diff --git a/src/app/puzzle/puzzleapplication.h b/src/app/puzzle/puzzleapplication.h index 9f2b15760..73d22c03b 100644 --- a/src/app/puzzle/puzzleapplication.h +++ b/src/app/puzzle/puzzleapplication.h @@ -31,6 +31,9 @@ #include "../vmisc/def.h" #include "../vmisc/vpuzzlesettings.h" #include "../vmisc/vabstractapplication.h" +#include "vpuzzlecommandline.h" + +#include class PuzzleApplication;// use in define class PuzzleMainWindow; @@ -68,7 +71,7 @@ public: void ActivateDarkMode(); void ParseCommandLine(const SocketConnection &connection, const QStringList &arguments); - + const VPuzzleCommandLinePtr CommandLine(); public slots: void ProcessCMD(); diff --git a/src/app/puzzle/puzzlecommands.cpp b/src/app/puzzle/puzzlecommands.cpp new file mode 100644 index 000000000..57134ad2d --- /dev/null +++ b/src/app/puzzle/puzzlecommands.cpp @@ -0,0 +1,88 @@ +/************************************************************************ + ** + ** @file commands.cpp + ** @author Roman Telezhynskyi + ** @date 13 4, 2020 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentina project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2020 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ +#include "puzzlecommands.h" + +#include + +const QString LONG_OPTION_EXPORT_FILE = QStringLiteral("exportFile"); +const QString SINGLE_OPTION_EXPORT_FILE = QStringLiteral("e"); + +const QString LONG_OPTION_TEST = QStringLiteral("test"); +const QString SINGLE_OPTION_TEST = QStringLiteral("t"); + +const QString LONG_OPTION_RAW_LAYOUT = QStringLiteral("rawLayout"); +const QString SINGLE_OPTION_RAW_LAYOUT = QStringLiteral("r"); + +const QString LONG_OPTION_EXP2FORMAT = QStringLiteral("format"); +const QString SINGLE_OPTION_EXP2FORMAT = QStringLiteral("f"); + +const QString LONG_OPTION_BINARYDXF = QStringLiteral("bdxf"); +const QString LONG_OPTION_TEXT2PATHS = QStringLiteral("text2paths"); + +const QString LONG_OPTION_CROP_LENGTH = QStringLiteral("crop"); +const QString SINGLE_OPTION_CROP_LENGTH = QStringLiteral("c"); + +const QString LONG_OPTION_CROP_WIDTH = QStringLiteral("cropWidth"); + +const QString LONG_OPTION_TILED_PDF_PAGE_TEMPLATE = QStringLiteral("tiledPageformat"); +const QString LONG_OPTION_TILED_PDF_LEFT_MARGIN = QStringLiteral("tiledlmargin"); +const QString LONG_OPTION_TILED_PDF_RIGHT_MARGIN = QStringLiteral("tiledrmargin"); +const QString LONG_OPTION_TILED_PDF_TOP_MARGIN = QStringLiteral("tiledtmargin"); +const QString LONG_OPTION_TILED_PDF_BOTTOM_MARGIN = QStringLiteral("tiledbmargin"); +const QString LONG_OPTION_TILED_PDF_LANDSCAPE = QStringLiteral("tiledLandscape"); + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief AllKeys return list with all command line keys (short and long forms). Used for testing on conflicts. + * @return list with all command line keys + */ +QStringList AllKeys() +{ + return QStringList + { + LONG_OPTION_EXPORT_FILE, + SINGLE_OPTION_EXPORT_FILE, + LONG_OPTION_TEST, + SINGLE_OPTION_TEST, + LONG_OPTION_RAW_LAYOUT, + SINGLE_OPTION_RAW_LAYOUT, + LONG_OPTION_EXP2FORMAT, + SINGLE_OPTION_EXP2FORMAT, + LONG_OPTION_BINARYDXF, + LONG_OPTION_TEXT2PATHS, + LONG_OPTION_CROP_LENGTH, + SINGLE_OPTION_CROP_LENGTH, + LONG_OPTION_CROP_WIDTH, + LONG_OPTION_TILED_PDF_PAGE_TEMPLATE, + LONG_OPTION_TILED_PDF_LEFT_MARGIN, + LONG_OPTION_TILED_PDF_RIGHT_MARGIN, + LONG_OPTION_TILED_PDF_TOP_MARGIN, + LONG_OPTION_TILED_PDF_BOTTOM_MARGIN, + LONG_OPTION_TILED_PDF_LANDSCAPE + }; +} diff --git a/src/app/puzzle/puzzlecommands.h b/src/app/puzzle/puzzlecommands.h new file mode 100644 index 000000000..ae362b032 --- /dev/null +++ b/src/app/puzzle/puzzlecommands.h @@ -0,0 +1,63 @@ +/************************************************************************ + ** + ** @file commands.h + ** @author Roman Telezhynskyi + ** @date 13 4, 2020 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentina project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2020 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ +#ifndef COMMANDS_H +#define COMMANDS_H + + +#include + +extern const QString LONG_OPTION_EXPORT_FILE; +extern const QString SINGLE_OPTION_EXPORT_FILE; + +extern const QString LONG_OPTION_TEST; +extern const QString SINGLE_OPTION_TEST; + +extern const QString LONG_OPTION_RAW_LAYOUT; +extern const QString SINGLE_OPTION_RAW_LAYOUT; + +extern const QString LONG_OPTION_EXP2FORMAT; +extern const QString SINGLE_OPTION_EXP2FORMAT; + +extern const QString LONG_OPTION_BINARYDXF; +extern const QString LONG_OPTION_TEXT2PATHS; + +extern const QString LONG_OPTION_CROP_LENGTH; +extern const QString SINGLE_OPTION_CROP_LENGTH; + +extern const QString LONG_OPTION_CROP_WIDTH; + +extern const QString LONG_OPTION_TILED_PDF_PAGE_TEMPLATE; +extern const QString LONG_OPTION_TILED_PDF_LEFT_MARGIN; +extern const QString LONG_OPTION_TILED_PDF_RIGHT_MARGIN; +extern const QString LONG_OPTION_TILED_PDF_TOP_MARGIN; +extern const QString LONG_OPTION_TILED_PDF_BOTTOM_MARGIN; +extern const QString LONG_OPTION_TILED_PDF_LANDSCAPE; + +QStringList AllKeys(); + +#endif // COMMANDS_H diff --git a/src/app/puzzle/vpuzzlecommandline.cpp b/src/app/puzzle/vpuzzlecommandline.cpp new file mode 100644 index 000000000..0242e1356 --- /dev/null +++ b/src/app/puzzle/vpuzzlecommandline.cpp @@ -0,0 +1,174 @@ +#include "vpuzzlecommandline.h" +#include "puzzlecommands.h" +#include "../vmisc/vsysexits.h" +#include "../vmisc/literals.h" +#include + +std::shared_ptr VPuzzleCommandLine::instance = nullptr; + +#define translate(context, source) QCoreApplication::translate((context), source) + +//------------------------------------------------------------------------------------------------ +bool VPuzzleCommandLine::IsExportEnabled() const +{ + const bool result = IsOptionSet(LONG_OPTION_EXPORT_FILE); + int argSize = parser.positionalArguments().size(); + if (result && argSize != 1) + { + qCritical() << translate("Puzzle", "Export options can be used with single input file only.") << "/n"; + const_cast(this)->parser.showHelp(V_EX_USAGE); + } + return result; +} + +//---------------------------------------------------------------------------------------------- +QString VPuzzleCommandLine::OptionExportFile() const +{ + QString path; + if (IsExportEnabled()) + { + path = OptionValue(LONG_OPTION_EXPORT_FILE); + } + + return path; +} + +//--------------------------------------------------------------------------------------------------------------------- +QStringList VPuzzleCommandLine::OptionRawLayouts() const +{ + return OptionValues(LONG_OPTION_RAW_LAYOUT); +} + +//-------------------------------------------------------------------------------------------- +bool VPuzzleCommandLine::IsTestModeEnabled() const +{ + const bool r = IsOptionSet(LONG_OPTION_TEST); + if (r && parser.positionalArguments().size() != 1) + { + qCritical() << translate("VCommandLine", "Test option can be used with single input file only.") << "/n"; + const_cast(this)->parser.showHelp(V_EX_USAGE); + } + return r; +} + +//-------------------------------------------------------------------------------------------- +bool VPuzzleCommandLine::IsGuiEnabled() const +{ + return isGuiEnabled; +} + +//-------------------------------------------------------------------------------------------- +QStringList VPuzzleCommandLine::OptionFileNames() const +{ + return parser.positionalArguments(); +} + +//------------------------------------------------------------------------------------------- +bool VPuzzleCommandLine::IsNoScalingEnabled() const +{ + return IsOptionSet(LONG_OPTION_NO_HDPI_SCALING); +} + +//---------------------------------------------------------------------------------------------- +VPuzzleCommandLine::VPuzzleCommandLine(): + parser(), + isGuiEnabled(false) +{ + parser.setApplicationDescription(translate("Puzzle", "Valentina's manual layout editor.")); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument(QStringLiteral("filename"), translate("Puzzle", "The manual layout file.")); + + InitCommandLineOptions(); +} + +//------------------------------------------------------------------------------------------- +VPuzzleCommandLinePtr VPuzzleCommandLine::Instance(const QCoreApplication &app) +{ + if (instance == nullptr) + { + instance.reset(new VPuzzleCommandLine); + } + instance->parser.process(app); + + instance->isGuiEnabled = not (instance->IsGuiEnabled() || instance->IsExportEnabled()); + return instance; +} + +//------------------------------------------------------------------------------------------- +void VPuzzleCommandLine::InitCommandLineOptions() +{ + //keep in mind order here - that is how user will see it, so group-up for usability + //================================================================================================================= + parser.addOptions({ + {{SINGLE_OPTION_EXPORT_FILE, LONG_OPTION_EXPORT_FILE}, + translate("VCommandLine", "The filename of exported layout file. Use it to enable console export mode."), + translate("VCommandLine", "The filename of layout file")}, + {{SINGLE_OPTION_RAW_LAYOUT, LONG_OPTION_RAW_LAYOUT}, + translate("VCommandLine", "Load pattern pieces form the raw layout data file."), + translate("VCommandLine", "The raw layout data file")}, + {{SINGLE_OPTION_EXP2FORMAT, LONG_OPTION_EXP2FORMAT}, + translate("VCommandLine", "Number corresponding to output format (default = 0, export mode): "), + translate("VCommandLine", "Format number"), QChar('0')}, + {LONG_OPTION_BINARYDXF, translate("VCommandLine", "Export dxf in binary form.")}, + {LONG_OPTION_TEXT2PATHS, translate("VCommandLine", "Export text as paths.")}, + //================================================================================================================= + {{SINGLE_OPTION_CROP_LENGTH, LONG_OPTION_CROP_LENGTH}, + translate("VCommandLine", "Auto crop unused length (export mode).")}, + {{LONG_OPTION_CROP_WIDTH}, + translate("VCommandLine", "Auto crop unused width (export mode).")}, + //================================================================================================================= + {LONG_OPTION_TILED_PDF_PAGE_TEMPLATE, + translate("VCommandLine", "Number corresponding to tiled pdf page template (default = 0, export mode with " + "tiled pdf format): "), + translate("VCommandLine", "Template number"), QChar('0')}, + {LONG_OPTION_TILED_PDF_LEFT_MARGIN, + translate("VCommandLine","Tiled page left margin in current units like 3.0 (export mode). If not set will be " + "used default value 1 cm."), + translate("VCommandLine", "The left margin")}, + {LONG_OPTION_TILED_PDF_RIGHT_MARGIN, + translate("VCommandLine", "Tiled page right margin in current units like 3.0 (export mode). If not set will " + "be used default value 1 cm."), + translate("VCommandLine", "The right margin")}, + {LONG_OPTION_TILED_PDF_TOP_MARGIN, + translate("VCommandLine", "Tiled page top margin in current units like 3.0 (export mode). If not set will be " + "used value default value 1 cm."), + translate("VCommandLine", "The top margin")}, + {LONG_OPTION_TILED_PDF_BOTTOM_MARGIN, + translate("VCommandLine", "Tiled page bottom margin in current units like 3.0 (export mode). If not set will " + "be used value default value 1 cm."), + translate("VCommandLine", "The bottom margin")}, + {LONG_OPTION_TILED_PDF_LANDSCAPE, + translate("VCommandLine", "Set tiled page orienatation to landscape (export mode). Default value if not set " + "portrait.")}, + //================================================================================================================= + {{SINGLE_OPTION_TEST, LONG_OPTION_TEST}, + translate("VCommandLine", "Run the program in a test mode. The program in this mode loads a single layout " + "file and silently quit without showing the main window. The key have priority " + "before key '%1'.").arg(LONG_OPTION_EXPORT_FILE)}, + {LONG_OPTION_NO_HDPI_SCALING, + translate("VCommandLine", "Disable high dpi scaling. Call this option if has problem with scaling (by default " + "scaling enabled). Alternatively you can use the %1 environment variable.") + .arg(QStringLiteral("QT_AUTO_SCREEN_SCALE_FACTOR=0"))}, + }); +} + +//-------------------------------------------------------------------------------------------- +bool VPuzzleCommandLine::IsOptionSet(const QString &option) const +{ + return parser.isSet(option); +} + +//------------------------------------------------------------------------------------------- +QString VPuzzleCommandLine::OptionValue(const QString &option) const +{ + return parser.value(option); +} + +//-------------------------------------------------------------------------------------------- +QStringList VPuzzleCommandLine::OptionValues(const QString &option) const +{ + return parser.values(option); +} + + diff --git a/src/app/puzzle/vpuzzlecommandline.h b/src/app/puzzle/vpuzzlecommandline.h new file mode 100644 index 000000000..52d0e6836 --- /dev/null +++ b/src/app/puzzle/vpuzzlecommandline.h @@ -0,0 +1,57 @@ +#ifndef VPUZZLECOMMANDLINE_H +#define VPUZZLECOMMANDLINE_H + +#include +#include +#include + +class VPuzzleCommandLine; +using VPuzzleCommandLinePtr = std::shared_ptr; + +class VPuzzleCommandLine: public QObject +{ + Q_OBJECT +public: + virtual ~VPuzzleCommandLine() = default; + + /** @brief if user enabled export from cmd */ + bool IsExportEnabled() const; + + /** @brief path to export file or empty string if not */ + QString OptionExportFile() const; + + /** @brief list with paths to the raw layout data files */ + QStringList OptionRawLayouts() const; + + /** @brief if user enabled test mode from cmd */ + bool IsTestModeEnabled() const; + + /** @brief if gui enabled or not */ + bool IsGuiEnabled() const; + + /** @brief the file name which should be loaded */ + QStringList OptionFileNames() const; + + /** @brief if high dpi scaling is enabled */ + bool IsNoScalingEnabled() const; +protected: + VPuzzleCommandLine(); + + /** @brief create the single instance of the class inside puzzleapplication */ + static VPuzzleCommandLinePtr Instance(const QCoreApplication &app); +private: + Q_DISABLE_COPY(VPuzzleCommandLine) + static VPuzzleCommandLinePtr instance; + QCommandLineParser parser; + bool isGuiEnabled; + friend class PuzzleApplication; + + /** @brief add options to the QCommandLineParser that there are in the cmd can be */ + void InitCommandLineOptions(); + + bool IsOptionSet(const QString &option)const; + QString OptionValue(const QString &option) const; + QStringList OptionValues(const QString &option) const; +}; + +#endif // VPUZZLECOMMANDLINE_H