From 5004c12342e759d207e20da347e0a3b7ee0084fc Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Sun, 18 Nov 2018 09:52:08 +0200 Subject: [PATCH] Seepd up pattern file validation making it parallel. --HG-- branch : develop --- src/app/tape/tmainwindow.cpp | 6 +- src/app/valentina/mainwindow.cpp | 51 ++++++++++++--- src/app/valentina/xml/vpattern.cpp | 2 +- src/libs/fervor/fvupdater.cpp | 6 +- src/libs/ifc/xml/vabstractconverter.cpp | 82 +------------------------ src/libs/ifc/xml/vabstractconverter.h | 5 -- src/libs/ifc/xml/vabstractpattern.cpp | 82 ++++++++++++++++++++----- src/libs/ifc/xml/vabstractpattern.h | 2 + src/libs/ifc/xml/vdomdocument.cpp | 79 ++++++++++++++++++++++++ src/libs/ifc/xml/vdomdocument.h | 4 ++ src/libs/vmisc/literals.cpp | 1 + src/libs/vmisc/literals.h | 1 + 12 files changed, 205 insertions(+), 116 deletions(-) diff --git a/src/app/tape/tmainwindow.cpp b/src/app/tape/tmainwindow.cpp index 8112ed09a..dd5f6d6e4 100644 --- a/src/app/tape/tmainwindow.cpp +++ b/src/app/tape/tmainwindow.cpp @@ -267,14 +267,14 @@ bool TMainWindow::LoadFile(const QString &path) { VVSTConverter converter(path); m_curFileFormatVersion = converter.GetCurrentFormatVersion(); - m_curFileFormatVersionStr = converter.GetVersionStr(); + m_curFileFormatVersionStr = converter.GetFormatVersionStr(); m->setXMLContent(converter.Convert());// Read again after conversion } else { VVITConverter converter(path); m_curFileFormatVersion = converter.GetCurrentFormatVersion(); - m_curFileFormatVersionStr = converter.GetVersionStr(); + m_curFileFormatVersionStr = converter.GetFormatVersionStr(); m->setXMLContent(converter.Convert());// Read again after conversion } @@ -2910,7 +2910,7 @@ bool TMainWindow::LoadFromExistingFile(const QString &path) { VVITConverter converter(path); m_curFileFormatVersion = converter.GetCurrentFormatVersion(); - m_curFileFormatVersionStr = converter.GetVersionStr(); + m_curFileFormatVersionStr = converter.GetFormatVersionStr(); m->setXMLContent(converter.Convert());// Read again after conversion } diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 9a838b9bd..0aaae93ea 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -4487,6 +4487,12 @@ bool MainWindow::LoadPattern(QString fileName, const QString& customMeasureFile) } } + QFuture futureConverter = QtConcurrent::run([fileName]() + { + QScopedPointer converter(new VPatternConverter(fileName)); + return converter.take(); + }); + //We have unsaved changes or load more then one file per time if (OpenNewValentina(fileName)) { @@ -4557,15 +4563,30 @@ bool MainWindow::LoadPattern(QString fileName, const QString& customMeasureFile) qApp->setOpeningPattern();//Begin opening file try { - VPatternConverter converter(fileName); - m_curFileFormatVersion = converter.GetCurrentFormatVersion(); - m_curFileFormatVersionStr = converter.GetVersionStr(); - doc->setXMLContent(converter.Convert()); - if (!customMeasureFile.isEmpty()) - { - doc->SetMPath(RelativeMPath(fileName, customMeasureFile)); + // Quick reading measurements + doc->setXMLContent(fileName); + const int currentFormatVersion = doc->GetFormatVersion(doc->GetFormatVersionStr()); + if (currentFormatVersion != VPatternConverter::PatternMaxVer) + { // Because we rely on the fact that we know where is path to measurements optimization available only for + // the latest format version + QScopedPointer converter(futureConverter.result()); + m_curFileFormatVersion = converter->GetCurrentFormatVersion(); + m_curFileFormatVersionStr = converter->GetFormatVersionStr(); + doc->setXMLContent(converter->Convert()); + if (!customMeasureFile.isEmpty()) + { + doc->SetMPath(RelativeMPath(fileName, customMeasureFile)); + } + qApp->setPatternUnit(doc->MUnit()); + } + else + { + if (!customMeasureFile.isEmpty()) + { + doc->SetMPath(RelativeMPath(fileName, customMeasureFile)); + } + qApp->setPatternUnit(doc->MUnit()); } - qApp->setPatternUnit(doc->MUnit()); const QString path = AbsoluteMPath(fileName, doc->MPath()); if (not path.isEmpty()) @@ -4610,6 +4631,20 @@ bool MainWindow::LoadPattern(QString fileName, const QString& customMeasureFile) {// Show toolbar only if was not uploaded any measurements. ToolBarOption(); } + + if (currentFormatVersion == VPatternConverter::PatternMaxVer) + { + // Real read + QScopedPointer converter(futureConverter.result()); + m_curFileFormatVersion = converter->GetCurrentFormatVersion(); + m_curFileFormatVersionStr = converter->GetFormatVersionStr(); + doc->setXMLContent(converter->Convert()); + if (!customMeasureFile.isEmpty()) + { + doc->SetMPath(RelativeMPath(fileName, customMeasureFile)); + } + qApp->setPatternUnit(doc->MUnit()); + } } catch (VException &e) { diff --git a/src/app/valentina/xml/vpattern.cpp b/src/app/valentina/xml/vpattern.cpp index 0701d5829..2c91d447c 100644 --- a/src/app/valentina/xml/vpattern.cpp +++ b/src/app/valentina/xml/vpattern.cpp @@ -132,7 +132,7 @@ void VPattern::CreateEmptyFile() //--------------------------------------------------------------------------------------------------------------------- void VPattern::setXMLContent(const QString &fileName) { - VDomDocument::setXMLContent(fileName); + VAbstractPattern::setXMLContent(fileName); GarbageCollector(); } diff --git a/src/libs/fervor/fvupdater.cpp b/src/libs/fervor/fvupdater.cpp index 7e89d896b..7c8cf6128 100644 --- a/src/libs/fervor/fvupdater.cpp +++ b/src/libs/fervor/fvupdater.cpp @@ -112,7 +112,7 @@ int FvUpdater::CurrentVersion() QTextStream in(&file); try { - return VAbstractConverter::GetVersion(in.read(15)); + return VAbstractConverter::GetFormatVersion(in.read(15)); } catch(const VException &) { @@ -569,7 +569,7 @@ bool FvUpdater::VersionIsIgnored(const QString &version) int decVersion = 0x0; try { - decVersion = VAbstractConverter::GetVersion(version); + decVersion = VAbstractConverter::GetFormatVersion(version); } catch (const VException &e) { @@ -608,7 +608,7 @@ void FvUpdater::IgnoreVersion(const QString &version) int decVersion = 0x0; try { - decVersion = VAbstractConverter::GetVersion(version); + decVersion = VAbstractConverter::GetFormatVersion(version); } catch (const VException &e) { diff --git a/src/libs/ifc/xml/vabstractconverter.cpp b/src/libs/ifc/xml/vabstractconverter.cpp index 414271726..9fe6a722f 100644 --- a/src/libs/ifc/xml/vabstractconverter.cpp +++ b/src/libs/ifc/xml/vabstractconverter.cpp @@ -55,7 +55,7 @@ VAbstractConverter::VAbstractConverter(const QString &fileName) m_tmpFile() { setXMLContent(m_convertedFileName);// Throw an exception on error - m_ver = GetVersion(GetVersionStr()); + m_ver = GetFormatVersion(GetFormatVersionStr()); } //--------------------------------------------------------------------------------------------------------------------- @@ -92,84 +92,6 @@ int VAbstractConverter::GetCurrentFormatVersion() const return m_ver; } -//--------------------------------------------------------------------------------------------------------------------- -QString VAbstractConverter::GetVersionStr() const -{ - const QDomNodeList nodeList = this->elementsByTagName(TagVersion); - if (nodeList.isEmpty()) - { - const QString errorMsg(tr("Couldn't get version information.")); - throw VException(errorMsg); - } - - if (nodeList.count() > 1) - { - const QString errorMsg(tr("Too many tags <%1> in file.").arg(TagVersion)); - throw VException(errorMsg); - } - - const QDomNode domNode = nodeList.at(0); - if (domNode.isNull() == false && domNode.isElement()) - { - const QDomElement domElement = domNode.toElement(); - if (domElement.isNull() == false) - { - return domElement.text(); - } - } - return QString(QStringLiteral("0.0.0")); -} - -//--------------------------------------------------------------------------------------------------------------------- -int VAbstractConverter::GetVersion(const QString &version) -{ - ValidateVersion(version); - - const QStringList ver = version.split(QChar('.')); - - bool ok = false; - const int major = ver.at(0).toInt(&ok); - if (not ok) - { - return 0x0; - } - - ok = false; - const int minor = ver.at(1).toInt(&ok); - if (not ok) - { - return 0x0; - } - - ok = false; - const int patch = ver.at(2).toInt(&ok); - if (not ok) - { - return 0x0; - } - - return (major<<16)|(minor<<8)|(patch); -} - -//--------------------------------------------------------------------------------------------------------------------- -void VAbstractConverter::ValidateVersion(const QString &version) -{ - const QRegularExpression rx(QStringLiteral("^([0-9]|[1-9][0-9]|[1-2][0-5][0-5]).([0-9]|[1-9][0-9]|[1-2][0-5][0-5])" - ".([0-9]|[1-9][0-9]|[1-2][0-5][0-5])$")); - - if (rx.match(version).hasMatch() == false) - { - const QString errorMsg(tr("Version \"%1\" invalid.").arg(version)); - throw VException(errorMsg); - } - - if (version == QLatin1String("0.0.0")) - { - const QString errorMsg(tr("Version \"0.0.0\" invalid.")); - throw VException(errorMsg); - } -} - //--------------------------------------------------------------------------------------------------------------------- void VAbstractConverter::ReserveFile() const { @@ -178,7 +100,7 @@ void VAbstractConverter::ReserveFile() const QString error; QFileInfo info(m_convertedFileName); const QString reserveFileName = QString("%1/%2(v%3).%4.bak") - .arg(info.absoluteDir().absolutePath(), info.baseName(), GetVersionStr(), info.completeSuffix()); + .arg(info.absoluteDir().absolutePath(), info.baseName(), GetFormatVersionStr(), info.completeSuffix()); if (not SafeCopy(m_convertedFileName, reserveFileName, error)) { #ifdef Q_OS_WIN32 diff --git a/src/libs/ifc/xml/vabstractconverter.h b/src/libs/ifc/xml/vabstractconverter.h index 86d7d2b69..ca8527eda 100644 --- a/src/libs/ifc/xml/vabstractconverter.h +++ b/src/libs/ifc/xml/vabstractconverter.h @@ -56,9 +56,6 @@ public: QString Convert(); int GetCurrentFormatVersion() const; - QString GetVersionStr() const; - - static int GetVersion(const QString &version); protected: int m_ver; @@ -90,8 +87,6 @@ private: QTemporaryFile m_tmpFile; - static void ValidateVersion(const QString &version); - void ReserveFile() const; }; diff --git a/src/libs/ifc/xml/vabstractpattern.cpp b/src/libs/ifc/xml/vabstractpattern.cpp index aa555a0e5..ad852a0b4 100644 --- a/src/libs/ifc/xml/vabstractpattern.cpp +++ b/src/libs/ifc/xml/vabstractpattern.cpp @@ -208,6 +208,13 @@ bool VAbstractPattern::patternLabelWasChanged = false; namespace { +// Need to be reinited in setXMLContent as well +Q_GLOBAL_STATIC_WITH_ARGS(QString, patternNumberCached, (unknownCharacter)) +Q_GLOBAL_STATIC_WITH_ARGS(QString, labelDateFormatCached, (unknownCharacter)) +Q_GLOBAL_STATIC_WITH_ARGS(QString, patternNameCached, (unknownCharacter)) +Q_GLOBAL_STATIC_WITH_ARGS(QString, MPathCached, (unknownCharacter)) +Q_GLOBAL_STATIC_WITH_ARGS(QString, companyNameCached, (unknownCharacter)) + void ReadExpressionAttribute(QVector &expressions, const QDomElement &element, const QString &attribute) { VFormulaField formula; @@ -601,6 +608,18 @@ void VAbstractPattern::setCursor(const quint32 &value) } } +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::setXMLContent(const QString &fileName) +{ + VDomDocument::setXMLContent(fileName); + + *patternNumberCached = unknownCharacter; + *labelDateFormatCached = unknownCharacter; + *patternNameCached = unknownCharacter; + *MPathCached = unknownCharacter; + *companyNameCached = unknownCharacter; +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief getTool return tool from tool list. @@ -807,7 +826,11 @@ QVector VAbstractPattern::getLocalHistory() const //--------------------------------------------------------------------------------------------------------------------- QString VAbstractPattern::MPath() const { - return UniqueTagText(TagMeasurements); + if (*MPathCached == unknownCharacter) + { + *MPathCached = UniqueTagText(TagMeasurements); + } + return *MPathCached; } //--------------------------------------------------------------------------------------------------------------------- @@ -817,6 +840,7 @@ void VAbstractPattern::SetMPath(const QString &path) { emit patternChanged(false); patternLabelWasChanged = true; + *MPathCached = path; } else { @@ -1303,14 +1327,19 @@ void VAbstractPattern::SetNotes(const QString &text) //--------------------------------------------------------------------------------------------------------------------- QString VAbstractPattern::GetPatternName() const { - return UniqueTagText(TagPatternName); + if (*patternNameCached == unknownCharacter) + { + *patternNameCached = UniqueTagText(TagPatternName); + } + return *patternNameCached; } //--------------------------------------------------------------------------------------------------------------------- void VAbstractPattern::SetPatternName(const QString &qsName) { + *patternNameCached = qsName; CheckTagExists(TagPatternName); - setTagText(TagPatternName, qsName); + setTagText(TagPatternName, *patternNameCached); patternLabelWasChanged = true; modified = true; emit patternChanged(false); @@ -1319,14 +1348,19 @@ void VAbstractPattern::SetPatternName(const QString &qsName) //--------------------------------------------------------------------------------------------------------------------- QString VAbstractPattern::GetCompanyName() const { - return UniqueTagText(TagCompanyName); + if (*companyNameCached == unknownCharacter) + { + *companyNameCached = UniqueTagText(TagCompanyName); + } + return *companyNameCached; } //--------------------------------------------------------------------------------------------------------------------- void VAbstractPattern::SetCompanyName(const QString& qsName) { + *companyNameCached = qsName; CheckTagExists(TagCompanyName); - setTagText(TagCompanyName, qsName); + setTagText(TagCompanyName, *companyNameCached); patternLabelWasChanged = true; modified = true; emit patternChanged(false); @@ -1335,14 +1369,19 @@ void VAbstractPattern::SetCompanyName(const QString& qsName) //--------------------------------------------------------------------------------------------------------------------- QString VAbstractPattern::GetPatternNumber() const { - return UniqueTagText(TagPatternNum); + if (*patternNumberCached == unknownCharacter) + { + *patternNumberCached = UniqueTagText(TagPatternNum); + } + return *patternNumberCached; } //--------------------------------------------------------------------------------------------------------------------- void VAbstractPattern::SetPatternNumber(const QString& qsNum) { + *patternNumberCached = qsNum; CheckTagExists(TagPatternNum); - setTagText(TagPatternNum, qsNum); + setTagText(TagPatternNum, *patternNumberCached); patternLabelWasChanged = true; modified = true; emit patternChanged(false); @@ -1367,23 +1406,34 @@ void VAbstractPattern::SetCustomerName(const QString& qsName) //--------------------------------------------------------------------------------------------------------------------- QString VAbstractPattern::GetLabelDateFormat() const { - QString globalLabelDateFormat = qApp->Settings()->GetLabelDateFormat(); - - const QDomNodeList list = elementsByTagName(TagPatternLabel); - if (list.isEmpty()) + if (*labelDateFormatCached == unknownCharacter) { - return globalLabelDateFormat; - } + const QString globalLabelDateFormat = qApp->Settings()->GetLabelDateFormat(); - QDomElement tag = list.at(0).toElement(); - return GetParametrString(tag, AttrDateFormat, globalLabelDateFormat); + const QDomNodeList list = elementsByTagName(TagPatternLabel); + if (list.isEmpty()) + { + return globalLabelDateFormat; + } + + try + { + *labelDateFormatCached = GetParametrString(list.at(0).toElement(), AttrDateFormat); + } + catch (const VExceptionEmptyParameter &) + { + return globalLabelDateFormat; + } + } + return *labelDateFormatCached; } //--------------------------------------------------------------------------------------------------------------------- void VAbstractPattern::SetLabelDateFormat(const QString &format) { + *labelDateFormatCached = format; QDomElement tag = CheckTagExists(TagPatternLabel); - SetAttribute(tag, AttrDateFormat, format); + SetAttribute(tag, AttrDateFormat, *labelDateFormatCached); patternLabelWasChanged = true; modified = true; emit patternChanged(false); diff --git a/src/libs/ifc/xml/vabstractpattern.h b/src/libs/ifc/xml/vabstractpattern.h index 8e154bdeb..5fc80e416 100644 --- a/src/libs/ifc/xml/vabstractpattern.h +++ b/src/libs/ifc/xml/vabstractpattern.h @@ -105,6 +105,8 @@ public: quint32 getCursor() const; void setCursor(const quint32 &value); + virtual void setXMLContent(const QString &fileName) override; + virtual void IncrementReferens(quint32 id) const=0; virtual void DecrementReferens(quint32 id) const=0; diff --git a/src/libs/ifc/xml/vdomdocument.cpp b/src/libs/ifc/xml/vdomdocument.cpp index 0533fe49b..63b26a8e0 100644 --- a/src/libs/ifc/xml/vdomdocument.cpp +++ b/src/libs/ifc/xml/vdomdocument.cpp @@ -62,6 +62,7 @@ #include #include #include +#include namespace { @@ -795,6 +796,65 @@ QString VDomDocument::Patch() const return v.at(2); } +//--------------------------------------------------------------------------------------------------------------------- +QString VDomDocument::GetFormatVersionStr() const +{ + const QDomNodeList nodeList = this->elementsByTagName(TagVersion); + if (nodeList.isEmpty()) + { + const QString errorMsg(tr("Couldn't get version information.")); + throw VException(errorMsg); + } + + if (nodeList.count() > 1) + { + const QString errorMsg(tr("Too many tags <%1> in file.").arg(TagVersion)); + throw VException(errorMsg); + } + + const QDomNode domNode = nodeList.at(0); + if (domNode.isNull() == false && domNode.isElement()) + { + const QDomElement domElement = domNode.toElement(); + if (domElement.isNull() == false) + { + return domElement.text(); + } + } + return QString(QStringLiteral("0.0.0")); +} + +//--------------------------------------------------------------------------------------------------------------------- +int VDomDocument::GetFormatVersion(const QString &version) +{ + ValidateVersion(version); + + const QStringList ver = version.split(QChar('.')); + + bool ok = false; + const int major = ver.at(0).toInt(&ok); + if (not ok) + { + return 0x0; + } + + ok = false; + const int minor = ver.at(1).toInt(&ok); + if (not ok) + { + return 0x0; + } + + ok = false; + const int patch = ver.at(2).toInt(&ok); + if (not ok) + { + return 0x0; + } + + return (major<<16)|(minor<<8)|(patch); +} + //--------------------------------------------------------------------------------------------------------------------- bool VDomDocument::setTagText(const QString &tag, const QString &text) { @@ -992,3 +1052,22 @@ void VDomDocument::SetLabelTemplate(QDomElement &element, const QVector &vector)const; + static void ValidateVersion(const QString &version); + protected slots: void RefreshElementIdCache(); diff --git a/src/libs/vmisc/literals.cpp b/src/libs/vmisc/literals.cpp index 1de623558..05c2e9e7d 100644 --- a/src/libs/vmisc/literals.cpp +++ b/src/libs/vmisc/literals.cpp @@ -34,3 +34,4 @@ const QString preferencesOtherIcon = QStringLiteral("preferences-other"); const QString degreeSymbol = QStringLiteral("°"); const QString trueStr = QStringLiteral("true"); const QString falseStr = QStringLiteral("false"); +const QString unknownCharacter = QStringLiteral("�"); diff --git a/src/libs/vmisc/literals.h b/src/libs/vmisc/literals.h index 3c3b57dfc..57313a0ed 100644 --- a/src/libs/vmisc/literals.h +++ b/src/libs/vmisc/literals.h @@ -40,5 +40,6 @@ extern const QString preferencesOtherIcon; extern const QString degreeSymbol; extern const QString trueStr; extern const QString falseStr; +extern const QString unknownCharacter; #endif // LITERALS_H