diff --git a/Valentina.pro b/Valentina.pro index 78f02f597..1749518c6 100644 --- a/Valentina.pro +++ b/Valentina.pro @@ -6,7 +6,7 @@ # Use out-of-source builds (shadow builds) -QT += core gui widgets xml svg printsupport +QT += core gui widgets xml svg printsupport xmlpatterns TEMPLATE = app @@ -44,7 +44,8 @@ include(src/xml/xml.pri) RESOURCES += \ share/resources/icon.qrc \ share/resources/cursor.qrc \ - share/resources/theme.qrc + share/resources/theme.qrc \ + share/resources/schema.qrc OTHER_FILES += share/resources/valentina.rc \ share/resources/icon/64x64/icon64x64.ico diff --git a/share/resources/schema.qrc b/share/resources/schema.qrc new file mode 100644 index 000000000..ddc4b4e88 --- /dev/null +++ b/share/resources/schema.qrc @@ -0,0 +1,5 @@ + + + schema/pattern.xsd + + diff --git a/share/resources/schema/pattern.xsd b/share/resources/schema/pattern.xsd new file mode 100644 index 000000000..afc28d690 --- /dev/null +++ b/share/resources/schema/pattern.xsd @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/exception/vexception.cpp b/src/exception/vexception.cpp index 478a7613f..3778f3341 100644 --- a/src/exception/vexception.cpp +++ b/src/exception/vexception.cpp @@ -27,6 +27,7 @@ *************************************************************************/ #include "vexception.h" +#include VException::VException(const QString &what):QException(), what(what) { @@ -38,3 +39,19 @@ QString VException::ErrorMessage() const QString error = QString("Exception: %1").arg(what); return error; } + +void VException::CriticalMessageBox(const QString &situation) const +{ + QMessageBox msgBox; + msgBox.setWindowTitle("Critical error!"); + msgBox.setText(situation); + msgBox.setInformativeText(ErrorMessage()); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + if (DetailedInformation().isEmpty() == false) + { + msgBox.setDetailedText(DetailedInformation()); + } + msgBox.setIcon(QMessageBox::Critical); + msgBox.exec(); +} diff --git a/src/exception/vexception.h b/src/exception/vexception.h index ce58a7e27..06e939891 100644 --- a/src/exception/vexception.h +++ b/src/exception/vexception.h @@ -74,6 +74,7 @@ public: * @return string with error */ inline QString What() const {return what;} + virtual void CriticalMessageBox(const QString &situation) const; protected: /** * @brief what string with error diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f29c7b2b1..d8dae5b8b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -43,6 +43,35 @@ #include #include #include +#include +#include +#include +#include + +class MessageHandler : public QAbstractMessageHandler +{ +public: + MessageHandler() : QAbstractMessageHandler(0), m_messageType(QtMsgType()), m_description(QString()), + m_sourceLocation(QSourceLocation()){} + inline QString statusMessage() const {return m_description;} + inline qint64 line() const {return m_sourceLocation.line();} + inline qint64 column() const {return m_sourceLocation.column();} +protected: + virtual void handleMessage(QtMsgType type, const QString &description, + const QUrl &identifier, const QSourceLocation &sourceLocation) + { + Q_UNUSED(type); + Q_UNUSED(identifier); + + m_messageType = type; + m_description = description; + m_sourceLocation = sourceLocation; + } +private: + QtMsgType m_messageType; + QString m_description; + QSourceLocation m_sourceLocation; +}; MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::MainWindow), pattern(0), doc(0), tool(Tool::ArrowTool), currentScene(0), @@ -1211,6 +1240,65 @@ void MainWindow::MinimumScrollBar() verScrollBar->setValue(verScrollBar->minimum()); } +bool MainWindow::ValidatePattern(const QString &schema, const QString &fileName, QString &errorMsg, qint64 &errorLine, + qint64 &errorColumn) const +{ + QFile pattern(fileName); + if (pattern.open(QIODevice::ReadOnly) == false) + { + errorMsg = QString(tr("Can't open pattern file.")); + errorLine = -1; + errorColumn = -1; + return false; + } + if(schema.isEmpty()) + { + errorMsg = QString(tr("Empty schema path.")); + errorLine = -1; + errorColumn = -1; + return false; + } + QFile fileSchema(schema); + if(fileSchema.open(QIODevice::ReadOnly) == false) + { + errorMsg = QString(tr("Can't open schema file.")); + errorLine = -1; + errorColumn = -1; + return false; + } + + MessageHandler messageHandler; + QXmlSchema sch; + sch.setMessageHandler(&messageHandler); + sch.load(&fileSchema, QUrl::fromLocalFile(fileSchema.fileName())); + + bool errorOccurred = false; + if (!sch.isValid()) + { + errorOccurred = true; + } + else + { + QXmlSchemaValidator validator(sch); + if (!validator.validate(&pattern, QUrl::fromLocalFile(pattern.fileName()))) + { + errorOccurred = true; + } + } + + if (errorOccurred) + { + errorMsg = messageHandler.statusMessage(); + errorLine = messageHandler.line(); + errorColumn = messageHandler.column(); + return false; + } + else + { + return true; + } +} + bool MainWindow::SafeSaveing(const QString &fileName) const { try @@ -1318,119 +1406,100 @@ void MainWindow::OpenPattern(const QString &fileName) } QFile file(fileName); QString errorMsg; - qint32 errorLine = 0; - qint32 errorColumn = 0; + qint64 errorLine = 0; + qint64 errorColumn = 0; if (file.open(QIODevice::ReadOnly)) { - if (doc->setContent(&file, &errorMsg, &errorLine, &errorColumn)) + if(ValidatePattern("://schema/pattern.xsd", fileName, errorMsg, errorLine, errorColumn)) { - disconnect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), - this, &MainWindow::currentDrawChanged); - try + qint32 errorLine = 0; + qint32 errorColumn = 0; + if (doc->setContent(&file, &errorMsg, &errorLine, &errorColumn)) { - doc->Parse(Document::FullParse, sceneDraw, sceneDetails); - } - catch (const VExceptionObjectError &e) - { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error!")); - msgBox.setText(tr("Error parsing file.")); - msgBox.setInformativeText(e.ErrorMessage()); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setDefaultButton(QMessageBox::Ok); - msgBox.setDetailedText(e.DetailedInformation()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); - file.close(); - Clear(); - return; - } - catch (const VExceptionConversionError &e) - { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error!")); - msgBox.setText(tr("Error can't convert value.")); - msgBox.setInformativeText(e.ErrorMessage()); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setDefaultButton(QMessageBox::Ok); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); - file.close(); - Clear(); - return; - } - catch (const VExceptionEmptyParameter &e) - { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error!")); - msgBox.setText(tr("Error empty parameter.")); - msgBox.setInformativeText(e.ErrorMessage()); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setDefaultButton(QMessageBox::Ok); - msgBox.setDetailedText(e.DetailedInformation()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); - file.close(); - Clear(); - return; - } - catch (const VExceptionWrongParameterId &e) - { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error!")); - msgBox.setText(tr("Error wrong id.")); - msgBox.setInformativeText(e.ErrorMessage()); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setDefaultButton(QMessageBox::Ok); - msgBox.setDetailedText(e.DetailedInformation()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); - file.close(); - Clear(); - return; - } - catch (const VExceptionUniqueId &e) - { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error!")); - msgBox.setText(tr("Error no unique id.")); - msgBox.setInformativeText(e.ErrorMessage()); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setDefaultButton(QMessageBox::Ok); - msgBox.setDetailedText(e.DetailedInformation()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); - file.close(); - Clear(); - return; - } - connect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), - this, &MainWindow::currentDrawChanged); - QString nameDraw = doc->GetNameActivDraw(); - qint32 index = comboBoxDraws->findText(nameDraw); - if ( index != -1 ) - { // -1 for not found - comboBoxDraws->setCurrentIndex(index); - } - if (comboBoxDraws->count() > 0) - { - SetEnableTool(true); + disconnect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), + this, &MainWindow::currentDrawChanged); + try + { + doc->Parse(Document::FullParse, sceneDraw, sceneDetails); + } + catch (const VExceptionObjectError &e) + { + e.CriticalMessageBox(tr("Error parsing file.")); + file.close(); + Clear(); + return; + } + catch (const VExceptionConversionError &e) + { + e.CriticalMessageBox(tr("Error can't convert value.")); + file.close(); + Clear(); + return; + } + catch (const VExceptionEmptyParameter &e) + { + e.CriticalMessageBox(tr("Error empty parameter.")); + file.close(); + Clear(); + return; + } + catch (const VExceptionWrongParameterId &e) + { + e.CriticalMessageBox(tr("Error wrong id.")); + file.close(); + Clear(); + return; + } + catch (const VExceptionUniqueId &e) + { + e.CriticalMessageBox(tr("Error no unique id.")); + file.close(); + Clear(); + return; + } + connect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), + this, &MainWindow::currentDrawChanged); + QString nameDraw = doc->GetNameActivDraw(); + qint32 index = comboBoxDraws->findText(nameDraw); + if ( index != -1 ) + { // -1 for not found + comboBoxDraws->setCurrentIndex(index); + } + if (comboBoxDraws->count() > 0) + { + SetEnableTool(true); + } + else + { + SetEnableTool(false); + } + SetEnableWidgets(true); } else { - SetEnableTool(false); + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error!")); + msgBox.setText(tr("Parsing pattern file error.")); + msgBox.setInformativeText(errorMsg); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + QString error = QString(tr("Error in line %1 column %2")).arg(errorLine).arg(errorColumn); + msgBox.setDetailedText(error); + msgBox.exec(); + file.close(); + Clear(); + return; } - SetEnableWidgets(true); } else { QMessageBox msgBox; msgBox.setWindowTitle(tr("Error!")); - msgBox.setText(tr("Error parsing pattern file.")); + msgBox.setText(tr("Validation file error.")); msgBox.setInformativeText(errorMsg); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); - QString error = QString(tr("Error in line %1 column %2")).arg(errorLine, errorColumn); + QString error = QString(tr("Error in line %1 column %2")).arg(errorLine).arg(errorColumn); msgBox.setDetailedText(error); msgBox.exec(); file.close(); @@ -1439,6 +1508,10 @@ void MainWindow::OpenPattern(const QString &fileName) } file.close(); } + else + { + qWarning()<fileName = fileName; QFileInfo info(fileName); QString title(info.fileName()); diff --git a/src/mainwindow.h b/src/mainwindow.h index 632773304..9f065b4cc 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -559,6 +559,8 @@ private: * @brief MinimumScrollBar */ void MinimumScrollBar(); + bool ValidatePattern(const QString &schema, const QString &fileName, QString &errorMsg, qint64 &errorLine, + qint64 &errorColumn) const; template /** * @brief AddToolToDetail diff --git a/src/tools/vabstracttool.h b/src/tools/vabstracttool.h index ce6faaced..592740618 100644 --- a/src/tools/vabstracttool.h +++ b/src/tools/vabstracttool.h @@ -317,7 +317,9 @@ protected: void AddAttribute(QDomElement &domElement, const QString &name, const T &value) { QDomAttr domAttr = doc->createAttribute(name); - domAttr.setValue(QString().setNum(value)); + QString val = QString().setNum(value); + val = val.replace(",", "."); + domAttr.setValue(val); domElement.setAttributeNode(domAttr); } private: diff --git a/src/xml/vdomdocument.cpp b/src/xml/vdomdocument.cpp index 87af9b76b..37a0c3af6 100644 --- a/src/xml/vdomdocument.cpp +++ b/src/xml/vdomdocument.cpp @@ -126,9 +126,6 @@ bool VDomDocument::find(const QDomElement &node, const QString& id) void VDomDocument::CreateEmptyFile() { QDomElement domElement = this->createElement("pattern"); - QDomAttr domAttr = createAttribute("xmlns"); - domAttr.setValue("http://www.opengis.net/kml/2.2"); - domElement.setAttributeNode(domAttr); this->appendChild(domElement); QDomNode xmlNode = this->createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");