From 078f6fad646d7fe13493c2363a7241947ea77d55 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 9 Jan 2020 18:56:37 +0200 Subject: [PATCH] Tracking changes/prevent "OK" recalculation after "Apply". --HG-- branch : develop --- ChangeLog.txt | 1 + src/libs/ifc/xml/vdomdocument.cpp | 123 ++++++++++++++ src/libs/ifc/xml/vdomdocument.h | 2 + src/libs/vtools/tools/drawTools/vdrawtool.cpp | 11 +- src/test/ValentinaTest/ValentinaTest.pro | 2 + src/test/ValentinaTest/qttestmainlambda.cpp | 1 + src/test/ValentinaTest/tst_vdomdocument.cpp | 157 ++++++++++++++++++ src/test/ValentinaTest/tst_vdomdocument.h | 46 +++++ 8 files changed, 339 insertions(+), 4 deletions(-) create mode 100644 src/test/ValentinaTest/tst_vdomdocument.cpp create mode 100644 src/test/ValentinaTest/tst_vdomdocument.h diff --git a/ChangeLog.txt b/ChangeLog.txt index 23d29727f..a05da0315 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -37,6 +37,7 @@ - Added a ruler at the bottom of a tiled PDF document. - Export tiled PDF with watermark. - [#984] Issue with up to date list of unique names. +- Tracking changes/prevent "OK" recalculation after "Apply". # Version 0.6.2 (unreleased) - [#903] Bug in tool Cut Spline path. diff --git a/src/libs/ifc/xml/vdomdocument.cpp b/src/libs/ifc/xml/vdomdocument.cpp index aa02dd3bf..fb5fb5efd 100644 --- a/src/libs/ifc/xml/vdomdocument.cpp +++ b/src/libs/ifc/xml/vdomdocument.cpp @@ -120,6 +120,122 @@ void SaveNodeCanonically(QXmlStreamWriter &stream, const QDomNode &domNode) stream.writeCharacters(domNode.nodeValue()); } } + +//--------------------------------------------------------------------------------------------------------------------- +QList GetChildElements(const QDomNode& e) +{ + QDomNodeList children = e.childNodes(); + QList r; + r.reserve(children.size()); + for (int k = 0; k < children.size(); ++k) + { + r << children.at(k); + } + return r; +} + +//--------------------------------------------------------------------------------------------------------------------- +QList GetElementAttributes(const QDomNode& e) +{ + QDomNamedNodeMap attributes = e.attributes(); + QList r; + r.reserve(attributes.size()); + for (int k = 0; k < attributes.size(); ++k) + { + r << attributes.item(k); + } + return r; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool LessThen(const QDomNode &element1, const QDomNode &element2) +{ + if (element1.nodeType() != element2.nodeType()) + { + return element1.nodeType() < element2.nodeType(); + } + + QString tag1 = element1.nodeName(); + QString tag2 = element2.nodeName(); + + //qDebug() << tag1 < attributes1 = GetElementAttributes(element1); + QList attributes2 = GetElementAttributes(element2); + + if(attributes1.size() != attributes2.size()) + { + return attributes1.size() < attributes2.size(); + } + + bool stop = false; + + auto CompareDomNodeLists = [&stop](QList list1, QList list2) + { + stop = false; + std::sort(list1.begin(), list1.end(), LessThen); + std::sort(list2.begin(), list2.end(), LessThen); + //qDebug() << "comparing sorted lists"; + for(int k = 0; k < list1.size(); ++k) + { + if (!LessThen(list1[k], list2[k])) + { + if (LessThen(list2[k], list1[k])) + { + stop = true; + //qDebug() << "false!"; + return false; + } + } + else + { + stop = true; + //qDebug() << "true!"; + return true; + } + } + return false; + }; + + bool result = CompareDomNodeLists(attributes1, attributes2); + if (stop) + { + return result; + } + + // Compare children + QList elts1 = GetChildElements(element1); + QList elts2 = GetChildElements(element2); + + QString value1, value2; + + if(elts1.size() != elts2.size()) + { + return elts1.size() < elts2.size(); + } + + if(elts1.isEmpty()) + { + value1 = element1.nodeValue(); + value2 = element2.nodeValue(); + + //qDebug() < lessThen2 = QtConcurrent::run(LessThen, element2, element1); + return !LessThen(element1, element2) && !lessThen2.result(); +} + //--------------------------------------------------------------------------------------------------------------------- void VDomDocument::CacheRefreshed() { diff --git a/src/libs/ifc/xml/vdomdocument.h b/src/libs/ifc/xml/vdomdocument.h index 3ec22a924..631ded651 100644 --- a/src/libs/ifc/xml/vdomdocument.h +++ b/src/libs/ifc/xml/vdomdocument.h @@ -147,6 +147,8 @@ public: void RefreshElementIdCache(); + static bool Compare(const QDomElement &element1, const QDomElement &element2); + protected: bool setTagText(const QString &tag, const QString &text); bool setTagText(const QDomElement &domElement, const QString &text); diff --git a/src/libs/vtools/tools/drawTools/vdrawtool.cpp b/src/libs/vtools/tools/drawTools/vdrawtool.cpp index 1050fdb7b..318077831 100644 --- a/src/libs/vtools/tools/drawTools/vdrawtool.cpp +++ b/src/libs/vtools/tools/drawTools/vdrawtool.cpp @@ -115,10 +115,13 @@ void VDrawTool::SaveDialogChange(const QString &undoText) QList newDependencies; SaveDialog(newDomElement, oldDependencies, newDependencies); - SaveToolOptions *saveOptions = new SaveToolOptions(oldDomElement, newDomElement, oldDependencies, - newDependencies, doc, m_id); - connect(saveOptions, &SaveToolOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); - qApp->getUndoStack()->push(saveOptions); + if (newDependencies != oldDependencies || not VDomDocument::Compare(newDomElement, oldDomElement)) + { + SaveToolOptions *saveOptions = new SaveToolOptions(oldDomElement, newDomElement, oldDependencies, + newDependencies, doc, m_id); + connect(saveOptions, &SaveToolOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(saveOptions); + } } else { diff --git a/src/test/ValentinaTest/ValentinaTest.pro b/src/test/ValentinaTest/ValentinaTest.pro index b09fd98ad..86a3f3808 100644 --- a/src/test/ValentinaTest/ValentinaTest.pro +++ b/src/test/ValentinaTest/ValentinaTest.pro @@ -52,6 +52,7 @@ DEFINES += SRCDIR=\\\"$$PWD/\\\" SOURCES += \ qttestmainlambda.cpp \ + tst_vdomdocument.cpp \ tst_vposter.cpp \ tst_vspline.cpp \ tst_nameregexp.cpp \ @@ -78,6 +79,7 @@ SOURCES += \ *msvc*:SOURCES += stable.cpp HEADERS += \ + tst_vdomdocument.h \ tst_vposter.h \ tst_vspline.h \ tst_nameregexp.h \ diff --git a/src/test/ValentinaTest/qttestmainlambda.cpp b/src/test/ValentinaTest/qttestmainlambda.cpp index d066ca849..740d7fa27 100644 --- a/src/test/ValentinaTest/qttestmainlambda.cpp +++ b/src/test/ValentinaTest/qttestmainlambda.cpp @@ -50,6 +50,7 @@ #include "tst_readval.h" #include "tst_vtranslatevars.h" #include "tst_vtooluniondetails.h" +#include "tst_vdomdocument.h" #include "../vmisc/def.h" #include "../qmuparser/qmudef.h" diff --git a/src/test/ValentinaTest/tst_vdomdocument.cpp b/src/test/ValentinaTest/tst_vdomdocument.cpp new file mode 100644 index 000000000..967981f1d --- /dev/null +++ b/src/test/ValentinaTest/tst_vdomdocument.cpp @@ -0,0 +1,157 @@ +/************************************************************************ + ** + ** @file tst_vdomdocument.cpp + ** @author Roman Telezhynskyi + ** @date 9 1, 2020 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentina project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2020 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ +#include "tst_vdomdocument.h" + +#include +#include "../ifc/xml/vdomdocument.h" + +//--------------------------------------------------------------------------------------------------------------------- +TST_VDomDocument::TST_VDomDocument(QObject *parent) + :QObject(parent) +{ +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VDomDocument::TestCompareDomElements_data() +{ + QTest::addColumn("element1Content"); + QTest::addColumn("element2Content"); + QTest::addColumn("compare"); + + QTest::newRow("Base point") + << "" + << "" + << true; + + QTest::newRow("Base point. Change attribute order") + << "" + << "" + << true; + + QTest::newRow("Base point. Change attribute value") + << "" + << "" + << false; + + QTest::newRow("Dirrent types") + << "" + << "" + << false; + + QTest::newRow("Equal details") + << "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + << "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + << true; + QTest::newRow("Not equal details") + << "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + << "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + << false; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_VDomDocument::TestCompareDomElements() +{ + QFETCH(QString, element1Content); + QFETCH(QString, element2Content); + QFETCH(bool, compare); + + QDomDocument xmlDoc; + + QVERIFY(xmlDoc.setContent(element1Content)); + QDomElement element1 = xmlDoc.firstChild().toElement(); + + QVERIFY(xmlDoc.setContent(element2Content)); + QDomElement element2 = xmlDoc.firstChild().toElement(); + + const bool result = VDomDocument::Compare(element1, element2); + QCOMPARE(compare, result); +} diff --git a/src/test/ValentinaTest/tst_vdomdocument.h b/src/test/ValentinaTest/tst_vdomdocument.h new file mode 100644 index 000000000..a07990589 --- /dev/null +++ b/src/test/ValentinaTest/tst_vdomdocument.h @@ -0,0 +1,46 @@ +/************************************************************************ + ** + ** @file tst_vdomdocument.h + ** @author Roman Telezhynskyi + ** @date 9 1, 2020 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentina project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2020 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ +#ifndef TST_VDOMDOCUMENT_H +#define TST_VDOMDOCUMENT_H + +#include + +class TST_VDomDocument :public QObject +{ + Q_OBJECT +public: + explicit TST_VDomDocument(QObject *parent = nullptr); + +private slots: + void TestCompareDomElements_data(); + void TestCompareDomElements(); +private: + Q_DISABLE_COPY(TST_VDomDocument) +}; + +#endif // TST_VDOMDOCUMENT_H