From 67b7e7545986c398958b3ce951ab5c35c70fadf8 Mon Sep 17 00:00:00 2001 From: Gennady Pospelov <g.pospelov@fz-juelich.de> Date: Tue, 19 Apr 2016 14:04:48 +0200 Subject: [PATCH] Message service restored, minimal supported project version introduced. --- GUI/coregui/Models/SessionModel.cpp | 27 +--- GUI/coregui/Models/SessionModel.h | 13 +- GUI/coregui/Models/SessionXML.cpp | 137 ++++++++++++------ GUI/coregui/Models/SessionXML.h | 11 +- GUI/coregui/mainwindow/projectdocument.cpp | 17 ++- GUI/coregui/utils/GUIHelpers.cpp | 32 ++++ GUI/coregui/utils/GUIHelpers.h | 4 + Tests/UnitTests/TestGUI/TestFormFactorItems.h | 1 - Tests/UnitTests/TestGUI/TestGUI.cpp | 3 + Tests/UnitTests/TestGUI/TestGUIHelpers.h | 35 +++++ 10 files changed, 193 insertions(+), 87 deletions(-) create mode 100644 Tests/UnitTests/TestGUI/TestGUIHelpers.h diff --git a/GUI/coregui/Models/SessionModel.cpp b/GUI/coregui/Models/SessionModel.cpp index b50a56566a7..171999d4533 100644 --- a/GUI/coregui/Models/SessionModel.cpp +++ b/GUI/coregui/Models/SessionModel.cpp @@ -33,10 +33,6 @@ namespace { const int MaxCompression = 9; - -const QString SET_ITEM_PROPERTY_ERROR = "SET_ITEM_PROPERTY_ERROR"; -const QString ITEM_IS_NOT_INITIALIZED = "ITEM_IS_NOT_INITIALIZED"; -const QString NON_EXISTING_SUBITEM = "NON_EXISTING_SUBITEM"; } SessionModel::SessionModel(QString model_tag, QObject *parent) @@ -44,7 +40,6 @@ SessionModel::SessionModel(QString model_tag, QObject *parent) , m_root_item(0) , m_name("DefaultName") , m_model_tag(model_tag) - , m_messageService(0) { createRootItem(); } @@ -348,7 +343,7 @@ SessionItem *SessionModel::itemForIndex(const QModelIndex &index) const return m_root_item; } -void SessionModel::readFrom(QXmlStreamReader *reader) +void SessionModel::readFrom(QXmlStreamReader *reader, WarningMessageService *messageService) { Q_ASSERT(reader); @@ -365,7 +360,7 @@ void SessionModel::readFrom(QXmlStreamReader *reader) createRootItem(); - SessionReader::readItems(reader, m_root_item); + SessionReader::readItems(reader, m_root_item, QString(), messageService); if (reader->hasError()) throw GUIHelpers::Error(reader->errorString()); endResetModel(); @@ -374,9 +369,6 @@ void SessionModel::readFrom(QXmlStreamReader *reader) void SessionModel::writeTo(QXmlStreamWriter *writer, SessionItem *parent) { - // MOVED OUT TO SessionXML.h - - qDebug() << "SessionModel::writeTo"; if (!parent) parent = m_root_item; SessionWriter::writeTo(writer, parent); @@ -488,11 +480,6 @@ SessionItem *SessionModel::getTopItem(const QString &model_type, return result; } -void SessionModel::setMessageService(WarningMessageService *messageService) -{ - m_messageService = messageService; -} - void SessionModel::initFrom(SessionModel *model, SessionItem *parent) { qDebug() << "SessionModel::initFrom() -> " << model->getModelTag() << parent; @@ -512,16 +499,6 @@ void SessionModel::initFrom(SessionModel *model, SessionItem *parent) } } -//! reports error -void SessionModel::report_error(const QString &error_type, const QString &message) -{ - if(m_messageService) { - m_messageService->send_message(this, error_type, message); - } else { - throw GUIHelpers::Error(error_type + QString(" ") + message); - } -} - SessionItem* SessionModel::rootItem() const{ return m_root_item; } diff --git a/GUI/coregui/Models/SessionModel.h b/GUI/coregui/Models/SessionModel.h index 4f1e616a16a..f417a2df441 100644 --- a/GUI/coregui/Models/SessionModel.h +++ b/GUI/coregui/Models/SessionModel.h @@ -20,9 +20,7 @@ #include <QAbstractItemModel> #include <QtCore/QXmlStreamReader> #include <QtCore/QXmlStreamWriter> - #include "SessionItem.h" - #include "SessionXML.h" class IconProvider; @@ -91,7 +89,7 @@ public: // Returns root item if index is not valid SessionItem *itemForIndex(const QModelIndex &index) const; - void readFrom(QXmlStreamReader *reader); + void readFrom(QXmlStreamReader *reader, WarningMessageService *messageService=0); void writeTo(QXmlStreamWriter *writer, SessionItem *parent = 0); SessionItem *moveParameterizedItem(SessionItem *item, @@ -110,27 +108,18 @@ public: SessionItem *getTopItem(const QString &model_type = QString(), const QString &item_name = QString()) const; - void setMessageService(WarningMessageService *messageService); - virtual void initFrom(SessionModel *model, SessionItem *parent); SessionItem* rootItem() const; - - - protected: void setRootItem(SessionItem *root) {m_root_item = root;} private: - - void report_error(const QString &error_type, const QString &message); - SessionItem *m_root_item; QString m_dragged_item_type; QString m_name; //!< model name QString m_model_tag; //!< model tag (SampleModel, InstrumentModel) std::unique_ptr<IconProvider> m_iconProvider; - WarningMessageService *m_messageService; }; inline bool SessionModel::setHeaderData(int, Qt::Orientation, const QVariant &, int) diff --git a/GUI/coregui/Models/SessionXML.cpp b/GUI/coregui/Models/SessionXML.cpp index 07e3c3df49b..923c2c02e0c 100644 --- a/GUI/coregui/Models/SessionXML.cpp +++ b/GUI/coregui/Models/SessionXML.cpp @@ -26,10 +26,16 @@ #include "GUIHelpers.h" #include "ItemFactory.h" #include "GroupItem.h" - +#include "WarningMessageService.h" #include <QXmlStreamWriter> #include <QDebug> +namespace +{ +const QString SET_ITEM_PROPERTY_ERROR = "SET_ITEM_PROPERTY_ERROR"; +const QString ITEM_IS_NOT_INITIALIZED = "ITEM_IS_NOT_INITIALIZED"; +const QString NON_EXISTING_SUBITEM = "NON_EXISTING_SUBITEM"; +} void SessionWriter::writeTo(QXmlStreamWriter *writer, SessionItem *parent) { @@ -136,14 +142,17 @@ void SessionWriter::writeVariant(QXmlStreamWriter *writer, QVariant variant, int QString::number(value, 'g')); writer->writeAttribute(SessionXML::AngleUnitsAttribute, variant.value<AngleProperty>().getUnits()); + } else { throw GUIHelpers::Error("SessionModel::writeProperty: Parameter type not supported " + type_name); } + writer->writeEndElement(); // end ParameterTag } } -void SessionReader::readItems(QXmlStreamReader *reader, SessionItem *item, const QString &topTag) +void SessionReader::readItems(QXmlStreamReader *reader, SessionItem *item, const QString &topTag, + WarningMessageService *messageService) { bool isTopItem = true; qDebug() << "SessionModel::readItems() item:" << item << "topTag:" << topTag; @@ -162,39 +171,53 @@ void SessionReader::readItems(QXmlStreamReader *reader, SessionItem *item, const if (tag == SessionItem::P_NAME) item->setItemName(""); if (model_type == Constants::PropertyType || model_type == Constants::GroupItemType) { - item = item->getItem(tag); - if (!item) { - qDebug() << "!!"; + SessionItem *newItem = item->getItem(tag); + if (!newItem) { + QString message = QString("Unrecoverable read error for model '%1', " + "Can't get item for tag '%2'").arg(item->model()->getModelTag()).arg(tag); + throw GUIHelpers::Error(message); } - Q_ASSERT(item); + item = newItem; + } else if (item->modelType() == Constants::GroupItemType) { - item = item->parent()->getGroupItem(item->parent()->tagFromItem(item), model_type); - if (!item) { - qDebug() << "!!"; + SessionItem *newItem = item->parent()->getGroupItem(item->parent() + ->tagFromItem(item), model_type); + if (!newItem) { + QString message = QString("Unrecoverable read error for model '%1', " + "Can't get group item").arg(item->model()->getModelTag()); + throw GUIHelpers::Error(message); } - Q_ASSERT(item); + item = newItem; } else { if (tag == "") tag = item->defaultTag(); - SessionItem *new_item(0); + SessionItem *newItem(0); SessionTagInfo info = item->getTagInfo(tag); if (info.min == 1 && info.max == 1 && info.childCount == 1) { - new_item = item->getItem(tag); + newItem = item->getItem(tag); } else { - new_item = ItemFactory::createItem(model_type); - if (!item->insertItem(-1, new_item, tag)) { - Q_ASSERT(0); + newItem = ItemFactory::createItem(model_type); + if (!item->insertItem(-1, newItem, tag)) { + QString message = QString("Attempt to create item '%1' for tag '%2' failed") + .arg(model_type).arg(tag); + report_error(messageService, item, ITEM_IS_NOT_INITIALIZED, message); + return; } } - Q_ASSERT(new_item); + if (!newItem) { + QString message = QString("Unrecoverable read error for model '%1', " + "Can't add item for tag").arg(item->model()->getModelTag()).arg(tag); + throw GUIHelpers::Error(message); + } + if (reader->attributes().hasAttribute(SessionXML::DisplayNameAttribute)) { - new_item->setDisplayName(reader->attributes().value(SessionXML::DisplayNameAttribute).toString()); + newItem->setDisplayName(reader->attributes().value(SessionXML::DisplayNameAttribute).toString()); } - item = new_item; + item = newItem; } if (!item) { // tag = -1; @@ -204,7 +227,7 @@ void SessionReader::readItems(QXmlStreamReader *reader, SessionItem *item, const isTopItem = false; } else if (reader->name() == SessionXML::ParameterTag) { - readProperty(reader, item); + readProperty(reader, item, messageService); } } else if (reader->isEndElement()) { if (reader->name() == SessionXML::ItemTag) { @@ -213,6 +236,7 @@ void SessionReader::readItems(QXmlStreamReader *reader, SessionItem *item, const } else { // handling the case when reading obsolete project file, when SubItem doesn't exist anymore qDebug() << "!!"; + Q_ASSERT(0); } } if (reader->name() == modelType) { @@ -224,7 +248,8 @@ void SessionReader::readItems(QXmlStreamReader *reader, SessionItem *item, const } } -QString SessionReader::readProperty(QXmlStreamReader *reader, SessionItem *item) +QString SessionReader::readProperty(QXmlStreamReader *reader, + SessionItem *item, WarningMessageService *messageService) { // qDebug() << "SessionModel::readProperty() for" << item; if (item) @@ -235,48 +260,50 @@ QString SessionReader::readProperty(QXmlStreamReader *reader, SessionItem *item) = reader->attributes().value(SessionXML::ParameterTypeAttribute).toString(); const int role = reader->attributes().value(SessionXML::ParameterRoleAttribute).toInt(); - // qDebug() << " SessionModel::readProperty " << item->itemName() << item->modelType() - // << parameter_name << parameter_type << parameter_name.toUtf8().constData(); if(!item) { QString message = QString("Attempt to set property '%1' for non existing item") .arg(parameter_name); -// report_error(ITEM_IS_NOT_INITIALIZED, message); + report_error(messageService, item, ITEM_IS_NOT_INITIALIZED, message); return parameter_name; } -// if(!item->isRegisteredTag(parameter_name)) { -// QString message = QString("Unknown property '%1' for item type '%2'") -// .arg(parameter_name).arg(item->modelType()); -//// report_error(SET_ITEM_PROPERTY_ERROR, message); -// return parameter_name; -// } QVariant variant; if (parameter_type == "double") { double parameter_value = reader->attributes().value(SessionXML::ParameterValueAttribute).toDouble(); variant = parameter_value; - } else if (parameter_type == "int") { + } + + else if (parameter_type == "int") { int parameter_value = reader->attributes().value(SessionXML::ParameterValueAttribute).toInt(); variant = parameter_value; - } else if (parameter_type == "bool") { + } + + else if (parameter_type == "bool") { bool parameter_value = reader->attributes().value(SessionXML::ParameterValueAttribute).toInt(); variant = parameter_value; - } else if (parameter_type == "QString") { + } + + else if (parameter_type == "QString") { QString parameter_value = reader->attributes().value(SessionXML::ParameterValueAttribute).toString(); variant = parameter_value; - } else if (parameter_type == "MaterialProperty") { + } + + else if (parameter_type == "MaterialProperty") { QString identifier = reader->attributes().value(SessionXML::IdentifierAttribute).toString(); MaterialProperty material_property(identifier); variant = material_property.getVariant(); - } else if (parameter_type == "ComboProperty") { + } + + else if (parameter_type == "ComboProperty") { QString parameter_value = reader->attributes().value(SessionXML::ParameterValueAttribute).toString(); @@ -287,7 +314,9 @@ QString SessionReader::readProperty(QXmlStreamReader *reader, SessionItem *item) } combo_property.setCachedValue(parameter_value); variant = combo_property.getVariant(); - } else if (parameter_type == "ScientificDoubleProperty") { + } + + else if (parameter_type == "ScientificDoubleProperty") { double parameter_value = reader->attributes().value(SessionXML::ParameterValueAttribute).toDouble(); @@ -295,22 +324,34 @@ QString SessionReader::readProperty(QXmlStreamReader *reader, SessionItem *item) QVariant v; v.setValue(scdouble_property); variant = v; - } else if (parameter_type == "GroupProperty_t") { + } + + else if (parameter_type == "GroupProperty_t") { QString parameter_value = reader->attributes().value(SessionXML::ParameterValueAttribute).toString(); - GroupProperty_t group_property - = item->value().value<GroupProperty_t>(); - group_property->setCurrentType(parameter_value); - variant = QVariant::fromValue<GroupProperty_t>(group_property); - } else if (parameter_type == "ColorProperty") { + QVariant v = item->value(); + if(!v.canConvert<GroupProperty_t>()) { + report_error(messageService, item, SET_ITEM_PROPERTY_ERROR, + QStringLiteral("GroupProperty conversion failed")); + } else { + GroupProperty_t group_property = v.value<GroupProperty_t>(); + group_property->setCurrentType(parameter_value); + variant = QVariant::fromValue<GroupProperty_t>(group_property); + } + + } + + else if (parameter_type == "ColorProperty") { int r = reader->attributes().value(SessionXML::ColorRedAttribute).toInt(); int g = reader->attributes().value(SessionXML::ColorGreenAttribute).toInt(); int b = reader->attributes().value(SessionXML::ColorBlueAttribute).toInt(); int a = reader->attributes().value(SessionXML::ColorAlphaAttribute).toInt(); ColorProperty color(QColor(r, g, b, a)); variant = color.getVariant(); - } else if (parameter_type == "AngleProperty") { + } + + else if (parameter_type == "AngleProperty") { double parameter_value = reader->attributes().value(SessionXML::ParameterValueAttribute).toDouble(); QString units = reader->attributes().value(SessionXML::AngleUnitsAttribute).toString(); @@ -323,9 +364,21 @@ QString SessionReader::readProperty(QXmlStreamReader *reader, SessionItem *item) throw GUIHelpers::Error("SessionModel::readProperty: " "Parameter type not supported" + parameter_type); } + if (variant.isValid()) { item->setData(role, variant); } return parameter_name; } + +void SessionReader::report_error(WarningMessageService *messageService, + SessionItem *item, const QString &error_type, + const QString &message) +{ + if(messageService) { + messageService->send_message(item->model(), error_type, message); + } else { + throw GUIHelpers::Error(error_type + QString(" ") + message); + } +} diff --git a/GUI/coregui/Models/SessionXML.h b/GUI/coregui/Models/SessionXML.h index f285ddb0231..1874463fbbe 100644 --- a/GUI/coregui/Models/SessionXML.h +++ b/GUI/coregui/Models/SessionXML.h @@ -24,6 +24,7 @@ class QXmlStreamWriter; class QXmlStreamReader; class SessionItem; +class WarningMessageService; namespace SessionXML { const QString MimeType = "application/org.bornagainproject.xml.item.z"; @@ -71,9 +72,15 @@ private: class BA_CORE_API_ SessionReader { public: - static void readItems(QXmlStreamReader *reader, SessionItem *item, const QString &topTag = QString()); + static void readItems(QXmlStreamReader *reader, SessionItem *item, + const QString &topTag = QString(), + WarningMessageService *messageService=0); private: - static QString readProperty(QXmlStreamReader *reader, SessionItem *item); + static QString readProperty(QXmlStreamReader *reader, SessionItem *item, + WarningMessageService *messageService=0); + + static void report_error(WarningMessageService *messageService, SessionItem *item, + const QString &error_type, const QString &message); }; #endif // SESSIONXML_H diff --git a/GUI/coregui/mainwindow/projectdocument.cpp b/GUI/coregui/mainwindow/projectdocument.cpp index c8e9fe26608..0cd11ee9f9d 100644 --- a/GUI/coregui/mainwindow/projectdocument.cpp +++ b/GUI/coregui/mainwindow/projectdocument.cpp @@ -44,6 +44,7 @@ namespace { const QString OPEN_FILE_ERROR = "OPEN_FILE_ERROR"; const QString EXCEPTION_THROW = "EXCEPTION_THROW"; const QString XML_FORMAT_ERROR = "XML_FORMAT_ERROR"; +const QString minimal_supported_version = "1.5.0"; } ProjectDocument::ProjectDocument() @@ -202,7 +203,6 @@ QString ProjectDocument::getDocumentVersion() const { QString result(m_currentVersion); if(result.isEmpty()) result = GUIHelpers::getBornAgainVersionString(); - return QString("1.2.0"); return result; } @@ -223,6 +223,15 @@ void ProjectDocument::readFrom(QIODevice *device) m_currentVersion = reader.attributes() .value(ProjectDocumentXML::BornAgainVersionAttribute) .toString(); + if(!GUIHelpers::isVersionMatchMinimal(m_currentVersion, minimal_supported_version)) { + m_documentStatus = EDocumentStatus(m_documentStatus | STATUS_FAILED); + QString message = QString("Can't open document version '%1', " + "minimal supported version '%2'").arg(m_currentVersion) + .arg(minimal_supported_version); + m_messageService->send_message(this, OPEN_FILE_ERROR, message); + return; + } + } else if (reader.name() == ProjectDocumentXML::InfoTag) { @@ -289,14 +298,12 @@ void ProjectDocument::writeTo(QIODevice *device) void ProjectDocument::readModel(SessionModel *model, QXmlStreamReader *reader) { - model->setMessageService(m_messageService); - - model->readFrom(reader); +// model->setMessageService(m_messageService); + model->readFrom(reader, m_messageService); if(m_messageService->hasWarnings(model)) { m_documentStatus = EDocumentStatus(m_documentStatus|STATUS_WARNING); } - model->setMessageService(0); } //! Adjusts name of IntensityData item to possibly changed name of JobItem. Take care of old diff --git a/GUI/coregui/utils/GUIHelpers.cpp b/GUI/coregui/utils/GUIHelpers.cpp index 871e41d5aa0..ca8bd6cbae5 100644 --- a/GUI/coregui/utils/GUIHelpers.cpp +++ b/GUI/coregui/utils/GUIHelpers.cpp @@ -150,5 +150,37 @@ QString getValidFileName(const QString &proposed_name) return result; } +//! parses version string into 3 numbers, returns true in the case of success +bool parseVersion(const QString &version, int &major_num, int &minor_num, int &patch_num) +{ + major_num = minor_num = patch_num = 0; + bool success(true); + QStringList nums = version.split(QStringLiteral(".")); + if(nums.size() != 3) return false; + + bool ok(false); + major_num = nums.at(0).toInt(&ok); success &= ok; + minor_num = nums.at(1).toInt(&ok); success &= ok; + patch_num = nums.at(2).toInt(&ok); success &= ok; + + return success; +} + + +//! returns true if current BornAgain version match minimal required version +bool isVersionMatchMinimal(const QString &version, const QString &minimal_version) +{ + int ba_major(0), ba_minor(0), ba_patch(0); + if(!parseVersion(version, ba_major, ba_minor, ba_patch)) + return false; + + int minv_major(0), minv_minor(0), minv_patch(0); + if(!parseVersion(minimal_version, minv_major, minv_minor, minv_patch)) + return false; + + int ba = ba_major*10000 + ba_minor*100 + ba_patch; + int minv = minv_major*10000 + minv_minor*100 + minv_patch; + return ba >= minv; +} } // namespace GUIHelpers diff --git a/GUI/coregui/utils/GUIHelpers.h b/GUI/coregui/utils/GUIHelpers.h index 4bec92f55f6..f87765365f5 100644 --- a/GUI/coregui/utils/GUIHelpers.h +++ b/GUI/coregui/utils/GUIHelpers.h @@ -57,6 +57,10 @@ BA_CORE_API_ QString getBornAgainVersionString(); BA_CORE_API_ QString getValidFileName(const QString &proposed_name); +BA_CORE_API_ bool parseVersion(const QString &version, int &major_num, int &minor_num, int &patch_num); + +BA_CORE_API_ bool isVersionMatchMinimal(const QString &version, const QString &minimal_version); + template<class T, class... Ts> std::unique_ptr<T> make_unique(Ts&&... params) { return std::unique_ptr<T>(new T(std::forward<Ts>(params)...)); diff --git a/Tests/UnitTests/TestGUI/TestFormFactorItems.h b/Tests/UnitTests/TestGUI/TestFormFactorItems.h index 6ec81cebc0f..1680afb36dd 100644 --- a/Tests/UnitTests/TestGUI/TestFormFactorItems.h +++ b/Tests/UnitTests/TestGUI/TestFormFactorItems.h @@ -1,7 +1,6 @@ #ifndef TESTFORMFACTORITEMS_H #define TESTFORMFACTORITEMS_H - #include <QtTest> #include "FormFactors.h" #include "FormFactorItems.h" diff --git a/Tests/UnitTests/TestGUI/TestGUI.cpp b/Tests/UnitTests/TestGUI/TestGUI.cpp index c99f1fc2fa3..bffe0132159 100644 --- a/Tests/UnitTests/TestGUI/TestGUI.cpp +++ b/Tests/UnitTests/TestGUI/TestGUI.cpp @@ -14,6 +14,7 @@ #include "TestGUICoreObjectCorrespondence.h" #include "TestMapperForItem.h" #include "TestParticleDistributionItem.h" +#include "TestGUIHelpers.h" int main(int argc, char** argv) { QCoreApplication app(argc, argv); @@ -31,6 +32,7 @@ int main(int argc, char** argv) { TestMapperCases testMapperCases; TestMapperForItem testMapperForItem; TestParticleDistributionItem testParticleDistributionItem; + TestGUIHelpers testGUIHelpers; bool status(false); @@ -47,6 +49,7 @@ int main(int argc, char** argv) { status |= QTest::qExec(&testSessionModel, argc, argv); status |= QTest::qExec(&testMapperForItem, argc, argv); status |= QTest::qExec(&testParticleDistributionItem, argc, argv); + status |= QTest::qExec(&testGUIHelpers, argc, argv); return status; } diff --git a/Tests/UnitTests/TestGUI/TestGUIHelpers.h b/Tests/UnitTests/TestGUI/TestGUIHelpers.h new file mode 100644 index 00000000000..9500889b1e9 --- /dev/null +++ b/Tests/UnitTests/TestGUI/TestGUIHelpers.h @@ -0,0 +1,35 @@ +#ifndef TESTGUIHELPERS_H +#define TESTGUIHELPERS_H + +#include <QtTest> +#include "GUIHelpers.h" + +class TestGUIHelpers : public QObject { + Q_OBJECT + +private slots: + void test_VersionString(); +}; + +inline void TestGUIHelpers::test_VersionString() +{ + int vmajor(0), vminor(0), vpatch(0); + + QCOMPARE(true, GUIHelpers::parseVersion(QString("1.5.0"), vmajor, vminor, vpatch)); + QCOMPARE(1, vmajor); + QCOMPARE(5, vminor); + QCOMPARE(0, vpatch); + + QCOMPARE(false, GUIHelpers::parseVersion(QString("15.0"), vmajor, vminor, vpatch)); + + QString min_version("1.5.0"); + QCOMPARE(GUIHelpers::isVersionMatchMinimal("1.5.0", min_version), true); + QCOMPARE(GUIHelpers::isVersionMatchMinimal("1.5.1", min_version), true); + QCOMPARE(GUIHelpers::isVersionMatchMinimal("1.6.0", min_version), true); + QCOMPARE(GUIHelpers::isVersionMatchMinimal("2.4.9", min_version), true); + + QCOMPARE(GUIHelpers::isVersionMatchMinimal("1.4.9", min_version), false); + QCOMPARE(GUIHelpers::isVersionMatchMinimal("0.6.9", min_version), false); +} + +#endif -- GitLab