|
- #ifndef XMLSYNTAXHIGHLIGHTER_H
- #define XMLSYNTAXHIGHLIGHTER_H
- #include <QtCore/QRegExp>
- #include <QtGui/QSyntaxHighlighter>
- class XmlSyntaxHighlighter : public QSyntaxHighlighter
- {
- public:
- explicit XmlSyntaxHighlighter(QTextDocument *parent = nullptr);
- protected:
- virtual void highlightBlock(const QString &text);
- private:
- struct HighlightingRule
- {
- QRegExp pattern;
- QTextCharFormat format;
- };
- QVector<HighlightingRule> highlightingRules;
- QRegExp commentStartExpression;
- QRegExp commentEndExpression;
- QTextCharFormat tagFormat;
- QTextCharFormat attributeFormat;
- QTextCharFormat attributeContentFormat;
- QTextCharFormat commentFormat;
- };
- #endif
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- #include "ui_schema.h"
- //! [0]
- class MainWindow : public QMainWindow,
- private Ui::SchemaMainWindow
- {
- Q_OBJECT
- public:
- MainWindow();
- private Q_SLOTS:
- void schemaSelected(int index);
- void instanceSelected(int index);
- void validate();
- void textChanged();
- private:
- void moveCursor(int line, int column);
- };
- //! [0]
- #endif
- #include "xmlsyntaxhighlighter.h"
- XmlSyntaxHighlighter::XmlSyntaxHighlighter(QTextDocument *parent)
- : QSyntaxHighlighter(parent)
- {
- HighlightingRule rule;
- // tag format
- tagFormat.setForeground(Qt::darkBlue);
- tagFormat.setFontWeight(QFont::Bold);
- rule.pattern = QRegExp("(<[a-zA-Z:]+\\b|<\\?[a-zA-Z:]+\\b|\\?>|>|/>|</[a-zA-Z:]+>)");
- rule.format = tagFormat;
- highlightingRules.append(rule);
- // attribute format
- attributeFormat.setForeground(Qt::darkGreen);
- rule.pattern = QRegExp("[a-zA-Z:]+=");
- rule.format = attributeFormat;
- highlightingRules.append(rule);
- // attribute content format
- attributeContentFormat.setForeground(Qt::red);
- rule.pattern = QRegExp("("[^"]*"|'[^']*')");
- rule.format = attributeContentFormat;
- highlightingRules.append(rule);
- commentFormat.setForeground(Qt::lightGray);
- commentFormat.setFontItalic(true);
- commentStartExpression = QRegExp("<!--");
- commentEndExpression = QRegExp("-->");
- }
- void XmlSyntaxHighlighter::highlightBlock(const QString &text)
- {
- for (const HighlightingRule &rule : qAsConst(highlightingRules)) {
- QRegExp expression(rule.pattern);
- int index = text.indexOf(expression);
- while (index >= 0) {
- int length = expression.matchedLength();
- setFormat(index, length, rule.format);
- index = text.indexOf(expression, index + length);
- }
- }
- setCurrentBlockState(0);
- int startIndex = 0;
- if (previousBlockState() != 1)
- startIndex = text.indexOf(commentStartExpression);
- while (startIndex >= 0) {
- int endIndex = text.indexOf(commentEndExpression, startIndex);
- int commentLength;
- if (endIndex == -1) {
- setCurrentBlockState(1);
- commentLength = text.length() - startIndex;
- } else {
- commentLength = endIndex - startIndex
- + commentEndExpression.matchedLength();
- }
- setFormat(startIndex, commentLength, commentFormat);
- startIndex = text.indexOf(commentStartExpression,
- startIndex + commentLength);
- }
- }
- #include <QtGui>
- #include <QtXmlPatterns>
- #include "mainwindow.h"
- #include "xmlsyntaxhighlighter.h"
- //! [4]
- class MessageHandler : public QAbstractMessageHandler
- {
- public:
- MessageHandler()
- : QAbstractMessageHandler(0)
- {
- }
- QString statusMessage() const
- {
- return m_description;
- }
- int line() const
- {
- return m_sourceLocation.line();
- }
- int 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_description = description;
- m_sourceLocation = sourceLocation;
- }
- private:
- QString m_description;
- QSourceLocation m_sourceLocation;
- };
- //! [4]
- //! [0]
- MainWindow::MainWindow()
- {
- setupUi(this);
- new XmlSyntaxHighlighter(schemaView->document());
- new XmlSyntaxHighlighter(instanceEdit->document());
- schemaSelection->addItem(tr("Contact Schema"));
- schemaSelection->addItem(tr("Recipe Schema"));
- schemaSelection->addItem(tr("Order Schema"));
- instanceSelection->addItem(tr("Valid Contact Instance"));
- instanceSelection->addItem(tr("Invalid Contact Instance"));
- connect(schemaSelection, SIGNAL(currentIndexChanged(int)), SLOT(schemaSelected(int)));
- connect(instanceSelection, SIGNAL(currentIndexChanged(int)), SLOT(instanceSelected(int)));
- connect(validateButton, SIGNAL(clicked()), SLOT(validate()));
- connect(instanceEdit, SIGNAL(textChanged()), SLOT(textChanged()));
- validationStatus->setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
- schemaSelected(0);
- instanceSelected(0);
- }
- //! [0]
- //! [1]
- void MainWindow::schemaSelected(int index)
- {
- instanceSelection->clear();
- if (index == 0) {
- instanceSelection->addItem(tr("Valid Contact Instance"));
- instanceSelection->addItem(tr("Invalid Contact Instance"));
- } else if (index == 1) {
- instanceSelection->addItem(tr("Valid Recipe Instance"));
- instanceSelection->addItem(tr("Invalid Recipe Instance"));
- } else if (index == 2) {
- instanceSelection->addItem(tr("Valid Order Instance"));
- instanceSelection->addItem(tr("Invalid Order Instance"));
- }
- textChanged();
- const QString fileName = QStringLiteral(":/schema_")
- + QString::number(index) + QStringLiteral(".xsd");
- QFile schemaFile(fileName);
- if (!schemaFile.open(QIODevice::ReadOnly)) {
- qWarning() << "Cannot open" << QDir::toNativeSeparators(fileName)
- << ':' << schemaFile.errorString();
- return;
- }
- const QString schemaText(QString::fromUtf8(schemaFile.readAll()));
- schemaView->setPlainText(schemaText);
- validate();
- }
- //! [1]
- //! [2]
- void MainWindow::instanceSelected(int index)
- {
- if (index < 0) {
- instanceEdit->setPlainText(QString());
- return;
- }
- const QString fileName = QStringLiteral(":/instance_")
- + QString::number(2 * schemaSelection->currentIndex() + index)
- + QStringLiteral(".xml");
- QFile instanceFile(fileName);
- if (!instanceFile.open(QIODevice::ReadOnly)) {
- qWarning() << "Cannot open" << QDir::toNativeSeparators(fileName)
- << ':' << instanceFile.errorString();
- return;
- }
- const QString instanceText(QString::fromUtf8(instanceFile.readAll()));
- instanceEdit->setPlainText(instanceText);
- validate();
- }
- //! [2]
- //! [3]
- void MainWindow::validate()
- {
- const QByteArray schemaData = schemaView->toPlainText().toUtf8();
- const QByteArray instanceData = instanceEdit->toPlainText().toUtf8();
- MessageHandler messageHandler;
- QXmlSchema schema;
- schema.setMessageHandler(&messageHandler);
- schema.load(schemaData);
- bool errorOccurred = false;
- if (!schema.isValid()) {
- errorOccurred = true;
- } else {
- QXmlSchemaValidator validator(schema);
- if (!validator.validate(instanceData))
- errorOccurred = true;
- }
- if (errorOccurred) {
- validationStatus->setText(messageHandler.statusMessage());
- moveCursor(messageHandler.line(), messageHandler.column());
- } else {
- validationStatus->setText(tr("validation successful"));
- }
- const QString styleSheet = QString("QLabel {background: %1; padding: 3px}")
- .arg(errorOccurred ? QColor(Qt::red).lighter(160).name() :
- QColor(Qt::green).lighter(160).name());
- validationStatus->setStyleSheet(styleSheet);
- }
- //! [3]
- void MainWindow::textChanged()
- {
- instanceEdit->setExtraSelections(QList<QTextEdit::ExtraSelection>());
- }
- void MainWindow::moveCursor(int line, int column)
- {
- instanceEdit->moveCursor(QTextCursor::Start);
- for (int i = 1; i < line; ++i)
- instanceEdit->moveCursor(QTextCursor::Down);
- for (int i = 1; i < column; ++i)
- instanceEdit->moveCursor(QTextCursor::Right);
- QList<QTextEdit::ExtraSelection> extraSelections;
- QTextEdit::ExtraSelection selection;
- const QColor lineColor = QColor(Qt::red).lighter(160);
- selection.format.setBackground(lineColor);
- selection.format.setProperty(QTextFormat::FullWidthSelection, true);
- selection.cursor = instanceEdit->textCursor();
- selection.cursor.clearSelection();
- extraSelections.append(selection);
- instanceEdit->setExtraSelections(extraSelections);
- instanceEdit->setFocus();
- }
- #include <QtGui>
- #include "mainwindow.h"
- //! [0]
- int main(int argc, char* argv[])
- {
- Q_INIT_RESOURCE(schema);
- QApplication app(argc, argv);
- MainWindow* const window = new MainWindow;
- window->show();
- return app.exec();
- }
复制代码
|
|