/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/#include <QVector>#include <QtDebug>#include <QCoreApplication>#include <QMetaProperty>#include <QXmlQuery>#include <QXmlResultItems>#include "qobjectxmlmodel.h"/*
<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,constQXmlNamePool&np)
: QSimpleXmlNodeModel(np),
m_baseURI(QUrl::fromLocalFile(QCoreApplication::applicationFilePath())),
m_root(object),
m_allMetaObjects(allMetaObjects())
{
Q_ASSERT(m_baseURI.isValid());
}
QXmlNodeModelIndexQObjectXmlModel::qObjectSibling(constint pos,constQXmlNodeModelIndex&n) const
{
Q_ASSERT(pos ==1|| pos ==-1);
Q_ASSERT(asQObject(n));
constQObject*parent = asQObject(n)->parent();
if (parent) {
constQList<QObject*>&children = parent->children();
constint siblingPos = children.indexOf(asQObject(n)) + pos;
if (siblingPos >=0&& siblingPos < children.count())
return createIndex(children.at(siblingPos));
elsereturnQXmlNodeModelIndex();
}
elsereturnQXmlNodeModelIndex();
}
QObjectXmlModel::QObjectNodeTypeQObjectXmlModel::toNodeType(constQXmlNodeModelIndex&n)
{
returnQObjectNodeType(n.additionalData() & (15<<26));
}
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()) {
constQMetaObject*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;
}
QXmlNodeModelIndexQObjectXmlModel::metaObjectSibling(constint pos,constQXmlNodeModelIndex&n) const
{
Q_ASSERT(pos ==1|| pos ==-1);
Q_ASSERT(!n.isNull());
constint indexOf = m_allMetaObjects.indexOf(static_cast<constQMetaObject*>(n.internalPointer())) + pos;
if (indexOf >=0&& indexOf < m_allMetaObjects.count())
return createIndex(const_cast<QMetaObject*>(m_allMetaObjects.at(indexOf)), MetaObject);
elsereturnQXmlNodeModelIndex();
}
QXmlNodeModelIndexQObjectXmlModel::nextFromSimpleAxis(SimpleAxis axis,constQXmlNodeModelIndex&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())
returnQXmlNodeModelIndex();
elsereturn createIndex(asQObject(n)->children().first());
}
case NextSibling:
return qObjectSibling(1, n);
case PreviousSibling:
{
if (asQObject(n) == m_root)
return createIndex(qint64(0), MetaObjects);
elsereturn qObjectSibling(-1, n);
}
}
Q_ASSERT(false);
}
caseQObjectClassName:
caseQObjectProperty:
{
Q_ASSERT(axis == Parent);
return createIndex(asQObject(n));
}
case MetaObjects:
{
switch (axis)
{
case Parent:
returnQXmlNodeModelIndex();
case PreviousSibling:
returnQXmlNodeModelIndex();
case NextSibling:
return root();
case FirstChild:
{
return createIndex(const_cast<QMetaObject*>(m_allMetaObjects.first()),MetaObject);
}
}
Q_ASSERT(false);
}
case MetaObject:
{
switch (axis)
{
case FirstChild:
returnQXmlNodeModelIndex();
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);
}
}
Q_ASSERT(false);
returnQXmlNodeModelIndex();
}
QVector<QXmlNodeModelIndex>QObjectXmlModel::attributes(constQXmlNodeModelIndex& n) const
{
QVector<QXmlNodeModelIndex> result;
QObject*const object = asQObject(n);
switch(toNodeType(n))
{
case IsQObject:
{
constQMetaObject*const metaObject = object->metaObject();
constint count = metaObject->propertyCount();
result.append(createIndex(object,QObjectClassName));
for (int i =0; i < count; ++i) {
constQMetaProperty qmp(metaObject->property(i));
constint ii = metaObject->indexOfProperty(qmp.name());
if (i == ii)
result.append(createIndex(object,QObjectProperty| i));
}
return result;
}
case MetaObject:
{
result.append(createIndex(object, MetaObjectClassName));
result.append(createIndex(object, MetaObjectSuperClass));
return result;
}
default:
returnQVector<QXmlNodeModelIndex>();
}
}
QObject*QObjectXmlModel::asQObject(constQXmlNodeModelIndex&n)
{
returnstatic_cast<QObject*>(n.internalPointer());
}
boolQObjectXmlModel::isProperty(constQXmlNodeModelIndex n)
{
return n.additionalData() &QObjectProperty;
}
QUrlQObjectXmlModel::documentUri(constQXmlNodeModelIndex& ) const
{
return m_baseURI;
}
QXmlNodeModelIndex::NodeKind QObjectXmlModel::kind(constQXmlNodeModelIndex& n) const
{
switch (toNodeType(n))
{
case IsQObject:
case MetaObject:
case MetaObjects:
returnQXmlNodeModelIndex::Element;
caseQObjectProperty:
case MetaObjectClassName:
case MetaObjectSuperClass:
caseQObjectClassName:
returnQXmlNodeModelIndex::Attribute;
}
Q_ASSERT(false);
returnQXmlNodeModelIndex::Element;
}
QXmlNodeModelIndex::DocumentOrder QObjectXmlModel::compareOrder(constQXmlNodeModelIndex&,constQXmlNodeModelIndex& ) const
{
returnQXmlNodeModelIndex::Follows; // TODO
}
QXmlNodeModelIndexQObjectXmlModel::root() const
{
return createIndex(m_root);
}
QXmlNodeModelIndexQObjectXmlModel::root(constQXmlNodeModelIndex& n) const
{
QObject*p = asQObject(n);
Q_ASSERT(p);
do {
QObject*const candidate = p->parent();
if (candidate)
p = candidate;
elsebreak;
}
while (true);
return createIndex(p);
}
/*!
We simply throw all of them into a QList and
return an iterator over it.
*/QXmlNodeModelIndex::List QObjectXmlModel::ancestors(constQXmlNodeModelIndex n) const
{
constQObject*p = asQObject(n);
Q_ASSERT(p);
QXmlNodeModelIndex::List result;
do {
QObject*const candidate = p->parent();
if (candidate) {
result.append(createIndex(candidate,0));
p = candidate;
}
elsebreak;
}
while (true);
return result;
}
QMetaPropertyQObjectXmlModel::toMetaProperty(constQXmlNodeModelIndex&n)
{
constint propertyOffset = n.additionalData() & (~QObjectProperty);
constQObject*const qo = asQObject(n);
return qo->metaObject()->property(propertyOffset);
}
QXmlNameQObjectXmlModel::name(constQXmlNodeModelIndex&n) const
{
switch (toNodeType(n))
{
case IsQObject:
returnQXmlName(namePool(), QLatin1String("QObject"));
case MetaObject:
returnQXmlName(namePool(), QLatin1String("metaObject"));
caseQObjectClassName:
case MetaObjectClassName:
returnQXmlName(namePool(), QLatin1String("className"));
caseQObjectProperty:
returnQXmlName(namePool(), toMetaProperty(n).name());
case MetaObjects:
returnQXmlName(namePool(), QLatin1String("metaObjects"));
case MetaObjectSuperClass:
returnQXmlName(namePool(), QLatin1String("superClass"));
}
Q_ASSERT(false);
returnQXmlName();
}
QVariantQObjectXmlModel::typedValue(constQXmlNodeModelIndex&n) const
{
switch (toNodeType(n))
{
caseQObjectProperty:
{
constQVariant&candidate = toMetaProperty(n).read(asQObject(n));
if (isTypeSupported(candidate.type()))
return candidate;
elsereturnQVariant();
}
case MetaObjectClassName:
returnQVariant(static_cast<QMetaObject*>(n.internalPointer())->className());
case MetaObjectSuperClass:
{
constQMetaObject*const superClass =static_cast<QMetaObject*>(n.internalPointer())->superClass();
if (superClass)
returnQVariant(superClass->className());
elsereturnQVariant();
}
caseQObjectClassName:
returnQVariant(asQObject(n)->metaObject()->className());
default:
returnQVariant();
}
}
/*!
Returns \c true if QVariants of type \a type can be used
in QtXmlPatterns, otherwise \c false.
*/boolQObjectXmlModel::isTypeSupported(QVariant::Type type)
{
/* See data/qatomicvalue.cpp too. */switch (type)
{
/* Fallthrough all these. */caseQVariant::Char:
caseQVariant::String:
caseQVariant::Url:
caseQVariant::Bool:
caseQVariant::ByteArray:
caseQVariant::Int:
caseQVariant::LongLong:
caseQVariant::ULongLong:
caseQVariant::Date:
caseQVariant::DateTime:
caseQVariant::Time:
caseQVariant::Double:
returntrue;
default:
returnfalse;
}
}
Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia.
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter
ou par MP !