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 "../vmisc/def.h"
#if defined(APPIMAGE) && defined(Q_OS_LINUX)
#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
# include "../vmisc/backport/qscopeguard.h"
@ -42,6 +41,10 @@
# include "../vmisc/appimage.h"
#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
{
#if defined(APPIMAGE) && defined(Q_OS_LINUX)
@ -68,6 +71,12 @@ auto main(int argc, char *argv[]) -> int
InitHighDpiScaling(argc, argv);
#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);
app.InitOptions();

View file

@ -40,6 +40,10 @@
# include "../vmisc/appimage.h"
#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
{
#if defined(APPIMAGE) && defined(Q_OS_LINUX)
@ -61,6 +65,12 @@ auto main(int argc, char *argv[]) -> int
VAbstractApplication::WinAttachConsole();
#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
InitHighDpiScaling(argc, argv);
#endif //Q_OS_MAC

View file

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

View file

@ -43,6 +43,10 @@
# include "../vmisc/appimage.h"
#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
@ -77,6 +81,12 @@ auto main(int argc, char *argv[]) -> int
InitHighDpiScaling(argc, argv);
#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);
app.InitOptions();

View file

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

View file

@ -14,6 +14,12 @@ VLib {
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"
files: [
"ifcdef.h",
@ -43,7 +49,7 @@ VLib {
"vexceptionwrongid.cpp",
"vexceptionundo.cpp",
"vexceptioninvalidnotch.cpp",
"vexceptioninvalidhistory.cpp",
"vexceptioninvalidhistory.cpp"
]
}
@ -56,6 +62,8 @@ VLib {
"vbackgroundpatternimage.h",
"vdomdocument.h",
"vlayoutconverter.h",
"vparsererrorhandler.cpp",
"vparsererrorhandler.h",
"vpatternconverter.h",
"vpatternimage.h",
"vtoolrecord.h",

View file

@ -27,8 +27,15 @@
*************************************************************************/
#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 <QDomElement>
#include <QDomNode>
@ -39,73 +46,13 @@
#include <QMap>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QSourceLocation>
#include <QStringList>
#include <QTextDocument>
#include <QUrl>
#include <QXmlSchema>
#include <QXmlSchemaValidator>
#include "../exception/vexception.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)
: m_ver(0x0),
@ -222,6 +169,70 @@ void VAbstractConverter::BiasTokens(vsizetype position, vsizetype bias, QMap<vsi
void VAbstractConverter::ValidateXML(const QString &schema) const
{
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);
if (not pattern.open(QIODevice::ReadOnly))
{
@ -229,22 +240,12 @@ void VAbstractConverter::ValidateXML(const QString &schema) const
throw VException(errorMsg);
}
QFile fileSchema(schema);
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;
VParserErrorHandler messageHandler;
QXmlSchema sch;
sch.setMessageHandler(&messageHandler);
if (sch.load(&fileSchema, QUrl::fromLocalFile(fileSchema.fileName()))==false)
{
pattern.close();
fileSchema.close();
VException e(messageHandler.statusMessage());
VException e(messageHandler.StatusMessage());
e.AddMoreInformation(tr("Could not load schema file '%1'.").arg(fileSchema.fileName()));
throw e;
}
@ -266,15 +267,12 @@ void VAbstractConverter::ValidateXML(const QString &schema) const
if (errorOccurred)
{
pattern.close();
fileSchema.close();
VException e(messageHandler.statusMessage());
e.AddMoreInformation(tr("Validation error file %3 in line %1 column %2").arg(messageHandler.line())
.arg(messageHandler.column()).arg(m_originalFileName));
VException e(messageHandler.StatusMessage());
e.AddMoreInformation(tr("Validation error file %3 in line %1 column %2").arg(messageHandler.Line())
.arg(messageHandler.Column()).arg(m_originalFileName));
throw e;
}
pattern.close();
fileSchema.close();
#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -39,7 +39,11 @@
#include "../exception/vexception.h"
#include "../ifcdef.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QAbstractMessageHandler>
#include <QSourceLocation>
#endif
#include <QByteArray>
#include <QDomNodeList>
#include <QDomText>
@ -47,7 +51,6 @@
#include <QIODevice>
#include <QMessageLogger>
#include <QObject>
#include <QSourceLocation>
#include <QStringList>
#include <QTemporaryFile>
#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//vabstractmconverter.h \
$$PWD/vlabeltemplateconverter.h \
$$PWD/vwatermarkconverter.h
$$PWD/vwatermarkconverter.h \
$$PWD/vparsererrorhandler.h
SOURCES += \
$$PWD/utils.cpp \
@ -31,4 +32,5 @@ SOURCES += \
$$PWD//vvitconverter.cpp \
$$PWD//vabstractmconverter.cpp \
$$PWD/vlabeltemplateconverter.cpp \
$$PWD/vwatermarkconverter.cpp
$$PWD/vwatermarkconverter.cpp \
$$PWD/vparsererrorhandler.cpp