Line data Source code
1 : /*
2 : Copyright (c) 2011, Stanislaw Adaszewski
3 : All rights reserved.
4 :
5 : Redistribution and use in source and binary forms, with or without
6 : modification, are permitted provided that the following conditions are met:
7 : * Redistributions of source code must retain the above copyright
8 : notice, this list of conditions and the following disclaimer.
9 : * Redistributions in binary form must reproduce the above copyright
10 : notice, this list of conditions and the following disclaimer in the
11 : documentation and/or other materials provided with the distribution.
12 : * Neither the name of Stanislaw Adaszewski nor the
13 : names of other contributors may be used to endorse or promote products
14 : derived from this software without specific prior written permission.
15 :
16 : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 : ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 : WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 : DISCLAIMED. IN NO EVENT SHALL STANISLAW ADASZEWSKI BE LIABLE FOR ANY
20 : DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 : (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 : LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 : ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 : SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 :
27 : Copyright (c) 2012-2017
28 : Changes made by Alexis Wilke so the model works in Qt 5.x and with Snap.
29 : */
30 :
31 :
32 : // self
33 : //
34 : #include "snapwebsites/qdomnodemodel.h"
35 :
36 :
37 : // Qt lib
38 : //
39 : #include <QDomNode>
40 : #include <QDomDocument>
41 : #include <QUrl>
42 : #include <QVector>
43 : #include <QSourceLocation>
44 : #include <QVariant>
45 : #include <QDebug>
46 :
47 :
48 : // last include
49 : //
50 : #include <snapdev/poison.h>
51 :
52 :
53 :
54 :
55 :
56 :
57 :
58 0 : class MyDomNode: public QDomNode
59 : {
60 : public:
61 0 : MyDomNode(const QDomNode& other):
62 0 : QDomNode(other)
63 : {
64 0 : }
65 :
66 0 : MyDomNode(QDomNodePrivate *otherImpl):
67 0 : QDomNode(otherImpl)
68 : {
69 0 : }
70 :
71 0 : QDomNodePrivate *getImpl()
72 : {
73 0 : return impl;
74 : }
75 : };
76 :
77 0 : QDomNodeModel::QDomNodeModel(QXmlNamePool pool, QDomDocument doc):
78 0 : f_pool(pool), f_doc(doc)
79 : {
80 0 : qDebug() << "QDomNodeModel::init";
81 0 : }
82 :
83 0 : QUrl QDomNodeModel::baseUri (const QXmlNodeModelIndex &) const
84 : {
85 : // TODO: Not implemented.
86 0 : qDebug() << "Not implemented: QDomNodeModel::baseUri()";
87 0 : return QUrl();
88 : }
89 :
90 0 : QXmlNodeModelIndex::DocumentOrder QDomNodeModel::compareOrder (
91 : const QXmlNodeModelIndex & ni1,
92 : const QXmlNodeModelIndex & ni2 ) const
93 : {
94 0 : qDebug() << "compareOrder";
95 0 : QDomNode n1 = toDomNode(ni1);
96 0 : QDomNode n2 = toDomNode(ni2);
97 :
98 : //qDebug() << "Comparing...";
99 0 : if (n1 == n2)
100 0 : return QXmlNodeModelIndex::Is;
101 :
102 0 : Path p1 = path(n1);
103 0 : Path p2 = path(n2);
104 :
105 0 : for (int i = 1; i < p1.size(); i++)
106 0 : if (p1[i] == n2)
107 0 : return QXmlNodeModelIndex::Follows;
108 :
109 0 : for (int i = 1; i < p2.size(); i++)
110 0 : if (p2[i] == n1)
111 0 : return QXmlNodeModelIndex::Precedes;
112 :
113 0 : for (int i = 1; i < p1.size(); i++)
114 0 : for (int j = 1; j < p2.size(); j++)
115 : {
116 0 : if (p1[i] == p2[j]) // Common ancestor
117 : {
118 0 : int ci1 = childIndex(p1[i-1]);
119 0 : int ci2 = childIndex(p2[j-1]);
120 :
121 0 : if (ci1 < ci2)
122 0 : return QXmlNodeModelIndex::Precedes;
123 : else
124 0 : return QXmlNodeModelIndex::Follows;
125 : }
126 : }
127 :
128 0 : return QXmlNodeModelIndex::Precedes; // Should be impossible!
129 : }
130 :
131 0 : QUrl QDomNodeModel::documentUri(const QXmlNodeModelIndex&) const
132 : {
133 : // TODO: Not implemented.
134 0 : qDebug() << "Not implemented: QDomNodeModel::documentUri()";
135 0 : return QUrl();
136 : }
137 :
138 0 : QXmlNodeModelIndex QDomNodeModel::elementById(const QXmlName& id) const
139 : {
140 0 : qDebug() << "id to element";
141 0 : return fromDomNode(f_doc.elementById(id.toClarkName(f_pool)));
142 : }
143 :
144 0 : QXmlNodeModelIndex::NodeKind QDomNodeModel::kind(const QXmlNodeModelIndex& ni) const
145 : {
146 0 : qDebug() << "kind";
147 0 : QDomNode n = toDomNode(ni);
148 0 : if (n.isAttr()) {
149 : //qDebug() << "Kind... attr";
150 0 : return QXmlNodeModelIndex::Attribute;
151 : }
152 0 : else if (n.isText()) {
153 : //qDebug() << "Kind... text";
154 0 : return QXmlNodeModelIndex::Text;
155 : }
156 0 : else if (n.isComment()) {
157 : //qDebug() << "Kind... comment";
158 0 : return QXmlNodeModelIndex::Comment;
159 : }
160 0 : else if (n.isDocument()) {
161 : //qDebug() << "Kind... document";
162 0 : return QXmlNodeModelIndex::Document;
163 : }
164 0 : else if (n.isElement()) {
165 : //qDebug() << "Kind... element";
166 0 : return QXmlNodeModelIndex::Element;
167 : }
168 0 : else if (n.isProcessingInstruction()) {
169 : //qDebug() << "Kind... processing?!";
170 0 : return QXmlNodeModelIndex::ProcessingInstruction;
171 : }
172 :
173 : //qDebug() << "No Kind??";
174 0 : return static_cast<QXmlNodeModelIndex::NodeKind>(0);
175 : }
176 :
177 0 : QXmlName QDomNodeModel::name(const QXmlNodeModelIndex& ni) const
178 : {
179 0 : qDebug() << "name";
180 0 : QDomNode n = toDomNode(ni);
181 :
182 0 : if (n.isAttr() || n.isElement() || n.isProcessingInstruction()) {
183 : //qDebug() << "Get name" << n.nodeName() << "/" << n.namespaceURI() << "/" << n.prefix();
184 0 : return QXmlName(f_pool, n.localName(), n.namespaceURI(), n.prefix());
185 : }
186 :
187 : //qDebug() << "No name?!";
188 0 : return QXmlName(f_pool, QString(), QString(), QString());
189 : }
190 :
191 0 : QVector<QXmlName> QDomNodeModel::namespaceBindings(const QXmlNodeModelIndex&) const
192 : {
193 : // TODO: Not implemented.
194 0 : qDebug() << "Not implemented: QDomNodeModel::namespaceBindings()";
195 0 : return QVector<QXmlName>();
196 : }
197 :
198 0 : QVector<QXmlNodeModelIndex> QDomNodeModel::nodesByIdref(const QXmlName&) const
199 : {
200 : // TODO: Not implemented.
201 0 : qDebug() << "Not implemented: QDomNodeModel::nodesByIdref()";
202 0 : return QVector<QXmlNodeModelIndex>();
203 : }
204 :
205 0 : QXmlNodeModelIndex QDomNodeModel::root ( const QXmlNodeModelIndex & ni ) const
206 : {
207 0 : qDebug() << "Get root";
208 0 : QDomNode n = toDomNode(ni);
209 0 : while (!n.parentNode().isNull()) {
210 0 : n = n.parentNode();
211 : }
212 :
213 0 : return fromDomNode(n);
214 : }
215 :
216 : // This is not a virtual function, we cannot overload it
217 : //QSourceLocation QDomNodeModel::sourceLocation(const QXmlNodeModelIndex&) const
218 : //{
219 : // // TODO: Not implemented.
220 : //qDebug() << "Not implemented: QDomNodeModel::sourceLocation()";
221 : // return QSourceLocation();
222 : //}
223 :
224 0 : QString QDomNodeModel::stringValue(const QXmlNodeModelIndex & ni) const
225 : {
226 0 : qDebug() << "stringValue";
227 0 : QDomNode n = toDomNode(ni);
228 :
229 0 : if (n.isProcessingInstruction()) {
230 0 : return n.toProcessingInstruction().data();
231 : }
232 0 : else if (n.isText()) {
233 : //qDebug() << "Text:" << n.toText().data();
234 0 : return n.toText().data();
235 : }
236 0 : else if (n.isComment()) {
237 0 : return n.toComment().data();
238 : }
239 0 : else if (n.isElement()) {
240 : //qDebug() << "Element:" << n.toElement().text();
241 0 : return n.toElement().text();
242 : }
243 0 : else if (n.isDocument()) {
244 0 : return n.toDocument().documentElement().text();
245 : }
246 0 : else if (n.isAttr()) {
247 : //qDebug() << "Attribute:" << n.toElement().text();
248 0 : return n.toAttr().value();
249 : }
250 :
251 0 : return QString();
252 : }
253 :
254 0 : QVariant QDomNodeModel::typedValue(const QXmlNodeModelIndex& ni) const
255 : {
256 0 : qDebug() << "Typed (hmmm?) value";
257 0 : return qVariantFromValue(stringValue(ni));
258 : }
259 :
260 0 : QXmlNodeModelIndex QDomNodeModel::fromDomNode(const QDomNode& n) const
261 : {
262 0 : qDebug() << "QDomNodeModel::fromDomNode()...";
263 0 : if(n.isNull()) {
264 0 : qDebug() << "QDomNodeModel::fromDomNode() -- NULL!?";
265 0 : return QXmlNodeModelIndex();
266 : }
267 :
268 0 : qDebug() << "QDomNodeModel::fromDomNode() -- createIndex() called..." << MyDomNode(n).getImpl();
269 0 : return createIndex(MyDomNode(n).getImpl(), 0);
270 : }
271 :
272 0 : QDomNode QDomNodeModel::toDomNode(const QXmlNodeModelIndex& ni) const
273 : {
274 0 : qDebug() << "toDomNode";
275 0 : return MyDomNode(reinterpret_cast<QDomNodePrivate *>(ni.data()));
276 : }
277 :
278 0 : QDomNodeModel::Path QDomNodeModel::path(const QDomNode& n) const
279 : {
280 0 : qDebug() << "path";
281 0 : Path res;
282 0 : QDomNode cur = n;
283 0 : while (!cur.isNull())
284 : {
285 0 : res.push_back(cur);
286 0 : cur = cur.parentNode();
287 : }
288 0 : return res;
289 : }
290 :
291 0 : int QDomNodeModel::childIndex(const QDomNode& n) const
292 : {
293 0 : qDebug() << "childIndex";
294 0 : QDomNodeList children = n.parentNode().childNodes();
295 0 : for (int i = 0; i < children.size(); i++)
296 0 : if (children.at(i) == n)
297 0 : return i;
298 :
299 0 : return -1;
300 : }
301 :
302 0 : QVector<QXmlNodeModelIndex> QDomNodeModel::attributes ( const QXmlNodeModelIndex & ni ) const
303 : {
304 0 : qDebug() << "attributes";
305 0 : QDomElement n = toDomNode(ni).toElement();
306 0 : QDomNamedNodeMap attrs = n.attributes();
307 0 : QVector<QXmlNodeModelIndex> res;
308 0 : for (int i = 0; i < attrs.size(); i++)
309 : {
310 0 : res.push_back(fromDomNode(attrs.item(i)));
311 : }
312 0 : return res;
313 : }
314 :
315 0 : QXmlNodeModelIndex QDomNodeModel::nextFromSimpleAxis ( SimpleAxis axis, const QXmlNodeModelIndex & ni ) const
316 : {
317 0 : qDebug() << "nextFromSimpleAxis";
318 0 : QDomNode n(toDomNode(ni));
319 0 : switch(axis) {
320 0 : case Parent:
321 0 : return fromDomNode(n.parentNode());
322 :
323 0 : case FirstChild:
324 0 : return fromDomNode(n.firstChild());
325 :
326 0 : case PreviousSibling:
327 0 : return fromDomNode(n.previousSibling());
328 :
329 0 : case NextSibling:
330 0 : return fromDomNode(n.nextSibling());
331 :
332 0 : default:
333 0 : return QXmlNodeModelIndex();
334 :
335 : }
336 : }
337 :
338 : // vim: ts=4 sw=4
|