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\"");