diff options
Diffstat (limited to 'examples/xmlpatterns/qobjectxmlmodel')
10 files changed, 1127 insertions, 0 deletions
diff --git a/examples/xmlpatterns/qobjectxmlmodel/forms/mainwindow.ui b/examples/xmlpatterns/qobjectxmlmodel/forms/mainwindow.ui new file mode 100644 index 0000000..ad43284 --- /dev/null +++ b/examples/xmlpatterns/qobjectxmlmodel/forms/mainwindow.ui @@ -0,0 +1,196 @@ +<ui version="4.0" > + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle" > + <string>QObjectXmlModel Example</string> + </property> + <widget class="QWidget" name="centralwidget" > + <property name="geometry" > + <rect> + <x>0</x> + <y>29</y> + <width>800</width> + <height>549</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4" > + <item> + <widget class="QLabel" name="label" > + <property name="font" > + <font> + <italic>true</italic> + </font> + </property> + <property name="text" > + <string>See the About menu entry for a description of this example.</string> + </property> + </widget> + </item> + <item> + <widget class="QTabWidget" name="inheritanceTab" > + <property name="autoFillBackground" > + <bool>true</bool> + </property> + <property name="currentIndex" > + <number>0</number> + </property> + <widget class="QWidget" name="wholeTreeTab" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>778</width> + <height>475</height> + </rect> + </property> + <attribute name="title" > + <string>Whole QObjectTree</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout" > + <item> + <widget class="QSplitter" name="splitter" > + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <widget class="QTextEdit" name="wholeTree" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Minimum" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly" > + <bool>true</bool> + </property> + <property name="html" > + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string> + </property> + <property name="acceptRichText" > + <bool>false</bool> + </property> + </widget> + <widget class="QTextEdit" name="wholeTreeOutput" > + <property name="readOnly" > + <bool>true</bool> + </property> + <property name="html" > + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string> + </property> + <property name="acceptRichText" > + <bool>false</bool> + </property> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="htmlTab" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>778</width> + <height>475</height> + </rect> + </property> + <attribute name="title" > + <string>Statistics in HTML </string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2" > + <item> + <widget class="QSplitter" name="splitter_2" > + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <widget class="QTextEdit" name="htmlQueryEdit" > + <property name="readOnly" > + <bool>true</bool> + </property> + <property name="html" > + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string> + </property> + <property name="acceptRichText" > + <bool>false</bool> + </property> + </widget> + <widget class="QWebView" name="htmlOutput" > + <property name="url" > + <url> + <string>about:blank</string> + </url> + </property> + </widget> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>29</height> + </rect> + </property> + <widget class="QMenu" name="menuHelp" > + <property name="title" > + <string>Help</string> + </property> + <addaction name="actionAbout" /> + </widget> + <addaction name="menuHelp" /> + </widget> + <widget class="QStatusBar" name="statusbar" > + <property name="geometry" > + <rect> + <x>0</x> + <y>578</y> + <width>800</width> + <height>22</height> + </rect> + </property> + </widget> + <action name="actionAbout" > + <property name="text" > + <string>About</string> + </property> + <property name="shortcut" > + <string>Ctrl+B</string> + </property> + </action> + </widget> + <customwidgets> + <customwidget> + <class>QWebView</class> + <extends>QWidget</extends> + <header>QtWebKit/QWebView</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/examples/xmlpatterns/qobjectxmlmodel/main.cpp b/examples/xmlpatterns/qobjectxmlmodel/main.cpp new file mode 100644 index 0000000..c73d211 --- /dev/null +++ b/examples/xmlpatterns/qobjectxmlmodel/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +#include "mainwindow.h" + +int main(int argc, char* argv[]) +{ + Q_INIT_RESOURCE(queries); + QApplication app(argc, argv); + MainWindow mainWindow; + mainWindow.show(); + return app.exec(); +} diff --git a/examples/xmlpatterns/qobjectxmlmodel/mainwindow.cpp b/examples/xmlpatterns/qobjectxmlmodel/mainwindow.cpp new file mode 100644 index 0000000..056ebae --- /dev/null +++ b/examples/xmlpatterns/qobjectxmlmodel/mainwindow.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> +#include <QtXmlPatterns> + +#include "mainwindow.h" +#include "qobjectxmlmodel.h" +#include "xmlsyntaxhighlighter.h" + +MainWindow::MainWindow() +{ + setupUi(this); + + new XmlSyntaxHighlighter(wholeTreeOutput->document()); + + /* Setup the font. */ + { + QFont font("Courier"); + font.setFixedPitch(true); + + wholeTree->setFont(font); + wholeTreeOutput->setFont(font); + htmlQueryEdit->setFont(font); + } + + QXmlNamePool namePool; + QObjectXmlModel qObjectModel(this, namePool); + QXmlQuery query(namePool); + + /* The QObject tree as XML view. */ + { + query.bindVariable("root", qObjectModel.root()); + query.setQuery(QUrl("qrc:/queries/wholeTree.xq")); + + Q_ASSERT(query.isValid()); + QByteArray output; + QBuffer buffer(&output); + buffer.open(QIODevice::WriteOnly); + + /* Let's the use the formatter, so it's a bit easier to read. */ + QXmlFormatter serializer(query, &buffer); + + query.evaluateTo(&serializer); + buffer.close(); + + { + QFile queryFile(":/queries/wholeTree.xq"); + queryFile.open(QIODevice::ReadOnly); + wholeTree->setPlainText(QString::fromUtf8(queryFile.readAll())); + wholeTreeOutput->setPlainText(QString::fromUtf8(output.constData())); + } + } + + /* The QObject occurrence statistics as HTML view. */ + { + query.setQuery(QUrl("qrc:/queries/statisticsInHTML.xq")); + Q_ASSERT(query.isValid()); + + QByteArray output; + QBuffer buffer(&output); + buffer.open(QIODevice::WriteOnly); + + /* Let's the use the serializer, so we gain a bit of speed. */ + QXmlSerializer serializer(query, &buffer); + + query.evaluateTo(&serializer); + buffer.close(); + + { + QFile queryFile(":/queries/statisticsInHTML.xq"); + queryFile.open(QIODevice::ReadOnly); + htmlQueryEdit->setPlainText(QString::fromUtf8(queryFile.readAll())); + htmlOutput->setHtml(QString(output)); + } + } +} + +void MainWindow::on_actionAbout_triggered() +{ + QMessageBox::about(this, + tr("About QObject XML Model"), + tr("<p>The <b>QObject XML Model</b> example shows " + "how to use XQuery on top of data of your choice " + "without converting it to an XML document.</p>" + "<p>In this example a QSimpleXmlNodeModel subclass " + "makes it possible to query a QObject tree using " + "XQuery and retrieve the result as pointers to " + "QObjects, or as XML.</p>" + "<p>A possible use case of this could be to write " + "an application that tests a graphical interface " + "against Human Interface Guidelines, or that " + "queries an application's data which is modeled " + "using a QObject tree and dynamic properties.")); +} + + diff --git a/examples/xmlpatterns/qobjectxmlmodel/mainwindow.h b/examples/xmlpatterns/qobjectxmlmodel/mainwindow.h new file mode 100644 index 0000000..362bd0e --- /dev/null +++ b/examples/xmlpatterns/qobjectxmlmodel/mainwindow.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> +#include <QFile> + +#include "ui_mainwindow.h" + +//! [0] +class MainWindow : public QMainWindow, + private Ui_MainWindow +{ + Q_OBJECT + + public: + MainWindow(); + + private slots: + void on_actionAbout_triggered(); +}; +//! [0] + +#endif diff --git a/examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp b/examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp new file mode 100644 index 0000000..3eee67a --- /dev/null +++ b/examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp @@ -0,0 +1,459 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QVector> +#include <QtDebug> + +#include <QCoreApplication> +#include <QMetaProperty> +#include <QXmlQuery> +#include <QXmlResultItems> + +#include "qobjectxmlmodel.h" + +QT_BEGIN_NAMESPACE + +/* +<metaObjects> + <metaObject className="QObject"/> + <metaObject className="QWidget" superClass="QObject"> + </metaObject> + ... +</metaObjects> +<QObject objectName="MyWidget" property1="..." property2="..."> <!-- This is root() --> + <QObject objectName="MyFOO" property1="..."/> + .... +</QObject> +*/ + +QObjectXmlModel::QObjectXmlModel(QObject *const object, const QXmlNamePool &np) + : QSimpleXmlNodeModel(np), + m_baseURI(QUrl::fromLocalFile(QCoreApplication::applicationFilePath())), + m_root(object), + m_allMetaObjects(allMetaObjects()) +{ + Q_ASSERT(m_baseURI.isValid()); +} + +//! [5] +QXmlNodeModelIndex QObjectXmlModel::qObjectSibling(const int pos, const QXmlNodeModelIndex &n) const +{ + Q_ASSERT(pos == 1 || pos == -1); + Q_ASSERT(asQObject(n)); + + const QObject *parent = asQObject(n)->parent(); + if (parent) { + const QList<QObject *> &children = parent->children(); + const int siblingPos = children.indexOf(asQObject(n)) + pos; + + if (siblingPos >= 0 && siblingPos < children.count()) + return createIndex(children.at(siblingPos)); + else + return QXmlNodeModelIndex(); + } + else + return QXmlNodeModelIndex(); +} +//! [5] + +//! [1] +QObjectXmlModel::QObjectNodeType QObjectXmlModel::toNodeType(const QXmlNodeModelIndex &n) +{ + return QObjectNodeType(n.additionalData() & (15 << 26)); +} +//! [1] + +//! [9] +QObjectXmlModel::AllMetaObjects QObjectXmlModel::allMetaObjects() const +{ + QXmlQuery query(namePool()); + query.bindVariable("root", root()); + query.setQuery("declare variable $root external;" + "$root/descendant-or-self::QObject"); + Q_ASSERT(query.isValid()); + + QXmlResultItems result; + query.evaluateTo(&result); + QXmlItem i(result.next()); + + AllMetaObjects objects; + while (!i.isNull()) { + const QMetaObject *moo = asQObject(i.toNodeModelIndex())->metaObject(); + while (moo) { + if (!objects.contains(moo)) + objects.append(moo); + moo = moo->superClass(); + } + i = result.next(); + } + + Q_ASSERT(!objects.contains(0)); + return objects; +} +//! [9] + +QXmlNodeModelIndex QObjectXmlModel::metaObjectSibling(const int pos, const QXmlNodeModelIndex &n) const +{ + Q_ASSERT(pos == 1 || pos == -1); + Q_ASSERT(!n.isNull()); + + const int indexOf = m_allMetaObjects.indexOf(static_cast<const QMetaObject *>(n.internalPointer())) + pos; + + if (indexOf >= 0 && indexOf < m_allMetaObjects.count()) + return createIndex(const_cast<QMetaObject *>(m_allMetaObjects.at(indexOf)), MetaObject); + else + return QXmlNodeModelIndex(); +} + +//! [2] +QXmlNodeModelIndex QObjectXmlModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &n) const +{ + switch (toNodeType(n)) + { + case IsQObject: + { + switch (axis) + { + case Parent: + return createIndex(asQObject(n)->parent()); + + case FirstChild: + { + if (!asQObject(n) || asQObject(n)->children().isEmpty()) + return QXmlNodeModelIndex(); + else + return createIndex(asQObject(n)->children().first()); + } + + case NextSibling: + return qObjectSibling(1, n); + +//! [10] + case PreviousSibling: + { + if (asQObject(n) == m_root) + return createIndex(qint64(0), MetaObjects); + else + return qObjectSibling(-1, n); + } +//! [10] + } + Q_ASSERT(false); + } + +//! [7] + case QObjectClassName: + case QObjectProperty: + { + Q_ASSERT(axis == Parent); + return createIndex(asQObject(n)); + } +//! [7] +//! [2] +//! [3] + +//! [11] + case MetaObjects: + { + switch (axis) + { + case Parent: + return QXmlNodeModelIndex(); + case PreviousSibling: + return QXmlNodeModelIndex(); + case NextSibling: + return root(); + case FirstChild: + { + return createIndex(const_cast<QMetaObject*>(m_allMetaObjects.first()),MetaObject); + } + } + Q_ASSERT(false); + } +//! [11] + + case MetaObject: + { + switch (axis) + { + case FirstChild: + return QXmlNodeModelIndex(); + case Parent: + return createIndex(qint64(0), MetaObjects); + case PreviousSibling: + return metaObjectSibling(-1, n); + case NextSibling: + return metaObjectSibling(1, n); + } + } + + case MetaObjectClassName: + case MetaObjectSuperClass: + { + Q_ASSERT(axis == Parent); + return createIndex(asQObject(n), MetaObject); + } +//! [3] +//! [4] + } + + Q_ASSERT(false); + return QXmlNodeModelIndex(); +} +//! [4] + +//! [6] +QVector<QXmlNodeModelIndex> QObjectXmlModel::attributes(const QXmlNodeModelIndex& n) const +{ + QVector<QXmlNodeModelIndex> result; + QObject *const object = asQObject(n); + + switch(toNodeType(n)) + { + case IsQObject: + { + const QMetaObject *const metaObject = object->metaObject(); + const int count = metaObject->propertyCount(); + result.append(createIndex(object, QObjectClassName)); + + for (int i = 0; i < count; ++i) { + const QMetaProperty qmp(metaObject->property(i)); + const int ii = metaObject->indexOfProperty(qmp.name()); + if (i == ii) + result.append(createIndex(object, QObjectProperty | i)); + } + return result; + } +//! [6] + + case MetaObject: + { + result.append(createIndex(object, MetaObjectClassName)); + result.append(createIndex(object, MetaObjectSuperClass)); + return result; + } +//! [8] + default: + return QVector<QXmlNodeModelIndex>(); + } +} +//! [8] + +QObject *QObjectXmlModel::asQObject(const QXmlNodeModelIndex &n) +{ + return static_cast<QObject *>(n.internalPointer()); +} + +bool QObjectXmlModel::isProperty(const QXmlNodeModelIndex n) +{ + return n.additionalData() & QObjectProperty; +} + +QUrl QObjectXmlModel::documentUri(const QXmlNodeModelIndex& ) const +{ + return m_baseURI; +} + +QXmlNodeModelIndex::NodeKind QObjectXmlModel::kind(const QXmlNodeModelIndex& n) const +{ + switch (toNodeType(n)) + { + case IsQObject: + case MetaObject: + case MetaObjects: + return QXmlNodeModelIndex::Element; + + case QObjectProperty: + case MetaObjectClassName: + case MetaObjectSuperClass: + case QObjectClassName: + return QXmlNodeModelIndex::Attribute; + } + + Q_ASSERT(false); + return QXmlNodeModelIndex::Element; +} + +QXmlNodeModelIndex::DocumentOrder QObjectXmlModel::compareOrder(const QXmlNodeModelIndex& , const QXmlNodeModelIndex& ) const +{ + return QXmlNodeModelIndex::Follows; // TODO +} + +//! [0] +QXmlNodeModelIndex QObjectXmlModel::root() const +{ + return createIndex(m_root); +} +//! [0] + +QXmlNodeModelIndex QObjectXmlModel::root(const QXmlNodeModelIndex& n) const +{ + QObject *p = asQObject(n); + Q_ASSERT(p); + + do { + QObject *const candidate = p->parent(); + if (candidate) + p = candidate; + else + break; + } + while (true); + + return createIndex(p); +} + +/*! + We simply throw all of them into a QList and + return an iterator over it. + */ +QXmlNodeModelIndex::List QObjectXmlModel::ancestors(const QXmlNodeModelIndex n) const +{ + const QObject *p = asQObject(n); + Q_ASSERT(p); + + QXmlNodeModelIndex::List result; + do { + QObject *const candidate = p->parent(); + if (candidate) { + result.append(createIndex(candidate, 0)); + p = candidate; + } + else + break; + } + while (true); + + return result; +} + +QMetaProperty QObjectXmlModel::toMetaProperty(const QXmlNodeModelIndex &n) +{ + const int propertyOffset = n.additionalData() & (~QObjectProperty); + const QObject *const qo = asQObject(n); + return qo->metaObject()->property(propertyOffset); +} + +QXmlName QObjectXmlModel::name(const QXmlNodeModelIndex &n) const +{ + switch (toNodeType(n)) + { + case IsQObject: + return QXmlName(namePool(), QLatin1String("QObject")); + case MetaObject: + return QXmlName(namePool(), QLatin1String("metaObject")); + case QObjectClassName: + case MetaObjectClassName: + return QXmlName(namePool(), QLatin1String("className")); + case QObjectProperty: + return QXmlName(namePool(), toMetaProperty(n).name()); + case MetaObjects: + return QXmlName(namePool(), QLatin1String("metaObjects")); + case MetaObjectSuperClass: + return QXmlName(namePool(), QLatin1String("superClass")); + } + + Q_ASSERT(false); + return QXmlName(); +} + +QVariant QObjectXmlModel::typedValue(const QXmlNodeModelIndex &n) const +{ + switch (toNodeType(n)) + { + case QObjectProperty: + { + const QVariant &candidate = toMetaProperty(n).read(asQObject(n)); + if (isTypeSupported(candidate.type())) + return candidate; + else + return QVariant(); + } + + case MetaObjectClassName: + return QVariant(static_cast<QMetaObject*>(n.internalPointer())->className()); + + case MetaObjectSuperClass: + { + const QMetaObject *const superClass = static_cast<QMetaObject*>(n.internalPointer())->superClass(); + if (superClass) + return QVariant(superClass->className()); + else + return QVariant(); + } + + case QObjectClassName: + return QVariant(asQObject(n)->metaObject()->className()); + + default: + return QVariant(); + } +} + +/*! + Returns \c true if QVariants of type \a type can be used + in QtXmlPatterns, otherwise \c false. + */ +bool QObjectXmlModel::isTypeSupported(QVariant::Type type) +{ + /* See data/qatomicvalue.cpp too. */ + switch (type) + { + /* Fallthrough all these. */ + case QVariant::Char: + case QVariant::String: + case QVariant::Url: + case QVariant::Bool: + case QVariant::ByteArray: + case QVariant::Int: + case QVariant::LongLong: + case QVariant::ULongLong: + case QVariant::Date: + case QVariant::DateTime: + case QVariant::Time: + case QVariant::Double: + return true; + default: + return false; + } +} + +QT_END_NAMESPACE diff --git a/examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.h b/examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.h new file mode 100644 index 0000000..2c2b468 --- /dev/null +++ b/examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Patternist_QObjectNodeModel_H +#define Patternist_QObjectNodeModel_H + +#include <QSimpleXmlNodeModel> + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +class QObject; +class PropertyToAtomicValue; + +/** + * @short Delegates QtCore's QObject into Patternist's QAbstractXmlNodeModel. + * known as pre/post numbering. + * + * QObjectXmlModel sets the toggle on QXmlNodeModelIndex to @c true, if it + * represents a property of the QObject. That is, if the QXmlNodeModelIndex is + * an attribute. + * + * @author Frans Englich <fenglich@trolltech.com> + */ +class QObjectXmlModel : public QSimpleXmlNodeModel +{ + public: + QObjectXmlModel(QObject *const object, const QXmlNamePool &np); + + QXmlNodeModelIndex root() const; + +//! [0] + virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex &n1, const QXmlNodeModelIndex &n2) const; + virtual QXmlName name(const QXmlNodeModelIndex &n) const; + virtual QUrl documentUri(const QXmlNodeModelIndex &n) const; + virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &n) const; + virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex &n) const; + virtual QVariant typedValue(const QXmlNodeModelIndex &n) const; + virtual QVector<QXmlNodeModelIndex> attributes(const QXmlNodeModelIndex&) const; + virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis, const QXmlNodeModelIndex&) const; +//! [0] + + private: + /** + * The highest three bits are used to signify whether the node index + * is an artificial node. + * + * @short if QXmlNodeModelIndex::additionalData() has the + * QObjectPropery flag set, then the QXmlNodeModelIndex is an + * attribute of the QObject element, and the remaining bits form + * an offset to the QObject property that the QXmlNodeModelIndex + * refers to. + * + */ +//! [3] + enum QObjectNodeType + { + IsQObject = 0, + QObjectProperty = 1 << 26, + MetaObjects = 2 << 26, + MetaObject = 3 << 26, + MetaObjectClassName = 4 << 26, + MetaObjectSuperClass = 5 << 26, + QObjectClassName = 6 << 26 + }; +//! [3] + +//! [1] + typedef QVector<const QMetaObject *> AllMetaObjects; +//! [1] + AllMetaObjects allMetaObjects() const; + + static QObjectNodeType toNodeType(const QXmlNodeModelIndex &n); + static bool isTypeSupported(QVariant::Type type); + static inline QObject *asQObject(const QXmlNodeModelIndex &n); + static inline bool isProperty(const QXmlNodeModelIndex n); + static inline QMetaProperty toMetaProperty(const QXmlNodeModelIndex &n); + /** + * Returns the ancestors of @p n. Does therefore not include + * @p n. + */ + inline QXmlNodeModelIndex::List ancestors(const QXmlNodeModelIndex n) const; + QXmlNodeModelIndex qObjectSibling(const int pos, + const QXmlNodeModelIndex &n) const; + QXmlNodeModelIndex metaObjectSibling(const int pos, + const QXmlNodeModelIndex &n) const; + +//! [2] + const QUrl m_baseURI; + QObject *const m_root; +//! [4] + const AllMetaObjects m_allMetaObjects; +//! [4] +//! [2] +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.pro b/examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.pro new file mode 100644 index 0000000..39f0106 --- /dev/null +++ b/examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.pro @@ -0,0 +1,13 @@ + +FORMS += forms/mainwindow.ui +QT += xmlpatterns webkit +SOURCES += qobjectxmlmodel.cpp main.cpp mainwindow.cpp ../shared/xmlsyntaxhighlighter.cpp +HEADERS += qobjectxmlmodel.h mainwindow.h ../shared/xmlsyntaxhighlighter.h +RESOURCES = queries.qrc +INCLUDEPATH += ../shared/ + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/xmlpatterns/qobjectxmlmodel +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro *.xq *.html +sources.path = $$[QT_INSTALL_EXAMPLES]/xmlpatterns/qobjectxmlmodel +INSTALLS += target sources diff --git a/examples/xmlpatterns/qobjectxmlmodel/queries.qrc b/examples/xmlpatterns/qobjectxmlmodel/queries.qrc new file mode 100644 index 0000000..ec8cc6b --- /dev/null +++ b/examples/xmlpatterns/qobjectxmlmodel/queries.qrc @@ -0,0 +1,7 @@ +<!DOCTYPE RCC> + <RCC version="1.0"> +<qresource> + <file>queries/wholeTree.xq</file> + <file>queries/statisticsInHTML.xq</file> +</qresource> +</RCC> diff --git a/examples/xmlpatterns/qobjectxmlmodel/queries/statisticsInHTML.xq b/examples/xmlpatterns/qobjectxmlmodel/queries/statisticsInHTML.xq new file mode 100644 index 0000000..14a7a14 --- /dev/null +++ b/examples/xmlpatterns/qobjectxmlmodel/queries/statisticsInHTML.xq @@ -0,0 +1,58 @@ +<html> + <head> + <title></title> + </head> + <body> + <p>In total the tree has {count($root//QObject)} QObject instances.</p> + <p>Order by occurrence, the QObjects are:</p> + + <ol> + { + for $i in $root/preceding-sibling::metaObjects/metaObject + let $count := count($root//QObject[@className eq $i/@className]) + stable order by $count descending + return if($count > 1) + then <li>{string($i/@className), $count} occurrences</li> + else () + } + </ol> + + <h1>Properties</h1> + { + (: For each QObject, we create a table listing + : the properties of that object. :) + for $object in $root//QObject + return (<h2>{let $name := string($object/@objectName) + return if(string-length($name)) + then $name + else "[no name]", + '(', string($object/@className), ')'}</h2>, + <table border="1"> + <thead> + <tr> + <td>Property Name</td> + <td>Value</td> + </tr> + </thead> + <tbody> + { + $object/@*/<tr> + <td> + { + name() + } + </td> + <td> + { + if(data(.)) + then string(.) + else "N/A" + } + </td> + </tr> + } + </tbody> + </table>) + } + </body> +</html> diff --git a/examples/xmlpatterns/qobjectxmlmodel/queries/wholeTree.xq b/examples/xmlpatterns/qobjectxmlmodel/queries/wholeTree.xq new file mode 100644 index 0000000..253cd43 --- /dev/null +++ b/examples/xmlpatterns/qobjectxmlmodel/queries/wholeTree.xq @@ -0,0 +1,3 @@ +<!-- This is the QObject tree for this application, rendered as XML. -->, +$root/preceding-sibling::metaObjects, +$root |