54 #include <qcompilerdetection.h>
58 #include "../exception/vexceptionbadid.h"
59 #include "../exception/vexceptionconversionerror.h"
60 #include "../exception/vexceptionemptyparameter.h"
61 #include "../exception/vexceptionwrongid.h"
62 #include "../exception/vexception.h"
63 #include "../vmisc/logging.h"
64 #include "../ifcdef.h"
66 #include <QAbstractMessageHandler>
68 #include <QDomNodeList>
72 #include <QMessageLogger>
74 #include <QSourceLocation>
75 #include <QStringList>
76 #include <QTemporaryFile>
77 #include <QTextDocument>
78 #include <QTextStream>
82 #include <QXmlSchemaValidator>
84 #include <QXmlStreamWriter>
91 if (stream.hasError())
96 if (domNode.isElement())
98 const QDomElement domElement = domNode.toElement();
99 if (not domElement.isNull())
101 stream.writeStartElement(domElement.tagName());
103 if (domElement.hasAttributes())
106 const QDomNamedNodeMap attributeMap = domElement.attributes();
107 for (
int i = 0; i < attributeMap.count(); ++i)
109 const QDomNode attribute = attributeMap.item(i);
110 attributes.insert(attribute.nodeName(), attribute.nodeValue());
114 while (i != attributes.constEnd())
116 stream.writeAttribute(i.key(), i.value());
121 if (domElement.hasChildNodes())
123 QDomNode elementChild = domElement.firstChild();
124 while (not elementChild.isNull())
127 elementChild = elementChild.nextSibling();
131 stream.writeEndElement();
134 else if (domNode.isComment())
136 stream.writeComment(domNode.nodeValue());
138 else if (domNode.isText())
140 stream.writeCharacters(domNode.nodeValue());
150 : QAbstractMessageHandler(),
161 virtual void handleMessage(QtMsgType type,
const QString &description,
162 const QUrl &identifier,
const QSourceLocation &sourceLocation) Q_DECL_OVERRIDE;
174 return doc.toPlainText();
192 const QSourceLocation &sourceLocation)
202 Q_LOGGING_CATEGORY(vXML,
"v.xml")
204 const QString
VDomDocument::AttrId = QStringLiteral("
id");
205 const QString
VDomDocument::AttrText = QStringLiteral("text");
206 const QString
VDomDocument::AttrBold = QStringLiteral("bold");
207 const QString
VDomDocument::AttrItalic = QStringLiteral("italic");
208 const QString
VDomDocument::AttrAlignment = QStringLiteral("alignment");
209 const QString
VDomDocument::AttrFSIncrement = QStringLiteral("sfIncrement");
211 const QString
VDomDocument::TagVersion = QStringLiteral("version");
212 const QString
VDomDocument::TagUnit = QStringLiteral("unit");
213 const QString
VDomDocument::TagLine = QStringLiteral("line");
226 return QDomElement();
229 if (
map.contains(
id))
231 const QDomElement e =
map[id];
232 if (e.parentNode().nodeType() != QDomNode::BaseNode)
239 if (tagName.isEmpty())
241 if (this->
find(this->documentElement(),
id))
248 const QDomNodeList list = elementsByTagName(tagName);
249 for (
int i=0; i < list.size(); ++i)
251 const QDomElement domElement = list.at(i).toElement();
252 if (not domElement.isNull() && domElement.hasAttribute(
AttrId))
258 this->
map[elementId] = domElement;
272 return QDomElement();
284 if (node.hasAttribute(
AttrId))
290 this->
map[elementId] = node;
302 for (qint32 i=0; i<node.childNodes().length(); ++i)
304 const QDomNode n = node.childNodes().at(i);
307 if (this->
find(n.toElement(),
id))
321 QXmlStreamWriter stream(file);
322 stream.setAutoFormatting(
true);
323 stream.setAutoFormattingIndent(indent);
324 stream.writeStartDocument();
326 QDomNode root = documentElement();
327 while (not root.isNull())
330 if (stream.hasError())
334 root = root.nextSibling();
337 stream.writeEndDocument();
339 if (stream.hasError())
341 error = tr(
"Fail to write Canonical XML.");
356 Q_ASSERT_X(not name.isEmpty(), Q_FUNC_INFO,
"name of parametr is empty");
357 Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO,
"domElement is null");
366 id = parametr.toUInt(&ok);
385 Q_ASSERT_X(not name.isEmpty(), Q_FUNC_INFO,
"name of parametr is empty");
386 Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO,
"domElement is null");
391 const QString message = QObject::tr(
"Can't convert toBool parameter");
396 const QStringList bools = QStringList() << QLatin1String(
"true")
397 << QLatin1String(
"false")
398 << QLatin1String(
"1")
399 << QLatin1String(
"0");
400 switch (bools.indexOf(parametr))
443 domElement.setAttribute(name,
trueStr);
447 domElement.setAttribute(name,
falseStr);
460 const QString &defValue)
462 Q_ASSERT_X(not name.isEmpty(), Q_FUNC_INFO,
"name of parametr is empty");
463 Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO,
"domElement is null");
464 const QString parameter = domElement.attribute(name, defValue);
465 if (parameter.isEmpty())
467 if (defValue.isEmpty())
503 Q_ASSERT_X(not name.isEmpty(), Q_FUNC_INFO,
"name of parametr is empty");
504 Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO,
"domElement is null");
509 const QString message = QObject::tr(
"Can't convert toDouble parameter");
513 param = parametr.replace(
",",
".").toDouble(&ok);
536 Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO,
"domElement is null");
540 const QString message = QObject::tr(
"Got wrong parameter id. Need only id > 0.");
574 const QDomNodeList nodeList = this->elementsByTagName(tagName);
575 if (nodeList.isEmpty())
581 const QDomNode domNode = nodeList.at(0);
582 if (domNode.isNull() ==
false && domNode.isElement())
584 const QDomElement domElement = domNode.toElement();
585 if (domElement.isNull() ==
false)
587 const QString text = domElement.text();
618 if (vector.contains(
id))
625 for (qint32 i=0; i<node.childNodes().length(); ++i)
627 const QDomNode n = node.childNodes().at(i);
643 qCDebug(vXML,
"Validation xml file %s.", qUtf8Printable(fileName));
644 QFile pattern(fileName);
646 if (pattern.open(QIODevice::ReadOnly) ==
false)
648 const QString errorMsg(tr(
"Can't open file %1:\n%2.").arg(fileName).arg(pattern.errorString()));
652 QFile fileSchema(schema);
654 if (fileSchema.open(QIODevice::ReadOnly) ==
false)
657 const QString errorMsg(tr(
"Can't open schema file %1:\n%2.").arg(schema).arg(fileSchema.errorString()));
663 sch.setMessageHandler(&messageHandler);
664 if (sch.load(&fileSchema, QUrl::fromLocalFile(fileSchema.fileName()))==
false)
669 e.
AddMoreInformation(tr(
"Could not load schema file '%1'.").arg(fileSchema.fileName()));
672 qCDebug(vXML,
"Schema loaded.");
674 bool errorOccurred =
false;
675 if (sch.isValid() ==
false)
677 errorOccurred =
true;
681 QXmlSchemaValidator validator(sch);
682 if (validator.validate(&pattern, QUrl::fromLocalFile(pattern.fileName())) ==
false)
684 errorOccurred =
true;
694 .arg(messageHandler.
column()).arg(fileName));
704 QFile file(fileName);
706 if (file.open(QIODevice::ReadOnly) ==
false)
708 const QString errorMsg(tr(
"Can't open file %1:\n%2.").arg(fileName).arg(file.errorString()));
714 int errorColumn = -1;
715 if (QDomDocument::setContent(&file, &errorMsg, &errorLine, &errorColumn) ==
false)
719 e.
AddMoreInformation(tr(
"Parsing error file %3 in line %1 column %2").arg(errorLine).arg(errorColumn)
743 if (fileName.isEmpty())
745 qDebug()<<
"Got empty file name.";
748 bool success =
false;
749 QSaveFile file(fileName);
751 if (file.open(QIODevice::WriteOnly))
754 const int indent = 4;
764 success = file.commit();
769 error = file.errorString();
780 QStringList v = version.split(
".");
789 QStringList v = version.split(
".");
798 QStringList v = version.split(
".");
805 const QDomNodeList nodeList = this->elementsByTagName(tag);
806 if (nodeList.isEmpty())
808 qDebug()<<
"Can't save tag "<<tag<<Q_FUNC_INFO;
812 const QDomNode domNode = nodeList.at(0);
813 if (domNode.isNull() ==
false && domNode.isElement())
815 const QDomElement domElement = domNode.toElement();
825 if (domElement.isNull() ==
false)
827 QDomElement parent = domElement.parentNode().toElement();
828 QDomElement newTag = createElement(domElement.tagName());
830 const QDomText newTagText = createTextNode(text);
831 newTag.appendChild(newTagText);
833 parent.replaceChild(newTag, domElement);
846 if ( domElement.hasChildNodes() )
848 while ( domElement.childNodes().length() >= 1 )
850 domElement.removeChild( domElement.firstChild() );
858 QDomElement domElement =
NodeById(nodeId);
859 return domElement.parentNode();
865 QDomElement domElement =
NodeById(nodeId);
866 return domElement.cloneNode().toElement();
873 if (domElement.isNull() || domElement.isElement() ==
false)
886 qt_ntfs_permission_lookup++;
889 QTemporaryFile destFile(destination + QLatin1String(
".XXXXXX"));
890 destFile.setAutoRemove(
false);
892 if (not destFile.open())
894 error = destFile.errorString();
898 QFile sourceFile(source);
900 if (sourceFile.open(QIODevice::ReadOnly))
905 while ((bytes = sourceFile.read(block,
sizeof(block))) > 0)
907 if (bytes != destFile.write(block, bytes))
909 error = destFile.errorString();
917 error = sourceFile.errorString();
923 QFile::remove(destination);
924 if (not destFile.rename(destination))
926 error = destFile.errorString();
937 error = sourceFile.errorString();
942 qt_ntfs_permission_lookup--;
952 Q_STATIC_ASSERT(Qt::AlignLeft == 1);
953 Q_STATIC_ASSERT(Qt::AlignRight == 2);
954 Q_STATIC_ASSERT(Qt::AlignHCenter == 4);
958 if (not element.isNull())
960 QDomElement tagLine = element.firstChildElement();
961 while (tagLine.isNull() ==
false)
963 if (tagLine.tagName() ==
TagLine)
973 tagLine = tagLine.nextSiblingElement(
TagLine);
983 if (not element.isNull())
985 for (
int i=0; i < lines.size(); ++i)
987 QDomElement tagLine = createElement(
TagLine);
995 element.appendChild(tagLine);
virtual void handleMessage(QtMsgType type, const QString &description, const QUrl &identifier, const QSourceLocation &sourceLocation) Q_DECL_OVERRIDE
QSourceLocation m_sourceLocation
QString statusMessage() const
The VDomDocument class represents a Seamly2D document (.val file).
static const QString AttrItalic
QDomElement elementById(quint32 id, const QString &tagName=QString())
static QString GetParametrString(const QDomElement &domElement, const QString &name, const QString &defValue=QString())
Returns the string value of the given attribute. RENAME: see above.
void SetLabelTemplate(QDomElement &element, const QVector< VLabelTemplateLine > &lines)
static const QString AttrBold
static quint32 GetParametrUInt(const QDomElement &domElement, const QString &name, const QString &defValue)
Returns the long long value of the given attribute. RENAME: GetParameterLongLong?
static QString GetParametrEmptyString(const QDomElement &domElement, const QString &name)
static const QString AttrAlignment
static void ValidateXML(const QString &schema, const QString &fileName)
ValidateXML validate xml file by xsd schema.
bool find(const QDomElement &node, quint32 id)
Find element by id.
static QString UnitsHelpString()
QDomElement CloneNodeById(const quint32 &nodeId)
void CollectId(const QDomElement &node, QVector< quint32 > &vector) const
bool SaveCanonicalXML(QIODevice *file, int indent, QString &error) const
static bool getParameterBool(const QDomElement &domElement, const QString &name, const QString &defValue)
void TestUniqueId() const
TestUniqueId test exist unique id in pattern file. Each id must be unique.
bool setTagText(const QString &tag, const QString &text)
QHash< quint32, QDomElement > map
Map used for finding element by id.
static void SetParametrUsage(QDomElement &domElement, const QString &name, const NodeUsage &value)
static qreal GetParametrDouble(const QDomElement &domElement, const QString &name, const QString &defValue)
Returns the double value of the given attribute.
QDomElement NodeById(const quint32 &nodeId)
static bool SafeCopy(const QString &source, const QString &destination, QString &error)
static const QString TagVersion
static const QString TagUnit
QString UniqueTagText(const QString &tagName, const QString &defVal=QString()) const
void SetAttribute(QDomElement &domElement, const QString &name, const T &value) const
SetAttribute set attribute in pattern file. Replace "," by ".".
QDomNode ParentNodeById(const quint32 &nodeId)
static const QString AttrId
virtual void setXMLContent(const QString &fileName)
static const QString TagLine
static const QString AttrText
static void RemoveAllChildren(QDomElement &domElement)
RemoveAllChildren remove all children from file.
virtual bool SaveDocument(const QString &fileName, QString &error)
static NodeUsage GetParametrUsage(const QDomElement &domElement, const QString &name)
QVector< VLabelTemplateLine > GetLabelTemplate(const QDomElement &element) const
static quint32 getParameterId(const QDomElement &domElement)
getParameterId return value id attribute.
static const QString AttrFSIncrement
The VExceptionBadId class for exception bad id.
The VExceptionConversionError class for exception of conversion error.
virtual QString ErrorMessage() const Q_DECL_OVERRIDE
ErrorMessage return main error message.
The VExceptionEmptyParameter class for exception empty parameter.
virtual QString ErrorMessage() const Q_DECL_OVERRIDE
ErrorMessage return main error message.
The VExceptionWrongId class for exception wrong id.
The VException class parent for all exception. Could be use for abstract exception.
void AddMoreInformation(const QString &info)
AddMoreInformation add more information for error.
Unit StrToUnits(const QString &unit)
QString UnitsToStr(const Unit &unit, const bool translate)
UnitsToStr translate unit to string.
void SaveNodeCanonically(QXmlStreamWriter &stream, const QDomNode &domNode)