1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#include <QtGui>
52#include <QtXmlPatterns>
53
54#include "mainwindow.h"
55#include "xmlsyntaxhighlighter.h"
56
57//! [4]
58class MessageHandler : public QAbstractMessageHandler
59{
60public:
61 MessageHandler()
62 : QAbstractMessageHandler(0)
63 {
64 }
65
66 QString statusMessage() const
67 {
68 return m_description;
69 }
70
71 int line() const
72 {
73 return m_sourceLocation.line();
74 }
75
76 int column() const
77 {
78 return m_sourceLocation.column();
79 }
80
81protected:
82 virtual void handleMessage(QtMsgType type, const QString &description,
83 const QUrl &identifier, const QSourceLocation &sourceLocation)
84 {
85 Q_UNUSED(type);
86 Q_UNUSED(identifier);
87
88 m_description = description;
89 m_sourceLocation = sourceLocation;
90 }
91
92private:
93 QString m_description;
94 QSourceLocation m_sourceLocation;
95};
96//! [4]
97
98//! [0]
99MainWindow::MainWindow()
100{
101 setupUi(this);
102
103 new XmlSyntaxHighlighter(schemaView->document());
104 new XmlSyntaxHighlighter(instanceEdit->document());
105
106 schemaSelection->addItem(atext: tr(s: "Contact Schema"));
107 schemaSelection->addItem(atext: tr(s: "Recipe Schema"));
108 schemaSelection->addItem(atext: tr(s: "Order Schema"));
109
110 instanceSelection->addItem(atext: tr(s: "Valid Contact Instance"));
111 instanceSelection->addItem(atext: tr(s: "Invalid Contact Instance"));
112
113 connect(asender: schemaSelection, SIGNAL(currentIndexChanged(int)), SLOT(schemaSelected(int)));
114 connect(asender: instanceSelection, SIGNAL(currentIndexChanged(int)), SLOT(instanceSelected(int)));
115 connect(asender: validateButton, SIGNAL(clicked()), SLOT(validate()));
116 connect(asender: instanceEdit, SIGNAL(textChanged()), SLOT(textChanged()));
117
118 validationStatus->setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
119
120 schemaSelected(index: 0);
121 instanceSelected(index: 0);
122}
123//! [0]
124
125//! [1]
126void MainWindow::schemaSelected(int index)
127{
128 instanceSelection->clear();
129 if (index == 0) {
130 instanceSelection->addItem(atext: tr(s: "Valid Contact Instance"));
131 instanceSelection->addItem(atext: tr(s: "Invalid Contact Instance"));
132 } else if (index == 1) {
133 instanceSelection->addItem(atext: tr(s: "Valid Recipe Instance"));
134 instanceSelection->addItem(atext: tr(s: "Invalid Recipe Instance"));
135 } else if (index == 2) {
136 instanceSelection->addItem(atext: tr(s: "Valid Order Instance"));
137 instanceSelection->addItem(atext: tr(s: "Invalid Order Instance"));
138 }
139 textChanged();
140
141 const QString fileName = QStringLiteral(":/schema_")
142 + QString::number(index) + QStringLiteral(".xsd");
143 QFile schemaFile(fileName);
144 if (!schemaFile.open(flags: QIODevice::ReadOnly)) {
145 qWarning() << "Cannot open" << QDir::toNativeSeparators(pathName: fileName)
146 << ':' << schemaFile.errorString();
147 return;
148 }
149
150 const QString schemaText(QString::fromUtf8(str: schemaFile.readAll()));
151 schemaView->setPlainText(schemaText);
152
153 validate();
154}
155//! [1]
156
157//! [2]
158void MainWindow::instanceSelected(int index)
159{
160 if (index < 0) {
161 instanceEdit->setPlainText(QString());
162 return;
163 }
164 const QString fileName = QStringLiteral(":/instance_")
165 + QString::number(2 * schemaSelection->currentIndex() + index)
166 + QStringLiteral(".xml");
167 QFile instanceFile(fileName);
168 if (!instanceFile.open(flags: QIODevice::ReadOnly)) {
169 qWarning() << "Cannot open" << QDir::toNativeSeparators(pathName: fileName)
170 << ':' << instanceFile.errorString();
171 return;
172 }
173 const QString instanceText(QString::fromUtf8(str: instanceFile.readAll()));
174 instanceEdit->setPlainText(instanceText);
175
176 validate();
177}
178//! [2]
179
180//! [3]
181void MainWindow::validate()
182{
183 const QByteArray schemaData = schemaView->toPlainText().toUtf8();
184 const QByteArray instanceData = instanceEdit->toPlainText().toUtf8();
185
186 MessageHandler messageHandler;
187
188 QXmlSchema schema;
189 schema.setMessageHandler(&messageHandler);
190
191 schema.load(data: schemaData);
192
193 bool errorOccurred = false;
194 if (!schema.isValid()) {
195 errorOccurred = true;
196 } else {
197 QXmlSchemaValidator validator(schema);
198 if (!validator.validate(data: instanceData))
199 errorOccurred = true;
200 }
201
202 if (errorOccurred) {
203 validationStatus->setText(messageHandler.statusMessage());
204 moveCursor(line: messageHandler.line(), column: messageHandler.column());
205 } else {
206 validationStatus->setText(tr(s: "validation successful"));
207 }
208
209 const QString styleSheet = QString("QLabel {background: %1; padding: 3px}")
210 .arg(a: errorOccurred ? QColor(Qt::red).lighter(f: 160).name() :
211 QColor(Qt::green).lighter(f: 160).name());
212 validationStatus->setStyleSheet(styleSheet);
213}
214//! [3]
215
216void MainWindow::textChanged()
217{
218 instanceEdit->setExtraSelections(QList<QTextEdit::ExtraSelection>());
219}
220
221void MainWindow::moveCursor(int line, int column)
222{
223 instanceEdit->moveCursor(operation: QTextCursor::Start);
224 for (int i = 1; i < line; ++i)
225 instanceEdit->moveCursor(operation: QTextCursor::Down);
226
227 for (int i = 1; i < column; ++i)
228 instanceEdit->moveCursor(operation: QTextCursor::Right);
229
230 QList<QTextEdit::ExtraSelection> extraSelections;
231 QTextEdit::ExtraSelection selection;
232
233 const QColor lineColor = QColor(Qt::red).lighter(f: 160);
234 selection.format.setBackground(lineColor);
235 selection.format.setProperty(propertyId: QTextFormat::FullWidthSelection, value: true);
236 selection.cursor = instanceEdit->textCursor();
237 selection.cursor.clearSelection();
238 extraSelections.append(t: selection);
239
240 instanceEdit->setExtraSelections(extraSelections);
241
242 instanceEdit->setFocus();
243}
244

source code of qtxmlpatterns/examples/xmlpatterns/schema/mainwindow.cpp