--HG--
branch : feature
This commit is contained in:
dismine 2014-01-19 12:00:20 +02:00
parent 9d283a6283
commit af7a188082
9 changed files with 386 additions and 103 deletions

View File

@ -6,7 +6,7 @@
# Use out-of-source builds (shadow builds) # Use out-of-source builds (shadow builds)
QT += core gui widgets xml svg printsupport QT += core gui widgets xml svg printsupport xmlpatterns
TEMPLATE = app TEMPLATE = app
@ -44,7 +44,8 @@ include(src/xml/xml.pri)
RESOURCES += \ RESOURCES += \
share/resources/icon.qrc \ share/resources/icon.qrc \
share/resources/cursor.qrc \ share/resources/cursor.qrc \
share/resources/theme.qrc share/resources/theme.qrc \
share/resources/schema.qrc
OTHER_FILES += share/resources/valentina.rc \ OTHER_FILES += share/resources/valentina.rc \
share/resources/icon/64x64/icon64x64.ico share/resources/icon/64x64/icon64x64.ico

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>schema/pattern.xsd</file>
</qresource>
</RCC>

View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- XML Schema Generated from XML Document-->
<xs:element name="pattern">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="increments" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="increment" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="ksize" type="xs:double"></xs:attribute>
<xs:attribute name="id" type="xs:long"></xs:attribute>
<xs:attribute name="description" type="xs:string"></xs:attribute>
<xs:attribute name="kgrowth" type="xs:double"></xs:attribute>
<xs:attribute name="name" type="xs:string"></xs:attribute>
<xs:attribute name="base" type="xs:double"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="draw" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="calculation" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:long"></xs:attribute>
<xs:attribute name="x" type="xs:double"></xs:attribute>
<xs:attribute name="y" type="xs:double"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="name" type="xs:string"></xs:attribute>
<xs:attribute name="firstPoint" type="xs:long"></xs:attribute>
<xs:attribute name="secondPoint" type="xs:long"></xs:attribute>
<xs:attribute name="basePoint" type="xs:long"></xs:attribute>
<xs:attribute name="pShoulder" type="xs:long"></xs:attribute>
<xs:attribute name="p1Line" type="xs:long"></xs:attribute>
<xs:attribute name="p2Line" type="xs:long"></xs:attribute>
<xs:attribute name="length" type="xs:string"></xs:attribute>
<xs:attribute name="angle" type="xs:double"></xs:attribute>
<xs:attribute name="typeLine" type="xs:string"></xs:attribute>
<xs:attribute name="splinePath" type="xs:long"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:long"></xs:attribute>
<xs:attribute name="firstPoint" type="xs:long"></xs:attribute>
<xs:attribute name="secondPoint" type="xs:long"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="arc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="angle1" type="xs:string"></xs:attribute>
<xs:attribute name="id" type="xs:long"></xs:attribute>
<xs:attribute name="angle2" type="xs:string"></xs:attribute>
<xs:attribute name="radius" type="xs:string"></xs:attribute>
<xs:attribute name="center" type="xs:long"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="spline" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="pathPoint">
<xs:complexType>
<xs:attribute name="kAsm2" type="xs:string"></xs:attribute>
<xs:attribute name="pSpline" type="xs:long"></xs:attribute>
<xs:attribute name="angle" type="xs:string"></xs:attribute>
<xs:attribute name="kAsm1" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:long"></xs:attribute>
<xs:attribute name="kCurve" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="kAsm1" type="xs:double"></xs:attribute>
<xs:attribute name="kAsm2" type="xs:double"></xs:attribute>
<xs:attribute name="angle1" type="xs:double"></xs:attribute>
<xs:attribute name="angle2" type="xs:double"></xs:attribute>
<xs:attribute name="point1" type="xs:long"></xs:attribute>
<xs:attribute name="point4" type="xs:long"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="modeling" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:long"></xs:attribute>
<xs:attribute name="idObject" type="xs:long"></xs:attribute>
<xs:attribute name="mx" type="xs:string"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="my" type="xs:string"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="arc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:long"></xs:attribute>
<xs:attribute name="idObject" type="xs:long"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="spline" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:long"></xs:attribute>
<xs:attribute name="idObject" type="xs:long"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="tools" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="det" minOccurs="2" maxOccurs="2">
<xs:complexType>
<xs:sequence>
<xs:element name="node" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="nodeType" type="xs:string"></xs:attribute>
<xs:attribute name="idObject" type="xs:long"></xs:attribute>
<xs:attribute name="mx" type="xs:long"></xs:attribute>
<xs:attribute name="my" type="xs:long"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:long"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="indexD1" type="xs:long"></xs:attribute>
<xs:attribute name="indexD2" type="xs:long"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="details" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="detail" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="node" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="nodeType" type="xs:string"></xs:attribute>
<xs:attribute name="idObject" type="xs:long"></xs:attribute>
<xs:attribute name="mx" type="xs:long"></xs:attribute>
<xs:attribute name="my" type="xs:long"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:long"></xs:attribute>
<xs:attribute name="supplement" type="xs:long"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="width" type="xs:long"></xs:attribute>
<xs:attribute name="name" type="xs:string"></xs:attribute>
<xs:attribute name="closed" type="xs:long"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -27,6 +27,7 @@
*************************************************************************/ *************************************************************************/
#include "vexception.h" #include "vexception.h"
#include <QMessageBox>
VException::VException(const QString &what):QException(), what(what) VException::VException(const QString &what):QException(), what(what)
{ {
@ -38,3 +39,19 @@ QString VException::ErrorMessage() const
QString error = QString("Exception: %1").arg(what); QString error = QString("Exception: %1").arg(what);
return error; 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();
}

View File

@ -74,6 +74,7 @@ public:
* @return string with error * @return string with error
*/ */
inline QString What() const {return what;} inline QString What() const {return what;}
virtual void CriticalMessageBox(const QString &situation) const;
protected: protected:
/** /**
* @brief what string with error * @brief what string with error

View File

@ -43,6 +43,35 @@
#include <QShowEvent> #include <QShowEvent>
#include <QScrollBar> #include <QScrollBar>
#include <QFileDialog> #include <QFileDialog>
#include <QXmlSchema>
#include <QXmlSchemaValidator>
#include <QSourceLocation>
#include <QAbstractMessageHandler>
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) MainWindow::MainWindow(QWidget *parent)
:QMainWindow(parent), ui(new Ui::MainWindow), pattern(0), doc(0), tool(Tool::ArrowTool), currentScene(0), :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()); 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 bool MainWindow::SafeSaveing(const QString &fileName) const
{ {
try try
@ -1318,119 +1406,100 @@ void MainWindow::OpenPattern(const QString &fileName)
} }
QFile file(fileName); QFile file(fileName);
QString errorMsg; QString errorMsg;
qint32 errorLine = 0; qint64 errorLine = 0;
qint32 errorColumn = 0; qint64 errorColumn = 0;
if (file.open(QIODevice::ReadOnly)) 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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), qint32 errorLine = 0;
this, &MainWindow::currentDrawChanged); qint32 errorColumn = 0;
try if (doc->setContent(&file, &errorMsg, &errorLine, &errorColumn))
{ {
doc->Parse(Document::FullParse, sceneDraw, sceneDetails); disconnect(comboBoxDraws, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
} this, &MainWindow::currentDrawChanged);
catch (const VExceptionObjectError &e) try
{ {
QMessageBox msgBox; doc->Parse(Document::FullParse, sceneDraw, sceneDetails);
msgBox.setWindowTitle(tr("Error!")); }
msgBox.setText(tr("Error parsing file.")); catch (const VExceptionObjectError &e)
msgBox.setInformativeText(e.ErrorMessage()); {
msgBox.setStandardButtons(QMessageBox::Ok); e.CriticalMessageBox(tr("Error parsing file."));
msgBox.setDefaultButton(QMessageBox::Ok); file.close();
msgBox.setDetailedText(e.DetailedInformation()); Clear();
msgBox.setIcon(QMessageBox::Critical); return;
msgBox.exec(); }
file.close(); catch (const VExceptionConversionError &e)
Clear(); {
return; e.CriticalMessageBox(tr("Error can't convert value."));
} file.close();
catch (const VExceptionConversionError &e) Clear();
{ return;
QMessageBox msgBox; }
msgBox.setWindowTitle(tr("Error!")); catch (const VExceptionEmptyParameter &e)
msgBox.setText(tr("Error can't convert value.")); {
msgBox.setInformativeText(e.ErrorMessage()); e.CriticalMessageBox(tr("Error empty parameter."));
msgBox.setStandardButtons(QMessageBox::Ok); file.close();
msgBox.setDefaultButton(QMessageBox::Ok); Clear();
msgBox.setIcon(QMessageBox::Critical); return;
msgBox.exec(); }
file.close(); catch (const VExceptionWrongParameterId &e)
Clear(); {
return; e.CriticalMessageBox(tr("Error wrong id."));
} file.close();
catch (const VExceptionEmptyParameter &e) Clear();
{ return;
QMessageBox msgBox; }
msgBox.setWindowTitle(tr("Error!")); catch (const VExceptionUniqueId &e)
msgBox.setText(tr("Error empty parameter.")); {
msgBox.setInformativeText(e.ErrorMessage()); e.CriticalMessageBox(tr("Error no unique id."));
msgBox.setStandardButtons(QMessageBox::Ok); file.close();
msgBox.setDefaultButton(QMessageBox::Ok); Clear();
msgBox.setDetailedText(e.DetailedInformation()); return;
msgBox.setIcon(QMessageBox::Critical); }
msgBox.exec(); connect(comboBoxDraws, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
file.close(); this, &MainWindow::currentDrawChanged);
Clear(); QString nameDraw = doc->GetNameActivDraw();
return; qint32 index = comboBoxDraws->findText(nameDraw);
} if ( index != -1 )
catch (const VExceptionWrongParameterId &e) { // -1 for not found
{ comboBoxDraws->setCurrentIndex(index);
QMessageBox msgBox; }
msgBox.setWindowTitle(tr("Error!")); if (comboBoxDraws->count() > 0)
msgBox.setText(tr("Error wrong id.")); {
msgBox.setInformativeText(e.ErrorMessage()); SetEnableTool(true);
msgBox.setStandardButtons(QMessageBox::Ok); }
msgBox.setDefaultButton(QMessageBox::Ok); else
msgBox.setDetailedText(e.DetailedInformation()); {
msgBox.setIcon(QMessageBox::Critical); SetEnableTool(false);
msgBox.exec(); }
file.close(); SetEnableWidgets(true);
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<void (QComboBox::*)(int)>(&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 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 else
{ {
QMessageBox msgBox; QMessageBox msgBox;
msgBox.setWindowTitle(tr("Error!")); msgBox.setWindowTitle(tr("Error!"));
msgBox.setText(tr("Error parsing pattern file.")); msgBox.setText(tr("Validation file error."));
msgBox.setInformativeText(errorMsg); msgBox.setInformativeText(errorMsg);
msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(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.setDetailedText(error);
msgBox.exec(); msgBox.exec();
file.close(); file.close();
@ -1439,6 +1508,10 @@ void MainWindow::OpenPattern(const QString &fileName)
} }
file.close(); file.close();
} }
else
{
qWarning()<<tr("Can't open pattern file.")<<Q_FUNC_INFO;
}
this->fileName = fileName; this->fileName = fileName;
QFileInfo info(fileName); QFileInfo info(fileName);
QString title(info.fileName()); QString title(info.fileName());

View File

@ -559,6 +559,8 @@ private:
* @brief MinimumScrollBar * @brief MinimumScrollBar
*/ */
void MinimumScrollBar(); void MinimumScrollBar();
bool ValidatePattern(const QString &schema, const QString &fileName, QString &errorMsg, qint64 &errorLine,
qint64 &errorColumn) const;
template <typename T> template <typename T>
/** /**
* @brief AddToolToDetail * @brief AddToolToDetail

View File

@ -317,7 +317,9 @@ protected:
void AddAttribute(QDomElement &domElement, const QString &name, const T &value) void AddAttribute(QDomElement &domElement, const QString &name, const T &value)
{ {
QDomAttr domAttr = doc->createAttribute(name); QDomAttr domAttr = doc->createAttribute(name);
domAttr.setValue(QString().setNum(value)); QString val = QString().setNum(value);
val = val.replace(",", ".");
domAttr.setValue(val);
domElement.setAttributeNode(domAttr); domElement.setAttributeNode(domAttr);
} }
private: private:

View File

@ -126,9 +126,6 @@ bool VDomDocument::find(const QDomElement &node, const QString& id)
void VDomDocument::CreateEmptyFile() void VDomDocument::CreateEmptyFile()
{ {
QDomElement domElement = this->createElement("pattern"); QDomElement domElement = this->createElement("pattern");
QDomAttr domAttr = createAttribute("xmlns");
domAttr.setValue("http://www.opengis.net/kml/2.2");
domElement.setAttributeNode(domAttr);
this->appendChild(domElement); this->appendChild(domElement);
QDomNode xmlNode = this->createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""); QDomNode xmlNode = this->createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");