Qt XML Patterns deprecated since Qt 5.13.

Use Xerces-C++ instead.
This commit is contained in:
Roman Telezhynskyi 2023-02-09 17:17:08 +02:00
parent e95a29c08e
commit c0deb4d27a
11 changed files with 347 additions and 86 deletions

View File

@ -32,7 +32,6 @@
#include "vpapplication.h" #include "vpapplication.h"
#include "../vmisc/def.h" #include "../vmisc/def.h"
#if defined(APPIMAGE) && defined(Q_OS_LINUX) #if defined(APPIMAGE) && defined(Q_OS_LINUX)
#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
# include "../vmisc/backport/qscopeguard.h" # include "../vmisc/backport/qscopeguard.h"
@ -42,6 +41,10 @@
# include "../vmisc/appimage.h" # include "../vmisc/appimage.h"
#endif // defined(APPIMAGE) && defined(Q_OS_LINUX) #endif // defined(APPIMAGE) && defined(Q_OS_LINUX)
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <xercesc/util/PlatformUtils.hpp>
#endif
auto main(int argc, char *argv[]) -> int auto main(int argc, char *argv[]) -> int
{ {
#if defined(APPIMAGE) && defined(Q_OS_LINUX) #if defined(APPIMAGE) && defined(Q_OS_LINUX)
@ -68,6 +71,12 @@ auto main(int argc, char *argv[]) -> int
InitHighDpiScaling(argc, argv); InitHighDpiScaling(argc, argv);
#endif //Q_OS_MAC #endif //Q_OS_MAC
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
XERCES_CPP_NAMESPACE::XMLPlatformUtils::Initialize();
auto Terminate = qScopeGuard([](){ XERCES_CPP_NAMESPACE::XMLPlatformUtils::Terminate(); });
#endif
VPApplication app(argc, argv); VPApplication app(argc, argv);
app.InitOptions(); app.InitOptions();

View File

@ -40,6 +40,10 @@
# include "../vmisc/appimage.h" # include "../vmisc/appimage.h"
#endif // defined(APPIMAGE) && defined(Q_OS_LINUX) #endif // defined(APPIMAGE) && defined(Q_OS_LINUX)
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <xercesc/util/PlatformUtils.hpp>
#endif
auto main(int argc, char *argv[]) -> int auto main(int argc, char *argv[]) -> int
{ {
#if defined(APPIMAGE) && defined(Q_OS_LINUX) #if defined(APPIMAGE) && defined(Q_OS_LINUX)
@ -61,6 +65,12 @@ auto main(int argc, char *argv[]) -> int
VAbstractApplication::WinAttachConsole(); VAbstractApplication::WinAttachConsole();
#endif #endif
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
XERCES_CPP_NAMESPACE::XMLPlatformUtils::Initialize();
auto Terminate = qScopeGuard([](){ XERCES_CPP_NAMESPACE::XMLPlatformUtils::Terminate(); });
#endif
#ifndef Q_OS_MAC // supports natively #ifndef Q_OS_MAC // supports natively
InitHighDpiScaling(argc, argv); InitHighDpiScaling(argc, argv);
#endif //Q_OS_MAC #endif //Q_OS_MAC

View File

@ -49,10 +49,13 @@
#include <QMessageBox> #include <QMessageBox>
#include <QThread> #include <QThread>
#include <QDateTime> #include <QDateTime>
#include <QtXmlPatterns>
#include <QIcon> #include <QIcon>
#include <Qt> #include <Qt>
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QtXmlPatterns>
#endif
#if !defined(BUILD_REVISION) && defined(QBS_BUILD) #if !defined(BUILD_REVISION) && defined(QBS_BUILD)
#include <vcsRepoState.h> #include <vcsRepoState.h>
#define BUILD_REVISION VCS_REPO_STATE_REVISION #define BUILD_REVISION VCS_REPO_STATE_REVISION

View File

@ -43,6 +43,10 @@
# include "../vmisc/appimage.h" # include "../vmisc/appimage.h"
#endif // defined(APPIMAGE) && defined(Q_OS_LINUX) #endif // defined(APPIMAGE) && defined(Q_OS_LINUX)
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <xercesc/util/PlatformUtils.hpp>
#endif
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto main(int argc, char *argv[]) -> int auto main(int argc, char *argv[]) -> int
@ -77,6 +81,12 @@ auto main(int argc, char *argv[]) -> int
InitHighDpiScaling(argc, argv); InitHighDpiScaling(argc, argv);
#endif //Q_OS_MAC #endif //Q_OS_MAC
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
XERCES_CPP_NAMESPACE::XMLPlatformUtils::Initialize();
auto Terminate = qScopeGuard([](){ XERCES_CPP_NAMESPACE::XMLPlatformUtils::Terminate(); });
#endif
VApplication app(argc, argv); VApplication app(argc, argv);
app.InitOptions(); app.InitOptions();

View File

@ -185,7 +185,11 @@
#include <QShowEvent> #include <QShowEvent>
#include <QScrollBar> #include <QScrollBar>
#include <QFileDialog> #include <QFileDialog>
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QSourceLocation> #include <QSourceLocation>
#endif
#include <QUndoStack> #include <QUndoStack>
#include <QAction> #include <QAction>
#include <QProcess> #include <QProcess>

View File

@ -14,6 +14,12 @@ VLib {
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 condition: Utilities.versionCompare(Qt.core.version, "6") >= 0
} }
Depends {
name: "xerces-c"
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && qbs.targetOS.contains("unix")
&& !qbs.targetOS.contains("macos")
}
name: "IFCLib" name: "IFCLib"
files: [ files: [
"ifcdef.h", "ifcdef.h",
@ -43,7 +49,7 @@ VLib {
"vexceptionwrongid.cpp", "vexceptionwrongid.cpp",
"vexceptionundo.cpp", "vexceptionundo.cpp",
"vexceptioninvalidnotch.cpp", "vexceptioninvalidnotch.cpp",
"vexceptioninvalidhistory.cpp", "vexceptioninvalidhistory.cpp"
] ]
} }
@ -56,6 +62,8 @@ VLib {
"vbackgroundpatternimage.h", "vbackgroundpatternimage.h",
"vdomdocument.h", "vdomdocument.h",
"vlayoutconverter.h", "vlayoutconverter.h",
"vparsererrorhandler.cpp",
"vparsererrorhandler.h",
"vpatternconverter.h", "vpatternconverter.h",
"vpatternimage.h", "vpatternimage.h",
"vtoolrecord.h", "vtoolrecord.h",

View File

@ -27,8 +27,15 @@
*************************************************************************/ *************************************************************************/
#include "vabstractconverter.h" #include "vabstractconverter.h"
#include "vparsererrorhandler.h"
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <xercesc/parsers/XercesDOMParser.hpp>
#else
#include <QXmlSchema>
#include <QXmlSchemaValidator>
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <QAbstractMessageHandler>
#include <QDir> #include <QDir>
#include <QDomElement> #include <QDomElement>
#include <QDomNode> #include <QDomNode>
@ -39,73 +46,13 @@
#include <QMap> #include <QMap>
#include <QRegularExpression> #include <QRegularExpression>
#include <QRegularExpressionMatch> #include <QRegularExpressionMatch>
#include <QSourceLocation>
#include <QStringList> #include <QStringList>
#include <QTextDocument> #include <QTextDocument>
#include <QUrl> #include <QUrl>
#include <QXmlSchema>
#include <QXmlSchemaValidator>
#include "../exception/vexception.h" #include "../exception/vexception.h"
#include "vdomdocument.h" #include "vdomdocument.h"
//This class need for validation pattern file using XSD shema
class MessageHandler : public QAbstractMessageHandler
{
public:
MessageHandler()
: QAbstractMessageHandler(),
m_messageType(QtMsgType()),
m_description(),
m_sourceLocation(QSourceLocation())
{}
QString statusMessage() const;
qint64 line() const;
qint64 column() const;
protected:
// cppcheck-suppress unusedFunction
virtual void handleMessage(QtMsgType type, const QString &description,
const QUrl &identifier, const QSourceLocation &sourceLocation) override;
private:
QtMsgType m_messageType;
QString m_description;
QSourceLocation m_sourceLocation;
};
//---------------------------------------------------------------------------------------------------------------------
QString MessageHandler::statusMessage() const
{
QTextDocument doc;
doc.setHtml(m_description);
return doc.toPlainText();
}
//---------------------------------------------------------------------------------------------------------------------
inline qint64 MessageHandler::line() const
{
return m_sourceLocation.line();
}
//---------------------------------------------------------------------------------------------------------------------
inline qint64 MessageHandler::column() const
{
return m_sourceLocation.column();
}
//---------------------------------------------------------------------------------------------------------------------
// cppcheck-suppress unusedFunction
void MessageHandler::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;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VAbstractConverter::VAbstractConverter(const QString &fileName) VAbstractConverter::VAbstractConverter(const QString &fileName)
: m_ver(0x0), : m_ver(0x0),
@ -222,6 +169,70 @@ void VAbstractConverter::BiasTokens(vsizetype position, vsizetype bias, QMap<vsi
void VAbstractConverter::ValidateXML(const QString &schema) const void VAbstractConverter::ValidateXML(const QString &schema) const
{ {
qCDebug(vXML, "Validation xml file %s.", qUtf8Printable(m_convertedFileName)); qCDebug(vXML, "Validation xml file %s.", qUtf8Printable(m_convertedFileName));
QFile fileSchema(schema);
if (not fileSchema.open(QIODevice::ReadOnly))
{
const QString errorMsg(tr("Can't open schema file %1:\n%2.").arg(schema, fileSchema.errorString()));
throw VException(errorMsg);
}
VParserErrorHandler parserErrorHandler;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QScopedPointer<QTemporaryFile> tempSchema(QTemporaryFile::createNativeFile(fileSchema));
if (tempSchema == nullptr)
{
const QString errorMsg(tr("Can't create native file for schema file %1:\n%2.")
.arg(schema, fileSchema.errorString()));
throw VException(errorMsg);
}
if (tempSchema->open())
{
XercesDOMParser domParser;
domParser.setErrorHandler(&parserErrorHandler);
if (domParser.loadGrammar(
tempSchema->fileName().toUtf8().constData(), Grammar::SchemaGrammarType, true) == nullptr)
{
VException e(parserErrorHandler.StatusMessage());
e.AddMoreInformation(tr("Could not load schema file '%1'.").arg(fileSchema.fileName()));
throw e;
}
qCDebug(vXML, "Schema loaded.");
if (parserErrorHandler.HasError())
{
VException e(parserErrorHandler.StatusMessage());
e.AddMoreInformation(tr("Schema file %3 invalid in line %1 column %2").arg(parserErrorHandler.Line())
.arg(parserErrorHandler.Column()).arg(fileSchema.fileName()));
throw e;
}
domParser.setValidationScheme(XercesDOMParser::Val_Always);
domParser.setDoNamespaces(true);
domParser.setDoSchema(true);
domParser.setValidationConstraintFatal(true);
domParser.setValidationSchemaFullChecking(true);
domParser.useCachedGrammarInParse(true);
domParser.parse(m_convertedFileName.toUtf8().constData());
if (domParser.getErrorCount() > 0)
{
VException e(parserErrorHandler.StatusMessage());
e.AddMoreInformation(tr("Validation error file %3 in line %1 column %2").arg(parserErrorHandler.Line())
.arg(parserErrorHandler.Column()).arg(m_originalFileName));
throw e;
}
}
else
{
qCritical() << tr("Unable to open native file for schema");
}
#else
QFile pattern(m_convertedFileName); QFile pattern(m_convertedFileName);
if (not pattern.open(QIODevice::ReadOnly)) if (not pattern.open(QIODevice::ReadOnly))
{ {
@ -229,22 +240,12 @@ void VAbstractConverter::ValidateXML(const QString &schema) const
throw VException(errorMsg); throw VException(errorMsg);
} }
QFile fileSchema(schema); VParserErrorHandler messageHandler;
if (not fileSchema.open(QIODevice::ReadOnly))
{
pattern.close();
const QString errorMsg(tr("Can't open schema file %1:\n%2.").arg(schema, fileSchema.errorString()));
throw VException(errorMsg);
}
MessageHandler messageHandler;
QXmlSchema sch; QXmlSchema sch;
sch.setMessageHandler(&messageHandler); sch.setMessageHandler(&messageHandler);
if (sch.load(&fileSchema, QUrl::fromLocalFile(fileSchema.fileName()))==false) if (sch.load(&fileSchema, QUrl::fromLocalFile(fileSchema.fileName()))==false)
{ {
pattern.close(); VException e(messageHandler.StatusMessage());
fileSchema.close();
VException e(messageHandler.statusMessage());
e.AddMoreInformation(tr("Could not load schema file '%1'.").arg(fileSchema.fileName())); e.AddMoreInformation(tr("Could not load schema file '%1'.").arg(fileSchema.fileName()));
throw e; throw e;
} }
@ -266,15 +267,12 @@ void VAbstractConverter::ValidateXML(const QString &schema) const
if (errorOccurred) if (errorOccurred)
{ {
pattern.close(); VException e(messageHandler.StatusMessage());
fileSchema.close(); e.AddMoreInformation(tr("Validation error file %3 in line %1 column %2").arg(messageHandler.Line())
VException e(messageHandler.statusMessage()); .arg(messageHandler.Column()).arg(m_originalFileName));
e.AddMoreInformation(tr("Validation error file %3 in line %1 column %2").arg(messageHandler.line())
.arg(messageHandler.column()).arg(m_originalFileName));
throw e; throw e;
} }
pattern.close(); #endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
fileSchema.close();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -39,7 +39,11 @@
#include "../exception/vexception.h" #include "../exception/vexception.h"
#include "../ifcdef.h" #include "../ifcdef.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QAbstractMessageHandler> #include <QAbstractMessageHandler>
#include <QSourceLocation>
#endif
#include <QByteArray> #include <QByteArray>
#include <QDomNodeList> #include <QDomNodeList>
#include <QDomText> #include <QDomText>
@ -47,7 +51,6 @@
#include <QIODevice> #include <QIODevice>
#include <QMessageLogger> #include <QMessageLogger>
#include <QObject> #include <QObject>
#include <QSourceLocation>
#include <QStringList> #include <QStringList>
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QTextDocument> #include <QTextDocument>

View File

@ -0,0 +1,128 @@
/************************************************************************
**
** @file vparsererrorhandler.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 8 2, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vparsererrorhandler.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
//---------------------------------------------------------------------------------------------------------------------
QString VParserErrorHandler::StatusMessage() const
{
QTextDocument doc;
doc.setHtml(m_description);
return doc.toPlainText();
}
//---------------------------------------------------------------------------------------------------------------------
qint64 VParserErrorHandler::Line() const
{
return m_sourceLocation.line();
}
//---------------------------------------------------------------------------------------------------------------------
qint64 VParserErrorHandler::Column() const
{
return m_sourceLocation.column();
}
//---------------------------------------------------------------------------------------------------------------------
// cppcheck-suppress unusedFunction
void VParserErrorHandler::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;
}
#else
//---------------------------------------------------------------------------------------------------------------------
auto VParserErrorHandler::StatusMessage() const -> QString
{
return m_description;
}
//---------------------------------------------------------------------------------------------------------------------
auto VParserErrorHandler::Line() const -> XMLFileLoc
{
return m_line;
}
//---------------------------------------------------------------------------------------------------------------------
auto VParserErrorHandler::Column() const -> XMLFileLoc
{
return m_column;
}
//---------------------------------------------------------------------------------------------------------------------
void VParserErrorHandler::handleMessage(const SAXParseException &ex)
{
char* msg = XMLString::transcode(ex.getMessage());
m_description = QString(msg);
m_line = ex.getLineNumber();
m_column = ex.getColumnNumber();
m_hasError = true;
XMLString::release(&msg);
}
//---------------------------------------------------------------------------------------------------------------------
void VParserErrorHandler::warning(const SAXParseException &ex)
{
handleMessage(ex);
}
//---------------------------------------------------------------------------------------------------------------------
void VParserErrorHandler::error(const SAXParseException &ex)
{
handleMessage(ex);
}
//---------------------------------------------------------------------------------------------------------------------
void VParserErrorHandler::fatalError(const SAXParseException &ex)
{
handleMessage(ex);
}
//---------------------------------------------------------------------------------------------------------------------
void VParserErrorHandler::resetErrors()
{
m_description.clear();
m_line = 0;
m_column = 0;
m_hasError = false;
}
//---------------------------------------------------------------------------------------------------------------------
auto VParserErrorHandler::HasError() const -> bool
{
return m_hasError;
}
#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)

View File

@ -0,0 +1,86 @@
/************************************************************************
**
** @file vparsererrorhandler.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 8 2, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VPARSERERRORHANDLER_H
#define VPARSERERRORHANDLER_H
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QAbstractMessageHandler>
#include <QSourceLocation>
//This class need for validation pattern file using XSD shema
class VParserErrorHandler : public QAbstractMessageHandler
{
public:
VParserErrorHandler() =default;
QString StatusMessage() const;
qint64 Line() const;
qint64 Column() const;
protected:
// cppcheck-suppress unusedFunction
virtual void handleMessage(QtMsgType type, const QString &description,
const QUrl &identifier, const QSourceLocation &sourceLocation) override;
private:
QtMsgType m_messageType{};
QString m_description{};
QSourceLocation m_sourceLocation{};
};
#else
#include <xercesc/sax/ErrorHandler.hpp>
#include <xercesc/sax/SAXParseException.hpp>
XERCES_CPP_NAMESPACE_USE
class VParserErrorHandler : public ErrorHandler
{
public:
QString StatusMessage() const;
XMLFileLoc Line() const;
XMLFileLoc Column() const;
void warning(const SAXParseException& ex) override;
void error(const SAXParseException& ex) override;
void fatalError(const SAXParseException& ex) override;
void resetErrors() override;
bool HasError() const;
private:
XMLFileLoc m_line{0};
XMLFileLoc m_column{0};
QString m_description{};
bool m_hasError{false};
void handleMessage(const SAXParseException& ex);
};
#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#endif // VPARSERERRORHANDLER_H

View File

@ -15,7 +15,8 @@ HEADERS += \
$$PWD//vvitconverter.h \ $$PWD//vvitconverter.h \
$$PWD//vabstractmconverter.h \ $$PWD//vabstractmconverter.h \
$$PWD/vlabeltemplateconverter.h \ $$PWD/vlabeltemplateconverter.h \
$$PWD/vwatermarkconverter.h $$PWD/vwatermarkconverter.h \
$$PWD/vparsererrorhandler.h
SOURCES += \ SOURCES += \
$$PWD/utils.cpp \ $$PWD/utils.cpp \
@ -31,4 +32,5 @@ SOURCES += \
$$PWD//vvitconverter.cpp \ $$PWD//vvitconverter.cpp \
$$PWD//vabstractmconverter.cpp \ $$PWD//vabstractmconverter.cpp \
$$PWD/vlabeltemplateconverter.cpp \ $$PWD/vlabeltemplateconverter.cpp \
$$PWD/vwatermarkconverter.cpp $$PWD/vwatermarkconverter.cpp \
$$PWD/vparsererrorhandler.cpp