diff --git a/src/app/app.pri b/src/app/app.pri index 24a7551f4..63f1a6720 100644 --- a/src/app/app.pri +++ b/src/app/app.pri @@ -21,7 +21,6 @@ HEADERS += \ $$PWD/stable.h \ $$PWD/version.h \ $$PWD/mainwindowsnogui.h - # Main forms FORMS += \ $$PWD/mainwindow.ui diff --git a/src/app/app.pro b/src/app/app.pro index a8e1ac2a2..71ccc3848 100644 --- a/src/app/app.pro +++ b/src/app/app.pro @@ -108,6 +108,8 @@ CONFIG(debug, debug|release){ # -isystem key works only for headers. In some cases it's not enough. But we can't delete this warnings and # want them in global list. Compromise decision delete them from local list. QMAKE_CXXFLAGS -= \ + -Wuninitialized \ + -Winit-self \ -Wmissing-prototypes \ -Wundefined-reinterpret-cast } diff --git a/src/app/core/core.pri b/src/app/core/core.pri index 7627b9046..8cd2a23c9 100644 --- a/src/app/core/core.pri +++ b/src/app/core/core.pri @@ -5,10 +5,12 @@ HEADERS += \ $$PWD/vapplication.h \ $$PWD/vformulaproperty.h \ $$PWD/vformulapropertyeditor.h \ - $$PWD/vtooloptionspropertybrowser.h + $$PWD/vtooloptionspropertybrowser.h \ + $$PWD/vcmdexport.h SOURCES += \ $$PWD/vapplication.cpp \ $$PWD/vformulaproperty.cpp \ $$PWD/vformulapropertyeditor.cpp \ - $$PWD/vtooloptionspropertybrowser.cpp + $$PWD/vtooloptionspropertybrowser.cpp \ + $$PWD/vcmdexport.cpp diff --git a/src/app/core/vapplication.cpp b/src/app/core/vapplication.cpp index 91415c7ed..9e16c176e 100644 --- a/src/app/core/vapplication.cpp +++ b/src/app/core/vapplication.cpp @@ -48,6 +48,8 @@ #include #include #include +#include + #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) # include #endif @@ -87,29 +89,32 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con QCoreApplication *instance = QCoreApplication::instance(); const bool isGuiThread = instance && (QThread::currentThread() == instance->thread()); + if (isGuiThread) { + //fixme: trying to make sure there are no save/load dialogs are opened, because error message during them will lead to crash + const bool topWinAllowsPop = (qApp->activeModalWidget() == nullptr) || !qApp->activeModalWidget()->inherits("QFileDialog"); QString debugdate = "[" + QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss"); QMessageBox messageBox; switch (type) { case QtDebugMsg: debugdate += QString(":DEBUG:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line) - .arg(context.function).arg(context.category).arg(msg); + .arg(context.function).arg(context.category).arg(msg); break; case QtWarningMsg: debugdate += QString(":WARNING:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line) - .arg(context.function).arg(context.category).arg(msg); + .arg(context.function).arg(context.category).arg(msg); messageBox.setIcon(QMessageBox::Warning); break; case QtCriticalMsg: debugdate += QString(":CRITICAL:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line) - .arg(context.function).arg(context.category).arg(msg); + .arg(context.function).arg(context.category).arg(msg); messageBox.setIcon(QMessageBox::Critical); break; case QtFatalMsg: debugdate += QString(":FATAL:%1(%2)] %3: %4: %5").arg(context.file).arg(context.line) - .arg(context.function).arg(context.category).arg(msg); + .arg(context.function).arg(context.category).arg(msg); messageBox.setIcon(QMessageBox::Critical); break; default: @@ -120,11 +125,22 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con if (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg) { - messageBox.setInformativeText(msg); - messageBox.setStandardButtons(QMessageBox::Ok); - messageBox.setWindowModality(Qt::ApplicationModal); - messageBox.setModal(true); - messageBox.exec(); + + if (VApplication::CheckGUI()) + { + if (topWinAllowsPop) + { + messageBox.setInformativeText(msg); + messageBox.setStandardButtons(QMessageBox::Ok); + messageBox.setWindowModality(Qt::ApplicationModal); + messageBox.setModal(true); + messageBox.exec(); + } + } + else + { + qStdErr() << msg << "\n"; + } } if (QtFatalMsg == type) @@ -159,12 +175,14 @@ VApplication::VApplication(int &argc, char **argv) : VAbstractApplication(argc, argv), trVars(nullptr), autoSaveTimer(nullptr), log(nullptr), -#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) out(nullptr), logLock(nullptr) -#else + #else out(nullptr) -#endif + #endif { + VCommandLine::Reset(); // making sure will create new instance...just in case we will ever do 2 objects of VApplication + VCommandLine::Get(*this); undoStack = new QUndoStack(this); } @@ -183,8 +201,8 @@ VApplication::~VApplication() delete logLock; #endif } - delete trVars; + VCommandLine::Reset(); } //--------------------------------------------------------------------------------------------------------------------- @@ -269,7 +287,7 @@ bool VApplication::notify(QObject *receiver, QEvent *event) } catch (std::exception& e) { - qCritical() << "Exception thrown:" << e.what(); + qCritical() << "Exception thrown:" << e.what(); } return false; } @@ -323,17 +341,17 @@ QString VApplication::translationsPath() const #else #ifdef QT_DEBUG return QApplication::applicationDirPath() + trPath; - #else - QDir dir(QApplication::applicationDirPath() + trPath); - if (dir.exists()) - { - return dir.absolutePath(); - } - else - { - return QStringLiteral("/usr/share/valentina/translations"); - } - #endif +#else + QDir dir(QApplication::applicationDirPath() + trPath); + if (dir.exists()) + { + return dir.absolutePath(); + } + else + { + return QStringLiteral("/usr/share/valentina/translations"); + } +#endif #endif } @@ -374,6 +392,7 @@ void VApplication::BeginLogging() { out = new QTextStream(log); qInstallMessageHandler(noisyFailureMsgHandler); + #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) logLock = new QLockFile(LogPath()+".lock"); logLock->setStaleLockTime(0); @@ -512,11 +531,11 @@ void VApplication::InitOptions() static const char * GENERIC_ICON_TO_CHECK = "document-open"; if (QIcon::hasThemeIcon(GENERIC_ICON_TO_CHECK) == false) { - //If there is no default working icon theme then we should - //use an icon theme that we provide via a .qrc file - //This case happens under Windows and Mac OS X - //This does not happen under GNOME or KDE - QIcon::setThemeName("win.icon.theme"); + //If there is no default working icon theme then we should + //use an icon theme that we provide via a .qrc file + //This case happens under Windows and Mac OS X + //This does not happen under GNOME or KDE + QIcon::setThemeName("win.icon.theme"); } } @@ -578,6 +597,17 @@ void VApplication::InitTrVars() { trVars = new VTranslateVars(Settings()); } +//--------------------------------------------------------------------------------------------------------------------- +bool VApplication::CheckGUI() +{ + return (VCommandLine::instance != nullptr) && VCommandLine::instance->IsGuiEnabled(); +} +//--------------------------------------------------------------------------------------------------------------------- +const VCommandLinePtr VApplication::CommandLine() const +{ + return VCommandLine::instance; +} +//--------------------------------------------------------------------------------------------------------------------- #if defined(Q_OS_WIN) && defined(Q_CC_GNU) //--------------------------------------------------------------------------------------------------------------------- @@ -686,7 +716,7 @@ void VApplication::CollectReports() const { // Seek file "binary_name.RPT" const QString reportName = QString("%1/%2.RPT").arg(applicationDirPath()) - .arg(QFileInfo(arguments().at(0)).baseName()); + .arg(QFileInfo(arguments().at(0)).baseName()); QFile reportFile(reportName); if (reportFile.exists()) { // Hooray we have found crash @@ -837,7 +867,7 @@ void VApplication::SendReport(const QString &reportName) const {// Trying send report // Change token if need const QStringList token = QStringList()<<"78"<<"5e"<<"02"<<"bd"<<"41"<<"e9"<<"6a"<<"63"<<"ab"<<"18"<<"09"<<"2f" - <<"13"<<"cf"<<"48"<<"b4"<<"75"<<"6a"<<"42"<<"39"; + <<"13"<<"cf"<<"48"<<"b4"<<"75"<<"6a"<<"42"<<"39"; const QString arg = QString("curl.exe -k -H \"Authorization: bearer ")+token.join("")+ QString("\" -H \"Accept: application/json\" -H \"Content-type: application/json\" -X POST " diff --git a/src/app/core/vapplication.h b/src/app/core/vapplication.h index 82962ce9e..ec3d1a19e 100644 --- a/src/app/core/vapplication.h +++ b/src/app/core/vapplication.h @@ -34,6 +34,8 @@ #include "../libs/vwidgets/vmaingraphicsview.h" #include "../libs/vpatterndb/vtranslatevars.h" #include "vsettings.h" +#include "vcmdexport.h" + class VApplication;// use in define class VMainGraphicsView; @@ -55,6 +57,7 @@ class VApplication : public VAbstractApplication { Q_OBJECT public: + VApplication(int &argc, char ** argv); virtual ~VApplication() Q_DECL_OVERRIDE; static void NewValentina(const QString &fileName = QString()); @@ -83,7 +86,10 @@ public: static void DrMingw(); void CollectReports() const; #endif // defined(Q_OS_WIN) && defined(Q_CC_GNU) + bool static CheckGUI(); + + const VCommandLinePtr CommandLine() const; private slots: #if defined(Q_OS_WIN) && defined(Q_CC_GNU) void CleanGist() const; @@ -129,5 +135,7 @@ inline void VApplication::setAutoSaveTimer(QTimer *value) { autoSaveTimer = value; } +//--------------------------------------------------------------------------------------------------------------------- + #endif // VAPPLICATION_H diff --git a/src/app/core/vcmdexport.cpp b/src/app/core/vcmdexport.cpp new file mode 100644 index 000000000..eefe28d6b --- /dev/null +++ b/src/app/core/vcmdexport.cpp @@ -0,0 +1,318 @@ +#include "vcmdexport.h" +#include "dialogs/dialoglayoutsettings.h" +#include "dialogs/dialogsavelayout.h" +#include "xml/vdomdocument.h" + +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) +# include "../libs/vmisc/backport/qcommandlineparser.h" +#else +# include +#endif + +VCommandLinePtr VCommandLine::instance = nullptr; + +const static auto OPTION_OUTFILE = QStringLiteral("outfile"); +const static auto OPTION_MEASUREFILE = QStringLiteral("mfile"); +const static auto OPTION_PAGETEMPLATE = QStringLiteral("pageformat"); +const static auto OPTION_EXP2FORMAT = QStringLiteral("format"); +const static auto OPTION_ROTATE = QStringLiteral("rotate"); +const static auto OPTION_CROP = QStringLiteral("crop"); +const static auto OPTION_UNITE = QStringLiteral("unite"); + +const static auto OPTION_PAGEW = QStringLiteral("pagew"); +const static auto OPTION_PAGEH = QStringLiteral("pageh"); +const static auto OPTION_PAGEUNITS = QStringLiteral("pageunits"); + +const static auto OPTION_SAVELENGTH = QStringLiteral("savelen"); +const static auto OPTION_SHIFTLENGTH = QStringLiteral("shiftlen"); +const static auto OPTION_SHIFTUNITS = QStringLiteral("layounits"); +const static auto OPTION_GAPWIDTH = QStringLiteral("gapwidth"); +const static auto OPTION_GROUPPING = QStringLiteral("groups"); + +#define tr(A) QCoreApplication::translate("VCommandLine",(A)) +//------------------------------------------------------------------------------------------------------ + +//such a tricky initialization is used, because it uses static functions which relay on static variables and order of initialization is not defined between compiled units. +//i.e. - segv is possible (I hit it when VDomDocument::UnitsHelpString() was crashing because of not inited string vars). +//------------------------------------------------------------------------------------------------------ +VCommandLine::VCommandLine() : parser() + , optionsUsed ({ + QCommandLineOption(OPTION_OUTFILE, tr("Path to output exported layout file. Use it to enable console export mode."), OPTION_OUTFILE), + + QCommandLineOption(OPTION_MEASUREFILE, tr("Path to custom measure file (export mode)."), OPTION_MEASUREFILE), + + QCommandLineOption(OPTION_EXP2FORMAT, tr("Number corresponding to output format (default = 0, export mode): ") + + DialogSaveLayout::MakeHelpFormatList(), OPTION_EXP2FORMAT, "0"), + + QCommandLineOption(OPTION_PAGETEMPLATE, tr("Number corresponding to page template (default = 0, export mode): ")+ + DialogLayoutSettings::MakeHelpTemplateList(), OPTION_PAGETEMPLATE, "0"), + + + QCommandLineOption(OPTION_PAGEW, tr("Page width in current units like 12.0 (cannot be used with \"")+OPTION_PAGETEMPLATE+tr("\", export mode)."), OPTION_PAGEW), + + QCommandLineOption(OPTION_PAGEH, tr("Page height in current units like 12.0 (cannot be used with \"")+OPTION_PAGETEMPLATE+tr("\", export mode)."), OPTION_PAGEH), + + QCommandLineOption(OPTION_PAGEUNITS, tr("Page height/width measure units (cannot be used with \"")+ + OPTION_PAGETEMPLATE+tr("\", export mode): ") + VDomDocument::UnitsHelpString(), OPTION_PAGEUNITS), + + QCommandLineOption(OPTION_ROTATE, tr("Rotation in degrees (one of predefined). Default (or 0) is no-rotate (export mode)."), OPTION_ROTATE), + + QCommandLineOption(OPTION_CROP, tr("Auto crop unused length (export mode).")), + + QCommandLineOption(OPTION_UNITE, tr("Unite pages if possible (export mode).")), + + QCommandLineOption(OPTION_SAVELENGTH, tr("Save length of the sheet if set. (export mode).")), + + QCommandLineOption(OPTION_SHIFTUNITS, tr("Layout units (as paper's one except px, export mode)."), OPTION_SHIFTUNITS), + + QCommandLineOption(OPTION_SHIFTLENGTH, tr("Shift layout length measured in layout units (export mode)."), OPTION_SHIFTLENGTH), + + QCommandLineOption(OPTION_GAPWIDTH, tr("Gap width x2, measured in layout units. (export mode)."), OPTION_GAPWIDTH), + + QCommandLineOption(OPTION_GROUPPING, tr("Sets layout groupping (export mode): ") + DialogLayoutSettings::MakeGroupsHelp(), OPTION_GROUPPING, "2"), + }), + isGuiEnabled(false) +{ + parser.setApplicationDescription(QCoreApplication::translate("main", "Pattern making program.")); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("filename", QCoreApplication::translate("main", "Pattern file.")); + + foreach(const auto& o, optionsUsed) + { + parser.addOption(o); + } +} +//------------------------------------------------------------------------------------------------------ +int VCommandLine::Lo2Px(const QString &src, const DialogLayoutSettings &converter) +{ + //that is dirty-dirty hack ...eventually number is converted float <--> int 3 or 4 times including inside dialog ... that will loose precision for sure + return converter.LayoutToPixels(src.toFloat()); +} +//------------------------------------------------------------------------------------------------------ +int VCommandLine::Pg2Px(const QString& src, const DialogLayoutSettings& converter) +{ + return converter.PageToPixels(src.toFloat()); +} +//------------------------------------------------------------------------------------------------------ +VLayoutGeneratorPtr VCommandLine::DefaultGenerator() const +{ + //this functions covers all options found into layout setup dialog, nothing to add here, unless dialog extended + + VLayoutGeneratorPtr res(new VLayoutGenerator()); + DialogLayoutSettings diag(res.get(), nullptr, true); + + { + //just anonymous namespace ...don' like to have a,b,c,d everywhere defined + bool x = parser.isSet(OPTION_PAGETEMPLATE); + + bool a = parser.isSet(OPTION_PAGEH); + bool b = parser.isSet(OPTION_PAGEW); + bool c = parser.isSet(OPTION_PAGEUNITS); + + if ((a || b || c) && x) + { + Error(tr("Cannot use pageformat and page explicit size/units together.")); + } + + if ((a || b || c) && !(a && b && c)) + { + Error(tr("Page height, width, units must be used all 3 at once.")); + } + + } + + //fixme: not really sure ...if shift length must be set with shift units ...or separated, will comment for now. Uncomment if need them both only. + +// { +// //just anonymous namespace ...don' like to have a,b,c,d everywhere defined +// bool a = parser.isSet(OPTION_SHIFTLENGTH); +// bool b = parser.isSet(OPTION_SHIFTUNITS); + +// if ((a || b) && !(a && b)) +// { +// Error(tr("Shift length must be used together with shift units.")); +// } +// } + + int rotateDegree = OptRotation(); + diag.SetRotate(rotateDegree != 0 ); + + if (rotateDegree != 0) + { + if (!diag.SetIncrease(rotateDegree)) + { + Error(tr("Invalid rotation value. That must be one of predefined values.")); + } + } + + // if present units MUST be set before any other to keep conversions correct + if (!diag.SelectTemplate(OptPaperSize())) + { + Error(tr("Unknown page templated selected.")); + } + + if (parser.isSet(OPTION_PAGEH)) //at this point we already sure 3 are set or none + { + + if (!diag.SelectPaperUnit(parser.value(OPTION_PAGEUNITS))) + { + Error(tr("Unsupported paper units.")); + } + + diag.SetPaperHeight (Pg2Px(parser.value(OPTION_PAGEH), diag)); + diag.SetPaperWidth (Pg2Px(parser.value(OPTION_PAGEW), diag)); + } + + if (parser.isSet(OPTION_SHIFTUNITS)) + { + if (!diag.SelectLayoutUnit(parser.value(OPTION_SHIFTUNITS))) + { + Error(tr("Unsupported layout units.")); + } + } + + if (parser.isSet(OPTION_SHIFTLENGTH)) + { + + diag.SetShift(Lo2Px(parser.value(OPTION_SHIFTLENGTH), diag)); + } + + if (parser.isSet(OPTION_GAPWIDTH)) + { + diag.SetLayoutWidth(Lo2Px(parser.value(OPTION_GAPWIDTH), diag)); + } + + diag.SetAutoCrop(parser.isSet(OPTION_CROP)); + diag.SetUnitePages(parser.isSet(OPTION_UNITE)); + diag.SetSaveLength(parser.isSet(OPTION_SAVELENGTH)); + diag.SetGroup(OptGroup()); + + + + diag.DialogAccepted(); // filling VLayoutGenerator + + return res; +} +//------------------------------------------------------------------------------------------------------ + +VCommandLinePtr VCommandLine::Get(const QCoreApplication& app) +{ + if (instance == nullptr) + { + instance.reset(new VCommandLine()); + } + instance->parser.process(app); + + //fixme: in case of additional options/modes which will need to disable GUI - add it here too + instance->isGuiEnabled = !instance->IsExportEnabled(); + + return instance; +} +//------------------------------------------------------------------------------------------------------ +NORET_ATTR void VCommandLine::Error(const QString &text) const +{ + qStdErr() << text << "\n"; + const_cast(this)->parser.showHelp(FAILED_HELP_SHOWN_STATUS); +} +//------------------------------------------------------------------------------------------------------ +void VCommandLine::Reset() +{ + instance.reset(); +} + +//------------------------------------------------------------------------------------------------------ +bool VCommandLine::IsExportEnabled() const +{ + bool r = parser.isSet(OPTION_OUTFILE); + if (r && parser.positionalArguments().size() != 1) + { + Error(tr("Export options can be used with single input file only.")); + } + return r; +} +//------------------------------------------------------------------------------------------------------ +DialogLayoutSettings::PaperSizeTemplate VCommandLine::OptPaperSize() const +{ + int ppsize = 0; + if (parser.isSet(OPTION_PAGETEMPLATE)) + { + ppsize = parser.value(OPTION_PAGETEMPLATE).toInt(); + } + return static_cast(ppsize); +} + +//------------------------------------------------------------------------------------------------------ +int VCommandLine::OptRotation() const +{ + int rotate = 0; + if (parser.isSet(OPTION_ROTATE)) + { + rotate = parser.value(OPTION_ROTATE).toInt(); + } + + return rotate; +} +//------------------------------------------------------------------------------------------------------ +Cases VCommandLine::OptGroup() const +{ + int r = parser.value(OPTION_GROUPPING).toInt(); + if ( r < 0 || r >= static_cast(Cases::UnknownCase)) + { + r = 0; + } + return static_cast(r); +} +//------------------------------------------------------------------------------------------------------ + +QString VCommandLine::OptMeasurePath() const +{ + QString measure; + if (parser.isSet(OPTION_MEASUREFILE) + && IsExportEnabled() //todo: don't want yet to allow user set measure file for general loading, because need to fix multiply opened windows as well + ) + { + measure = parser.value(OPTION_MEASUREFILE); + } + + return measure; +} + +//------------------------------------------------------------------------------------------------------ + +QString VCommandLine::OptExportPath() const +{ + QString path; + if (IsExportEnabled()) + { + path = parser.value(OPTION_OUTFILE); + } + + return path; +} +//------------------------------------------------------------------------------------------------------ + +int VCommandLine::OptExportType() const +{ + int r = 0; + if (parser.isSet(OPTION_EXP2FORMAT)) + { + r = parser.value(OPTION_EXP2FORMAT).toInt(); + } + return r; +} + +//--------------------------------------------------------------------------------------------------------------------- + +QStringList VCommandLine::OptInputFileNames() const +{ + return parser.positionalArguments(); +} +//------------------------------------------------------------------------------------------------------ +bool VCommandLine::IsGuiEnabled() const +{ + return isGuiEnabled; +} + +//------------------------------------------------------------------------------------------------------ +#undef tr diff --git a/src/app/core/vcmdexport.h b/src/app/core/vcmdexport.h new file mode 100644 index 000000000..6d2695270 --- /dev/null +++ b/src/app/core/vcmdexport.h @@ -0,0 +1,104 @@ +#ifndef VCMDEXPORT_H +#define VCMDEXPORT_H +#include +#include +#include + +#include "dialogs/dialoglayoutsettings.h" + + +constexpr auto GENERAL_ERROR_STATUS = 255; +constexpr auto INVALID_PARAMS_STATUS = 254; +constexpr auto FAILED_TO_GEN_LAYOUT_STATUS = 253; +constexpr auto FAILED_HELP_SHOWN_STATUS = 250; + +//making QtCReator happy....[[noreturn]] is part of C++11 standard +//http://en.cppreference.com/w/cpp/language/attributes + +#define NORET_ATTR [[noreturn]] + +//--------------------------------------------------------------------------------------------------------------------- +inline QTextStream& qStdErr() +{ + static QTextStream ts( stderr ); + return ts; +} + +//--------------------------------------------------------------------------------------------------------------------- +NORET_ATTR inline void AppAbort(const QString& text, int code = GENERAL_ERROR_STATUS) +{ + //well ..std::runtime_error was leading to zombies in memory and a lot of dumping all the time ...better to do just exit + //possibly compiler do not have -fexceptions set + qStdErr() << text << "\n"; + std::exit(code); +} +//--------------------------------------------------------------------------------------------------------------------- + + +class VCommandLine; +typedef std::shared_ptr VCommandLinePtr; + +//@brief: class used to install export command line options and parse their values +//QCommandLineParser* object must exists until this object alive +class VCommandLine +{ +private: + static VCommandLinePtr instance; + QCommandLineParser parser; + const std::vector optionsUsed; + bool isGuiEnabled; + friend class VApplication; + + static int Lo2Px(const QString& src, const DialogLayoutSettings& converter); + static int Pg2Px(const QString& src, const DialogLayoutSettings& converter); +protected: + + explicit VCommandLine(); + + + //@brief returns DialogLayoutSettings::PaperSizeTemplate + DialogLayoutSettings::PaperSizeTemplate OptPaperSize() const; + //@brief returns rotation in degrees or 0 if not set + int OptRotation() const; + + Cases OptGroup() const; + + //@brief convinient shortcut to show error and help and exit + NORET_ATTR void Error(const QString& text) const; + + //@brief: called in destructor of application, so instance destroyed and new maybe created (never happen scenario though) + static void Reset(); + + //@brief called to create single object, by VApplication only + static VCommandLinePtr Get(const QCoreApplication& app); + +public: + VCommandLine(const VCommandLine&) = delete; + VCommandLine& operator =(const VCommandLine&) = delete; + virtual ~VCommandLine(){} + + //@brief creates object and applies export related options to parser + + //@brief tests if user enabled export from cmd, throws exception if not exactly 1 input VAL file supplied in case export enabled + bool IsExportEnabled() const; + + //@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 export type set, defaults 0 - svg + int OptExportType() const; + + //generator creation is moved here ... because most options are for it only, so no need to create extra getters... + //@brief creates VLayoutGenerator + VLayoutGeneratorPtr DefaultGenerator() const; + + //@brief gets filenames which should be loaded + QStringList OptInputFileNames() const; + + bool IsGuiEnabled()const; +}; + +#endif // VCMDEXPORT_H diff --git a/src/app/dialogs/dialoglayoutsettings.cpp b/src/app/dialogs/dialoglayoutsettings.cpp index 019edcc19..c1a8d2716 100644 --- a/src/app/dialogs/dialoglayoutsettings.cpp +++ b/src/app/dialogs/dialoglayoutsettings.cpp @@ -31,7 +31,7 @@ #include "../core/vapplication.h" #include "../../libs/ifc/xml/vdomdocument.h" #include "../../libs/vmisc/vsettings.h" -#include "../../libs/vlayout/vlayoutgenerator.h" +#include #if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) # include "../../libs/vmisc/vmath.h" @@ -41,20 +41,48 @@ #include - -enum class PaperSizeTemplate : char { A0, A1, A2, A3, A4, Letter, Legal, Roll24in, Roll30in, Roll36in, Roll42in, - Roll44in}; +//must be the same order as PaperSizeTemplate constants +const DialogLayoutSettings::FormatsVector DialogLayoutSettings::pageFormatNames={ + "A0", + "A1", + "A2", + "A3", + "A4", + tr("Letter"), + tr("Legal"), + tr("Roll 24in"), + tr("Roll 30in"), + tr("Roll 36in"), + tr("Roll 42in"), + tr("Roll 44in"), +}; //--------------------------------------------------------------------------------------------------------------------- -DialogLayoutSettings::DialogLayoutSettings(VLayoutGenerator *generator, QWidget *parent) - : QDialog(parent), ui(new Ui::DialogLayoutSettings), oldPaperUnit(Unit::Mm), oldLayoutUnit(Unit::Mm), +DialogLayoutSettings::DialogLayoutSettings(VLayoutGenerator *generator, QWidget *parent, bool disableSetting) + : QDialog(parent), disableSettings(disableSetting),ui(new Ui::DialogLayoutSettings), oldPaperUnit(Unit::Mm), oldLayoutUnit(Unit::Mm), generator(generator) { ui->setupUi(this); qApp->Settings()->GetOsSeparator() ? setLocale(QLocale::system()) : setLocale(QLocale(QLocale::C)); - ReadSettings(); + //moved from ReadSettings - well...it seems it can be done once only (i.e. constructor) because Init funcs dont even cleanse lists before adding + InitPaperUnits(); + InitLayoutUnits(); + InitTemplates(); + MinimumPaperSize(); + MinimumLayoutSize(); + + //in export console mode going to use defaults + if (!disableSettings) + { + ReadSettings(); + } + else + { + RestoreDefaults(); + } + connect(ui->comboBoxTemplates, static_cast(&QComboBox::currentIndexChanged), this, &DialogLayoutSettings::TemplateSelected); @@ -193,16 +221,17 @@ int DialogLayoutSettings::GetIncrease() const //--------------------------------------------------------------------------------------------------------------------- // cppcheck-suppress unusedFunction -void DialogLayoutSettings::SetIncrease(int increase) +bool DialogLayoutSettings::SetIncrease(int increase) { int index = ui->comboBoxIncrease->findText(QString::number(increase)); - - if (index == -1) + bool failed = (index == -1); + if (failed) { index = 21;//180 degree } ui->comboBoxIncrease->setCurrentIndex(index); + return failed; } //--------------------------------------------------------------------------------------------------------------------- @@ -240,7 +269,6 @@ void DialogLayoutSettings::SetUnitePages(bool save) { ui->checkBoxUnitePages->setChecked(save); } - //--------------------------------------------------------------------------------------------------------------------- void DialogLayoutSettings::TemplateSelected() { @@ -266,6 +294,43 @@ void DialogLayoutSettings::ConvertPaperSize() MinimumPaperSize(); } +//--------------------------------------------------------------------------------------------------------------------- +bool DialogLayoutSettings::SelectPaperUnit(const QString& units) +{ + qint32 indexUnit = ui->comboBoxPaperSizeUnit->findData(units); + if (indexUnit != -1) + { + ui->comboBoxPaperSizeUnit->setCurrentIndex(indexUnit); + } + return indexUnit != -1; +} +//--------------------------------------------------------------------------------------------------------------------- +bool DialogLayoutSettings::SelectLayoutUnit(const QString &units) +{ + qint32 indexUnit = ui->comboBoxLayoutUnit->findData(units); + if (indexUnit != -1) + { + ui->comboBoxLayoutUnit->setCurrentIndex(indexUnit); + } + return indexUnit != -1; +} +//--------------------------------------------------------------------------------------------------------------------- +int DialogLayoutSettings::LayoutToPixels(qreal value) const +{ + return static_cast(qFloor(UnitConvertor(value, LayoutUnit(), Unit::Px))); +} +//--------------------------------------------------------------------------------------------------------------------- +int DialogLayoutSettings::PageToPixels(qreal value) const +{ + return static_cast(qFloor(UnitConvertor(value, PaperUnit(), Unit::Px))); +} +//--------------------------------------------------------------------------------------------------------------------- +QString DialogLayoutSettings::MakeGroupsHelp() +{ + //that is REALLY dummy ... can't figure fast how to automate generation... :/ + return tr("\n\tThree groups: big, middle, small = 0\n\tTwo groups: big, small = 1\n\tDescending area = 2\n"); +} + //--------------------------------------------------------------------------------------------------------------------- void DialogLayoutSettings::ConvertLayoutSize() { @@ -301,8 +366,20 @@ void DialogLayoutSettings::PaperSizeChanged() Label(); } - //--------------------------------------------------------------------------------------------------------------------- + +bool DialogLayoutSettings::SelectTemplate(const PaperSizeTemplate& id) +{ + int index = ui->comboBoxTemplates->findData(static_cast(id)); + if (index > -1) + { + ui->comboBoxTemplates->setCurrentIndex(index); + } + + return (index > -1); +} +//--------------------------------------------------------------------------------------------------------------------- + void DialogLayoutSettings::Swap(bool checked) { if (checked) @@ -337,7 +414,11 @@ void DialogLayoutSettings::DialogAccepted() generator->SetSaveLength(IsSaveLength()); generator->SetUnitePages(IsUnitePages()); - WriteSettings(); + //don't want to break visual settings when cmd used + if (!disableSettings) + { + WriteSettings(); + } accepted(); } @@ -393,26 +474,26 @@ void DialogLayoutSettings::InitTemplates() const QIcon icoRoll("://icon/16x16/roll.png"); const QString pdi = QString("(%1ppi)").arg(PrintDPI); - ui->comboBoxTemplates->addItem(icoPaper, "A0 "+pdi, QVariant(static_cast(PaperSizeTemplate::A0))); - ui->comboBoxTemplates->addItem(icoPaper, "A1 "+pdi, QVariant(static_cast(PaperSizeTemplate::A1))); - ui->comboBoxTemplates->addItem(icoPaper, "A2 "+pdi, QVariant(static_cast(PaperSizeTemplate::A2))); - ui->comboBoxTemplates->addItem(icoPaper, "A3 "+pdi, QVariant(static_cast(PaperSizeTemplate::A3))); - ui->comboBoxTemplates->addItem(icoPaper, "A4 "+pdi, QVariant(static_cast(PaperSizeTemplate::A4))); - ui->comboBoxTemplates->addItem(icoPaper, tr("Letter ")+pdi, QVariant(static_cast(PaperSizeTemplate::Letter))); - ui->comboBoxTemplates->addItem(icoPaper, tr("Legal ")+pdi, QVariant(static_cast(PaperSizeTemplate::Legal))); - ui->comboBoxTemplates->addItem(icoRoll, - tr("Roll 24in ")+pdi, QVariant(static_cast(PaperSizeTemplate::Roll24in))); - ui->comboBoxTemplates->addItem(icoRoll, - tr("Roll 30in ")+pdi, QVariant(static_cast(PaperSizeTemplate::Roll30in))); - ui->comboBoxTemplates->addItem(icoRoll, - tr("Roll 36in ")+pdi, QVariant(static_cast(PaperSizeTemplate::Roll36in))); - ui->comboBoxTemplates->addItem(icoRoll, - tr("Roll 42in ")+pdi, QVariant(static_cast(PaperSizeTemplate::Roll42in))); - ui->comboBoxTemplates->addItem(icoRoll, - tr("Roll 44in ")+pdi, QVariant(static_cast(PaperSizeTemplate::Roll44in))); - + auto cntr = static_cast(PaperSizeTemplate::A0); + foreach(const auto& v, pageFormatNames) + { + ui->comboBoxTemplates->addItem(icoPaper, v+" "+pdi, QVariant(cntr++)); + } ui->comboBoxTemplates->setCurrentIndex(-1); } +//--------------------------------------------------------------------------------------------------------------------- + +QString DialogLayoutSettings::MakeHelpTemplateList() +{ + QString out = "\n"; + + auto cntr = static_cast(PaperSizeTemplate::A0); + foreach(const auto& v, pageFormatNames) + { + out += "\t"+v+" = "+ QString::number(cntr++)+"\n"; + } + return out; +} //--------------------------------------------------------------------------------------------------------------------- QSizeF DialogLayoutSettings::Template() @@ -604,12 +685,6 @@ void DialogLayoutSettings::MinimumLayoutSize() //--------------------------------------------------------------------------------------------------------------------- void DialogLayoutSettings::ReadSettings() { - InitPaperUnits(); - InitLayoutUnits(); - InitTemplates(); - MinimumPaperSize(); - MinimumLayoutSize(); - SetLayoutWidth(qApp->Settings()->GetLayoutWidth()); SetShift(qApp->Settings()->GetLayoutShift()); diff --git a/src/app/dialogs/dialoglayoutsettings.h b/src/app/dialogs/dialoglayoutsettings.h index 4a90958ed..386c0ec3a 100644 --- a/src/app/dialogs/dialoglayoutsettings.h +++ b/src/app/dialogs/dialoglayoutsettings.h @@ -34,6 +34,7 @@ #include "../../libs/vlayout/vbank.h" #include "../../libs/ifc/ifcdef.h" +#include "../../libs/vlayout/vlayoutgenerator.h" namespace Ui { @@ -46,7 +47,8 @@ class DialogLayoutSettings : public QDialog { Q_OBJECT public: - DialogLayoutSettings(VLayoutGenerator *generator, QWidget *parent = 0); + enum class PaperSizeTemplate : char { A0 = 0, A1, A2, A3, A4, Letter, Legal, Roll24in, Roll30in, Roll36in, Roll42in, Roll44in}; + DialogLayoutSettings(VLayoutGenerator *generator, QWidget *parent = 0, bool disableSetting = false); ~DialogLayoutSettings(); int GetPaperHeight() const; @@ -68,7 +70,7 @@ public: void SetRotate(bool state); int GetIncrease() const; - void SetIncrease(int increase); + bool SetIncrease(int increase); bool GetAutoCrop() const; void SetAutoCrop(bool crop); @@ -79,6 +81,14 @@ public: bool IsUnitePages() const; void SetUnitePages(bool save); + //support functions for the command line parser which uses invisible dialog to properly build layout generator + bool SelectTemplate(const PaperSizeTemplate& id); + static QString MakeHelpTemplateList(); + bool SelectPaperUnit(const QString& units); + bool SelectLayoutUnit(const QString& units); + int LayoutToPixels(qreal value) const; + int PageToPixels(qreal value) const; + static QString MakeGroupsHelp(); public slots: void ConvertPaperSize(); void ConvertLayoutSize(); @@ -92,6 +102,12 @@ public slots: private: Q_DISABLE_COPY(DialogLayoutSettings) + typedef std::vector FormatsVector; + typedef int VIndexType; + const static FormatsVector pageFormatNames; + + bool disableSettings; + Ui::DialogLayoutSettings *ui; Unit oldPaperUnit; Unit oldLayoutUnit; diff --git a/src/app/dialogs/dialogsavelayout.cpp b/src/app/dialogs/dialogsavelayout.cpp index c2fe40e0f..bd0bec0d9 100644 --- a/src/app/dialogs/dialogsavelayout.cpp +++ b/src/app/dialogs/dialogsavelayout.cpp @@ -36,8 +36,23 @@ #include #include +using namespace nm_DialogSaveLayout; + +bool VFrmWithTest::havePdf = false; +bool VFrmWithTest::tested = false; + +const std::vector DialogSaveLayout::availFormats = { + VFrmWithTest(tr("Svg files (*.svg)"), ".svg"), + VFrmWithTest(tr("PDF files (*.pdf)"), ".pdf"), + VFrmWithTest(tr("Images (*.png)"), ".png"), + VFrmWithTest(tr("Wavefront OBJ (*.obj)"), ".obj"), + VFrmWithTest(tr("PS files (*.ps)"), ".ps", 1), //fixme: use 1 to have exe once tested on 1st run, or any other value to test always as original do + VFrmWithTest(tr("EPS files (*.eps)"), ".eps", 1), +}; + + //--------------------------------------------------------------------------------------------------------------------- -DialogSaveLayout::DialogSaveLayout(const QMap &formates, int count, const QString &fileName, +DialogSaveLayout::DialogSaveLayout(int count, const QString &fileName, QWidget *parent) :QDialog(parent), ui(new Ui::DialogSaveLAyout), count(count) { @@ -53,13 +68,13 @@ DialogSaveLayout::DialogSaveLayout(const QMap &formates, int c ui->lineEditFileName->setValidator(validator); ui->lineEditFileName->setText(fileName+"_"); - QMap::const_iterator i = formates.constBegin(); - while (i != formates.constEnd()) + foreach (auto& v , availFormats) { - ui->comboBoxFormat->addItem(i.key(), QVariant(i.value())); - ++i; + 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); connect(ui->comboBoxFormat, static_cast(&QComboBox::currentIndexChanged), this, @@ -73,6 +88,37 @@ DialogSaveLayout::DialogSaveLayout(const QMap &formates, int c setMaximumSize(size()); setMinimumSize(size()); } +//--------------------------------------------------------------------------------------------------------------------- + +void DialogSaveLayout::SelectFormate(const size_t formate) +{ + if (formate >= availFormats.size()) + { + AppAbort(tr("Tried to use out of range format number."), INVALID_PARAMS_STATUS); + } + + int i = ui->comboBoxFormat->findData(availFormats[formate].pair.second); + if (i < 0) + { + AppAbort(tr("Selected not present format."), INVALID_PARAMS_STATUS); + } + ui->comboBoxFormat->setCurrentIndex(i); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogSaveLayout::MakeHelpFormatList() +{ + QString out = "\n"; + int cntr = 0; + foreach(auto& v, availFormats) + { + if (v.test()) + { + out += "\t"+v.pair.first+" = "+ QString::number(cntr++)+"\n"; + } + } + return out; +} //--------------------------------------------------------------------------------------------------------------------- DialogSaveLayout::~DialogSaveLayout() @@ -163,3 +209,25 @@ void DialogSaveLayout::PathChanged(const QString &text) ui->lineEditPath->setPalette(palette); } +//--------------------------------------------------------------------------------------------------------------------- + +bool VFrmWithTest::TestPdf() +{ + bool res = false; + + QProcess proc; +#if defined(Q_OS_WIN) || defined(Q_OS_OSX) + proc.start(qApp->applicationDirPath()+"/"+PDFTOPS); // Seek pdftops in app bundle or near valentin.exe +#else + proc.start(PDFTOPS); // Seek pdftops in standard path +#endif + if (proc.waitForFinished(15000)) + { + res = true; + } + else + { + qDebug()< +#ifdef Q_OS_WIN +# define PDFTOPS "pdftops.exe" +#else +# define PDFTOPS "pdftops" +#endif +#include +#include + +namespace nm_DialogSaveLayout +{ + struct VFrmWithTest //could declare inside dialog class, but using namespace shorter to write and understand + { + typedef std::function test_func; + const std::pair pair; + const test_func test; + + VFrmWithTest(const QString& v1, const QString& v2) + :pair(std::make_pair(v1,v2)), + test([](){return true;}) + { + } + + VFrmWithTest(const QString& v1, const QString& v2, int dummy) + :pair(std::make_pair(v1,v2)), test((dummy != 1 )?TestPdf:VFrmWithTest::SingleTest) + { + } + private: + static bool havePdf; + static bool tested; + + static bool TestPdf(); + static bool SingleTest() + { + if (!tested) + { + havePdf = TestPdf(); + tested = true; + } + return havePdf; + } + }; +} + namespace Ui { class DialogSaveLAyout; @@ -41,13 +84,15 @@ class DialogSaveLayout : public QDialog Q_OBJECT public: - DialogSaveLayout(const QMap &formates, int count, const QString &fileName = QString(), + DialogSaveLayout(int count, const QString &fileName = QString(), QWidget *parent = 0); ~DialogSaveLayout(); QString Path() const; QString FileName() const; QString Formate() const; + void SelectFormate(const size_t formate); + static QString MakeHelpFormatList(); public slots: void Save(); @@ -56,6 +101,7 @@ public slots: void PathChanged(const QString &text); private: + const static std::vector availFormats; Q_DISABLE_COPY(DialogSaveLayout) Ui::DialogSaveLAyout *ui; int count; diff --git a/src/app/main.cpp b/src/app/main.cpp index 95ad92b7f..9b05f5828 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -28,16 +28,11 @@ #include "mainwindow.h" #include "core/vapplication.h" - +#include #include // For QT_REQUIRE_VERSION -#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) -# include "../libs/vmisc/backport/qcommandlineparser.h" -#else -# include -#endif - //--------------------------------------------------------------------------------------------------------------------- + int main(int argc, char *argv[]) { Q_INIT_RESOURCE(cursor); @@ -51,29 +46,31 @@ int main(int argc, char *argv[]) QT_REQUIRE_VERSION(argc, argv, "5.0.0"); VApplication app(argc, argv); + app.InitOptions(); MainWindow w; app.setWindowIcon(QIcon(":/icon/64x64/icon64x64.png")); app.setMainWindow(&w); - QCommandLineParser parser; - parser.setApplicationDescription(QCoreApplication::translate("main", "Pattern making program.")); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addPositionalArgument("filename", QCoreApplication::translate("main", "Pattern file.")); - parser.process(app); - QStringList args = parser.positionalArguments(); + auto args = app.CommandLine()->OptInputFileNames(); //Before we load pattern show window. - w.show(); - - w.ReopenFilesAfterCrash(args); - - for (int i=0;i(i)), app.CommandLine()->OptMeasurePath()); + if (app.CommandLine()->IsExportEnabled()) + { + w.DoExport(app.CommandLine()); + break; + } + } + + return (VApplication::CheckGUI()) ? app.exec() : 0; // single return point is always better than more } diff --git a/src/app/mainwindow.cpp b/src/app/mainwindow.cpp index 5285da6ce..d5493e5fa 100644 --- a/src/app/mainwindow.cpp +++ b/src/app/mainwindow.cpp @@ -754,7 +754,13 @@ void MainWindow::ToolTrueDarts(bool checked) "://cursor/true_darts_cursor.png", tr("Select the first base line point"), &MainWindow::ClosedDialogWithApply, - &MainWindow::ApplyDialog); + &MainWindow::ApplyDialog); +} +//--------------------------------------------------------------------------------------------------------------------- + +void MainWindow::ToolRotate(bool checked) +{ + } //--------------------------------------------------------------------------------------------------------------------- @@ -1073,6 +1079,8 @@ void MainWindow::InitToolButtons() connect(ui->toolButtonPointFromArcAndTangent, &QToolButton::clicked, this, &MainWindow::ToolPointFromArcAndTangent); connect(ui->toolButtonArcWithLength, &QToolButton::clicked, this, &MainWindow::ToolArcWithLength); connect(ui->toolButtonTrueDarts, &QToolButton::clicked, this, &MainWindow::ToolTrueDarts); + + //connect(ui->toolButtonRotate, &QToolButton::clicked, this, &MainWindow::ToolRotate); } //--------------------------------------------------------------------------------------------------------------------- @@ -2797,7 +2805,7 @@ MainWindow::~MainWindow() * @brief LoadPattern open pattern file. * @param fileName name of file. */ -void MainWindow::LoadPattern(const QString &fileName) +void MainWindow::LoadPattern(const QString &fileName, const QString& customMeasureFile) { qCDebug(vMainWindow, "Loading new file %s.", fileName.toUtf8().constData()); @@ -2851,7 +2859,10 @@ void MainWindow::LoadPattern(const QString &fileName) VDomDocument::ValidateXML(VPatternConverter::CurrentSchema, fileName); doc->setXMLContent(fileName); - + if (!customMeasureFile.isEmpty()) + { + doc->SetPath(customMeasureFile); + } qApp->setPatternUnit(doc->MUnit()); qApp->setPatternType(doc->MType()); QString path = doc->MPath(); @@ -3054,6 +3065,27 @@ void MainWindow::ReopenFilesAfterCrash(QStringList &args) } } +//--------------------------------------------------------------------------------------------------------------------- +void MainWindow::DoExport(const VCommandLinePtr &expParams) +{ + auto settings = expParams->DefaultGenerator(); + + const QHash *details = pattern->DataDetails(); + if(not qApp->getOpeningPattern()) + { + if (details->count() == 0) + { + AppAbort(tr("You can't export empty scene.")); + return; + } + } + PrepareDetailsForLayout(details); + LayoutSettings(*settings.get()); + DialogSaveLayout dialog(scenes.size(), expParams->OptExportPath(), this); + dialog.SelectFormate(expParams->OptExportType()); + ExportLayout(dialog); +} + //--------------------------------------------------------------------------------------------------------------------- QString MainWindow::CheckPathToMeasurements(const QString &path, const MeasurementsType &patternType) { diff --git a/src/app/mainwindow.h b/src/app/mainwindow.h index 08975286a..ba5327e35 100644 --- a/src/app/mainwindow.h +++ b/src/app/mainwindow.h @@ -36,6 +36,7 @@ #include "tools/vtooldetail.h" #include "tools/vtooluniondetails.h" #include "tools/drawTools/drawtools.h" +#include "core/vcmdexport.h" namespace Ui { @@ -53,8 +54,10 @@ class MainWindow : public MainWindowsNoGUI public: explicit MainWindow(QWidget *parent = nullptr); virtual ~MainWindow() Q_DECL_OVERRIDE; - void LoadPattern(const QString &curFile); + void LoadPattern(const QString &curFile, const QString &customMeasureFile = QString()); void ReopenFilesAfterCrash(QStringList &args); + + void DoExport(const VCommandLinePtr& expParams); public slots: void mouseMove(const QPointF &scenePos); void ArrowTool(); @@ -122,6 +125,7 @@ public slots: void ToolPointFromArcAndTangent(bool checked); void ToolArcWithLength(bool checked); void ToolTrueDarts(bool checked); + void ToolRotate(bool checked); void ClosedDialogDetail(int result); void ClosedDialogUnionDetails(int result); diff --git a/src/app/mainwindowsnogui.cpp b/src/app/mainwindowsnogui.cpp index 6f94254dc..346d87629 100644 --- a/src/app/mainwindowsnogui.cpp +++ b/src/app/mainwindowsnogui.cpp @@ -30,11 +30,11 @@ #include "core/vapplication.h" #include "../libs/vpatterndb/vcontainer.h" #include "../libs/vobj/vobjpaintdevice.h" -#include "dialogs/dialoglayoutsettings.h" -#include "../libs/vlayout/vlayoutgenerator.h" + #include "dialogs/dialoglayoutprogress.h" -#include "dialogs/dialogsavelayout.h" #include "../libs/vlayout/vposter.h" +#include "dialogs/dialoglayoutsettings.h" + #include #include @@ -80,8 +80,8 @@ void MainWindowsNoGUI::ToolLayoutSettings(bool checked) if (checked) { - VLayoutGenerator lGenerator(this); - lGenerator.SetDetails(listDetails); + VLayoutGenerator lGenerator; + DialogLayoutSettings layout(&lGenerator, this); if (layout.exec() == QDialog::Rejected) @@ -89,40 +89,7 @@ void MainWindowsNoGUI::ToolLayoutSettings(bool checked) tButton->setChecked(false); return; } - - DialogLayoutProgress progress(listDetails.count(), this); - - connect(&lGenerator, &VLayoutGenerator::Start, &progress, &DialogLayoutProgress::Start); - connect(&lGenerator, &VLayoutGenerator::Arranged, &progress, &DialogLayoutProgress::Arranged); - connect(&lGenerator, &VLayoutGenerator::Error, &progress, &DialogLayoutProgress::Error); - connect(&lGenerator, &VLayoutGenerator::Finished, &progress, &DialogLayoutProgress::Finished); - connect(&progress, &DialogLayoutProgress::Abort, &lGenerator, &VLayoutGenerator::Abort); - - lGenerator.Generate(); - - switch (lGenerator.State()) - { - case LayoutErrors::NoError: - CleanLayout(); - papers = lGenerator.GetPapersItems();// Blank sheets - details = lGenerator.GetAllDetails();// All details - if (lGenerator.IsUnitePages()) - { - UnitePages(); - } - CreateShadows(); - CreateScenes(); - PrepareSceneList(); - isLayoutStale = false; - break; - case LayoutErrors::ProcessStoped: - break; - case LayoutErrors::PrepareLayoutError: - case LayoutErrors::EmptyPaperError: - break; - default: - break; - } + LayoutSettings(lGenerator); tButton->setChecked(false); } else @@ -132,6 +99,73 @@ void MainWindowsNoGUI::ToolLayoutSettings(bool checked) } //--------------------------------------------------------------------------------------------------------------------- +void MainWindowsNoGUI::LayoutSettings(VLayoutGenerator& lGenerator) +{ + lGenerator.SetDetails(listDetails); + DialogLayoutProgress progress(listDetails.count(), this); + if (VApplication::CheckGUI()) + { + connect(&lGenerator, &VLayoutGenerator::Start, &progress, &DialogLayoutProgress::Start); + connect(&lGenerator, &VLayoutGenerator::Arranged, &progress, &DialogLayoutProgress::Arranged); + connect(&lGenerator, &VLayoutGenerator::Error, &progress, &DialogLayoutProgress::Error); + connect(&lGenerator, &VLayoutGenerator::Finished, &progress, &DialogLayoutProgress::Finished); + connect(&progress, &DialogLayoutProgress::Abort, &lGenerator, &VLayoutGenerator::Abort); + } + else + { + connect(&lGenerator, &VLayoutGenerator::Error, this, &MainWindowsNoGUI::ErrorConsoleMode); + } + lGenerator.Generate(); + + switch (lGenerator.State()) + { + case LayoutErrors::NoError: + CleanLayout(); + papers = lGenerator.GetPapersItems();// Blank sheets + details = lGenerator.GetAllDetails();// All details + if (lGenerator.IsUnitePages()) + { + UnitePages(); + } + CreateShadows(); + CreateScenes(); + PrepareSceneList(); + isLayoutStale = false; + break; + case LayoutErrors::ProcessStoped: + break; + case LayoutErrors::PrepareLayoutError: + case LayoutErrors::EmptyPaperError: + break; + default: + break; + + } +} +//--------------------------------------------------------------------------------------------------------------------- +void MainWindowsNoGUI::ErrorConsoleMode(const LayoutErrors &state) +{ + QString text; + switch (state) + { + case LayoutErrors::NoError: + return; + case LayoutErrors::PrepareLayoutError: + text = tr("Couldn't prepare data for creation layout"); + break; + case LayoutErrors::ProcessStoped: + break; + case LayoutErrors::EmptyPaperError: + text = tr("Several workpieces left not arranged, but none of them match for paper"); + break; + default: + break; + } + AppAbort(text, FAILED_TO_GEN_LAYOUT_STATUS); +} + +//--------------------------------------------------------------------------------------------------------------------- + void MainWindowsNoGUI::ExportLayoutAs() { if (isLayoutStale) @@ -141,14 +175,20 @@ void MainWindowsNoGUI::ExportLayoutAs() return; } } - QMap extByMessage = InitFormates(); - DialogSaveLayout dialog(extByMessage, scenes.size(), FileName(), this); + DialogSaveLayout dialog(scenes.size(), FileName(), this); if (dialog.exec() == QDialog::Rejected) { return; } + ExportLayout(dialog); +} +//--------------------------------------------------------------------------------------------------------------------- + +void MainWindowsNoGUI::ExportLayout(const DialogSaveLayout &dialog) +{ + QString suf = dialog.Formate(); suf.replace(".", ""); @@ -353,7 +393,7 @@ void MainWindowsNoGUI::PrintTiled() void MainWindowsNoGUI::PrepareDetailsForLayout(const QHash *details) { SCASSERT(details != nullptr) - if (details->count() == 0) + if (details->count() == 0) { listDetails.clear(); return; @@ -459,33 +499,6 @@ void MainWindowsNoGUI::CreateScenes() } } -//--------------------------------------------------------------------------------------------------------------------- -QMap MainWindowsNoGUI::InitFormates() const -{ - QMap extByMessage; - extByMessage[ tr("Svg files (*.svg)") ] = ".svg"; - extByMessage[ tr("PDF files (*.pdf)") ] = ".pdf"; - extByMessage[ tr("Images (*.png)") ] = ".png"; - extByMessage[ tr("Wavefront OBJ (*.obj)") ] = ".obj"; - - QProcess proc; -#if defined(Q_OS_WIN) || defined(Q_OS_OSX) - proc.start(qApp->applicationDirPath()+"/"+PDFTOPS); // Seek pdftops in app bundle or near valentin.exe -#else - proc.start(PDFTOPS); // Seek pdftops in standard path -#endif - if (proc.waitForFinished(15000)) - { - extByMessage[ tr("PS files (*.ps)") ] = ".ps"; - extByMessage[ tr("EPS files (*.eps)") ] = ".eps"; - } - else - { - qDebug()<setCreator(qApp->applicationDisplayName()+" "+qApp->applicationVersion()); + printer->setCreator(qApp->applicationDisplayName()+" "+qApp->applicationVersion()); // Set orientation if (papers.size() > 0) { QGraphicsRectItem *paper = qgraphicsitem_cast(papers.at(0)); SCASSERT(paper != nullptr) - if (paper->rect().height()>= paper->rect().width()) + if (paper->rect().height()>= paper->rect().width()) { printer->setOrientation(QPrinter::Portrait); } @@ -820,8 +833,8 @@ void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer) { QGraphicsRectItem *paper = qgraphicsitem_cast(papers.at(0)); SCASSERT(paper != nullptr) - printer->setPaperSize ( QSizeF(FromPixel(paper->rect().width(), Unit::Mm), - FromPixel(paper->rect().height(), Unit::Mm)), QPrinter::Millimeter ); + printer->setPaperSize ( QSizeF(FromPixel(paper->rect().width(), Unit::Mm), + FromPixel(paper->rect().height(), Unit::Mm)), QPrinter::Millimeter ); } printer->setDocName(FileName()); @@ -838,11 +851,11 @@ bool MainWindowsNoGUI::isPagesUniform() const { QGraphicsRectItem *paper = qgraphicsitem_cast(papers.at(0)); SCASSERT(paper != nullptr) - for (int i=1; i < papers.size(); ++i) + for (int i=1; i < papers.size(); ++i) { QGraphicsRectItem *p = qgraphicsitem_cast(papers.at(i)); SCASSERT(p != nullptr) - if (paper->rect() != p->rect()) + if (paper->rect() != p->rect()) { return false; } @@ -893,7 +906,7 @@ void MainWindowsNoGUI::UnitePages() { QGraphicsRectItem *paper = qgraphicsitem_cast(papers.at(i)); SCASSERT(paper != nullptr) - if (length + paper->rect().height() <= QIMAGE_MAX) + if (length + paper->rect().height() <= QIMAGE_MAX) { UniteDetails(j, nDetails, length, i); length += paper->rect().height(); diff --git a/src/app/mainwindowsnogui.h b/src/app/mainwindowsnogui.h index 4b1b78760..1a82483a8 100644 --- a/src/app/mainwindowsnogui.h +++ b/src/app/mainwindowsnogui.h @@ -34,10 +34,14 @@ #include "../libs/vpatterndb/vdetail.h" #include "../libs/vlayout/vlayoutdetail.h" #include "xml/vpattern.h" +#include "dialogs/dialogsavelayout.h" +#include "../libs/vlayout/vlayoutgenerator.h" + class QGraphicsScene; class QPrinter; + class MainWindowsNoGUI : public QMainWindow { Q_OBJECT @@ -55,7 +59,7 @@ public slots: void PrintPreviewTiled(); void PrintOrigin(); void PrintTiled(); - + void ErrorConsoleMode(const LayoutErrors &state); protected: QVector listDetails; @@ -85,12 +89,13 @@ protected: bool isLayoutStale; void PrepareDetailsForLayout(const QHash *details); + void ExportLayout(const DialogSaveLayout &dialog); void InitTempLayoutScene(); virtual void CleanLayout()=0; virtual void PrepareSceneList()=0; QIcon ScenePreview(int i) const; - + void LayoutSettings(VLayoutGenerator& lGenerator); private: Q_DISABLE_COPY(MainWindowsNoGUI) @@ -99,7 +104,6 @@ private: void CreateShadows(); void CreateScenes(); - QMap InitFormates() const; void SvgFile(const QString &name, int i)const; void PngFile(const QString &name, int i)const; diff --git a/src/libs/ifc/xml/vdomdocument.cpp b/src/libs/ifc/xml/vdomdocument.cpp index 3487d54f9..88ce5f6bb 100644 --- a/src/libs/ifc/xml/vdomdocument.cpp +++ b/src/libs/ifc/xml/vdomdocument.cpp @@ -597,6 +597,21 @@ QString VDomDocument::UnitsToStr(const Unit &unit, const bool translate) return result; } +//--------------------------------------------------------------------------------------------------------------------- +QString VDomDocument::UnitsHelpString() +{ + QString r; + for (auto i = static_cast(Unit::Mm), last = static_cast(Unit::LAST_UNIT_DO_NOT_USE); i < last;++i) + { + r += UnitsToStr(static_cast(i)); + if (i < last - 1) + { + r += ", "; + } + } + return r; +} + //--------------------------------------------------------------------------------------------------------------------- bool VDomDocument::SaveDocument(const QString &fileName, QString &error) const { diff --git a/src/libs/ifc/xml/vdomdocument.h b/src/libs/ifc/xml/vdomdocument.h index 421f56144..fdb1c11d7 100644 --- a/src/libs/ifc/xml/vdomdocument.h +++ b/src/libs/ifc/xml/vdomdocument.h @@ -97,6 +97,8 @@ public: void setXMLContent(const QString &fileName); static Unit StrToUnits(const QString &unit); static QString UnitsToStr(const Unit &unit, const bool translate = false); + static QString UnitsHelpString(); + virtual bool SaveDocument(const QString &fileName, QString &error) const; QString Major() const; QString Minor() const; diff --git a/src/libs/vlayout/vbank.h b/src/libs/vlayout/vbank.h index f7f061dfc..79f04e680 100644 --- a/src/libs/vlayout/vbank.h +++ b/src/libs/vlayout/vbank.h @@ -36,7 +36,7 @@ class QPointF; class VLayoutDetail; -enum class Cases : char { CaseThreeGroup, CaseTwoGroup, CaseDesc, UnknownCase}; +enum class Cases : char { CaseThreeGroup = 0, CaseTwoGroup, CaseDesc, UnknownCase}; class VBank { diff --git a/src/libs/vlayout/vlayoutgenerator.h b/src/libs/vlayout/vlayoutgenerator.h index 5f1846d3f..233d102ae 100644 --- a/src/libs/vlayout/vlayoutgenerator.h +++ b/src/libs/vlayout/vlayoutgenerator.h @@ -34,6 +34,7 @@ #include "vlayoutdef.h" #include "vbank.h" +#include class VLayoutPaper; class VLayoutDetail; @@ -107,4 +108,6 @@ private: bool unitePages; }; +typedef std::shared_ptr VLayoutGeneratorPtr; + #endif // VLAYOUTGENERATOR_H diff --git a/src/libs/vmisc/def.h b/src/libs/vmisc/def.h index 22f3026c7..a6837175b 100644 --- a/src/libs/vmisc/def.h +++ b/src/libs/vmisc/def.h @@ -39,7 +39,7 @@ enum class NodeDetail : char { Contour, Modeling }; enum class SceneObject : char { Point, Line, Spline, Arc, SplinePath, Detail, Unknown }; enum class MeasurementsType : char { Standard, Individual }; -enum class Unit : char { Mm, Cm, Inch, Px }; +enum class Unit : char { Mm = 0, Cm, Inch, Px, LAST_UNIT_DO_NOT_USE}; enum class Source : char { FromGui, FromFile, FromTool }; enum class Tool : unsigned char @@ -81,12 +81,13 @@ enum class Tool : unsigned char PointFromCircleAndTangent, PointFromArcAndTangent, TrueDarts, - UnionDetails // 37 + UnionDetails, // 37 + LAST_ONE_DO_NOT_USE //add new stuffs above this, this constant must be last and never used }; enum class Vis : unsigned char { - ControlPointSpline = 38, // increase this value if need more positions in Tool enum + ControlPointSpline = static_cast(Tool::LAST_ONE_DO_NOT_USE), //38,// increase this value if need more positions in Tool enum GraphicsSimpleTextItem, SimpleSplinePath, SimplePoint,