From 8c84cff91dbe81bd2826bb642558925cfbb074c3 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 26 Sep 2017 12:54:52 +0300 Subject: [PATCH 01/12] Read/write list of final measurements. --HG-- branch : feature --- src/app/valentina/xml/vpattern.cpp | 26 +- src/libs/ifc/schema.qrc | 1 + src/libs/ifc/schema/pattern/v0.6.4.xsd | 985 +++++++++++++++++++++++++ src/libs/ifc/xml/vabstractpattern.cpp | 84 ++- src/libs/ifc/xml/vabstractpattern.h | 20 +- src/libs/ifc/xml/vpatternconverter.cpp | 22 +- src/libs/ifc/xml/vpatternconverter.h | 3 +- 7 files changed, 1117 insertions(+), 24 deletions(-) create mode 100644 src/libs/ifc/schema/pattern/v0.6.4.xsd diff --git a/src/app/valentina/xml/vpattern.cpp b/src/app/valentina/xml/vpattern.cpp index 57a7c6509..9149dc0c1 100644 --- a/src/app/valentina/xml/vpattern.cpp +++ b/src/app/valentina/xml/vpattern.cpp @@ -152,7 +152,8 @@ void VPattern::Parse(const Document &parse) QStringList tags = QStringList() << TagDraw << TagIncrements << TagDescription << TagNotes << TagMeasurements << TagVersion << TagGradation << TagImage << TagUnit << TagPatternName << TagPatternNum << TagCompanyName << TagCustomerName - << TagPatternLabel << TagPatternMaterials << TagPreviewCalculations; + << TagPatternLabel << TagPatternMaterials << TagPreviewCalculations + << TagFinalMeasurements; PrepareForParse(parse); QDomNode domNode = documentElement().firstChild(); while (domNode.isNull() == false) @@ -231,6 +232,9 @@ void VPattern::Parse(const Document &parse) qCDebug(vXML, "Tag prewiew calculations."); ParseIncrementsElement(domElement); break; + case 16: // TagFinalMeasurements + qCDebug(vXML, "Tag final measurements."); + break; default: qCDebug(vXML, "Wrong tag name %s", qUtf8Printable(domElement.tagName())); break; @@ -3128,9 +3132,9 @@ qreal VPattern::EvalFormula(VContainer *data, const QString &formula, bool *ok) QDomElement VPattern::MakeEmptyIncrement(const QString &name) { QDomElement element = createElement(TagIncrement); - SetAttribute(element, IncrementName, name); - SetAttribute(element, IncrementFormula, QString("0")); - SetAttribute(element, IncrementDescription, QString("")); + SetAttribute(element, AttrName, name); + SetAttribute(element, AttrFormula, QString("0")); + SetAttribute(element, AttrDescription, QString("")); return element; } @@ -3144,7 +3148,7 @@ QDomElement VPattern::FindIncrement(const QString &name) const const QDomElement domElement = list.at(i).toElement(); if (domElement.isNull() == false) { - const QString parameter = domElement.attribute(IncrementName); + const QString parameter = domElement.attribute(AttrName); if (parameter == name) { return domElement; @@ -3573,19 +3577,19 @@ void VPattern::ParseIncrementsElement(const QDomNode &node) { if (domElement.tagName() == TagIncrement) { - const QString name = GetParametrString(domElement, IncrementName, ""); + const QString name = GetParametrString(domElement, AttrName, ""); QString desc; try { - desc = GetParametrString(domElement, IncrementDescription); + desc = GetParametrString(domElement, AttrDescription); } catch (VExceptionEmptyParameter &e) { Q_UNUSED(e) } - const QString formula = GetParametrString(domElement, IncrementFormula, "0"); + const QString formula = GetParametrString(domElement, AttrFormula, "0"); bool ok = false; const qreal value = EvalFormula(data, formula, &ok); @@ -3664,19 +3668,19 @@ void VPattern::MoveDownPreviewCalculation(const QString &name) //--------------------------------------------------------------------------------------------------------------------- void VPattern::SetIncrementName(const QString &name, const QString &text) { - SetIncrementAttribute(name, IncrementName, text); + SetIncrementAttribute(name, AttrName, text); } //--------------------------------------------------------------------------------------------------------------------- void VPattern::SetIncrementFormula(const QString &name, const QString &text) { - SetIncrementAttribute(name, IncrementFormula, text); + SetIncrementAttribute(name, AttrFormula, text); } //--------------------------------------------------------------------------------------------------------------------- void VPattern::SetIncrementDescription(const QString &name, const QString &text) { - SetIncrementAttribute(name, IncrementDescription, text); + SetIncrementAttribute(name, AttrDescription, text); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/ifc/schema.qrc b/src/libs/ifc/schema.qrc index a07196c68..c6f701026 100644 --- a/src/libs/ifc/schema.qrc +++ b/src/libs/ifc/schema.qrc @@ -38,6 +38,7 @@ schema/pattern/v0.6.1.xsd schema/pattern/v0.6.2.xsd schema/pattern/v0.6.3.xsd + schema/pattern/v0.6.4.xsd schema/standard_measurements/v0.3.0.xsd schema/standard_measurements/v0.4.0.xsd schema/standard_measurements/v0.4.1.xsd diff --git a/src/libs/ifc/schema/pattern/v0.6.4.xsd b/src/libs/ifc/schema/pattern/v0.6.4.xsd new file mode 100644 index 000000000..ad9dc1934 --- /dev/null +++ b/src/libs/ifc/schema/pattern/v0.6.4.xsd @@ -0,0 +1,985 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/ifc/xml/vabstractpattern.cpp b/src/libs/ifc/xml/vabstractpattern.cpp index 1e442e673..5c26c377b 100644 --- a/src/libs/ifc/xml/vabstractpattern.cpp +++ b/src/libs/ifc/xml/vabstractpattern.cpp @@ -88,7 +88,9 @@ const QString VAbstractPattern::TagCustomerName = QStringLiteral("customer") const QString VAbstractPattern::TagCompanyName = QStringLiteral("company"); const QString VAbstractPattern::TagPatternLabel = QStringLiteral("patternLabel"); const QString VAbstractPattern::TagPatternMaterials = QStringLiteral("patternMaterials"); +const QString VAbstractPattern::TagFinalMeasurements= QStringLiteral("finalMeasurements"); const QString VAbstractPattern::TagMaterial = QStringLiteral("material"); +const QString VAbstractPattern::TagFMeasurement = QStringLiteral("finalMeasurment"); const QString VAbstractPattern::TagGrainline = QStringLiteral("grainline"); const QString VAbstractPattern::TagPath = QStringLiteral("path"); const QString VAbstractPattern::TagNodes = QStringLiteral("nodes"); @@ -187,9 +189,8 @@ const QString VAbstractPattern::AttrDefHeight = QStringLiteral("defHeight" const QString VAbstractPattern::AttrDefSize = QStringLiteral("defSize"); const QString VAbstractPattern::AttrExtension = QStringLiteral("extension"); -const QString VAbstractPattern::IncrementName = QStringLiteral("name"); -const QString VAbstractPattern::IncrementFormula = QStringLiteral("formula"); -const QString VAbstractPattern::IncrementDescription = QStringLiteral("description"); +const QString VAbstractPattern::AttrFormula = QStringLiteral("formula"); +const QString VAbstractPattern::AttrDescription = QStringLiteral("description"); const QString VAbstractPattern::NodeArc = QStringLiteral("NodeArc"); const QString VAbstractPattern::NodeElArc = QStringLiteral("NodeElArc"); @@ -1444,6 +1445,28 @@ QMap VAbstractPattern::GetPatternMaterials() const return patternMaterials; } +//--------------------------------------------------------------------------------------------------------------------- +QVector VAbstractPattern::GetFinalMeasurements() const +{ + const QDomNodeList list = elementsByTagName(TagFinalMeasurements); + if (list.isEmpty() || list.at(0).childNodes().count() == 0) + { + return QVector(); + } + + return GetFMeasurements(list.at(0).toElement()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::SetFinalMeasurements(const QVector &measurements) +{ + QDomElement tag = CheckTagExists(TagFinalMeasurements); + RemoveAllChildren(tag); + SetFMeasurements(tag, measurements); + modified = true; + emit patternChanged(false); +} + //--------------------------------------------------------------------------------------------------------------------- void VAbstractPattern::SetPatternWasChanged(bool changed) { @@ -1598,7 +1621,8 @@ QDomElement VAbstractPattern::CheckTagExists(const QString &tag) { const QStringList tags = QStringList() << TagUnit << TagImage << TagDescription << TagNotes << TagGradation << TagPatternName << TagPatternNum << TagCompanyName - << TagCustomerName << TagPatternLabel << TagPatternMaterials; + << TagCustomerName << TagPatternLabel << TagPatternMaterials + << TagFinalMeasurements; switch (tags.indexOf(tag)) { case 1: //TagImage @@ -1641,6 +1665,9 @@ QDomElement VAbstractPattern::CheckTagExists(const QString &tag) case 10: // TagPatternMaterials element = createElement(TagPatternMaterials); break; + case 11: // TagFinalMeasurements + element = createElement(TagFinalMeasurements); + break; case 0: //TagUnit (Mandatory tag) default: return QDomElement(); @@ -1703,7 +1730,7 @@ QStringList VAbstractPattern::ListIncrements() const try { - increments.append(GetParametrString(dom, IncrementName)); + increments.append(GetParametrString(dom, AttrName)); } catch (VExceptionEmptyParameter &e) { @@ -1853,7 +1880,7 @@ QVector VAbstractPattern::ListIncrementExpressions() const { const QDomElement dom = list.at(i).toElement(); - ReadExpressionAttribute(expressions, dom, IncrementFormula); + ReadExpressionAttribute(expressions, dom, AttrFormula); } return expressions; @@ -2103,6 +2130,51 @@ void VAbstractPattern::SetMaterials(QDomElement &element, const QMap VAbstractPattern::GetFMeasurements(const QDomElement &element) const +{ + QVector measurements; + + if (not element.isNull()) + { + QDomElement tagFMeasurement = element.firstChildElement(); + while (not tagFMeasurement.isNull()) + { + if (tagFMeasurement.tagName() == TagFMeasurement) + { + VFinalMeasurement m; + + m.name = GetParametrString(tagFMeasurement, AttrName, tr("measurement")); + m.formula = GetParametrString(tagFMeasurement, AttrFormula, "0"); + m.description = GetParametrEmptyString(tagFMeasurement, AttrDescription); + + measurements.append(m); + } + tagFMeasurement = tagFMeasurement.nextSiblingElement(TagFMeasurement); + } + } + + return measurements; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::SetFMeasurements(QDomElement &element, const QVector &measurements) +{ + if (not element.isNull()) + { + for (int i=0; i < measurements.size(); ++i) + { + QDomElement tagFMeasurement = createElement(TagFMeasurement); + + SetAttribute(tagFMeasurement, AttrName, measurements.at(i).name); + SetAttribute(tagFMeasurement, AttrFormula, measurements.at(i).formula); + SetAttribute(tagFMeasurement, AttrDescription, measurements.at(i).description); + + element.appendChild(tagFMeasurement); + } + } +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief IsModified state of the document for cases that do not cover QUndoStack. diff --git a/src/libs/ifc/xml/vabstractpattern.h b/src/libs/ifc/xml/vabstractpattern.h index 6b5ae7b76..b10b39391 100644 --- a/src/libs/ifc/xml/vabstractpattern.h +++ b/src/libs/ifc/xml/vabstractpattern.h @@ -70,6 +70,13 @@ struct VFormulaField QString attribute; }; +struct VFinalMeasurement +{ + QString name; + QString formula; + QString description; +}; + QT_WARNING_POP class VAbstractPattern : public QObject, public VDomDocument @@ -163,6 +170,9 @@ public: void SetPatternMaterials(const QMap &materials); QMap GetPatternMaterials() const; + QVector GetFinalMeasurements() const; + void SetFinalMeasurements(const QVector &measurements); + void SetPatternWasChanged(bool changed); bool GetPatternWasChanged() const; @@ -221,7 +231,9 @@ public: static const QString TagCustomerName; static const QString TagPatternLabel; static const QString TagPatternMaterials; + static const QString TagFinalMeasurements; static const QString TagMaterial; + static const QString TagFMeasurement; static const QString TagGrainline; static const QString TagPath; static const QString TagNodes; @@ -320,9 +332,8 @@ public: static const QString AttrDefSize; static const QString AttrExtension; - static const QString IncrementName; - static const QString IncrementFormula; - static const QString IncrementDescription; + static const QString AttrFormula; + static const QString AttrDescription; static const QString NodeArc; static const QString NodeElArc; @@ -444,6 +455,9 @@ private: QMap GetMaterials(const QDomElement &element) const; void SetMaterials(QDomElement &element, const QMap &materials); + + QVector GetFMeasurements(const QDomElement &element) const; + void SetFMeasurements(QDomElement &element, const QVector &measurements); }; //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/ifc/xml/vpatternconverter.cpp b/src/libs/ifc/xml/vpatternconverter.cpp index beca47c34..ae7fa52fa 100644 --- a/src/libs/ifc/xml/vpatternconverter.cpp +++ b/src/libs/ifc/xml/vpatternconverter.cpp @@ -58,8 +58,8 @@ class QDomElement; */ const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.0"); -const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.6.3"); -const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.6.3.xsd"); +const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.6.4"); +const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.6.4.xsd"); //VPatternConverter::PatternMinVer; // <== DON'T FORGET TO UPDATE TOO!!!! //VPatternConverter::PatternMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!! @@ -250,6 +250,8 @@ QString VPatternConverter::XSDSchema(int ver) const case (0x000602): return QStringLiteral("://schema/pattern/v0.6.2.xsd"); case (0x000603): + return QStringLiteral("://schema/pattern/v0.6.3.xsd"); + case (0x000604): return CurrentSchema; default: InvalidVersion(ver); @@ -412,6 +414,10 @@ void VPatternConverter::ApplyPatches() ValidateXML(XSDSchema(0x000603), m_convertedFileName); V_FALLTHROUGH case (0x000603): + ToV0_6_4(); + ValidateXML(XSDSchema(0x000604), m_convertedFileName); + V_FALLTHROUGH + case (0x000604): break; default: InvalidVersion(m_ver); @@ -430,7 +436,7 @@ void VPatternConverter::DowngradeToCurrentMaxVersion() bool VPatternConverter::IsReadOnly() const { // Check if attribute readOnly was not changed in file format - Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == CONVERTER_VERSION_CHECK(0, 6, 3), + Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == CONVERTER_VERSION_CHECK(0, 6, 4), "Check attribute readOnly."); // Possibly in future attribute readOnly will change position etc. @@ -864,6 +870,16 @@ void VPatternConverter::ToV0_6_3() Save(); } +//--------------------------------------------------------------------------------------------------------------------- +void VPatternConverter::ToV0_6_4() +{ + // TODO. Delete if minimal supported version is 0.6.4 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 6, 4), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.6.4")); + Save(); +} + //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::TagUnitToV0_2_0() { diff --git a/src/libs/ifc/xml/vpatternconverter.h b/src/libs/ifc/xml/vpatternconverter.h index 441cbd584..e6b83b7dc 100644 --- a/src/libs/ifc/xml/vpatternconverter.h +++ b/src/libs/ifc/xml/vpatternconverter.h @@ -53,7 +53,7 @@ public: static const QString PatternMaxVerStr; static const QString CurrentSchema; static Q_DECL_CONSTEXPR const int PatternMinVer = CONVERTER_VERSION_CHECK(0, 1, 0); - static Q_DECL_CONSTEXPR const int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 6, 3); + static Q_DECL_CONSTEXPR const int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 6, 4); protected: virtual int MinVer() const Q_DECL_OVERRIDE; @@ -109,6 +109,7 @@ private: void ToV0_6_1(); void ToV0_6_2(); void ToV0_6_3(); + void ToV0_6_4(); void TagUnitToV0_2_0(); void TagIncrementToV0_2_0(); From 0eb6b8b30ff4a62eda2a27f173dff489a65d45ca Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 26 Sep 2017 17:24:02 +0300 Subject: [PATCH 02/12] Dialog Final measurements. --HG-- branch : feature --- .../dialogs/dialogfinalmeasurements.cpp | 741 ++++++++++++++++++ .../dialogs/dialogfinalmeasurements.h | 102 +++ .../dialogs/dialogfinalmeasurements.ui | 469 +++++++++++ src/app/valentina/dialogs/dialogs.h | 1 + src/app/valentina/dialogs/dialogs.pri | 9 +- src/app/valentina/mainwindow.cpp | 29 +- src/app/valentina/mainwindow.h | 8 +- src/app/valentina/mainwindow.ui | 20 +- src/libs/vmisc/vcommonsettings.cpp | 13 + src/libs/vmisc/vcommonsettings.h | 3 + src/libs/vpatterndb/vtranslatevars.cpp | 14 + src/libs/vpatterndb/vtranslatevars.h | 2 + 12 files changed, 1403 insertions(+), 8 deletions(-) create mode 100644 src/app/valentina/dialogs/dialogfinalmeasurements.cpp create mode 100644 src/app/valentina/dialogs/dialogfinalmeasurements.h create mode 100644 src/app/valentina/dialogs/dialogfinalmeasurements.ui diff --git a/src/app/valentina/dialogs/dialogfinalmeasurements.cpp b/src/app/valentina/dialogs/dialogfinalmeasurements.cpp new file mode 100644 index 000000000..a2edafc6c --- /dev/null +++ b/src/app/valentina/dialogs/dialogfinalmeasurements.cpp @@ -0,0 +1,741 @@ +/************************************************************************ + ** + ** @file dialogfinalmeasurements.cpp + ** @author Roman Telezhynskyi + ** @date 26 9, 2017 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2017 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 "dialogfinalmeasurements.h" +#include "ui_dialogfinalmeasurements.h" +#include "../vmisc/vsettings.h" +#include "../qmuparser/qmudef.h" +#include "../qmuparser/qmutokenparser.h" +#include "../vpatterndb/vtranslatevars.h" +#include "../vpatterndb/calculator.h" +#include "../vtools/dialogs/support/dialogeditwrongformula.h" + +#define DIALOG_MAX_FORMULA_HEIGHT 64 + +namespace +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) +template +void Move(QVector &vector, int from, int to) +{ + Q_ASSERT_X(from >= 0 && from < vector.size(), "QVector::move(int,int)", "'from' is out-of-range"); + Q_ASSERT_X(to >= 0 && to < vector.size(), "QVector::move(int,int)", "'to' is out-of-range"); + if (from == to) // don't detach when no-op + { + return; + } + T * const b = vector.begin(); + if (from < to) + { + std::rotate(b + from, b + from + 1, b + to + 1); + } + else + { + std::rotate(b + to, b + from, b + from + 1); + } +} +#endif // QT_VERSION < QT_VERSION_CHECK(5, 6, 0) +} + +//--------------------------------------------------------------------------------------------------------------------- +DialogFinalMeasurements::DialogFinalMeasurements(VPattern *doc, QWidget *parent) + : QDialog(parent), + ui(new Ui::DialogFinalMeasurements), + m_doc(doc), + m_data(doc->GetCompleteData()), + m_measurements(doc->GetFinalMeasurements()), + m_search(), + formulaBaseHeight(0), + m_isInitialized(false) +{ + ui->setupUi(this); + + ui->lineEditName->setClearButtonEnabled(true); + ui->lineEditFind->setClearButtonEnabled(true); + + ui->lineEditFind->installEventFilter(this); + + m_search = QSharedPointer(new VTableSearch(ui->tableWidget)); + + formulaBaseHeight = ui->plainTextEditFormula->height(); + ui->plainTextEditFormula->installEventFilter(this); + + qApp->Settings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c()); + + qCDebug(vDialog, "Showing variables."); + ShowUnits(); + + const bool freshCall = true; + FillFinalMeasurements(freshCall); + + connect(m_doc, &VPattern::FullUpdateFromFile, this, &DialogFinalMeasurements::FullUpdateFromFile); + + ui->lineEditName->setValidator( new QRegularExpressionValidator(QRegularExpression( + QLatin1String("^$|")+NameRegExp()), this)); + + connect(ui->tableWidget, &QTableWidget::itemSelectionChanged, this, + &DialogFinalMeasurements::ShowFinalMeasurementDetails); + + connect(ui->toolButtonAdd, &QToolButton::clicked, this, &DialogFinalMeasurements::Add); + connect(ui->toolButtonRemove, &QToolButton::clicked, this, &DialogFinalMeasurements::Remove); + connect(ui->toolButtonUp, &QToolButton::clicked, this, &DialogFinalMeasurements::MoveUp); + connect(ui->toolButtonDown, &QToolButton::clicked, this, &DialogFinalMeasurements::MoveDown); + connect(ui->pushButtonGrow, &QPushButton::clicked, this, &DialogFinalMeasurements::DeployFormula); + connect(ui->toolButtonExpr, &QToolButton::clicked, this, &DialogFinalMeasurements::Fx); + connect(ui->lineEditName, &QLineEdit::textEdited, this, &DialogFinalMeasurements::SaveName); + connect(ui->plainTextEditDescription, &QPlainTextEdit::textChanged, this, + &DialogFinalMeasurements::SaveDescription); + connect(ui->plainTextEditFormula, &QPlainTextEdit::textChanged, this, &DialogFinalMeasurements::SaveFormula); + connect(ui->lineEditFind, &QLineEdit::textEdited, this, [this](const QString &term){m_search->Find(term);}); + connect(ui->toolButtonFindPrevious, &QToolButton::clicked, this, [this](){m_search->FindPrevious();}); + connect(ui->toolButtonFindNext, &QToolButton::clicked, this, [this](){m_search->FindNext();}); + + connect(m_search.data(), &VTableSearch::HasResult, this, [this] (bool state) + { + ui->toolButtonFindPrevious->setEnabled(state); + }); + + connect(m_search.data(), &VTableSearch::HasResult, this, [this] (bool state) + { + ui->toolButtonFindNext->setEnabled(state); + }); + + if (ui->tableWidget->rowCount() > 0) + { + ui->tableWidget->selectRow(0); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +DialogFinalMeasurements::~DialogFinalMeasurements() +{ + delete ui; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::closeEvent(QCloseEvent *event) +{ + ui->plainTextEditFormula->blockSignals(true); + ui->lineEditName->blockSignals(true); + ui->plainTextEditDescription->blockSignals(true); + + QDialog::closeEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + // retranslate designer form (single inheritance approach) + ui->retranslateUi(this); + FullUpdateFromFile(); + } + // remember to call base class implementation + QDialog::changeEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool DialogFinalMeasurements::eventFilter(QObject *object, QEvent *event) +{ + if (QLineEdit *textEdit = qobject_cast(object)) + { + if (event->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast(event); + if ((keyEvent->key() == Qt::Key_Period) && (keyEvent->modifiers() & Qt::KeypadModifier)) + { + if (qApp->Settings()->GetOsSeparator()) + { + textEdit->insert(QLocale().decimalPoint()); + } + else + { + textEdit->insert(QLocale::c().decimalPoint()); + } + return true; + } + } + } + else + { + // pass the event on to the parent class + return QDialog::eventFilter(object, event); + } + return false;// pass the event to the widget +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::showEvent(QShowEvent *event) +{ + QDialog::showEvent(event); + if ( event->spontaneous() ) + { + return; + } + + if (m_isInitialized) + { + return; + } + // do your init stuff here + + const QSize sz = qApp->Settings()->GetFinalMeasurementsDialogSize(); + if (not sz.isEmpty()) + { + resize(sz); + } + + m_isInitialized = true;//first show windows are held +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::resizeEvent(QResizeEvent *event) +{ + // remember the size for the next time this dialog is opened, but only + // if widget was already initialized, which rules out the resize at + // dialog creating, which would + if (m_isInitialized) + { + qApp->Settings()->SetFinalMeasurementsDialogSize(size()); + } + QDialog::resizeEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::ShowFinalMeasurementDetails() +{ + if (ui->tableWidget->rowCount() > 0 && m_measurements.size() == ui->tableWidget->rowCount()) + { + EnableDetails(true); + + const VFinalMeasurement &m = m_measurements.at(ui->tableWidget->currentRow()); + + ui->lineEditName->blockSignals(true); + ui->lineEditName->setText(m.name); + ui->lineEditName->blockSignals(false); + + ui->plainTextEditDescription->blockSignals(true); + ui->plainTextEditDescription->setPlainText(m.description); + ui->plainTextEditDescription->blockSignals(false); + + EvalUserFormula(m.formula, false); + ui->plainTextEditFormula->blockSignals(true); + + const QString formula = VTranslateVars::TryFormulaToUser(m.formula, qApp->Settings()->GetOsSeparator()); + + ui->plainTextEditFormula->setPlainText(formula); + ui->plainTextEditFormula->blockSignals(false); + } + else + { + EnableDetails(false); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::Add() +{ + const int currentRow = ui->tableWidget->currentRow()+1; + + VFinalMeasurement m; + m.name = tr("measurement"); + m.formula = "0"; + + m_measurements.append(m); + + UpdateTree(); + ui->tableWidget->selectRow(currentRow); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::Remove() +{ + const int row = ui->tableWidget->currentRow(); + + if (row == -1 || row >= m_measurements.size()) + { + return; + } + + m_measurements.remove(row); + + UpdateTree(); + + if (ui->tableWidget->rowCount() > 0) + { + ui->tableWidget->selectRow(0); + } + else + { + EnableDetails(false); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::MoveUp() +{ + const int row = ui->tableWidget->currentRow(); + + if (row == -1 || row == 0 || row >= m_measurements.size()) + { + return; + } + +#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) + Move(m_measurements, row, row-1); +#else + m_measurements.move(row, row-1); +#endif + UpdateTree(); + + ui->tableWidget->selectRow(row-1); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::MoveDown() +{ + const int row = ui->tableWidget->currentRow(); + + if (row == -1 || row == ui->tableWidget->rowCount()-1 || row >= m_measurements.size()) + { + return; + } + +#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) + Move(m_measurements, row, row+1); +#else + m_measurements.move(row, row+1); +#endif + UpdateTree(); + + ui->tableWidget->selectRow(row+1); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::SaveName(const QString &text) +{ + const int row = ui->tableWidget->currentRow(); + + if (row == -1 || row >= m_measurements.size()) + { + return; + } + + m_measurements[row].name = text.isEmpty() ? tr("measurement") : text; + + UpdateTree(); + + ui->tableWidget->blockSignals(true); + ui->tableWidget->selectRow(row); + ui->tableWidget->blockSignals(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::SaveDescription() +{ + const int row = ui->tableWidget->currentRow(); + + if (row == -1 || row >= m_measurements.size()) + { + return; + } + + const QTextCursor cursor = ui->plainTextEditDescription->textCursor(); + + m_measurements[row].description = ui->plainTextEditDescription->toPlainText(); + + UpdateTree(); + + ui->tableWidget->blockSignals(true); + ui->tableWidget->selectRow(row); + ui->tableWidget->blockSignals(false); + ui->plainTextEditDescription->setTextCursor(cursor); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::SaveFormula() +{ + const int row = ui->tableWidget->currentRow(); + + if (row == -1 || row >= m_measurements.size()) + { + return; + } + + // Replace line return character with spaces for calc if exist + QString text = ui->plainTextEditFormula->toPlainText(); + text.replace("\n", " "); + + QTableWidgetItem *formulaField = ui->tableWidget->item(row, 2); + if (formulaField->text() == text) + { + QTableWidgetItem *result = ui->tableWidget->item(row, 1); + //Show unit in dialog lable (cm, mm or inch) + const QString postfix = UnitsToStr(qApp->patternUnit()); + ui->labelCalculatedValue->setText(result->text() + " " +postfix); + return; + } + + if (text.isEmpty()) + { + //Show unit in dialog lable (cm, mm or inch) + const QString postfix = UnitsToStr(qApp->patternUnit()); + ui->labelCalculatedValue->setText(tr("Error") + " (" + postfix + "). " + tr("Empty field.")); + return; + } + + if (not EvalUserFormula(text, true)) + { + return; + } + + try + { + m_measurements[row].formula = qApp->TrVars()->FormulaFromUser(text, qApp->Settings()->GetOsSeparator()); + } + catch (qmu::QmuParserError &e) // Just in case something bad will happen + { + Q_UNUSED(e) + return; + } + + const QTextCursor cursor = ui->plainTextEditFormula->textCursor(); + + UpdateTree(); + + ui->tableWidget->blockSignals(true); + ui->tableWidget->selectRow(row); + ui->tableWidget->blockSignals(false); + ui->plainTextEditFormula->setTextCursor(cursor); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::DeployFormula() +{ + const QTextCursor cursor = ui->plainTextEditFormula->textCursor(); + + if (ui->plainTextEditFormula->height() < DIALOG_MAX_FORMULA_HEIGHT) + { + ui->plainTextEditFormula->setFixedHeight(DIALOG_MAX_FORMULA_HEIGHT); + //Set icon from theme (internal for Windows system) + ui->pushButtonGrow->setIcon(QIcon::fromTheme("go-next", + QIcon(":/icons/win.icon.theme/16x16/actions/go-next.png"))); + } + else + { + ui->plainTextEditFormula->setFixedHeight(formulaBaseHeight); + //Set icon from theme (internal for Windows system) + ui->pushButtonGrow->setIcon(QIcon::fromTheme("go-down", + QIcon(":/icons/win.icon.theme/16x16/actions/go-down.png"))); + } + + // I found that after change size of formula field, it was filed for angle formula, field for formula became black. + // This code prevent this. + setUpdatesEnabled(false); + repaint(); + setUpdatesEnabled(true); + + ui->plainTextEditFormula->setFocus(); + ui->plainTextEditFormula->setTextCursor(cursor); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::Fx() +{ + const int row = ui->tableWidget->currentRow(); + + if (row == -1 || row >= m_measurements.size()) + { + return; + } + + QScopedPointer dialog(new DialogEditWrongFormula(&m_data, NULL_ID, this)); + dialog->setWindowTitle(tr("Edit measurement")); + dialog->SetFormula(qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditFormula->toPlainText().replace("\n", " "), + qApp->Settings()->GetOsSeparator())); + const QString postfix = UnitsToStr(qApp->patternUnit(), true); + dialog->setPostfix(postfix);//Show unit in dialog lable (cm, mm or inch) + + if (dialog->exec() == QDialog::Accepted) + { + m_measurements[row].formula = dialog->GetFormula(); + UpdateTree(); + + ui->tableWidget->selectRow(row); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::FullUpdateFromFile() +{ + m_data = m_doc->GetCompleteData(); + m_measurements = m_doc->GetFinalMeasurements(); + + FillFinalMeasurements(); + + m_search->RefreshList(ui->lineEditFind->text()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::FillFinalMeasurements(bool freshCall) +{ + ui->tableWidget->blockSignals(true); + ui->tableWidget->clearContents(); + + ui->tableWidget->setRowCount(m_measurements.size()); + for (int i=0; i < m_measurements.size(); ++i) + { + const VFinalMeasurement &m = m_measurements.at(i); + + AddCell(m.name, i, 0, Qt::AlignVCenter); // name + + bool ok = true; + const qreal result = EvalFormula(m.formula, ok); + AddCell(qApp->LocaleToString(result), i, 1, Qt::AlignHCenter | Qt::AlignVCenter, ok); // calculated value + + const QString formula = VTranslateVars::TryFormulaFromUser(m.formula, qApp->Settings()->GetOsSeparator()); + AddCell(formula, i, 2, Qt::AlignVCenter); // formula + + } + + if (freshCall) + { + ui->tableWidget->resizeColumnsToContents(); + ui->tableWidget->resizeRowsToContents(); + } + ui->tableWidget->horizontalHeader()->setStretchLastSection(true); + ui->tableWidget->blockSignals(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::ShowUnits() +{ + const QString unit = UnitsToStr(qApp->patternUnit()); + + { + // calculated value + const QString header = ui->tableWidget->horizontalHeaderItem(1)->text(); + const QString unitHeader = QString("%1 (%2)").arg(header).arg(unit); + ui->tableWidget->horizontalHeaderItem(1)->setText(unitHeader); + } + + { + // formula + const QString header = ui->tableWidget->horizontalHeaderItem(2)->text(); + const QString unitHeader = QString("%1 (%2)").arg(header).arg(unit); + ui->tableWidget->horizontalHeaderItem(2)->setText(unitHeader); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::AddCell(const QString &text, int row, int column, int aligment, bool ok) +{ + QTableWidgetItem *item = new QTableWidgetItem(text); + item->setTextAlignment(aligment); + + // set the item non-editable (view only), and non-selectable + Qt::ItemFlags flags = item->flags(); + flags &= ~(Qt::ItemIsEditable); // reset/clear the flag + item->setFlags(flags); + + if (not ok) + { + QBrush brush = item->foreground(); + brush.setColor(Qt::red); + item->setForeground(brush); + } + + ui->tableWidget->setItem(row, column, item); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool DialogFinalMeasurements::EvalUserFormula(const QString &formula, bool fromUser) +{ + const QString postfix = UnitsToStr(qApp->patternUnit());//Show unit in dialog lable (cm, mm or inch) + if (formula.isEmpty()) + { + ui->labelCalculatedValue->setText(tr("Error") + " (" + postfix + "). " + tr("Empty field.")); + ui->labelCalculatedValue->setToolTip(tr("Empty field")); + return false; + } + else + { + try + { + QString f; + // Replace line return character with spaces for calc if exist + if (fromUser) + { + f = qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator()); + } + else + { + f = formula; + } + f.replace("\n", " "); + QScopedPointer cal(new Calculator()); + const qreal result = cal->EvalFormula(m_data.DataVariables(), f); + + if (qIsInf(result) || qIsNaN(result)) + { + ui->labelCalculatedValue->setText(tr("Error") + " (" + postfix + ")."); + ui->labelCalculatedValue->setToolTip(tr("Invalid result. Value is infinite or NaN. Please, check your " + "calculations.")); + return false; + } + + ui->labelCalculatedValue->setText(qApp->LocaleToString(result) + " " + postfix); + ui->labelCalculatedValue->setToolTip(tr("Value")); + return true; + } + catch (qmu::QmuParserError &e) + { + ui->labelCalculatedValue->setText(tr("Error") + " (" + postfix + "). " + + tr("Parser error: %1").arg(e.GetMsg())); + ui->labelCalculatedValue->setToolTip(tr("Parser error: %1").arg(e.GetMsg())); + return false; + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::Controls() +{ + ui->toolButtonRemove->setEnabled(ui->tableWidget->rowCount() > 0); + + if (ui->tableWidget->rowCount() >= 2) + { + if (ui->tableWidget->currentRow() == 0) + { + ui->toolButtonUp->setEnabled(false); + ui->toolButtonDown->setEnabled(true); + } + else if (ui->tableWidget->currentRow() == ui->tableWidget->rowCount()-1) + { + ui->toolButtonUp->setEnabled(true); + ui->toolButtonDown->setEnabled(false); + } + else + { + ui->toolButtonUp->setEnabled(true); + ui->toolButtonDown->setEnabled(true); + } + } + else + { + ui->toolButtonUp->setEnabled(false); + ui->toolButtonDown->setEnabled(false); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::EnableDetails(bool enabled) +{ + if (enabled) + { + Controls(); + } + else + { + ui->toolButtonRemove->setEnabled(enabled); + ui->toolButtonUp->setEnabled(enabled); + ui->toolButtonDown->setEnabled(enabled); + } + + if (not enabled) + { // Clear + ui->lineEditName->blockSignals(true); + ui->lineEditName->clear(); + ui->lineEditName->blockSignals(false); + + ui->plainTextEditDescription->blockSignals(true); + ui->plainTextEditDescription->clear(); + ui->plainTextEditDescription->blockSignals(false); + + ui->labelCalculatedValue->blockSignals(true); + ui->labelCalculatedValue->clear(); + ui->labelCalculatedValue->blockSignals(false); + + ui->plainTextEditFormula->blockSignals(true); + ui->plainTextEditFormula->clear(); + ui->plainTextEditFormula->blockSignals(false); + } + + ui->pushButtonGrow->setEnabled(enabled); + ui->toolButtonExpr->setEnabled(enabled); + ui->lineEditName->setEnabled(enabled); + ui->plainTextEditDescription->setEnabled(enabled); + ui->plainTextEditFormula->setEnabled(enabled); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogFinalMeasurements::UpdateTree() +{ + int row = ui->tableWidget->currentRow(); + FillFinalMeasurements(); + ui->tableWidget->selectRow(row); + + m_search->RefreshList(ui->lineEditFind->text()); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal DialogFinalMeasurements::EvalFormula(const QString &formula, bool &ok) +{ + qreal result = 0; + if (formula.isEmpty()) + { + ok = false; + return result; + } + else + { + try + { + QString f = formula; + // Replace line return character with spaces for calc if exist + f.replace("\n", " "); + QScopedPointer cal(new Calculator()); + result = cal->EvalFormula(m_data.DataVariables(), f); + + if (qIsInf(result) || qIsNaN(result)) + { + ok = false; + return 0; + } + } + catch (qmu::QmuParserError &) + { + ok = false; + return 0; + } + } + + ok = true; + return result; +} diff --git a/src/app/valentina/dialogs/dialogfinalmeasurements.h b/src/app/valentina/dialogs/dialogfinalmeasurements.h new file mode 100644 index 000000000..a4aa725be --- /dev/null +++ b/src/app/valentina/dialogs/dialogfinalmeasurements.h @@ -0,0 +1,102 @@ +/************************************************************************ + ** + ** @file dialogfinalmeasurements.h + ** @author Roman Telezhynskyi + ** @date 26 9, 2017 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2017 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 DIALOGFINALMEASUREMENTS_H +#define DIALOGFINALMEASUREMENTS_H + +#include + +#include "../vmisc/vtablesearch.h" +#include "../vpatterndb/vcontainer.h" +#include "../xml/vpattern.h" + +namespace Ui +{ + class DialogFinalMeasurements; +} + +class DialogFinalMeasurements : public QDialog +{ + Q_OBJECT + +public: + DialogFinalMeasurements(VPattern *doc, QWidget *parent = nullptr); + virtual ~DialogFinalMeasurements(); + + QVector FinalMeasurements() const; + +protected: + virtual void closeEvent ( QCloseEvent * event ) Q_DECL_OVERRIDE; + virtual void changeEvent ( QEvent * event) Q_DECL_OVERRIDE; + virtual bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; + virtual void showEvent( QShowEvent *event ) Q_DECL_OVERRIDE; + virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; +private slots: + void ShowFinalMeasurementDetails(); + void Add(); + void Remove(); + void MoveUp(); + void MoveDown(); + void SaveName(const QString &text); + void SaveDescription(); + void SaveFormula(); + void DeployFormula(); + void Fx(); + void FullUpdateFromFile(); +private: + Q_DISABLE_COPY(DialogFinalMeasurements) + Ui::DialogFinalMeasurements *ui; + /** @brief doc dom document container */ + VPattern *m_doc; + VContainer m_data; + QVector m_measurements; + QSharedPointer m_search; + int formulaBaseHeight; + bool m_isInitialized; + + void FillFinalMeasurements(bool freshCall = false); + + void ShowUnits(); + + void AddCell(const QString &text, int row, int column, int aligment, bool ok = true); + bool EvalUserFormula(const QString &formula, bool fromUser); + void Controls(); + void EnableDetails(bool enabled); + + void UpdateTree(); + + qreal EvalFormula(const QString &formula, bool &ok); +}; + +//--------------------------------------------------------------------------------------------------------------------- +inline QVector DialogFinalMeasurements::FinalMeasurements() const +{ + return m_measurements; +} + +#endif // DIALOGFINALMEASUREMENTS_H diff --git a/src/app/valentina/dialogs/dialogfinalmeasurements.ui b/src/app/valentina/dialogs/dialogfinalmeasurements.ui new file mode 100644 index 000000000..074a08f00 --- /dev/null +++ b/src/app/valentina/dialogs/dialogfinalmeasurements.ui @@ -0,0 +1,469 @@ + + + DialogFinalMeasurements + + + + 0 + 0 + 717 + 518 + + + + Dialog + + + + + + 0 + + + + + Find: + + + + + + + Search + + + + + + + ... + + + + :/icons/win.icon.theme/16x16/actions/go-previous.png:/icons/win.icon.theme/16x16/actions/go-previous.png + + + + + + + ... + + + + :/icons/win.icon.theme/16x16/actions/go-next.png:/icons/win.icon.theme/16x16/actions/go-next.png + + + + + + + + + + 0 + 8 + + + + + 0 + 150 + + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + true + + + false + + + 120 + + + 70 + + + false + + + true + + + false + + + false + + + 25 + + + 8 + + + false + + + + Name + + + + + The calculated value + + + + + Formula + + + + + + + + + 0 + 4 + + + + + 0 + 236 + + + + Details + + + Details + + + + + + 6 + + + + + Qt::Horizontal + + + + 5000 + 20 + + + + + + + + + 0 + 0 + + + + ... + + + + .. + + + + + + + false + + + ... + + + + .. + + + + + + + + + Name: + + + + + + + false + + + + + + + Calculated value: + + + + + + + + + + + + + + Formula: + + + + + + + + + false + + + + 0 + 0 + + + + + 16777215 + 28 + + + + Calculation + + + true + + + + + + + false + + + + 18 + 18 + + + + + 0 + 0 + + + + Qt::StrongFocus + + + <html><head/><body><p>Show full calculation in message box</p></body></html> + + + + + + + ../../../libs/vtools/dialogs/support../../../libs/vtools/dialogs/support + + + + 16 + 16 + + + + false + + + true + + + + + + + false + + + + 24 + 24 + + + + Formula wizard + + + ... + + + + :/icon/24x24/fx.png:/icon/24x24/fx.png + + + + 24 + 24 + + + + + + + + + + Description: + + + + + + + false + + + + 0 + 1 + + + + + + + + + + false + + + Move measurement up + + + ... + + + + ../../tape../../tape + + + + + + + false + + + Move measurement down + + + ... + + + + ../../tape../../tape + + + + + + + Qt::Horizontal + + + + 5000 + 20 + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + + buttonBox + accepted() + DialogFinalMeasurements + accept() + + + 227 + 523 + + + 157 + 274 + + + + + buttonBox + rejected() + DialogFinalMeasurements + reject() + + + 295 + 529 + + + 286 + 274 + + + + + diff --git a/src/app/valentina/dialogs/dialogs.h b/src/app/valentina/dialogs/dialogs.h index 5ab889460..d91458e6c 100644 --- a/src/app/valentina/dialogs/dialogs.h +++ b/src/app/valentina/dialogs/dialogs.h @@ -35,5 +35,6 @@ #include "dialognewpattern.h" #include "dialogaboutapp.h" #include "dialogpreferences.h" +#include "dialogfinalmeasurements.h" #endif // DIALOGS_H diff --git a/src/app/valentina/dialogs/dialogs.pri b/src/app/valentina/dialogs/dialogs.pri index 7962f91dc..61c91e73c 100644 --- a/src/app/valentina/dialogs/dialogs.pri +++ b/src/app/valentina/dialogs/dialogs.pri @@ -19,7 +19,8 @@ HEADERS += \ $$PWD/configpages/preferencespathpage.h \ $$PWD/dialogdatetimeformats.h \ $$PWD/dialogknownmaterials.h \ - $$PWD/dialogpatternmaterials.h + $$PWD/dialogpatternmaterials.h \ + $$PWD/dialogfinalmeasurements.h SOURCES += \ $$PWD/dialogincrements.cpp \ @@ -38,7 +39,8 @@ SOURCES += \ $$PWD/configpages/preferencespathpage.cpp \ $$PWD/dialogdatetimeformats.cpp \ $$PWD/dialogknownmaterials.cpp \ - $$PWD/dialogpatternmaterials.cpp + $$PWD/dialogpatternmaterials.cpp \ + $$PWD/dialogfinalmeasurements.cpp FORMS += \ $$PWD/dialogincrements.ui \ @@ -57,4 +59,5 @@ FORMS += \ $$PWD/configpages/preferencespathpage.ui \ $$PWD/dialogdatetimeformats.ui \ $$PWD/dialogknownmaterials.ui \ - $$PWD/dialogpatternmaterials.ui + $$PWD/dialogpatternmaterials.ui \ + $$PWD/dialogfinalmeasurements.ui diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 2f86f60e9..c1d1567e8 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -117,7 +117,9 @@ MainWindow::MainWindow(QWidget *parent) patternReadOnly(false), dialogTable(nullptr), dialogTool(), - dialogHistory(nullptr), comboBoxDraws(nullptr), patternPieceLabel(nullptr), mode(Draw::Calculation), + dialogHistory(nullptr), + dialogFMeasurements(nullptr), + comboBoxDraws(nullptr), patternPieceLabel(nullptr), mode(Draw::Calculation), currentDrawIndex(0), currentToolBoxIndex(0), isDockToolOptionsVisible(true), isDockGroupsVisible(true), @@ -2833,6 +2835,8 @@ void MainWindow::Clear() ui->actionZoomOriginal->setEnabled(false); ui->actionHistory->setEnabled(false); ui->actionTable->setEnabled(false); + ui->actionExportIncrementsToCSV->setEnabled(false); + ui->actionFinalMeasurements->setEnabled(false); ui->actionLast_tool->setEnabled(false); ui->actionShowCurveDetails->setEnabled(false); ui->actionLoadIndividual->setEnabled(false); @@ -3078,6 +3082,8 @@ void MainWindow::SetEnableWidgets(bool enable) ui->actionDetails->setEnabled(enable); ui->actionLayout->setEnabled(enable); ui->actionTable->setEnabled(enable && drawStage); + ui->actionExportIncrementsToCSV->setEnabled(enable); + ui->actionFinalMeasurements->setEnabled(enable); ui->actionZoomFitBest->setEnabled(enable); ui->actionZoomFitBestCurrent->setEnabled(enable && drawStage); ui->actionZoomOriginal->setEnabled(enable); @@ -3993,6 +3999,27 @@ void MainWindow::CreateActions() } }); + connect(ui->actionFinalMeasurements, &QAction::triggered, this, [this]() + { + if (dialogFMeasurements.isNull()) + { + dialogFMeasurements = new DialogFinalMeasurements(doc, this); + connect(dialogFMeasurements.data(), &DialogFinalMeasurements::finished, this, [this](int result) + { + if (result == QDialog::Accepted) + { + doc->SetFinalMeasurements(dialogFMeasurements->FinalMeasurements()); + } + delete dialogFMeasurements; + }); + dialogFMeasurements->show(); + } + else + { + dialogFMeasurements->activateWindow(); + } + }); + connect(ui->actionAbout_Qt, &QAction::triggered, this, [this]() { QMessageBox::aboutQt(this, tr("About Qt")); diff --git a/src/app/valentina/mainwindow.h b/src/app/valentina/mainwindow.h index 47a5d651c..38a6bfeeb 100644 --- a/src/app/valentina/mainwindow.h +++ b/src/app/valentina/mainwindow.h @@ -47,6 +47,7 @@ class QLabel; class DialogIncrements; class DialogTool; class DialogHistory; +class DialogFinalMeasurements; class VWidgetGroups; class VWidgetDetails; class QToolButton; @@ -226,9 +227,10 @@ private: bool patternReadOnly; - QPointer dialogTable; - QSharedPointer dialogTool; - QPointer dialogHistory; + QPointer dialogTable; + QSharedPointer dialogTool; + QPointer dialogHistory; + QPointer dialogFMeasurements; /** @brief comboBoxDraws comboc who show name of pattern peaces. */ QComboBox *comboBoxDraws; diff --git a/src/app/valentina/mainwindow.ui b/src/app/valentina/mainwindow.ui index 64be47238..dad8e7a57 100644 --- a/src/app/valentina/mainwindow.ui +++ b/src/app/valentina/mainwindow.ui @@ -1699,12 +1699,16 @@ + + + + @@ -2649,6 +2653,9 @@ + + false + Export increments to CSV @@ -2657,6 +2664,9 @@ + + false + Zoom fit best current @@ -2675,6 +2685,14 @@ Label template editor + + + false + + + Final measurements + + @@ -2685,8 +2703,8 @@ - + diff --git a/src/libs/vmisc/vcommonsettings.cpp b/src/libs/vmisc/vcommonsettings.cpp index 063423140..b7a97d3d9 100644 --- a/src/libs/vmisc/vcommonsettings.cpp +++ b/src/libs/vmisc/vcommonsettings.cpp @@ -78,6 +78,7 @@ const QString settingPreferenceDialogSize = QStringLiteral("preferenceDia const QString settingToolSeamAllowanceDialogSize = QStringLiteral("toolSeamAllowanceDialogSize"); const QString settingIncrementsDialogSize = QStringLiteral("toolIncrementsDialogSize"); const QString settingFormulaWizardDialogSize = QStringLiteral("formulaWizardDialogSize"); +const QString settingFinalMeasurementsDialogSize = QStringLiteral("finalMeasurementsDialogSize"); const QString settingLatestSkippedVersion = QStringLiteral("lastestSkippedVersion"); const QString settingDateOfLastRemind = QStringLiteral("dateOfLastRemind"); @@ -616,6 +617,18 @@ void VCommonSettings::SetIncrementsDialogSize(const QSize &sz) setValue(settingIncrementsDialogSize, sz); } +//--------------------------------------------------------------------------------------------------------------------- +QSize VCommonSettings::GetFinalMeasurementsDialogSize() const +{ + return value(settingFinalMeasurementsDialogSize, QSize(0, 0)).toSize(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VCommonSettings::SetFinalMeasurementsDialogSize(const QSize &sz) +{ + setValue(settingFinalMeasurementsDialogSize, sz); +} + //--------------------------------------------------------------------------------------------------------------------- int VCommonSettings::GetLatestSkippedVersion() const { diff --git a/src/libs/vmisc/vcommonsettings.h b/src/libs/vmisc/vcommonsettings.h index 2232d0ec5..231c44527 100644 --- a/src/libs/vmisc/vcommonsettings.h +++ b/src/libs/vmisc/vcommonsettings.h @@ -129,6 +129,9 @@ public: QSize GetIncrementsDialogSize() const; void SetIncrementsDialogSize(const QSize& sz); + QSize GetFinalMeasurementsDialogSize() const; + void SetFinalMeasurementsDialogSize(const QSize& sz); + int GetLatestSkippedVersion() const; void SetLatestSkippedVersion(int value); diff --git a/src/libs/vpatterndb/vtranslatevars.cpp b/src/libs/vpatterndb/vtranslatevars.cpp index 95aed8c2c..5224b5a5f 100644 --- a/src/libs/vpatterndb/vtranslatevars.cpp +++ b/src/libs/vpatterndb/vtranslatevars.cpp @@ -1069,6 +1069,20 @@ QString VTranslateVars::FormulaToUser(const QString &formula, bool osSeparator) return newFormula; } +//--------------------------------------------------------------------------------------------------------------------- +QString VTranslateVars::TryFormulaToUser(const QString &formula, bool osSeparator) +{ + try + { + return qApp->TrVars()->FormulaToUser(formula, osSeparator); + } + catch (qmu::QmuParserError &e)// In case something bad will happen + { + Q_UNUSED(e) + return formula; + } +} + //--------------------------------------------------------------------------------------------------------------------- void VTranslateVars::Retranslate() { diff --git a/src/libs/vpatterndb/vtranslatevars.h b/src/libs/vpatterndb/vtranslatevars.h index 0596c0f58..22a0034bc 100644 --- a/src/libs/vpatterndb/vtranslatevars.h +++ b/src/libs/vpatterndb/vtranslatevars.h @@ -62,7 +62,9 @@ public: QString FormulaFromUser(const QString &formula, bool osSeparator) const; static QString TryFormulaFromUser(const QString &formula, bool osSeparator); + QString FormulaToUser(const QString &formula, bool osSeparator) const; + static QString TryFormulaToUser(const QString &formula, bool osSeparator); virtual void Retranslate() Q_DECL_OVERRIDE; From 661e71bad040a5fe946ed0d36e15b6bbd5249277 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 26 Sep 2017 17:46:28 +0300 Subject: [PATCH 03/12] Refactoring use static methods VTranslateVars::TryFormula*User(). --HG-- branch : feature --- src/app/tape/tmainwindow.cpp | 22 +------ .../valentina/dialogs/dialogincrements.cpp | 22 +------ src/app/valentina/mainwindow.cpp | 12 +--- .../vtools/dialogs/tools/dialogsplinepath.cpp | 60 ++++--------------- src/test/ValentinaTest/tst_vtranslatevars.cpp | 22 +------ 5 files changed, 19 insertions(+), 119 deletions(-) diff --git a/src/app/tape/tmainwindow.cpp b/src/app/tape/tmainwindow.cpp index 42c506f80..71db1cfde 100644 --- a/src/app/tape/tmainwindow.cpp +++ b/src/app/tape/tmainwindow.cpp @@ -1506,16 +1506,7 @@ void TMainWindow::ShowNewMData(bool fresh) ui->plainTextEditFormula->blockSignals(true); - QString formula; - try - { - formula = qApp->TrVars()->FormulaToUser(meash->GetFormula(), qApp->Settings()->GetOsSeparator()); - } - catch (qmu::QmuParserError &e) - { - Q_UNUSED(e) - formula = meash->GetFormula(); - } + QString formula = VTranslateVars::TryFormulaToUser(meash->GetFormula(), qApp->Settings()->GetOsSeparator()); ui->plainTextEditFormula->setPlainText(formula); ui->plainTextEditFormula->blockSignals(false); @@ -2416,16 +2407,7 @@ void TMainWindow::RefreshTable(bool freshCall) AddCell(locale().toString(value), currentRow, ColumnCalcValue, Qt::AlignHCenter | Qt::AlignVCenter, meash->IsFormulaOk()); // calculated value - QString formula; - try - { - formula = qApp->TrVars()->FormulaToUser(meash->GetFormula(), qApp->Settings()->GetOsSeparator()); - } - catch (qmu::QmuParserError &e) - { - Q_UNUSED(e) - formula = meash->GetFormula(); - } + QString formula = VTranslateVars::TryFormulaToUser(meash->GetFormula(), qApp->Settings()->GetOsSeparator()); AddCell(formula, currentRow, ColumnFormula, Qt::AlignVCenter); // formula } diff --git a/src/app/valentina/dialogs/dialogincrements.cpp b/src/app/valentina/dialogs/dialogincrements.cpp index b1b6abd71..63f5adea9 100644 --- a/src/app/valentina/dialogs/dialogincrements.cpp +++ b/src/app/valentina/dialogs/dialogincrements.cpp @@ -713,16 +713,7 @@ void DialogIncrements::FillIncrementsTable(QTableWidget *table, AddCell(table, qApp->LocaleToString(*incr->GetValue()), currentRow, 1, Qt::AlignHCenter | Qt::AlignVCenter, incr->IsFormulaOk()); // calculated value - QString formula; - try - { - formula = qApp->TrVars()->FormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator()); - } - catch (qmu::QmuParserError &e) - { - Q_UNUSED(e) - formula = incr->GetFormula(); - } + QString formula = VTranslateVars::TryFormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator()); AddCell(table, formula, currentRow, 2, Qt::AlignVCenter); // formula } @@ -1394,16 +1385,7 @@ void DialogIncrements::ShowIncrementDetails() EvalIncrementFormula(incr->GetFormula(), false, incr->GetData(), labelCalculatedValue); plainTextEditFormula->blockSignals(true); - QString formula; - try - { - formula = qApp->TrVars()->FormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator()); - } - catch (qmu::QmuParserError &e) - { - Q_UNUSED(e) - formula = incr->GetFormula(); - } + QString formula = VTranslateVars::TryFormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator()); plainTextEditFormula->setPlainText(formula); plainTextEditFormula->blockSignals(false); diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index c1d1567e8..691d4f427 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -1520,17 +1520,7 @@ void MainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCS csv.setText(currentRow, 0, incr->GetName()); // name csv.setText(currentRow, 1, qApp->LocaleToString(*incr->GetValue())); // calculated value - QString formula; - try - { - formula = qApp->TrVars()->FormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator()); - } - catch (qmu::QmuParserError &e) - { - Q_UNUSED(e) - formula = incr->GetFormula(); - } - + QString formula = VTranslateVars::TryFormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator()); csv.setText(currentRow, 2, formula); // formula } diff --git a/src/libs/vtools/dialogs/tools/dialogsplinepath.cpp b/src/libs/vtools/dialogs/tools/dialogsplinepath.cpp index 3cbff396e..420768836 100644 --- a/src/libs/vtools/dialogs/tools/dialogsplinepath.cpp +++ b/src/libs/vtools/dialogs/tools/dialogsplinepath.cpp @@ -326,16 +326,7 @@ void DialogSplinePath::Angle1Changed() const QString angle1F = ui->plainTextEditAngle1F->toPlainText().replace("\n", " "); const qreal angle1 = Visualization::FindVal(angle1F, data->DataVariables()); - - try - { - p.SetAngle1(angle1, qApp->TrVars()->FormulaFromUser(angle1F, qApp->Settings()->GetOsSeparator())); - } - catch (qmu::QmuParserError &e) - { - Q_UNUSED(e) - p.SetAngle1(angle1, angle1F); - } + p.SetAngle1(angle1, VTranslateVars::TryFormulaFromUser(angle1F, qApp->Settings()->GetOsSeparator())); item->setData(Qt::UserRole, QVariant::fromValue(p)); @@ -369,16 +360,7 @@ void DialogSplinePath::Angle2Changed() const QString angle2F = ui->plainTextEditAngle2F->toPlainText().replace("\n", " "); const qreal angle2 = Visualization::FindVal(angle2F, data->DataVariables()); - - try - { - p.SetAngle2(angle2, qApp->TrVars()->FormulaFromUser(angle2F, qApp->Settings()->GetOsSeparator())); - } - catch (qmu::QmuParserError &e) - { - Q_UNUSED(e) - p.SetAngle2(angle2, angle2F); - } + p.SetAngle2(angle2, VTranslateVars::TryFormulaFromUser(angle2F, qApp->Settings()->GetOsSeparator())); item->setData(Qt::UserRole, QVariant::fromValue(p)); @@ -412,16 +394,7 @@ void DialogSplinePath::Length1Changed() const QString length1F = ui->plainTextEditLength1F->toPlainText().replace("\n", " "); const qreal length1 = Visualization::FindLength(length1F, data->DataVariables()); - - try - { - p.SetLength1(length1, qApp->TrVars()->FormulaFromUser(length1F, qApp->Settings()->GetOsSeparator())); - } - catch (qmu::QmuParserError &e) - { - Q_UNUSED(e) - p.SetLength1(length1, length1F); - } + p.SetLength1(length1, VTranslateVars::TryFormulaFromUser(length1F, qApp->Settings()->GetOsSeparator())); item->setData(Qt::UserRole, QVariant::fromValue(p)); @@ -446,16 +419,7 @@ void DialogSplinePath::Length2Changed() const QString length2F = ui->plainTextEditLength2F->toPlainText().replace("\n", " "); const qreal length2 = Visualization::FindLength(length2F, data->DataVariables()); - - try - { - p.SetLength2(length2, qApp->TrVars()->FormulaFromUser(length2F, qApp->Settings()->GetOsSeparator())); - } - catch (qmu::QmuParserError &e) - { - Q_UNUSED(e) - p.SetLength2(length2, length2F); - } + p.SetLength2(length2, VTranslateVars::TryFormulaFromUser(length2F, qApp->Settings()->GetOsSeparator())); item->setData(Qt::UserRole, QVariant::fromValue(p)); @@ -469,14 +433,14 @@ void DialogSplinePath::FXAngle1() auto dialog = new DialogEditWrongFormula(data, toolId, this); dialog->setWindowTitle(tr("Edit first control point angle")); - QString angle1F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditAngle1F->toPlainText().replace("\n", " "), + QString angle1F = VTranslateVars::TryFormulaFromUser(ui->plainTextEditAngle1F->toPlainText().replace("\n", " "), qApp->Settings()->GetOsSeparator()); dialog->SetFormula(angle1F); dialog->setPostfix(degreeSymbol); if (dialog->exec() == QDialog::Accepted) { - angle1F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator()); + angle1F = VTranslateVars::TryFormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator()); // increase height if needed. if (angle1F.length() > 80) { @@ -494,14 +458,14 @@ void DialogSplinePath::FXAngle2() auto dialog = new DialogEditWrongFormula(data, toolId, this); dialog->setWindowTitle(tr("Edit second control point angle")); - QString angle2F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditAngle2F->toPlainText().replace("\n", " "), + QString angle2F = VTranslateVars::TryFormulaFromUser(ui->plainTextEditAngle2F->toPlainText().replace("\n", " "), qApp->Settings()->GetOsSeparator()); dialog->SetFormula(angle2F); dialog->setPostfix(degreeSymbol); if (dialog->exec() == QDialog::Accepted) { - angle2F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator()); + angle2F = VTranslateVars::TryFormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator()); // increase height if needed. if (angle2F.length() > 80) { @@ -519,14 +483,14 @@ void DialogSplinePath::FXLength1() auto dialog = new DialogEditWrongFormula(data, toolId, this); dialog->setWindowTitle(tr("Edit first control point length")); - QString length1F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditLength1F->toPlainText().replace("\n", " "), + QString length1F = VTranslateVars::TryFormulaFromUser(ui->plainTextEditLength1F->toPlainText().replace("\n", " "), qApp->Settings()->GetOsSeparator()); dialog->SetFormula(length1F); dialog->setPostfix(UnitsToStr(qApp->patternUnit(), true)); if (dialog->exec() == QDialog::Accepted) { - length1F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator()); + length1F = VTranslateVars::TryFormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator()); // increase height if needed. if (length1F.length() > 80) { @@ -544,14 +508,14 @@ void DialogSplinePath::FXLength2() auto dialog = new DialogEditWrongFormula(data, toolId, this); dialog->setWindowTitle(tr("Edit second control point length")); - QString length2F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditLength2F->toPlainText().replace("\n", " "), + QString length2F = VTranslateVars::TryFormulaFromUser(ui->plainTextEditLength2F->toPlainText().replace("\n", " "), qApp->Settings()->GetOsSeparator()); dialog->SetFormula(length2F); dialog->setPostfix(UnitsToStr(qApp->patternUnit(), true)); if (dialog->exec() == QDialog::Accepted) { - length2F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator()); + length2F = VTranslateVars::TryFormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator()); // increase height if needed. if (length2F.length() > 80) { diff --git a/src/test/ValentinaTest/tst_vtranslatevars.cpp b/src/test/ValentinaTest/tst_vtranslatevars.cpp index d02c6950b..4dc35b3fd 100644 --- a/src/test/ValentinaTest/tst_vtranslatevars.cpp +++ b/src/test/ValentinaTest/tst_vtranslatevars.cpp @@ -72,16 +72,7 @@ void TST_VTranslateVars::TestFormulaFromUser() QLocale::setDefault(locale); - QString result; - try - { - result = m_trMs->FormulaFromUser(input, true); - } - catch (qmu::QmuParserError &e)// In case something bad will happen - { - Q_UNUSED(e) - result = input; - } + const QString result = VTranslateVars::TryFormulaFromUser(input, true); QCOMPARE(result, output); } @@ -111,16 +102,7 @@ void TST_VTranslateVars::TestFormulaToUser() QLocale::setDefault(locale); - QString result; - try - { - result = m_trMs->FormulaToUser(input, true); - } - catch (qmu::QmuParserError &e)// In case something bad will happen - { - Q_UNUSED(e) - result = input; - } + const QString result = VTranslateVars::TryFormulaToUser(input, true); QCOMPARE(result, output); } From 4caab9a479bb1beaafb214d601a435a060733f0f Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Wed, 27 Sep 2017 11:53:17 +0300 Subject: [PATCH 04/12] Fix export increments and preview calculations. Separate both types. First write increments then preview calculations. --HG-- branch : feature --- src/app/valentina/mainwindow.cpp | 50 ++++++++++++-------- src/libs/vpatterndb/variables/vincrement.cpp | 3 +- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 691d4f427..6ba2aff97 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -1499,30 +1499,42 @@ void MainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCS } const QMap > increments = pattern->DataIncrements(); - QMap >::const_iterator i; - QMap map; - //Sorting QHash by id - for (i = increments.constBegin(); i != increments.constEnd(); ++i) - { - QSharedPointer incr = i.value(); - map.insert(incr->getIndex(), i.key()); - } qint32 currentRow = -1; - QMapIterator iMap(map); - while (iMap.hasNext()) + + auto SavePreviewCalculation = [¤tRow, &csv, increments](bool save) { - iMap.next(); - QSharedPointer incr = increments.value(iMap.value()); - currentRow++; + QMap >::const_iterator i; + QMap map; + //Sorting QHash by id + for (i = increments.constBegin(); i != increments.constEnd(); ++i) + { + const QSharedPointer incr = i.value(); + if (incr->IsPreviewCalculation() == save) + { + map.insert(incr->getIndex(), i.key()); + } + } - csv.insertRow(currentRow); - csv.setText(currentRow, 0, incr->GetName()); // name - csv.setText(currentRow, 1, qApp->LocaleToString(*incr->GetValue())); // calculated value + QMapIterator iMap(map); + while (iMap.hasNext()) + { + iMap.next(); + QSharedPointer incr = increments.value(iMap.value()); + currentRow++; - QString formula = VTranslateVars::TryFormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator()); - csv.setText(currentRow, 2, formula); // formula - } + csv.insertRow(currentRow); + csv.setText(currentRow, 0, incr->GetName()); // name + csv.setText(currentRow, 1, qApp->LocaleToString(*incr->GetValue())); // calculated value + + QString formula = VTranslateVars::TryFormulaToUser(incr->GetFormula(), + qApp->Settings()->GetOsSeparator()); + csv.setText(currentRow, 2, formula); // formula + } + }; + + SavePreviewCalculation(false); + SavePreviewCalculation(true); csv.toCSV(fileName, dialog.WithHeader(), dialog.Separator(), QTextCodec::codecForMib(dialog.SelectedMib())); } diff --git a/src/libs/vpatterndb/variables/vincrement.cpp b/src/libs/vpatterndb/variables/vincrement.cpp index 211a21763..eb1a4981d 100644 --- a/src/libs/vpatterndb/variables/vincrement.cpp +++ b/src/libs/vpatterndb/variables/vincrement.cpp @@ -80,7 +80,8 @@ VIncrement::~VIncrement() //--------------------------------------------------------------------------------------------------------------------- /** - * @brief getIndex return index of row + * @brief getIndex return index of row. Row index for increments and preview calucalations is unique. Check type before + * using. * @return index */ quint32 VIncrement::getIndex() const From 257fb2f913b581668d900af39d87a0e426e05c5f Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Wed, 27 Sep 2017 13:25:18 +0300 Subject: [PATCH 05/12] Refactor export to CSV. Preparation for export final measurements. --HG-- branch : feature --- src/app/tape/tmainwindow.cpp | 9 ++-- src/app/tape/tmainwindow.h | 3 +- src/app/valentina/mainwindow.cpp | 9 ++-- src/app/valentina/mainwindow.h | 3 +- src/libs/vmisc/dialogs/dialogexporttocsv.cpp | 43 ++++++++++++++++---- src/libs/vmisc/dialogs/dialogexporttocsv.h | 18 ++++---- src/libs/vmisc/vcommonsettings.cpp | 6 +-- src/libs/vmisc/vcommonsettings.h | 6 +-- src/libs/vwidgets/vabstractmainwindow.cpp | 41 +++++++++++++------ src/libs/vwidgets/vabstractmainwindow.h | 6 ++- 10 files changed, 96 insertions(+), 48 deletions(-) diff --git a/src/app/tape/tmainwindow.cpp b/src/app/tape/tmainwindow.cpp index 71db1cfde..914b4b848 100644 --- a/src/app/tape/tmainwindow.cpp +++ b/src/app/tape/tmainwindow.cpp @@ -32,7 +32,6 @@ #include "dialogs/dialognewmeasurements.h" #include "dialogs/dialogmdatabase.h" #include "dialogs/dialogtapepreferences.h" -#include "dialogs/dialogexporttocsv.h" #include "../vpatterndb/calculator.h" #include "../vpatterndb/pmsystems.h" #include "../ifc/ifcdef.h" @@ -663,7 +662,7 @@ bool TMainWindow::eventFilter(QObject *object, QEvent *event) } //--------------------------------------------------------------------------------------------------------------------- -void TMainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCSV &dialog) +void TMainWindow::ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator) { QxtCsvModel csv; const int columns = ui->tableWidget->columnCount(); @@ -678,7 +677,7 @@ void TMainWindow::ExportToCSVData(const QString &fileName, const DialogExportToC } } - if (dialog.WithHeader()) + if (withHeader) { int colCount = 0; for (int column = 0; column < columns; ++column) @@ -708,7 +707,7 @@ void TMainWindow::ExportToCSVData(const QString &fileName, const DialogExportToC } } - csv.toCSV(fileName, dialog.WithHeader(), dialog.Separator(), QTextCodec::codecForMib(dialog.SelectedMib())); + csv.toCSV(fileName, withHeader, separator, QTextCodec::codecForMib(mib)); } //--------------------------------------------------------------------------------------------------------------------- @@ -1886,7 +1885,7 @@ void TMainWindow::SetupMenu() connect(ui->actionSaveAs, &QAction::triggered, this, &TMainWindow::FileSaveAs); ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs); - connect(ui->actionExportToCSV, &QAction::triggered, this, &TMainWindow::ExportToCSV); + connect(ui->actionExportToCSV, &QAction::triggered, this, &TMainWindow::ExportDataToCSV); connect(ui->actionReadOnly, &QAction::triggered, this, [this](bool ro) { if (not mIsReadOnly) diff --git a/src/app/tape/tmainwindow.h b/src/app/tape/tmainwindow.h index 9a3163b88..f602d260b 100644 --- a/src/app/tape/tmainwindow.h +++ b/src/app/tape/tmainwindow.h @@ -70,7 +70,8 @@ protected: virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE; virtual void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; virtual bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; - virtual void ExportToCSVData(const QString &fileName, const DialogExportToCSV &dialog) Q_DECL_FINAL; + virtual void ExportToCSVData(const QString &fileName, bool withHeader, int mib, + const QChar &separator) Q_DECL_FINAL; private slots: void FileNew(); diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 6ba2aff97..8d66bf784 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -40,7 +40,6 @@ #include "../vmisc/vsettings.h" #include "../vmisc/def.h" #include "../vmisc/qxtcsvmodel.h" -#include "../vmisc/dialogs/dialogexporttocsv.h" #include "undocommands/renamepp.h" #include "core/vtooloptionspropertybrowser.h" #include "options.h" @@ -1483,7 +1482,7 @@ void MainWindow::PrepareSceneList() } //--------------------------------------------------------------------------------------------------------------------- -void MainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCSV &dialog) +void MainWindow::ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator) { QxtCsvModel csv; @@ -1491,7 +1490,7 @@ void MainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCS csv.insertColumn(1); csv.insertColumn(2); - if (dialog.WithHeader()) + if (withHeader) { csv.setHeaderText(0, tr("Name")); csv.setHeaderText(1, tr("The calculated value")); @@ -1536,7 +1535,7 @@ void MainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCS SavePreviewCalculation(false); SavePreviewCalculation(true); - csv.toCSV(fileName, dialog.WithHeader(), dialog.Separator(), QTextCodec::codecForMib(dialog.SelectedMib())); + csv.toCSV(fileName, withHeader, separator, QTextCodec::codecForMib(mib)); } //--------------------------------------------------------------------------------------------------------------------- @@ -3978,7 +3977,7 @@ void MainWindow::CreateActions() connect(ui->actionSave, &QAction::triggered, this, &MainWindow::Save); connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::Open); connect(ui->actionNew, &QAction::triggered, this, &MainWindow::New); - connect(ui->actionExportIncrementsToCSV, &QAction::triggered, this, &MainWindow::ExportToCSV); + connect(ui->actionExportIncrementsToCSV, &QAction::triggered, this, &MainWindow::ExportDataToCSV); connect(ui->actionTable, &QAction::triggered, this, [this](bool checked) { diff --git a/src/app/valentina/mainwindow.h b/src/app/valentina/mainwindow.h index 38a6bfeeb..627820e6e 100644 --- a/src/app/valentina/mainwindow.h +++ b/src/app/valentina/mainwindow.h @@ -103,7 +103,8 @@ protected: virtual void customEvent(QEvent * event) Q_DECL_OVERRIDE; virtual void CleanLayout() Q_DECL_OVERRIDE; virtual void PrepareSceneList() Q_DECL_OVERRIDE; - virtual void ExportToCSVData(const QString &fileName, const DialogExportToCSV &dialog) Q_DECL_FINAL; + virtual void ExportToCSVData(const QString &fileName, bool withHeader, int mib, + const QChar &separator) Q_DECL_FINAL; private slots: void MouseMove(const QPointF &scenePos); void Clear(); diff --git a/src/libs/vmisc/dialogs/dialogexporttocsv.cpp b/src/libs/vmisc/dialogs/dialogexporttocsv.cpp index 4e3dae8de..8584d305c 100644 --- a/src/libs/vmisc/dialogs/dialogexporttocsv.cpp +++ b/src/libs/vmisc/dialogs/dialogexporttocsv.cpp @@ -44,23 +44,21 @@ DialogExportToCSV::DialogExportToCSV(QWidget *parent) { ui->setupUi(this); - ui->checkBoxWithHeader->setChecked(qApp->Settings()->GetCSVWithHeader()); - foreach (int mib, QTextCodec::availableMibs()) { ui->comboBoxCodec->addItem(QTextCodec::codecForMib(mib)->name(), mib); } - ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(qApp->Settings()->GetCSVCodec())); + ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(VCommonSettings::GetDefCSVCodec())); - SetSeparator(qApp->Settings()->GetCSVSeparator()); + SetSeparator(qApp->Settings()->GetDefCSVSeparator()); QPushButton *bDefaults = ui->buttonBox->button(QDialogButtonBox::RestoreDefaults); SCASSERT(bDefaults != nullptr) connect(bDefaults, &QPushButton::clicked, this, [this]() { ui->checkBoxWithHeader->setChecked(qApp->Settings()->GetDefCSVWithHeader()); - ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(qApp->Settings()->GetDefCSVCodec())); + ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(VCommonSettings::GetDefCSVCodec())); SetSeparator(qApp->Settings()->GetDefCSVSeparator()); }); @@ -73,19 +71,46 @@ DialogExportToCSV::~DialogExportToCSV() } //--------------------------------------------------------------------------------------------------------------------- -bool DialogExportToCSV::WithHeader() const +bool DialogExportToCSV::IsWithHeader() const { return ui->checkBoxWithHeader->isChecked(); } //--------------------------------------------------------------------------------------------------------------------- -int DialogExportToCSV::SelectedMib() const +void DialogExportToCSV::SetWithHeader(bool value) { - return ui->comboBoxCodec->currentData().toInt(); + ui->checkBoxWithHeader->setChecked(value); } //--------------------------------------------------------------------------------------------------------------------- -QChar DialogExportToCSV::Separator() const +int DialogExportToCSV::GetSelectedMib() const +{ + if (ui->comboBoxCodec->currentIndex() != -1) + { + return ui->comboBoxCodec->currentData().toInt(); + } + else + { + return VCommonSettings::GetDefCSVCodec(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogExportToCSV::SetSelectedMib(int value) +{ + const int index = ui->comboBoxCodec->findData(value); + if (index != -1) + { + ui->comboBoxCodec->setCurrentIndex(index); + } + else + { + ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(VCommonSettings::GetDefCSVCodec())); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QChar DialogExportToCSV::GetSeparator() const { if (ui->radioButtonTab->isChecked()) { diff --git a/src/libs/vmisc/dialogs/dialogexporttocsv.h b/src/libs/vmisc/dialogs/dialogexporttocsv.h index 5c684d934..d1782aa26 100644 --- a/src/libs/vmisc/dialogs/dialogexporttocsv.h +++ b/src/libs/vmisc/dialogs/dialogexporttocsv.h @@ -31,8 +31,9 @@ #include -namespace Ui { -class DialogExportToCSV; +namespace Ui +{ + class DialogExportToCSV; } class DialogExportToCSV : public QDialog @@ -43,9 +44,14 @@ public: explicit DialogExportToCSV(QWidget *parent = nullptr); virtual ~DialogExportToCSV(); - bool WithHeader() const; - int SelectedMib() const; - QChar Separator() const; + bool IsWithHeader() const; + void SetWithHeader(bool value); + + int GetSelectedMib() const; + void SetSelectedMib(int value); + + QChar GetSeparator() const; + void SetSeparator(const QChar &separator); protected: virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE; @@ -55,8 +61,6 @@ private: Q_DISABLE_COPY(DialogExportToCSV) Ui::DialogExportToCSV *ui; bool isInitialized; - - void SetSeparator(const QChar &separator); }; #endif // DIALOGEXPORTTOCSV_H diff --git a/src/libs/vmisc/vcommonsettings.cpp b/src/libs/vmisc/vcommonsettings.cpp index b7a97d3d9..cc3a410ba 100644 --- a/src/libs/vmisc/vcommonsettings.cpp +++ b/src/libs/vmisc/vcommonsettings.cpp @@ -710,7 +710,7 @@ bool VCommonSettings::GetCSVWithHeader() const } //--------------------------------------------------------------------------------------------------------------------- -bool VCommonSettings::GetDefCSVWithHeader() const +bool VCommonSettings::GetDefCSVWithHeader() { return false; } @@ -730,7 +730,7 @@ int VCommonSettings::GetCSVCodec() const } //--------------------------------------------------------------------------------------------------------------------- -int VCommonSettings::GetDefCSVCodec() const +int VCommonSettings::GetDefCSVCodec() { return QTextCodec::codecForLocale()->mibEnum(); } @@ -775,7 +775,7 @@ QChar VCommonSettings::GetCSVSeparator() const } //--------------------------------------------------------------------------------------------------------------------- -QChar VCommonSettings::GetDefCSVSeparator() const +QChar VCommonSettings::GetDefCSVSeparator() { return QChar(','); } diff --git a/src/libs/vmisc/vcommonsettings.h b/src/libs/vmisc/vcommonsettings.h index 231c44527..4460dbb53 100644 --- a/src/libs/vmisc/vcommonsettings.h +++ b/src/libs/vmisc/vcommonsettings.h @@ -149,15 +149,15 @@ public: void SetCSVWithHeader(bool withHeader); bool GetCSVWithHeader() const; - bool GetDefCSVWithHeader() const; + static bool GetDefCSVWithHeader(); void SetCSVCodec(int mib); int GetCSVCodec() const; - int GetDefCSVCodec() const; + static int GetDefCSVCodec(); void SetCSVSeparator(const QChar &separator); QChar GetCSVSeparator() const; - QChar GetDefCSVSeparator() const; + static QChar GetDefCSVSeparator(); void SetDefaultSeamAllowance(double value); double GetDefaultSeamAllowance(); diff --git a/src/libs/vwidgets/vabstractmainwindow.cpp b/src/libs/vwidgets/vabstractmainwindow.cpp index 6454ae80a..58dfec4b7 100644 --- a/src/libs/vwidgets/vabstractmainwindow.cpp +++ b/src/libs/vwidgets/vabstractmainwindow.cpp @@ -87,13 +87,7 @@ void VAbstractMainWindow::ToolBarStyle(QToolBar *bar) } //--------------------------------------------------------------------------------------------------------------------- -void VAbstractMainWindow::WindowsLocale() -{ - qApp->Settings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c()); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VAbstractMainWindow::ExportToCSV() +QString VAbstractMainWindow::CSVFilePath() { const QString filters = tr("Comma-Separated Values") + QLatin1String(" (*.csv)"); const QString suffix("csv"); @@ -104,7 +98,7 @@ void VAbstractMainWindow::ExportToCSV() if (fileName.isEmpty()) { - return; + return fileName; } QFileInfo f( fileName ); @@ -113,13 +107,36 @@ void VAbstractMainWindow::ExportToCSV() fileName += QLatin1String(".") + suffix; } + return fileName; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractMainWindow::WindowsLocale() +{ + qApp->Settings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractMainWindow::ExportDataToCSV() +{ + QString fileName = CSVFilePath(); + + if (fileName.isEmpty()) + { + return; + } + DialogExportToCSV dialog(this); + dialog.SetWithHeader(qApp->Settings()->GetCSVWithHeader()); + dialog.SetSelectedMib(qApp->Settings()->GetCSVCodec()); + dialog.SetSeparator(qApp->Settings()->GetCSVSeparator()); + if (dialog.exec() == QDialog::Accepted) { - ExportToCSVData(fileName, dialog); + ExportToCSVData(fileName, dialog.IsWithHeader(), dialog.GetSelectedMib(), dialog.GetSeparator()); - qApp->Settings()->SetCSVSeparator(dialog.Separator()); - qApp->Settings()->SetCSVCodec(dialog.SelectedMib()); - qApp->Settings()->SetCSVWithHeader(dialog.WithHeader()); + qApp->Settings()->SetCSVSeparator(dialog.GetSeparator()); + qApp->Settings()->SetCSVCodec(dialog.GetSelectedMib()); + qApp->Settings()->SetCSVWithHeader(dialog.IsWithHeader()); } } diff --git a/src/libs/vwidgets/vabstractmainwindow.h b/src/libs/vwidgets/vabstractmainwindow.h index 95e89ab1f..588d978ae 100644 --- a/src/libs/vwidgets/vabstractmainwindow.h +++ b/src/libs/vwidgets/vabstractmainwindow.h @@ -49,7 +49,7 @@ public slots: protected slots: void WindowsLocale(); - void ExportToCSV(); + void ExportDataToCSV(); protected: int m_curFileFormatVersion; @@ -58,9 +58,11 @@ protected: bool ContinueFormatRewrite(const QString ¤tFormatVersion, const QString &maxFormatVersion); void ToolBarStyle(QToolBar *bar); - virtual void ExportToCSVData(const QString &fileName, const DialogExportToCSV &dialog)=0; + virtual void ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator)=0; private: Q_DISABLE_COPY(VAbstractMainWindow) + + QString CSVFilePath(); }; #endif // VABSTRACTMAINWINDOW_H From ac96ce6b84f2dcee8d3e1489e9efefe8663ae1cc Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Wed, 27 Sep 2017 14:47:05 +0300 Subject: [PATCH 06/12] Export Final measurements to CSV. --HG-- branch : feature --- src/app/valentina/mainwindow.cpp | 3 + src/app/valentina/mainwindow.ui | 11 ++- src/app/valentina/mainwindowsnogui.cpp | 81 +++++++++++++++++++++++ src/app/valentina/mainwindowsnogui.h | 5 ++ src/libs/vwidgets/vabstractmainwindow.cpp | 1 + src/libs/vwidgets/vabstractmainwindow.h | 7 +- 6 files changed, 104 insertions(+), 4 deletions(-) diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 8d66bf784..3800f0275 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -2837,6 +2837,7 @@ void MainWindow::Clear() ui->actionHistory->setEnabled(false); ui->actionTable->setEnabled(false); ui->actionExportIncrementsToCSV->setEnabled(false); + ui->actionExportFinalMeasurementsToCSV->setEnabled(false); ui->actionFinalMeasurements->setEnabled(false); ui->actionLast_tool->setEnabled(false); ui->actionShowCurveDetails->setEnabled(false); @@ -3084,6 +3085,7 @@ void MainWindow::SetEnableWidgets(bool enable) ui->actionLayout->setEnabled(enable); ui->actionTable->setEnabled(enable && drawStage); ui->actionExportIncrementsToCSV->setEnabled(enable); + ui->actionExportFinalMeasurementsToCSV->setEnabled(enable); ui->actionFinalMeasurements->setEnabled(enable); ui->actionZoomFitBest->setEnabled(enable); ui->actionZoomFitBestCurrent->setEnabled(enable && drawStage); @@ -3978,6 +3980,7 @@ void MainWindow::CreateActions() connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::Open); connect(ui->actionNew, &QAction::triggered, this, &MainWindow::New); connect(ui->actionExportIncrementsToCSV, &QAction::triggered, this, &MainWindow::ExportDataToCSV); + connect(ui->actionExportFinalMeasurementsToCSV, &QAction::triggered, this, &MainWindow::ExportFMeasurementsToCSV); connect(ui->actionTable, &QAction::triggered, this, [this](bool checked) { diff --git a/src/app/valentina/mainwindow.ui b/src/app/valentina/mainwindow.ui index dad8e7a57..9da3d2538 100644 --- a/src/app/valentina/mainwindow.ui +++ b/src/app/valentina/mainwindow.ui @@ -1709,6 +1709,7 @@ + @@ -2693,6 +2694,14 @@ Final measurements + + + false + + + Export Final Measurements to CSV + + @@ -2703,8 +2712,8 @@ - + diff --git a/src/app/valentina/mainwindowsnogui.cpp b/src/app/valentina/mainwindowsnogui.cpp index 39047e802..2dd5ac119 100644 --- a/src/app/valentina/mainwindowsnogui.cpp +++ b/src/app/valentina/mainwindowsnogui.cpp @@ -33,6 +33,8 @@ #include "../vdxf/vdxfpaintdevice.h" #include "dialogs/dialoglayoutsettings.h" #include "../vwidgets/vmaingraphicsscene.h" +#include "../vmisc/dialogs/dialogexporttocsv.h" +#include "../vmisc/qxtcsvmodel.h" #include "../vlayout/vlayoutgenerator.h" #include "dialogs/dialoglayoutprogress.h" #include "dialogs/dialogsavelayout.h" @@ -41,6 +43,7 @@ #include "../vpatterndb/floatItemData/vpatternlabeldata.h" #include "../vpatterndb/floatItemData/vgrainlinedata.h" #include "../vpatterndb/measurements.h" +#include "../vpatterndb/calculator.h" #include "../vtools/tools/vabstracttool.h" #include "../vtools/tools/vtoolseamallowance.h" @@ -224,6 +227,31 @@ void MainWindowsNoGUI::ErrorConsoleMode(const LayoutErrors &state) qApp->exit(V_EX_DATAERR); } +//--------------------------------------------------------------------------------------------------------------------- +void MainWindowsNoGUI::ExportFMeasurementsToCSV() +{ + QString fileName = CSVFilePath(); + + if (fileName.isEmpty()) + { + return; + } + + DialogExportToCSV dialog(this); + dialog.SetWithHeader(qApp->Settings()->GetCSVWithHeader()); + dialog.SetSelectedMib(qApp->Settings()->GetCSVCodec()); + dialog.SetSeparator(qApp->Settings()->GetCSVSeparator()); + + if (dialog.exec() == QDialog::Accepted) + { + ExportFMeasurementsToCSVData(fileName, dialog.IsWithHeader(), dialog.GetSelectedMib(), dialog.GetSeparator()); + + qApp->Settings()->SetCSVSeparator(dialog.GetSeparator()); + qApp->Settings()->SetCSVCodec(dialog.GetSelectedMib()); + qApp->Settings()->SetCSVWithHeader(dialog.IsWithHeader()); + } +} + //--------------------------------------------------------------------------------------------------------------------- void MainWindowsNoGUI::ExportData(const QVector &listDetails, const DialogSaveLayout &dialog) { @@ -1543,6 +1571,59 @@ void MainWindowsNoGUI::SetSizeHeightForIndividualM() const emit doc->UpdatePatternLabel(); } +//--------------------------------------------------------------------------------------------------------------------- +void MainWindowsNoGUI::ExportFMeasurementsToCSVData(const QString &fileName, bool withHeader, int mib, + const QChar &separator) const +{ + QxtCsvModel csv; + + csv.insertColumn(0); + csv.insertColumn(1); + + if (withHeader) + { + csv.setHeaderText(0, tr("Name")); + csv.setHeaderText(1, tr("Value")); + } + + const QVector measurements = doc->GetFinalMeasurements(); + const VContainer completeData = doc->GetCompleteData(); + + for (int i=0; i < measurements.size(); ++i) + { + const VFinalMeasurement &m = measurements.at(i); + + csv.insertRow(i); + csv.setText(i, 0, m.name); // name + + qreal result = 0; + if (not m.formula.isEmpty()) + { + try + { + QString f = m.formula; + // Replace line return character with spaces for calc if exist + f.replace("\n", " "); + QScopedPointer cal(new Calculator()); + result = cal->EvalFormula(completeData.DataVariables(), f); + + if (qIsInf(result) || qIsNaN(result)) + { + result = 0; + } + } + catch (qmu::QmuParserError &) + { + result = 0; + } + } + + csv.setText(i, 1, qApp->LocaleToString(result)); // value + } + + csv.toCSV(fileName, withHeader, separator, QTextCodec::codecForMib(mib)); +} + //--------------------------------------------------------------------------------------------------------------------- int MainWindowsNoGUI::ContinueIfLayoutStale() { diff --git a/src/app/valentina/mainwindowsnogui.h b/src/app/valentina/mainwindowsnogui.h index 1af1651ef..4df454544 100644 --- a/src/app/valentina/mainwindowsnogui.h +++ b/src/app/valentina/mainwindowsnogui.h @@ -56,6 +56,8 @@ public slots: void PrintOrigin(); void PrintTiled(); void RefreshDetailsLabel(); +protected slots: + void ExportFMeasurementsToCSV(); protected: QVector listDetails; @@ -100,6 +102,9 @@ protected: int ContinueIfLayoutStale(); QString FileName() const; void SetSizeHeightForIndividualM() const; + + void ExportFMeasurementsToCSVData(const QString &fileName, + bool withHeader, int mib, const QChar &separator) const; private slots: void PrintPages (QPrinter *printer); void ErrorConsoleMode(const LayoutErrors &state); diff --git a/src/libs/vwidgets/vabstractmainwindow.cpp b/src/libs/vwidgets/vabstractmainwindow.cpp index 58dfec4b7..e4820d95c 100644 --- a/src/libs/vwidgets/vabstractmainwindow.cpp +++ b/src/libs/vwidgets/vabstractmainwindow.cpp @@ -30,6 +30,7 @@ #include "../vpropertyexplorer/checkablemessagebox.h" #include "../vmisc/vabstractapplication.h" #include "dialogs/dialogexporttocsv.h" +#include "../ifc/xml/vabstractpattern.h" #include #include diff --git a/src/libs/vwidgets/vabstractmainwindow.h b/src/libs/vwidgets/vabstractmainwindow.h index 588d978ae..b1a2f1365 100644 --- a/src/libs/vwidgets/vabstractmainwindow.h +++ b/src/libs/vwidgets/vabstractmainwindow.h @@ -35,7 +35,7 @@ #include #include -class DialogExportToCSV; +class VFinalMeasurement; class VAbstractMainWindow : public QMainWindow { @@ -58,11 +58,12 @@ protected: bool ContinueFormatRewrite(const QString ¤tFormatVersion, const QString &maxFormatVersion); void ToolBarStyle(QToolBar *bar); + QString CSVFilePath(); + virtual void ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator)=0; + private: Q_DISABLE_COPY(VAbstractMainWindow) - - QString CSVFilePath(); }; #endif // VABSTRACTMAINWINDOW_H From d01edb53c3ffac2ae75f26ca29ed0afeb1f14c94 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Wed, 27 Sep 2017 15:23:40 +0300 Subject: [PATCH 07/12] Abort export if cannot retrive a value. --HG-- branch : feature --- .../dialogs/dialogfinalmeasurements.ui | 2 +- src/app/valentina/mainwindowsnogui.cpp | 26 ++++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/app/valentina/dialogs/dialogfinalmeasurements.ui b/src/app/valentina/dialogs/dialogfinalmeasurements.ui index 074a08f00..1b9225122 100644 --- a/src/app/valentina/dialogs/dialogfinalmeasurements.ui +++ b/src/app/valentina/dialogs/dialogfinalmeasurements.ui @@ -102,7 +102,7 @@ true - false + true false diff --git a/src/app/valentina/mainwindowsnogui.cpp b/src/app/valentina/mainwindowsnogui.cpp index 2dd5ac119..fa11912d2 100644 --- a/src/app/valentina/mainwindowsnogui.cpp +++ b/src/app/valentina/mainwindowsnogui.cpp @@ -1596,7 +1596,6 @@ void MainWindowsNoGUI::ExportFMeasurementsToCSVData(const QString &fileName, boo csv.insertRow(i); csv.setText(i, 0, m.name); // name - qreal result = 0; if (not m.formula.isEmpty()) { try @@ -1605,20 +1604,33 @@ void MainWindowsNoGUI::ExportFMeasurementsToCSVData(const QString &fileName, boo // Replace line return character with spaces for calc if exist f.replace("\n", " "); QScopedPointer cal(new Calculator()); - result = cal->EvalFormula(completeData.DataVariables(), f); + const qreal result = cal->EvalFormula(completeData.DataVariables(), f); + + csv.setText(i, 1, qApp->LocaleToString(result)); // value if (qIsInf(result) || qIsNaN(result)) { - result = 0; + qCritical("%s\n\n%s", qUtf8Printable(tr("Export final measurements error.")), + qUtf8Printable(tr("Value in line %1 is infinite or NaN. Please, check your calculations.") + .arg(i+1))); + if (not VApplication::IsGUIMode()) + { + qApp->exit(V_EX_DATAERR); + } + return; } } - catch (qmu::QmuParserError &) + catch (qmu::QmuParserError &e) { - result = 0; + qCritical("%s\n\n%s", qUtf8Printable(tr("Export final measurements error.")), + qUtf8Printable(tr("Parser error at line %1: %2.").arg(i+1).arg(e.GetMsg()))); + if (not VApplication::IsGUIMode()) + { + qApp->exit(V_EX_DATAERR); + } + return; } } - - csv.setText(i, 1, qApp->LocaleToString(result)); // value } csv.toCSV(fileName, withHeader, separator, QTextCodec::codecForMib(mib)); From b673ec0fc73bc84f23fae37bc1322a401cb8137f Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 28 Sep 2017 16:05:04 +0300 Subject: [PATCH 08/12] Command line options to export final measurements. --HG-- branch : feature --- dist/OBS_debian/debian.valentina.1 | 364 ++++++++++++++++++- dist/debian/valentina.1 | 358 +++++++++++++++++- src/app/tape/tmainwindow.cpp | 3 +- src/app/valentina/core/vcmdexport.cpp | 90 ++++- src/app/valentina/core/vcmdexport.h | 14 + src/app/valentina/mainwindow.cpp | 117 ++++-- src/app/valentina/mainwindow.h | 3 +- src/app/valentina/mainwindowsnogui.cpp | 21 +- src/app/valentina/mainwindowsnogui.h | 2 +- src/libs/vmisc/commandoptions.cpp | 11 +- src/libs/vmisc/commandoptions.h | 5 + src/libs/vmisc/dialogs/dialogexporttocsv.cpp | 37 +- src/libs/vmisc/dialogs/dialogexporttocsv.h | 3 + src/libs/vmisc/qxtcsvmodel.cpp | 14 +- src/libs/vmisc/qxtcsvmodel.h | 5 +- 15 files changed, 986 insertions(+), 61 deletions(-) diff --git a/dist/OBS_debian/debian.valentina.1 b/dist/OBS_debian/debian.valentina.1 index dc731a0f8..56766c989 100644 --- a/dist/OBS_debian/debian.valentina.1 +++ b/dist/OBS_debian/debian.valentina.1 @@ -1,6 +1,6 @@ .\" Manpage for valentina. .\" Contact dismine@gmail.com to correct errors. -.TH valentina 1 "10 March, 2017" "valentina man page" +.TH valentina 1 "28 September, 2017" "valentina man page" .SH NAME Valentina \- Pattern making program. .SH SYNOPSIS @@ -106,6 +106,8 @@ The path to output destination folder. By default the directory at which the app .RB "Export text as paths." .IP "--exportOnlyDetails" .RB "Export only details. Export details as they positioned in the details mode. Any layout related options will be ignored." +.IP "--exportSuchDetails " +.RB "Export only details that match a piece name regex." .IP "-x, --gsize " .RB "Set size value a pattern file, that was opened with multisize measurements " "(export mode)" ". Valid values: 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56cm." .IP "-e, --gheight " @@ -193,14 +195,366 @@ The path to output destination folder. By default the directory at which the app Run the program in a test mode. The program in this mode loads a single pattern file and silently quit without showing the main window. The key have priority before key \*(lqbasename\*(rq. .IP "--no-scaling" .RB "Disable high dpi scaling. Call this option if has problem with scaling (by default scaling enabled). Alternatively you can use the QT_AUTO_SCREEN_SCALE_FACTOR=0 environment variable." +.IP "--csvWithHeader" +.RB "Export to csv with header. By default disabled." +.IP "--csvCodec " +.RB "Specify codec that will be used to save data. List of supported codecs provided by Qt. Default value depend from system. On Windows, the codec will be based on a system locale. On Unix systems, the codec will might fall back to using the iconv library if no builtin codec for the locale can be found. Valid values usually these:" +.RS +.BR "*" " US-ASCII," +.RE +.RS +.BR "*" " US-ASCII," +.RE +.RS +.BR "*" " ISO-8859-1," +.RE +.RS +.BR "*" " ISO-8859-2," +.RE +.RS +.BR "*" " ISO-8859-3," +.RE +.RS +.BR "*" " ISO-8859-4," +.RE +.RS +.BR "*" " ISO-8859-5," +.RE +.RS +.BR "*" " ISO-8859-6," +.RE +.RS +.BR "*" " ISO-8859-7," +.RE +.RS +.BR "*" " ISO-8859-8," +.RE +.RS +.BR "*" " ISO-8859-9," +.RE +.RS +.BR "*" " ISO-8859-10," +.RE +.RS +.BR "*" " ISO-2022-JP-1," +.RE +.RS +.BR "*" " Shift_JIS," +.RE +.RS +.BR "*" " EUC-JP," +.RE +.RS +.BR "*" " US-ASCII," +.RE +.RS +.BR "*" " windows-949," +.RE +.RS +.BR "*" " ISO-2022-KR," +.RE +.RS +.BR "*" " windows-949," +.RE +.RS +.BR "*" " ISO-2022-JP," +.RE +.RS +.BR "*" " ISO-2022-JP-2," +.RE +.RS +.BR "*" " GBK," +.RE +.RS +.BR "*" " ISO-8859-6," +.RE +.RS +.BR "*" " ISO-8859-6," +.RE +.RS +.BR "*" " ISO-8859-8," +.RE +.RS +.BR "*" " ISO-8859-8," +.RE +.RS +.BR "*" " ISO-2022-CN," +.RE +.RS +.BR "*" " ISO-2022-CN-EXT," +.RE +.RS +.BR "*" " UTF-8," +.RE +.RS +.BR "*" " ISO-8859-13," +.RE +.RS +.BR "*" " ISO-8859-14," +.RE +.RS +.BR "*" " ISO-8859-15," +.RE +.RS +.BR "*" " GBK," +.RE +.RS +.BR "*" " GB18030," +.RE +.RS +.BR "*" " UTF-16," +.RE +.RS +.BR "*" " UTF-32," +.RE +.RS +.BR "*" " SCSU," +.RE +.RS +.BR "*" " UTF-7," +.RE +.RS +.BR "*" " UTF-16BE," +.RE +.RS +.BR "*" " UTF-16LE," +.RE +.RS +.BR "*" " UTF-16," +.RE +.RS +.BR "*" " CESU-8," +.RE +.RS +.BR "*" " UTF-32," +.RE +.RS +.BR "*" " UTF-32BE," +.RE +.RS +.BR "*" " UTF-32LE," +.RE +.RS +.BR "*" " BOCU-1," +.RE +.RS +.BR "*" " hp-roman8," +.RE +.RS +.BR "*" " Adobe-Standard-Encoding," +.RE +.RS +.BR "*" " IBM850," +.RE +.RS +.BR "*" " IBM862," +.RE +.RS +.BR "*" " IBM-Thai," +.RE +.RS +.BR "*" " Shift_JIS," +.RE +.RS +.BR "*" " GBK," +.RE +.RS +.BR "*" " Big5," +.RE +.RS +.BR "*" " macintosh," +.RE +.RS +.BR "*" " IBM037," +.RE +.RS +.BR "*" " IBM273," +.RE +.RS +.BR "*" " IBM277," +.RE +.RS +.BR "*" " IBM278," +.RE +.RS +.BR "*" " IBM280," +.RE +.RS +.BR "*" " IBM284," +.RE +.RS +.BR "*" " IBM285," +.RE +.RS +.BR "*" " IBM290," +.RE +.RS +.BR "*" " IBM297," +.RE +.RS +.BR "*" " IBM420," +.RE +.RS +.BR "*" " IBM424," +.RE +.RS +.BR "*" " IBM437," +.RE +.RS +.BR "*" " IBM500," +.RE +.RS +.BR "*" " cp851," +.RE +.RS +.BR "*" " IBM852," +.RE +.RS +.BR "*" " IBM855," +.RE +.RS +.BR "*" " IBM857," +.RE +.RS +.BR "*" " IBM860," +.RE +.RS +.BR "*" " IBM861," +.RE +.RS +.BR "*" " IBM863," +.RE +.RS +.BR "*" " IBM864," +.RE +.RS +.BR "*" " IBM865," +.RE +.RS +.BR "*" " IBM868," +.RE +.RS +.BR "*" " IBM869," +.RE +.RS +.BR "*" " IBM870," +.RE +.RS +.BR "*" " IBM871," +.RE +.RS +.BR "*" " IBM918," +.RE +.RS +.BR "*" " IBM1026," +.RE +.RS +.BR "*" " KOI8-R," +.RE +.RS +.BR "*" " HZ-GB-2312," +.RE +.RS +.BR "*" " IBM866," +.RE +.RS +.BR "*" " IBM775," +.RE +.RS +.BR "*" " KOI8-U," +.RE +.RS +.BR "*" " IBM00858," +.RE +.RS +.BR "*" " IBM01140," +.RE +.RS +.BR "*" " IBM01141," +.RE +.RS +.BR "*" " IBM01142," +.RE +.RS +.BR "*" " IBM01143," +.RE +.RS +.BR "*" " IBM01144," +.RE +.RS +.BR "*" " IBM01145," +.RE +.RS +.BR "*" " IBM01146," +.RE +.RS +.BR "*" " IBM01147," +.RE +.RS +.BR "*" " IBM01148," +.RE +.RS +.BR "*" " IBM01149," +.RE +.RS +.BR "*" " Big5-HKSCS," +.RE +.RS +.BR "*" " IBM1047," +.RE +.RS +.BR "*" " windows-1250," +.RE +.RS +.BR "*" " windows-1251," +.RE +.RS +.BR "*" " windows-1252," +.RE +.RS +.BR "*" " windows-1253," +.RE +.RS +.BR "*" " windows-1254," +.RE +.RS +.BR "*" " windows-1255," +.RE +.RS +.BR "*" " windows-1256," +.RE +.RS +.BR "*" " windows-1257," +.RE +.RS +.BR "*" " windows-1258," +.RE +.RS +.BR "*" " TIS-620," +.RE +.RS +.BR "*" " TSCII." +.RE +.IP "--csvSeparator " +.RB "Specify csv separator character. Default value is ','. Valid characters:" +.RS +.BR "*" " 'Tab'," +.RE +.RS +.BR "*" " ';'," +.RE +.RS +.BR "*" " 'Space'," +.RE +.RS +.BR "*" " ','." +.RE +.IP "--csvExportFM " +.RB "Calling this command enable exporting final measurements. Specify path to csv file with final measurements. The path must contain path to directory and name of file. It can be absolute or relatetive. In case of relative path will be used current working directory to calc a destination path." .IP Arguments: .I filename \- a pattern file. .SH AUTHOR .RI "This manual page was written by Roman Telezhynskyi <" dismine@gmail.com ">" .SH "SEE ALSO" -.RB "Full " "User Manual" " is availiable in" -.UR https://bitbucket.org/dismine/valentina/wiki/manual/Content -.UE - .BR tape (1) diff --git a/dist/debian/valentina.1 b/dist/debian/valentina.1 index aa5a6c99d..56766c989 100644 --- a/dist/debian/valentina.1 +++ b/dist/debian/valentina.1 @@ -1,6 +1,6 @@ .\" Manpage for valentina. .\" Contact dismine@gmail.com to correct errors. -.TH valentina 1 "22 September, 2017" "valentina man page" +.TH valentina 1 "28 September, 2017" "valentina man page" .SH NAME Valentina \- Pattern making program. .SH SYNOPSIS @@ -195,6 +195,362 @@ The path to output destination folder. By default the directory at which the app Run the program in a test mode. The program in this mode loads a single pattern file and silently quit without showing the main window. The key have priority before key \*(lqbasename\*(rq. .IP "--no-scaling" .RB "Disable high dpi scaling. Call this option if has problem with scaling (by default scaling enabled). Alternatively you can use the QT_AUTO_SCREEN_SCALE_FACTOR=0 environment variable." +.IP "--csvWithHeader" +.RB "Export to csv with header. By default disabled." +.IP "--csvCodec " +.RB "Specify codec that will be used to save data. List of supported codecs provided by Qt. Default value depend from system. On Windows, the codec will be based on a system locale. On Unix systems, the codec will might fall back to using the iconv library if no builtin codec for the locale can be found. Valid values usually these:" +.RS +.BR "*" " US-ASCII," +.RE +.RS +.BR "*" " US-ASCII," +.RE +.RS +.BR "*" " ISO-8859-1," +.RE +.RS +.BR "*" " ISO-8859-2," +.RE +.RS +.BR "*" " ISO-8859-3," +.RE +.RS +.BR "*" " ISO-8859-4," +.RE +.RS +.BR "*" " ISO-8859-5," +.RE +.RS +.BR "*" " ISO-8859-6," +.RE +.RS +.BR "*" " ISO-8859-7," +.RE +.RS +.BR "*" " ISO-8859-8," +.RE +.RS +.BR "*" " ISO-8859-9," +.RE +.RS +.BR "*" " ISO-8859-10," +.RE +.RS +.BR "*" " ISO-2022-JP-1," +.RE +.RS +.BR "*" " Shift_JIS," +.RE +.RS +.BR "*" " EUC-JP," +.RE +.RS +.BR "*" " US-ASCII," +.RE +.RS +.BR "*" " windows-949," +.RE +.RS +.BR "*" " ISO-2022-KR," +.RE +.RS +.BR "*" " windows-949," +.RE +.RS +.BR "*" " ISO-2022-JP," +.RE +.RS +.BR "*" " ISO-2022-JP-2," +.RE +.RS +.BR "*" " GBK," +.RE +.RS +.BR "*" " ISO-8859-6," +.RE +.RS +.BR "*" " ISO-8859-6," +.RE +.RS +.BR "*" " ISO-8859-8," +.RE +.RS +.BR "*" " ISO-8859-8," +.RE +.RS +.BR "*" " ISO-2022-CN," +.RE +.RS +.BR "*" " ISO-2022-CN-EXT," +.RE +.RS +.BR "*" " UTF-8," +.RE +.RS +.BR "*" " ISO-8859-13," +.RE +.RS +.BR "*" " ISO-8859-14," +.RE +.RS +.BR "*" " ISO-8859-15," +.RE +.RS +.BR "*" " GBK," +.RE +.RS +.BR "*" " GB18030," +.RE +.RS +.BR "*" " UTF-16," +.RE +.RS +.BR "*" " UTF-32," +.RE +.RS +.BR "*" " SCSU," +.RE +.RS +.BR "*" " UTF-7," +.RE +.RS +.BR "*" " UTF-16BE," +.RE +.RS +.BR "*" " UTF-16LE," +.RE +.RS +.BR "*" " UTF-16," +.RE +.RS +.BR "*" " CESU-8," +.RE +.RS +.BR "*" " UTF-32," +.RE +.RS +.BR "*" " UTF-32BE," +.RE +.RS +.BR "*" " UTF-32LE," +.RE +.RS +.BR "*" " BOCU-1," +.RE +.RS +.BR "*" " hp-roman8," +.RE +.RS +.BR "*" " Adobe-Standard-Encoding," +.RE +.RS +.BR "*" " IBM850," +.RE +.RS +.BR "*" " IBM862," +.RE +.RS +.BR "*" " IBM-Thai," +.RE +.RS +.BR "*" " Shift_JIS," +.RE +.RS +.BR "*" " GBK," +.RE +.RS +.BR "*" " Big5," +.RE +.RS +.BR "*" " macintosh," +.RE +.RS +.BR "*" " IBM037," +.RE +.RS +.BR "*" " IBM273," +.RE +.RS +.BR "*" " IBM277," +.RE +.RS +.BR "*" " IBM278," +.RE +.RS +.BR "*" " IBM280," +.RE +.RS +.BR "*" " IBM284," +.RE +.RS +.BR "*" " IBM285," +.RE +.RS +.BR "*" " IBM290," +.RE +.RS +.BR "*" " IBM297," +.RE +.RS +.BR "*" " IBM420," +.RE +.RS +.BR "*" " IBM424," +.RE +.RS +.BR "*" " IBM437," +.RE +.RS +.BR "*" " IBM500," +.RE +.RS +.BR "*" " cp851," +.RE +.RS +.BR "*" " IBM852," +.RE +.RS +.BR "*" " IBM855," +.RE +.RS +.BR "*" " IBM857," +.RE +.RS +.BR "*" " IBM860," +.RE +.RS +.BR "*" " IBM861," +.RE +.RS +.BR "*" " IBM863," +.RE +.RS +.BR "*" " IBM864," +.RE +.RS +.BR "*" " IBM865," +.RE +.RS +.BR "*" " IBM868," +.RE +.RS +.BR "*" " IBM869," +.RE +.RS +.BR "*" " IBM870," +.RE +.RS +.BR "*" " IBM871," +.RE +.RS +.BR "*" " IBM918," +.RE +.RS +.BR "*" " IBM1026," +.RE +.RS +.BR "*" " KOI8-R," +.RE +.RS +.BR "*" " HZ-GB-2312," +.RE +.RS +.BR "*" " IBM866," +.RE +.RS +.BR "*" " IBM775," +.RE +.RS +.BR "*" " KOI8-U," +.RE +.RS +.BR "*" " IBM00858," +.RE +.RS +.BR "*" " IBM01140," +.RE +.RS +.BR "*" " IBM01141," +.RE +.RS +.BR "*" " IBM01142," +.RE +.RS +.BR "*" " IBM01143," +.RE +.RS +.BR "*" " IBM01144," +.RE +.RS +.BR "*" " IBM01145," +.RE +.RS +.BR "*" " IBM01146," +.RE +.RS +.BR "*" " IBM01147," +.RE +.RS +.BR "*" " IBM01148," +.RE +.RS +.BR "*" " IBM01149," +.RE +.RS +.BR "*" " Big5-HKSCS," +.RE +.RS +.BR "*" " IBM1047," +.RE +.RS +.BR "*" " windows-1250," +.RE +.RS +.BR "*" " windows-1251," +.RE +.RS +.BR "*" " windows-1252," +.RE +.RS +.BR "*" " windows-1253," +.RE +.RS +.BR "*" " windows-1254," +.RE +.RS +.BR "*" " windows-1255," +.RE +.RS +.BR "*" " windows-1256," +.RE +.RS +.BR "*" " windows-1257," +.RE +.RS +.BR "*" " windows-1258," +.RE +.RS +.BR "*" " TIS-620," +.RE +.RS +.BR "*" " TSCII." +.RE +.IP "--csvSeparator " +.RB "Specify csv separator character. Default value is ','. Valid characters:" +.RS +.BR "*" " 'Tab'," +.RE +.RS +.BR "*" " ';'," +.RE +.RS +.BR "*" " 'Space'," +.RE +.RS +.BR "*" " ','." +.RE +.IP "--csvExportFM " +.RB "Calling this command enable exporting final measurements. Specify path to csv file with final measurements. The path must contain path to directory and name of file. It can be absolute or relatetive. In case of relative path will be used current working directory to calc a destination path." .IP Arguments: .I filename \- a pattern file. diff --git a/src/app/tape/tmainwindow.cpp b/src/app/tape/tmainwindow.cpp index 914b4b848..0eda95711 100644 --- a/src/app/tape/tmainwindow.cpp +++ b/src/app/tape/tmainwindow.cpp @@ -707,7 +707,8 @@ void TMainWindow::ExportToCSVData(const QString &fileName, bool withHeader, int } } - csv.toCSV(fileName, withHeader, separator, QTextCodec::codecForMib(mib)); + QString error; + csv.toCSV(fileName, error, withHeader, separator, QTextCodec::codecForMib(mib)); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/valentina/core/vcmdexport.cpp b/src/app/valentina/core/vcmdexport.cpp index 9b985e222..286778938 100644 --- a/src/app/valentina/core/vcmdexport.cpp +++ b/src/app/valentina/core/vcmdexport.cpp @@ -33,8 +33,10 @@ #include "../vformat/vmeasurements.h" #include "../vmisc/commandoptions.h" #include "../vmisc/vsettings.h" +#include "../vmisc/dialogs/dialogexporttocsv.h" #include "../vlayout/vlayoutgenerator.h" #include +#include VCommandLinePtr VCommandLine::instance = nullptr; @@ -278,6 +280,46 @@ void VCommandLine::InitOptions(VCommandLineOptions &options, QMap "enabled). Alternatively you can use the " "%1 environment variable.") .arg("QT_AUTO_SCREEN_SCALE_FACTOR=0"))); + + //================================================================================================================= + optionsIndex.insert(LONG_OPTION_CSVWITHHEADER, index++); + options.append(new QCommandLineOption(QStringList() << LONG_OPTION_CSVWITHHEADER, + translate("VCommandLine", "Export to csv with header. By default " + "disabled."))); + + optionsIndex.insert(LONG_OPTION_CSVCODEC, index++); + options.append(new QCommandLineOption(QStringList() << LONG_OPTION_CSVCODEC, + translate("VCommandLine", "Specify codec that will be used to save data. List" + " of supported codecs provided by Qt. Default " + "value depend from system. On Windows, the codec " + "will be based on a system locale. On Unix " + "systems, the codec will might fall back to using " + "the iconv library if no builtin codec for the " + "locale can be found. Valid values for this " + "installation:") + + DialogExportToCSV::MakeHelpCodecsList(), + translate("VCommandLine", "Codec name"), QString("%1") + .arg(QString(QTextCodec::codecForLocale()->name())))); + + optionsIndex.insert(LONG_OPTION_CSVSEPARATOR, index++); + options.append(new QCommandLineOption(QStringList() << LONG_OPTION_CSVSEPARATOR, + translate("VCommandLine", "Specify csv separator character. Default value " + "is '%1'. Valid characters:") + .arg(VCommonSettings::GetDefCSVSeparator()) + + DialogExportToCSV::MakeHelpSeparatorList(), + translate("VCommandLine", "Separator character"), QString("%1") + .arg(VCommonSettings::GetDefCSVSeparator()))); + + optionsIndex.insert(LONG_OPTION_CSVEXPORTFM, index++); + options.append(new QCommandLineOption(QStringList() << LONG_OPTION_CSVEXPORTFM, + translate("VCommandLine", "Calling this command enable exporting final " + "measurements. Specify path to csv file with " + "final measurements. The path must contain path " + "to directory and name of file. It can be " + "absolute or relatetive. In case of " + "relative path will be used current working " + "directory to calc a destination path."), + translate("VCommandLine", "Path to csv file"))); } //------------------------------------------------------------------------------------------------------ @@ -499,7 +541,9 @@ VCommandLinePtr VCommandLine::Get(const QCoreApplication& app) instance->parser.process(app); //fixme: in case of additional options/modes which will need to disable GUI - add it here too - instance->isGuiEnabled = not (instance->IsExportEnabled() || instance->IsTestModeEnabled()); + instance->isGuiEnabled = not (instance->IsExportEnabled() + || instance->IsTestModeEnabled() + || instance->IsExportFMEnabled()); return instance; } @@ -547,6 +591,18 @@ bool VCommandLine::IsExportEnabled() const return r; } +//--------------------------------------------------------------------------------------------------------------------- +bool VCommandLine::IsExportFMEnabled() const +{ + const bool r = parser.isSet(*optionsUsed.value(optionsIndex.value(LONG_OPTION_CSVEXPORTFM))); + if (r && parser.positionalArguments().size() != 1) + { + qCritical() << translate("VCommandLine", "Export options can be used with single input file only.") << "/n"; + const_cast(this)->parser.showHelp(V_EX_USAGE); + } + return r; +} + //------------------------------------------------------------------------------------------------------ DialogLayoutSettings::PaperSizeTemplate VCommandLine::OptPaperSize() const { @@ -655,6 +711,12 @@ int VCommandLine::IsExportOnlyDetails() const return parser.isSet(*optionsUsed.value(optionsIndex.value(LONG_OPTION_EXPORTONLYDETAILS))); } +//--------------------------------------------------------------------------------------------------------------------- +int VCommandLine::IsCSVWithHeader() const +{ + return parser.isSet(*optionsUsed.value(optionsIndex.value(LONG_OPTION_CSVWITHHEADER))); +} + //--------------------------------------------------------------------------------------------------------------------- QString VCommandLine::OptExportSuchDetails() const { @@ -667,6 +729,32 @@ QString VCommandLine::OptExportSuchDetails() const return path; } +//--------------------------------------------------------------------------------------------------------------------- +QString VCommandLine::OptCSVCodecName() const +{ + return parser.value(*optionsUsed.value(optionsIndex.value(LONG_OPTION_CSVCODEC))); +} + +//--------------------------------------------------------------------------------------------------------------------- +QChar VCommandLine::OptCSVSeparator() const +{ + const QString value = parser.value(*optionsUsed.value(optionsIndex.value(LONG_OPTION_CSVSEPARATOR))); + if (not value.isEmpty()) + { + return value.at(0); + } + else + { + return QChar(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VCommandLine::OptExportFMTo() const +{ + return parser.value(*optionsUsed.value(optionsIndex.value(LONG_OPTION_CSVEXPORTFM))); +} + //--------------------------------------------------------------------------------------------------------------------- QStringList VCommandLine::OptInputFileNames() const { diff --git a/src/app/valentina/core/vcmdexport.h b/src/app/valentina/core/vcmdexport.h index 936e731a8..96d1e310e 100644 --- a/src/app/valentina/core/vcmdexport.h +++ b/src/app/valentina/core/vcmdexport.h @@ -62,6 +62,10 @@ public: //export enabled bool IsExportEnabled() const; + //@brief tests if user enabled export final measurements from cmd, throws exception if not exactly 1 input VAL + //file supplied in case export enabled + bool IsExportFMEnabled() const; + //@brief returns path to custom measure file or empty string QString OptMeasurePath() const; @@ -78,10 +82,20 @@ public: int IsBinaryDXF() const; int IsTextAsPaths() const; int IsExportOnlyDetails() const; + int IsCSVWithHeader() const; //@brief returns the piece name regex or empty string if not set QString OptExportSuchDetails() const; + //@brief returns user selected csv codec or empty string if not set + QString OptCSVCodecName() const; + + //@brief returns user selected csv separator or empty string if not set + QChar OptCSVSeparator() const; + + //@brief returns the destination path for export final measurements or empty string if not set + QString OptExportFMTo() 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; diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 3800f0275..960a1700b 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -1535,7 +1535,8 @@ void MainWindow::ExportToCSVData(const QString &fileName, bool withHeader, int m SavePreviewCalculation(false); SavePreviewCalculation(true); - csv.toCSV(fileName, withHeader, separator, QTextCodec::codecForMib(mib)); + QString error; + csv.toCSV(fileName, error, withHeader, separator, QTextCodec::codecForMib(mib)); } //--------------------------------------------------------------------------------------------------------------------- @@ -4841,7 +4842,7 @@ void MainWindow::ZoomFirstShow() } //--------------------------------------------------------------------------------------------------------------------- -void MainWindow::DoExport(const VCommandLinePtr &expParams) +bool MainWindow::DoExport(const VCommandLinePtr &expParams) { QHash details; if(not qApp->getOpeningPattern()) @@ -4851,7 +4852,7 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams) { qCCritical(vMainWindow, "%s", qUtf8Printable(tr("You can't export empty scene."))); qApp->exit(V_EX_DATAERR); - return; + return false; } else { @@ -4887,7 +4888,7 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams) qCCritical(vMainWindow, "%s", qUtf8Printable(tr("You can't export empty scene. Please, " "include at least one detail in layout."))); qApp->exit(V_EX_DATAERR); - return; + return false; } } } @@ -4910,7 +4911,7 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams) { qCCritical(vMainWindow, "%s\n\n%s", qUtf8Printable(tr("Export error.")), qUtf8Printable(e.ErrorMessage())); qApp->exit(V_EX_DATAERR); - return; + return false; } } else @@ -4934,16 +4935,61 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams) qCCritical(vMainWindow, "%s\n\n%s", qUtf8Printable(tr("Export error.")), qUtf8Printable(e.ErrorMessage())); qApp->exit(V_EX_DATAERR); - return; + return false; } } else { - return; + qApp->exit(V_EX_DATAERR); + return false; } } - qApp->exit(V_EX_OK); + return true; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief DoFMExport process export final measurements + * @param expParams command line options + * @return true if succesfull + */ +bool MainWindow::DoFMExport(const VCommandLinePtr &expParams) +{ + QString filePath = expParams->OptExportFMTo(); + + if (filePath.isEmpty()) + { + qCCritical(vMainWindow, "%s\n\n%s", qUtf8Printable(tr("Export final measurements error.")), + qUtf8Printable(tr("Destination path is empty."))); + qApp->exit(V_EX_DATAERR); + return false; + } + + QFileInfo info(filePath); + if (info.isRelative()) + { + filePath = QDir::currentPath() + QLatin1Char('/') + filePath; + } + + const QString codecName = expParams->OptCSVCodecName(); + int mib = QTextCodec::codecForLocale()->mibEnum(); + if (not codecName.isEmpty()) + { + if (QTextCodec *codec = QTextCodec::codecForName(codecName.toLatin1())) + { + mib = codec->mibEnum(); + } + } + + QChar separator = expParams->OptCSVSeparator(); + if (separator.isNull()) + { + separator = VCommonSettings::GetDefCSVSeparator(); + } + + return ExportFMeasurementsToCSVData(filePath, expParams->IsCSVWithHeader(), mib, separator); + } //--------------------------------------------------------------------------------------------------------------------- @@ -5043,6 +5089,11 @@ void MainWindow::ProcessCMD() if (VApplication::IsGUIMode()) { ReopenFilesAfterCrash(args); + + for (int i=0, sz = args.size(); i < sz; ++i) + { + LoadPattern(args.at(i)); + } } else { @@ -5052,53 +5103,45 @@ void MainWindow::ProcessCMD() qApp->exit(V_EX_NOINPUT); return; } - } - for (int i=0, sz = args.size(); i < sz; ++i) - { - const bool loaded = LoadPattern(args.at(static_cast(i)), cmd->OptMeasurePath()); + const bool loaded = LoadPattern(args.first(), cmd->OptMeasurePath()); - if (not loaded && not VApplication::IsGUIMode()) + if (not loaded) { return; // process only one input file } bool hSetted = true; bool sSetted = true; - if (loaded && (cmd->IsTestModeEnabled() || cmd->IsExportEnabled())) + if (cmd->IsSetGradationSize()) { - if (cmd->IsSetGradationSize()) - { - sSetted = SetSize(cmd->OptGradationSize()); - } + sSetted = SetSize(cmd->OptGradationSize()); + } - if (cmd->IsSetGradationHeight()) - { - hSetted = SetHeight(cmd->OptGradationHeight()); - } + if (cmd->IsSetGradationHeight()) + { + hSetted = SetHeight(cmd->OptGradationHeight()); + } + + if (not (hSetted && sSetted)) + { + qApp->exit(V_EX_DATAERR); + return; } if (not cmd->IsTestModeEnabled()) { - if (cmd->IsExportEnabled()) + if (cmd->IsExportEnabled() && not DoExport(cmd)) { - if (loaded && hSetted && sSetted) - { - DoExport(cmd); - return; // process only one input file - } - else - { - qApp->exit(V_EX_DATAERR); - return; - } - break; + return; + } + + if (cmd->IsExportFMEnabled() && not DoFMExport(cmd)) + { + return; } } - } - if (not VApplication::IsGUIMode()) - { qApp->exit(V_EX_OK);// close program after processing in console mode } } diff --git a/src/app/valentina/mainwindow.h b/src/app/valentina/mainwindow.h index 627820e6e..7f5aa5f39 100644 --- a/src/app/valentina/mainwindow.h +++ b/src/app/valentina/mainwindow.h @@ -351,7 +351,8 @@ private: void CheckRequiredMeasurements(const VMeasurements *m); void ReopenFilesAfterCrash(QStringList &args); - void DoExport(const VCommandLinePtr& expParams); + bool DoExport(const VCommandLinePtr& expParams); + bool DoFMExport(const VCommandLinePtr& expParams); bool SetSize(const QString &text); bool SetHeight(const QString & text); diff --git a/src/app/valentina/mainwindowsnogui.cpp b/src/app/valentina/mainwindowsnogui.cpp index fa11912d2..53e92b835 100644 --- a/src/app/valentina/mainwindowsnogui.cpp +++ b/src/app/valentina/mainwindowsnogui.cpp @@ -1572,7 +1572,7 @@ void MainWindowsNoGUI::SetSizeHeightForIndividualM() const } //--------------------------------------------------------------------------------------------------------------------- -void MainWindowsNoGUI::ExportFMeasurementsToCSVData(const QString &fileName, bool withHeader, int mib, +bool MainWindowsNoGUI::ExportFMeasurementsToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator) const { QxtCsvModel csv; @@ -1617,7 +1617,7 @@ void MainWindowsNoGUI::ExportFMeasurementsToCSVData(const QString &fileName, boo { qApp->exit(V_EX_DATAERR); } - return; + return false; } } catch (qmu::QmuParserError &e) @@ -1628,12 +1628,25 @@ void MainWindowsNoGUI::ExportFMeasurementsToCSVData(const QString &fileName, boo { qApp->exit(V_EX_DATAERR); } - return; + return false; } } } - csv.toCSV(fileName, withHeader, separator, QTextCodec::codecForMib(mib)); + QString error; + const bool success = csv.toCSV(fileName, error, withHeader, separator, QTextCodec::codecForMib(mib)); + + if (not success) + { + qCritical("%s\n\n%s", qUtf8Printable(tr("Export final measurements error.")), + qUtf8Printable(tr("File error %1.").arg(error))); + if (not VApplication::IsGUIMode()) + { + qApp->exit(V_EX_CANTCREAT); + } + } + + return success; } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/valentina/mainwindowsnogui.h b/src/app/valentina/mainwindowsnogui.h index 4df454544..6591f0bc4 100644 --- a/src/app/valentina/mainwindowsnogui.h +++ b/src/app/valentina/mainwindowsnogui.h @@ -103,7 +103,7 @@ protected: QString FileName() const; void SetSizeHeightForIndividualM() const; - void ExportFMeasurementsToCSVData(const QString &fileName, + bool ExportFMeasurementsToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator) const; private slots: void PrintPages (QPrinter *printer); diff --git a/src/libs/vmisc/commandoptions.cpp b/src/libs/vmisc/commandoptions.cpp index 7ed308473..54c70ce06 100644 --- a/src/libs/vmisc/commandoptions.cpp +++ b/src/libs/vmisc/commandoptions.cpp @@ -111,6 +111,11 @@ const QString SINGLE_OPTION_TOP_MARGIN = QStringLiteral("T"); const QString LONG_OPTION_BOTTOM_MARGIN = QStringLiteral("bmargin"); const QString SINGLE_OPTION_BOTTOM_MARGIN = QStringLiteral("B"); +const QString LONG_OPTION_CSVWITHHEADER = QStringLiteral("csvWithHeader"); +const QString LONG_OPTION_CSVCODEC = QStringLiteral("csvCodec"); +const QString LONG_OPTION_CSVSEPARATOR = QStringLiteral("csvSeparator"); +const QString LONG_OPTION_CSVEXPORTFM = QStringLiteral("csvExportFM"); + //--------------------------------------------------------------------------------------------------------------------- QStringList AllKeys() { @@ -143,7 +148,11 @@ QStringList AllKeys() << LONG_OPTION_RIGHT_MARGIN << SINGLE_OPTION_RIGHT_MARGIN << LONG_OPTION_TOP_MARGIN << SINGLE_OPTION_TOP_MARGIN << LONG_OPTION_BOTTOM_MARGIN << SINGLE_OPTION_BOTTOM_MARGIN - << LONG_OPTION_NO_HDPI_SCALING; + << LONG_OPTION_NO_HDPI_SCALING + << LONG_OPTION_CSVWITHHEADER + << LONG_OPTION_CSVCODEC + << LONG_OPTION_CSVSEPARATOR + << LONG_OPTION_CSVEXPORTFM; return list; } diff --git a/src/libs/vmisc/commandoptions.h b/src/libs/vmisc/commandoptions.h index 5a3cc581b..9386e1f07 100644 --- a/src/libs/vmisc/commandoptions.h +++ b/src/libs/vmisc/commandoptions.h @@ -108,6 +108,11 @@ extern const QString SINGLE_OPTION_TOP_MARGIN; extern const QString LONG_OPTION_BOTTOM_MARGIN; extern const QString SINGLE_OPTION_BOTTOM_MARGIN; +extern const QString LONG_OPTION_CSVWITHHEADER; +extern const QString LONG_OPTION_CSVCODEC; +extern const QString LONG_OPTION_CSVSEPARATOR; +extern const QString LONG_OPTION_CSVEXPORTFM; + QStringList AllKeys(); #endif // COMMANDOPTIONS_H diff --git a/src/libs/vmisc/dialogs/dialogexporttocsv.cpp b/src/libs/vmisc/dialogs/dialogexporttocsv.cpp index 8584d305c..89a845712 100644 --- a/src/libs/vmisc/dialogs/dialogexporttocsv.cpp +++ b/src/libs/vmisc/dialogs/dialogexporttocsv.cpp @@ -51,7 +51,7 @@ DialogExportToCSV::DialogExportToCSV(QWidget *parent) ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(VCommonSettings::GetDefCSVCodec())); - SetSeparator(qApp->Settings()->GetDefCSVSeparator()); + SetSeparator(VCommonSettings::GetDefCSVSeparator()); QPushButton *bDefaults = ui->buttonBox->button(QDialogButtonBox::RestoreDefaults); SCASSERT(bDefaults != nullptr) @@ -60,7 +60,7 @@ DialogExportToCSV::DialogExportToCSV(QWidget *parent) ui->checkBoxWithHeader->setChecked(qApp->Settings()->GetDefCSVWithHeader()); ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(VCommonSettings::GetDefCSVCodec())); - SetSeparator(qApp->Settings()->GetDefCSVSeparator()); + SetSeparator(VCommonSettings::GetDefCSVSeparator()); }); } @@ -126,7 +126,7 @@ QChar DialogExportToCSV::GetSeparator() const } else { - return QChar(','); + return VCommonSettings::GetDefCSVSeparator(); } } @@ -184,3 +184,34 @@ void DialogExportToCSV::SetSeparator(const QChar &separator) break; } } + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogExportToCSV::MakeHelpCodecsList() +{ + QString out("\n"); + const QList list = QTextCodec::availableMibs(); + for (int i = 0; i < list.size(); ++i) + { + out += QLatin1String("\t* ") + QTextCodec::codecForMib(list.at(i))->name(); + if (i < list.size()-1) + { + out += QLatin1String(",\n"); + } + else + { + out += QLatin1String(".\n"); + } + } + return out; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogExportToCSV::MakeHelpSeparatorList() +{ + QString out("\n"); + out += QLatin1String("\t* 'Tab',\n"); + out += QLatin1String("\t* ';',\n"); + out += QLatin1String("\t* 'Space',\n"); + out += QLatin1String("\t* ','.\n"); + return out; +} diff --git a/src/libs/vmisc/dialogs/dialogexporttocsv.h b/src/libs/vmisc/dialogs/dialogexporttocsv.h index d1782aa26..8e59334b8 100644 --- a/src/libs/vmisc/dialogs/dialogexporttocsv.h +++ b/src/libs/vmisc/dialogs/dialogexporttocsv.h @@ -53,6 +53,9 @@ public: QChar GetSeparator() const; void SetSeparator(const QChar &separator); + static QString MakeHelpCodecsList(); + static QString MakeHelpSeparatorList(); + protected: virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE; virtual void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; diff --git a/src/libs/vmisc/qxtcsvmodel.cpp b/src/libs/vmisc/qxtcsvmodel.cpp index 33573205a..a5644303b 100644 --- a/src/libs/vmisc/qxtcsvmodel.cpp +++ b/src/libs/vmisc/qxtcsvmodel.cpp @@ -591,7 +591,7 @@ static QString qxt_addCsvQuotes(QxtCsvModel::QuoteMode mode, QString field) to output a row of headers at the top of the file. */ // cppcheck-suppress funcArgNamesDifferent -void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QTextCodec* codec) const +bool QxtCsvModel::toCSV(QIODevice* dest, QString &error, bool withHeader, QChar separator, QTextCodec* codec) const { const QxtCsvModelPrivate& d_ptr = qxt_d(); int row, col, rows, cols; @@ -600,7 +600,11 @@ void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QText QString data; if (not dest->isOpen()) { - dest->open(QIODevice::WriteOnly | QIODevice::Truncate); + if ( not dest->open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + error = dest->errorString(); + return false; + } } QTextStream stream(dest); if (codec) @@ -643,6 +647,7 @@ void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QText } stream << flush; dest->close(); + return true; } /*! @@ -653,10 +658,11 @@ void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QText Fields in the output file will be separated by \a separator. Set \a withHeader to true to output a row of headers at the top of the file. */ -void QxtCsvModel::toCSV(const QString &filename, bool withHeader, QChar separator, QTextCodec* codec) const +bool QxtCsvModel::toCSV(const QString &filename, QString &error, bool withHeader, QChar separator, + QTextCodec* codec) const { QFile dest(filename); - toCSV(&dest, withHeader, separator, codec); + return toCSV(&dest, error, withHeader, separator, codec); } /*! diff --git a/src/libs/vmisc/qxtcsvmodel.h b/src/libs/vmisc/qxtcsvmodel.h index b43a6c340..3c380eba8 100644 --- a/src/libs/vmisc/qxtcsvmodel.h +++ b/src/libs/vmisc/qxtcsvmodel.h @@ -93,8 +93,9 @@ public: void setSource(const QString &filename, bool withHeader = false, QChar separator = ',', QTextCodec* codec = nullptr); - void toCSV(QIODevice *file, bool withHeader = false, QChar separator = ',', QTextCodec* codec = nullptr) const; - void toCSV(const QString &filename, bool withHeader = false, QChar separator = ',', + bool toCSV(QIODevice *file, QString &error, bool withHeader = false, QChar separator = ',', + QTextCodec* codec = nullptr) const; + bool toCSV(const QString &filename, QString &error, bool withHeader = false, QChar separator = ',', QTextCodec* codec = nullptr) const; enum QuoteOption { NoQuotes = 0, From ffe4affcbffc7a71f6979dacaaebf788b8b135f6 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 28 Sep 2017 16:05:55 +0300 Subject: [PATCH 09/12] Retrieve canonical file path if possible. --HG-- branch : feature --- src/app/valentina/mainwindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 960a1700b..797994915 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -4209,11 +4209,11 @@ bool MainWindow::LoadPattern(QString fileName, const QString& customMeasureFile) { qCDebug(vMainWindow, "Loading new file %s.", qUtf8Printable(fileName)); - { // Convert to absolute path is need + { // Convert to absolute path if need QFileInfo info(fileName); - if (info.isRelative()) + if (info.exists() && info.isRelative()) { - fileName = QDir::currentPath() + QLatin1Char('/') + fileName; + fileName = QFileInfo(QDir::currentPath() + QLatin1Char('/') + fileName).canonicalFilePath(); } } From 5d2e584d2fc930e8a364e7e13bc500e00a2de131 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 28 Sep 2017 16:22:35 +0300 Subject: [PATCH 10/12] Improving for embedded man page. Use bullet list where possible. --HG-- branch : feature --- .../valentina/dialogs/dialoglayoutsettings.cpp | 13 +++++++++++-- src/app/valentina/dialogs/dialogsavelayout.cpp | 16 +++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/app/valentina/dialogs/dialoglayoutsettings.cpp b/src/app/valentina/dialogs/dialoglayoutsettings.cpp index faa123c7a..92b1d2aae 100644 --- a/src/app/valentina/dialogs/dialoglayoutsettings.cpp +++ b/src/app/valentina/dialogs/dialoglayoutsettings.cpp @@ -825,11 +825,20 @@ QString DialogLayoutSettings::MakeHelpTemplateList() QString out = "\n"; auto cntr = static_cast(PaperSizeTemplate::A0); - foreach(const auto& v, pageFormatNames) + for (int i = 0; i < pageFormatNames.size(); ++i) { if (cntr <= static_cast(PaperSizeTemplate::Roll44in))// Don't include custom template { - out += "\t"+v+" = "+ QString::number(cntr++)+"\n"; + out += "\t* "+pageFormatNames.at(i)+" = "+ QString::number(cntr++); + + if (i < pageFormatNames.size() - 1) + { + out += ",\n"; + } + else + { + out += ".\n"; + } } } return out; diff --git a/src/app/valentina/dialogs/dialogsavelayout.cpp b/src/app/valentina/dialogs/dialogsavelayout.cpp index 7c8815329..b6b2735b0 100644 --- a/src/app/valentina/dialogs/dialogsavelayout.cpp +++ b/src/app/valentina/dialogs/dialogsavelayout.cpp @@ -250,10 +250,20 @@ bool DialogSaveLayout::IsBinaryDXFFormat() const QString DialogSaveLayout::MakeHelpFormatList() { QString out("\n"); - foreach(auto& v, InitFormats()) + const auto formats = InitFormats(); + for(int i = 0; i < formats.size(); ++i) { - out += QLatin1String("\t") + v.first + QLatin1String(" = ") + QString::number(static_cast(v.second)) - + QLatin1String("\n"); + out += QLatin1String("\t* ") + formats.at(i).first + QLatin1String(" = ") + + QString::number(static_cast(formats.at(i).second)); + + if (i < formats.size() - 1) + { + out += QLatin1String(",\n"); + } + else + { + out += QLatin1String(".\n"); + } } return out; } From 657c445e46bd8fd5282f2777502e09bba326c591 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 28 Sep 2017 16:39:27 +0300 Subject: [PATCH 11/12] Extract formulas from final measurements. --HG-- branch : feature --- src/libs/ifc/xml/vabstractpattern.cpp | 21 +++++++++++++++++++++ src/libs/ifc/xml/vabstractpattern.h | 1 + 2 files changed, 22 insertions(+) diff --git a/src/libs/ifc/xml/vabstractpattern.cpp b/src/libs/ifc/xml/vabstractpattern.cpp index 5c26c377b..63176c797 100644 --- a/src/libs/ifc/xml/vabstractpattern.cpp +++ b/src/libs/ifc/xml/vabstractpattern.cpp @@ -1761,6 +1761,7 @@ QVector VAbstractPattern::ListExpressions() const list << ListOperationExpressions(); list << ListPathExpressions(); list << ListPieceExpressions(); + list << ListFinalMeasurementsExpressions(); return list; } @@ -1997,6 +1998,26 @@ QVector VAbstractPattern::ListPieceExpressions() const return expressions; } +//--------------------------------------------------------------------------------------------------------------------- +QVector VAbstractPattern::ListFinalMeasurementsExpressions() const +{ + QVector expressions; + const QDomNodeList list = elementsByTagName(TagFMeasurement); + for (int i=0; i < list.size(); ++i) + { + const QDomElement dom = list.at(i).toElement(); + if (dom.isNull()) + { + continue; + } + + // Each tag can contains several attributes. + ReadExpressionAttribute(expressions, dom, AttrFormula); + } + + return expressions; +} + //--------------------------------------------------------------------------------------------------------------------- bool VAbstractPattern::IsVariable(const QString &token) const { diff --git a/src/libs/ifc/xml/vabstractpattern.h b/src/libs/ifc/xml/vabstractpattern.h index b10b39391..d1a681451 100644 --- a/src/libs/ifc/xml/vabstractpattern.h +++ b/src/libs/ifc/xml/vabstractpattern.h @@ -446,6 +446,7 @@ private: QVector ListPathExpressions() const; QVector ListGrainlineExpressions(const QDomElement &element) const; QVector ListPieceExpressions() const; + QVector ListFinalMeasurementsExpressions() const; bool IsVariable(const QString& token) const; bool IsPostfixOperator(const QString& token) const; From 2f6623b785b30f84874e2fbbea38be69730d774e Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 28 Sep 2017 17:08:52 +0300 Subject: [PATCH 12/12] Update Changelog. --HG-- branch : feature --- ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index eb83c1edf..27c843bab 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -20,6 +20,7 @@ - [#755] New feature. Toggle point label. - Fixed bug. After full parse undocommand Move labe losts connection to tool. - [#756] New feature. Select pieces from command line. +- [#761] New feature. Export final measurements. # Version 0.5.1 - [#683] Tool Seam allowance's dialog is off screen on small resolutions.