summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/declarative/qmlmodels.qdoc45
-rw-r--r--doc/src/snippets/declarative/listview/highlight.qml12
-rw-r--r--examples/declarative/loader/loader.pro3
-rw-r--r--examples/declarative/loader/qmlfolderlistmodel.cpp (renamed from src/declarative/extra/qmlfolderlistmodel.cpp)0
-rw-r--r--examples/declarative/loader/qmlfolderlistmodel.h (renamed from src/declarative/extra/qmlfolderlistmodel.h)0
-rw-r--r--examples/declarative/sql/README7
-rw-r--r--examples/declarative/sql/hello.qml7
-rw-r--r--src/corelib/animation/qabstractanimation.cpp27
-rw-r--r--src/declarative/extra/extra.pri4
-rw-r--r--src/declarative/fx/qfxlistview.cpp46
-rw-r--r--src/declarative/qml/qmlsqldatabase.cpp2
-rw-r--r--src/declarative/util/qmlanimation_p.h2
-rw-r--r--src/declarative/util/qmlpropertymap.cpp (renamed from src/declarative/extra/qbindablemap.cpp)88
-rw-r--r--src/declarative/util/qmlpropertymap.h (renamed from src/declarative/extra/qbindablemap.h)21
-rw-r--r--src/declarative/util/util.pri6
-rw-r--r--tests/auto/declarative/qmlpropertymap/qmlpropertymap.pro (renamed from tests/auto/declarative/qbindablemap/qbindablemap.pro)2
-rw-r--r--tests/auto/declarative/qmlpropertymap/tst_qmlpropertymap.cpp (renamed from tests/auto/declarative/qbindablemap/tst_qbindablemap.cpp)22
-rw-r--r--tools/qdoc3/cppcodemarker.cpp4
-rw-r--r--tools/qdoc3/node.h4
-rw-r--r--tools/qdoc3/qmlcodemarker.cpp1175
-rw-r--r--tools/qdoc3/qmlcodemarker.h96
21 files changed, 1478 insertions, 95 deletions
diff --git a/doc/src/declarative/qmlmodels.qdoc b/doc/src/declarative/qmlmodels.qdoc
index 6ebb734..45df29b 100644
--- a/doc/src/declarative/qmlmodels.qdoc
+++ b/doc/src/declarative/qmlmodels.qdoc
@@ -50,12 +50,18 @@ creates an instance for each item in the model. Models may be static, or
have items modified, inserted, removed or moved dynamically.
Data is provided to the delegate via named data roles which the
-delegate may bind to. A special \e index role containing the
-index of the item in the model is also available. Models that do
-not have named roles will have the data provided via the \e modelData
-role. The \e modelData role is also provided for Models that have
-only one role. In this case the \e modelData role contains the same
-data as the named role.
+delegate may bind to. The roles are exposed as properties of the
+\model property, though this property is set as a default property
+of the delegate so, unless there is a naming clash with a
+property in the delegate, the roles are usually accessed unqualified.
+
+A special \e index role containing the index of the item in the model
+is also available.
+
+Models that do not have named roles will have the data provided via
+the \e modelData role. The \e modelData role is also provided for
+Models that have only one role. In this case the \e modelData role
+contains the same data as the named role.
There are a number of QML elements that operate using data models:
@@ -189,4 +195,31 @@ ListView {
An Object Instance specifies a model with a single Object element. The
properties of the object are provided as roles.
+The example below creates a list with one item, showing the color of the
+\e myText text. Note the use of the \e model property to specify the model
+data rather than the \e color property of the Text element in the delegate.
+
+\code
+Rectangle {
+ Text {
+ id: myText
+ text: "Hello"
+ color: "#dd44ee"
+ }
+
+ Component {
+ id: myDelegate
+ Text {
+ text: model.color
+ }
+ }
+ ListView {
+ anchors.fill: parent
+ anchors.topMargin: 30
+ model: myText
+ delegate: myDelegate
+ }
+}
+\endcode
+
*/
diff --git a/doc/src/snippets/declarative/listview/highlight.qml b/doc/src/snippets/declarative/listview/highlight.qml
index 2234ee7..7970ede 100644
--- a/doc/src/snippets/declarative/listview/highlight.qml
+++ b/doc/src/snippets/declarative/listview/highlight.qml
@@ -20,6 +20,18 @@ Rectangle {
Text { text: '<b>Name:</b> ' + name }
Text { text: '<b>Number:</b> ' + number }
}
+ // Use the ListView.isCurrentItem attached property to
+ // indent the item if it is the current item.
+ states: [
+ State {
+ name: "Current"
+ when: wrapper.ListView.isCurrentItem
+ PropertyChanges { target: wrapper; x: 10 }
+ }
+ ]
+ transitions: [
+ Transition { NumberAnimation { properties: "x"; duration: 200 } }
+ ]
}
}
//! [0]
diff --git a/examples/declarative/loader/loader.pro b/examples/declarative/loader/loader.pro
index 9b03b8f..8c93210 100644
--- a/examples/declarative/loader/loader.pro
+++ b/examples/declarative/loader/loader.pro
@@ -1,4 +1,5 @@
-SOURCES = main.cpp
+SOURCES = main.cpp qmlfolderlistmodel.cpp
+HEADERS = qmlfolderlistmodel.h
RESOURCES = loader.qrc
QT += script declarative network
diff --git a/src/declarative/extra/qmlfolderlistmodel.cpp b/examples/declarative/loader/qmlfolderlistmodel.cpp
index 0e5c275..0e5c275 100644
--- a/src/declarative/extra/qmlfolderlistmodel.cpp
+++ b/examples/declarative/loader/qmlfolderlistmodel.cpp
diff --git a/src/declarative/extra/qmlfolderlistmodel.h b/examples/declarative/loader/qmlfolderlistmodel.h
index 66e600b..66e600b 100644
--- a/src/declarative/extra/qmlfolderlistmodel.h
+++ b/examples/declarative/loader/qmlfolderlistmodel.h
diff --git a/examples/declarative/sql/README b/examples/declarative/sql/README
deleted file mode 100644
index a7baab2..0000000
--- a/examples/declarative/sql/README
+++ /dev/null
@@ -1,7 +0,0 @@
-Simple demonstration of HTML5-compatible SQL database interface.
-Adds another "hello, world" every time you run it.
-Database is stored in:
- - %APPDATA%/Nokia/Qt/QML/Databases/ (Windows)
- - ~/.local/share/Nokia/Qt/QML/Databases/ (Unix)
- - ~/Library/Application Support/Nokia/Qt/QML/Databases/ (Mac OS X)
-No quota management.
diff --git a/examples/declarative/sql/hello.qml b/examples/declarative/sql/hello.qml
index 20ea611..dc3ca35 100644
--- a/examples/declarative/sql/hello.qml
+++ b/examples/declarative/sql/hello.qml
@@ -3,12 +3,17 @@ import Qt 4.6
Text {
Script {
function findGreetings() {
- var db = openDatabase("QmlExampleDB", "", "The Example QML SQL!", 1000000);
+ var db = openDatabase("QmlExampleDB", "1.0", "The Example QML SQL!", 1000000);
db.transaction(
function(tx) {
+ // Create the database if it doesn't already exist
tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)', []);
+
+ // Add (another) greeting row
tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]);
+
+ // Show all added greetings
tx.executeSql('SELECT * FROM Greeting', [],
function(tx, rs) {
var r = ""
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 8d34a98..0d5f278 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -228,7 +228,11 @@ void QUnifiedTimer::updateAnimationsTime()
void QUnifiedTimer::restartAnimationTimer()
{
- if (!animationTimer.isActive()) {
+ if (runningLeafAnimations == 0 && !runningPauseAnimations.isEmpty()) {
+ int closestTimeToFinish = closestPauseAnimationTimeToFinish();
+ animationTimer.start(closestTimeToFinish, this);
+ isPauseTimerActive = true;
+ } else if (!animationTimer.isActive() || isPauseTimerActive) {
animationTimer.start(timingInterval, this);
isPauseTimerActive = false;
}
@@ -274,11 +278,11 @@ void QUnifiedTimer::registerAnimation(QAbstractAnimation *animation, bool isTopL
void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation)
{
- unregisterRunningAnimation(animation);
-
if (!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer)
return;
+ unregisterRunningAnimation(animation);
+
int idx = animations.indexOf(animation);
if (idx != -1) {
animations.removeAt(idx);
@@ -314,6 +318,7 @@ void QUnifiedTimer::unregisterRunningAnimation(QAbstractAnimation *animation)
runningPauseAnimations.removeOne(animation);
else
runningLeafAnimations--;
+ Q_ASSERT(runningLeafAnimations >= 0);
}
int QUnifiedTimer::closestPauseAnimationTimeToFinish()
@@ -324,9 +329,9 @@ int QUnifiedTimer::closestPauseAnimationTimeToFinish()
int timeToFinish;
if (animation->direction() == QAbstractAnimation::Forward)
- timeToFinish = animation->duration() - QAbstractAnimationPrivate::get(animation)->currentTime;
+ timeToFinish = animation->duration() - animation->currentTime();
else
- timeToFinish = QAbstractAnimationPrivate::get(animation)->totalCurrentTime;
+ timeToFinish = animation->currentTime();
if (timeToFinish < closestTimeToFinish)
closestTimeToFinish = timeToFinish;
@@ -644,13 +649,13 @@ int QAbstractAnimation::currentLoop() const
*/
int QAbstractAnimation::totalDuration() const
{
- Q_D(const QAbstractAnimation);
- if (d->loopCount < 0)
- return -1;
int dura = duration();
- if (dura == -1)
+ if (dura <= 0)
+ return dura;
+ int loopcount = loopCount();
+ if (loopcount < 0)
return -1;
- return dura * d->loopCount;
+ return dura * loopcount;
}
/*!
@@ -681,7 +686,7 @@ void QAbstractAnimation::setCurrentTime(int msecs)
// Calculate new time and loop.
int dura = duration();
- int totalDura = (d->loopCount < 0 || dura == -1) ? -1 : dura * d->loopCount;
+ int totalDura = dura <= 0 ? dura : ((d->loopCount < 0) ? -1 : dura * d->loopCount);
if (totalDura != -1)
msecs = qMin(totalDura, msecs);
d->totalCurrentTime = msecs;
diff --git a/src/declarative/extra/extra.pri b/src/declarative/extra/extra.pri
index 6730550..502504a 100644
--- a/src/declarative/extra/extra.pri
+++ b/src/declarative/extra/extra.pri
@@ -3,11 +3,9 @@ SOURCES += \
extra/qmlnumberformatter.cpp \
extra/qmldatetimeformatter.cpp \
extra/qfxintegermodel.cpp \
- extra/qmlfolderlistmodel.cpp \
extra/qfxanimatedimageitem.cpp \
extra/qfxparticles.cpp \
extra/qmlbehavior.cpp \
- extra/qbindablemap.cpp \
extra/qmlfontloader.cpp
HEADERS += \
@@ -15,12 +13,10 @@ HEADERS += \
extra/qmlnumberformatter.h \
extra/qmldatetimeformatter.h \
extra/qfxintegermodel.h \
- extra/qmlfolderlistmodel.h \
extra/qfxanimatedimageitem.h \
extra/qfxanimatedimageitem_p.h \
extra/qfxparticles.h \
extra/qmlbehavior.h \
- extra/qbindablemap.h \
extra/qmlfontloader.h
contains(QT_CONFIG, xmlpatterns) {
diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp
index 4fb0ec1..2ea1cb7 100644
--- a/src/declarative/fx/qfxlistview.cpp
+++ b/src/declarative/fx/qfxlistview.cpp
@@ -864,6 +864,52 @@ QFxListView::~QFxListView()
}
/*!
+ \qmlattachedproperty bool ListView::isCurrentItem
+ This attched property is true if this delegate is the current item; otherwise false.
+
+ It is attached to each instance of the delegate.
+
+ This property may be used to adjust the appearance of the current item, for example:
+
+ \snippet doc/src/snippets/declarative/listview/highlight.qml 0
+*/
+
+/*!
+ \qmlattachedproperty ListView ListView::view
+ This attached property holds the view that manages this delegate instance.
+
+ It is attached to each instance of the delegate.
+*/
+
+/*!
+ \qmlattachedproperty string ListView::prevSection
+ This attached property holds the section of the previous element.
+
+ It is attached to each instance of the delegate.
+
+ The section is evaluated using the \l {ListView::sectionExpression}{sectionExpression} property.
+*/
+
+/*!
+ \qmlattachedproperty string ListView::section
+ This attached property holds the section of this element.
+
+ It is attached to each instance of the delegate.
+
+ The section is evaluated using the \l {ListView::sectionExpression}{sectionExpression} property.
+*/
+
+/*!
+ \qmlattachedproperty bool ListView::delayRemove
+ This attached property holds whether the delegate may be destroyed.
+
+ It is attached to each instance of the delegate.
+
+ It is sometimes necessary to delay the destruction of an item
+ until an animation completes.
+*/
+
+/*!
\qmlproperty model ListView::model
This property holds the model providing data for the list.
diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp
index 4a5983d..9e39ffc 100644
--- a/src/declarative/qml/qmlsqldatabase.cpp
+++ b/src/declarative/qml/qmlsqldatabase.cpp
@@ -340,7 +340,7 @@ static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine *
QString basename = QmlEnginePrivate::get(engine)->offlineStoragePath + QLatin1String("/Databases/");
QDir().mkpath(basename);
basename += dbid;
- database.setDatabaseName(basename+QLatin1String(".sqllite"));
+ database.setDatabaseName(basename+QLatin1String(".sqlite"));
QSettings ini(basename+QLatin1String(".ini"),QSettings::IniFormat);
ini.setValue(QLatin1String("Name"), dbname);
ini.setValue(QLatin1String("Version"), dbversion);
diff --git a/src/declarative/util/qmlanimation_p.h b/src/declarative/util/qmlanimation_p.h
index 4f6edb7..22c4e2d 100644
--- a/src/declarative/util/qmlanimation_p.h
+++ b/src/declarative/util/qmlanimation_p.h
@@ -92,6 +92,7 @@ private:
//performs an action of type QAbstractAnimationAction
class QActionAnimation : public QAbstractAnimation
{
+ Q_OBJECT
public:
QActionAnimation(QObject *parent = 0) : QAbstractAnimation(parent), animAction(0), policy(KeepWhenStopped) {}
QActionAnimation(QAbstractAnimationAction *action, QObject *parent = 0)
@@ -126,6 +127,7 @@ private:
//animates QmlTimeLineValue (assumes start and end values will be reals or compatible)
class QmlTimeLineValueAnimator : public QVariantAnimation
{
+ Q_OBJECT
public:
QmlTimeLineValueAnimator(QObject *parent = 0) : QVariantAnimation(parent), animValue(0), fromSourced(0), policy(KeepWhenStopped) {}
void setAnimValue(QmlTimeLineValue *value, DeletionPolicy p)
diff --git a/src/declarative/extra/qbindablemap.cpp b/src/declarative/util/qmlpropertymap.cpp
index 5254e2a..e23eebf 100644
--- a/src/declarative/extra/qbindablemap.cpp
+++ b/src/declarative/util/qmlpropertymap.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qbindablemap.h"
+#include "qmlpropertymap.h"
#include <qmlopenmetaobject.h>
#include <QDebug>
@@ -47,24 +47,45 @@ QT_BEGIN_NAMESPACE
//QBindableMapMetaObject lets us listen for changes coming from QML
//so we can emit the changed signal.
-class QBindableMapMetaObject : public QmlOpenMetaObject
+class QmlPropertyMapMetaObject : public QmlOpenMetaObject
{
public:
- QBindableMapMetaObject(QBindableMap *obj) : QmlOpenMetaObject(obj)
- {
- map = obj;
- }
+ QmlPropertyMapMetaObject(QmlPropertyMap *obj, QmlPropertyMapPrivate *objPriv);
protected:
- virtual void propertyWrite(int index)
- {
- map->emitChanged(QString::fromUtf8(name(index)));
- }
+ virtual void propertyWrite(int index);
private:
- QBindableMap *map;
+ QmlPropertyMap *map;
+ QmlPropertyMapPrivate *priv;
};
+class QmlPropertyMapPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlPropertyMap)
+public:
+ QmlPropertyMapMetaObject *mo;
+ QStringList keys;
+ void emitChanged(const QString &key);
+};
+
+void QmlPropertyMapPrivate::emitChanged(const QString &key)
+{
+ Q_Q(QmlPropertyMap);
+ emit q->changed(key);
+}
+
+QmlPropertyMapMetaObject::QmlPropertyMapMetaObject(QmlPropertyMap *obj, QmlPropertyMapPrivate *objPriv) : QmlOpenMetaObject(obj)
+{
+ map = obj;
+ priv = objPriv;
+}
+
+void QmlPropertyMapMetaObject::propertyWrite(int index)
+{
+ priv->emitChanged(QString::fromUtf8(name(index)));
+}
+
/*!
\class QBindableMap
\brief The QBindableMap class allows you to set key-value pairs that can be used in bindings.
@@ -104,34 +125,31 @@ private:
// can we provide a way to clear keys?
// do we want to make any claims regarding key ordering?
// should we have signals for insertion and and deletion -- becoming more model like
-// should we emit change for our own changes as well?
-// Bug or Feature?: values can be created in QML (owner.somethingElse = "Hello") will create somethingElse property. (need to verify if this is actually the case)
-// Bug or Feature?: all values are read-write (there are no read-only values)
/*!
Constructs a bindable map with parent object \a parent.
*/
-QBindableMap::QBindableMap(QObject *parent)
-: QObject(parent)
+QmlPropertyMap::QmlPropertyMap(QObject *parent)
+: QObject(*(new QmlPropertyMapPrivate), parent)
{
- m_mo = new QBindableMapMetaObject(this);
+ Q_D(QmlPropertyMap);
+ d->mo = new QmlPropertyMapMetaObject(this, d);
}
/*!
Destroys the bindable map.
*/
-QBindableMap::~QBindableMap()
+QmlPropertyMap::~QmlPropertyMap()
{
}
/*!
Clears the value (if any) associated with \a key.
*/
-void QBindableMap::clearValue(const QString &key)
+void QmlPropertyMap::clearValue(const QString &key)
{
- //m_keys.remove(); //###
- m_mo->setValue(key.toUtf8(), QVariant());
- //emit changed(key);
+ Q_D(QmlPropertyMap);
+ d->mo->setValue(key.toUtf8(), QVariant());
}
/*!
@@ -140,9 +158,10 @@ void QBindableMap::clearValue(const QString &key)
If no value has been set for this key (or if the value has been cleared),
an invalid QVariant is returned.
*/
-QVariant QBindableMap::value(const QString &key) const
+QVariant QmlPropertyMap::value(const QString &key) const
{
- return m_mo->value(key.toUtf8());
+ Q_D(const QmlPropertyMap);
+ return d->mo->value(key.toUtf8());
}
/*!
@@ -150,12 +169,12 @@ QVariant QBindableMap::value(const QString &key) const
If the key doesn't exist, it is automatically created.
*/
-void QBindableMap::setValue(const QString &key, QVariant value)
+void QmlPropertyMap::setValue(const QString &key, const QVariant &value)
{
- if (!m_keys.contains(key))
- m_keys.append(key);
- m_mo->setValue(key.toUtf8(), value);
- //emit changed(key);
+ Q_D(QmlPropertyMap);
+ if (!d->keys.contains(key))
+ d->keys.append(key);
+ d->mo->setValue(key.toUtf8(), value);
}
/*!
@@ -164,19 +183,16 @@ void QBindableMap::setValue(const QString &key, QVariant value)
Keys that have been cleared will still appear in this list, even though their
associated values are invalid QVariants.
*/
-QStringList QBindableMap::keys() const
+QStringList QmlPropertyMap::keys() const
{
- return m_keys;
+ Q_D(const QmlPropertyMap);
+ return d->keys;
}
/*!
\fn void QBindableMap::changed(const QString &key)
This signal is emitted whenever one of the values in the map is changed. \a key
is the key corresponding to the value that was changed.
- */
+*/
-void QBindableMap::emitChanged(const QString &key)
-{
- emit changed(key);
-}
QT_END_NAMESPACE
diff --git a/src/declarative/extra/qbindablemap.h b/src/declarative/util/qmlpropertymap.h
index aa1908e..295f4b7 100644
--- a/src/declarative/extra/qbindablemap.h
+++ b/src/declarative/util/qmlpropertymap.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QBINDABLEMAP_H
-#define QBINDABLEMAP_H
+#ifndef QMLPROPERTYMAP_H
+#define QMLPROPERTYMAP_H
#include <QtDeclarative/qfxglobal.h>
#include <QtCore/QObject>
@@ -54,16 +54,16 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QBindableMapMetaObject;
-class Q_DECLARATIVE_EXPORT QBindableMap : public QObject
+class QmlPropertyMapPrivate;
+class Q_DECLARATIVE_EXPORT QmlPropertyMap : public QObject
{
Q_OBJECT
public:
- QBindableMap(QObject *parent = 0);
- virtual ~QBindableMap();
+ QmlPropertyMap(QObject *parent = 0);
+ virtual ~QmlPropertyMap();
QVariant value(const QString &key) const;
- void setValue(const QString &key, QVariant value);
+ void setValue(const QString &key, const QVariant &value);
void clearValue(const QString &key);
Q_INVOKABLE QStringList keys() const;
@@ -72,11 +72,8 @@ Q_SIGNALS:
void changed(const QString &key);
private:
- Q_DISABLE_COPY(QBindableMap)
- void emitChanged(const QString &key);
- QBindableMapMetaObject *m_mo;
- QStringList m_keys;
- friend class QBindableMapMetaObject;
+ Q_DECLARE_PRIVATE(QmlPropertyMap)
+ Q_DISABLE_COPY(QmlPropertyMap)
};
QT_END_NAMESPACE
diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri
index ec9967c..01ad898 100644
--- a/src/declarative/util/util.pri
+++ b/src/declarative/util/util.pri
@@ -19,7 +19,8 @@ SOURCES += \
util/qmlopenmetaobject.cpp \
util/qmltimeline.cpp \
util/qmltimer.cpp \
- util/qmlbind.cpp
+ util/qmlbind.cpp \
+ util/qmlpropertymap.cpp
HEADERS += \
util/qmlview.h \
@@ -46,4 +47,5 @@ HEADERS += \
util/qmlnullablevalue_p.h \
util/qmltimeline_p.h \
util/qmltimer.h \
- util/qmlbind.h
+ util/qmlbind.h \
+ util/qmlpropertymap.h
diff --git a/tests/auto/declarative/qbindablemap/qbindablemap.pro b/tests/auto/declarative/qmlpropertymap/qmlpropertymap.pro
index b042405..94f138f 100644
--- a/tests/auto/declarative/qbindablemap/qbindablemap.pro
+++ b/tests/auto/declarative/qmlpropertymap/qmlpropertymap.pro
@@ -1,3 +1,3 @@
load(qttest_p4)
contains(QT_CONFIG,declarative): QT += declarative
-SOURCES += tst_qbindablemap.cpp
+SOURCES += tst_qmlpropertymap.cpp
diff --git a/tests/auto/declarative/qbindablemap/tst_qbindablemap.cpp b/tests/auto/declarative/qmlpropertymap/tst_qmlpropertymap.cpp
index c1b31c2..a923234 100644
--- a/tests/auto/declarative/qbindablemap/tst_qbindablemap.cpp
+++ b/tests/auto/declarative/qmlpropertymap/tst_qmlpropertymap.cpp
@@ -1,16 +1,16 @@
#include <qtest.h>
#include <QtDeclarative/qmlengine.h>
#include <QtDeclarative/qmlcontext.h>
-#include <QtDeclarative/qbindablemap.h>
+#include <QtDeclarative/qmlpropertymap.h>
#include <QtDeclarative/qmlcomponent.h>
#include <QtDeclarative/qfxtext.h>
#include <QSignalSpy>
-class tst_QBindableMap : public QObject
+class tst_QmlPropertyMap : public QObject
{
Q_OBJECT
public:
- tst_QBindableMap() {}
+ tst_QmlPropertyMap() {}
private slots:
void insert();
@@ -18,9 +18,9 @@ private slots:
void changed();
};
-void tst_QBindableMap::insert()
+void tst_QmlPropertyMap::insert()
{
- QBindableMap map;
+ QmlPropertyMap map;
map.setValue(QLatin1String("key1"),100);
map.setValue(QLatin1String("key2"),200);
QVERIFY(map.keys().count() == 2);
@@ -32,9 +32,9 @@ void tst_QBindableMap::insert()
QCOMPARE(map.value(QLatin1String("key1")), QVariant("Hello World"));
}
-void tst_QBindableMap::clear()
+void tst_QmlPropertyMap::clear()
{
- QBindableMap map;
+ QmlPropertyMap map;
map.setValue(QLatin1String("key1"),100);
QVERIFY(map.keys().count() == 1);
@@ -45,9 +45,9 @@ void tst_QBindableMap::clear()
QCOMPARE(map.value(QLatin1String("key1")), QVariant());
}
-void tst_QBindableMap::changed()
+void tst_QmlPropertyMap::changed()
{
- QBindableMap map;
+ QmlPropertyMap map;
QSignalSpy spy(&map, SIGNAL(changed(const QString&)));
map.setValue(QLatin1String("key1"),100);
map.setValue(QLatin1String("key2"),200);
@@ -72,6 +72,6 @@ void tst_QBindableMap::changed()
QCOMPARE(map.value(QLatin1String("key1")), QVariant("Hello World"));
}
-QTEST_MAIN(tst_QBindableMap)
+QTEST_MAIN(tst_QmlPropertyMap)
-#include "tst_qbindablemap.moc"
+#include "tst_qmlpropertymap.moc"
diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp
index 3bee3d9..30ea251 100644
--- a/tools/qdoc3/cppcodemarker.cpp
+++ b/tools/qdoc3/cppcodemarker.cpp
@@ -353,6 +353,10 @@ QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
QString name = taggedQmlNode(node);
if (summary) {
name = linkTag(node,name);
+ } else if (node->type() == Node::QmlProperty) {
+ const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
+ if (pn->isAttached())
+ name.prepend(pn->element() + QLatin1Char('.'));
}
name = "<@name>" + name + "</@name>";
QString synopsis = name;
diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h
index c6f860f..6b19f60 100644
--- a/tools/qdoc3/node.h
+++ b/tools/qdoc3/node.h
@@ -376,7 +376,7 @@ class QmlPropGroupNode : public FakeNode
bool attached);
virtual ~QmlPropGroupNode() { }
- const QString& element() const { return name(); }
+ const QString& element() const { return parent()->name(); }
void setDefault() { isdefault = true; }
bool isDefault() const { return isdefault; }
bool isAttached() const { return att; }
@@ -405,7 +405,7 @@ class QmlPropertyNode : public LeafNode
bool isDesignable() const { return fromTrool(des,false); }
bool isAttached() const { return att; }
- const QString& element() const { return parent()->name(); }
+ const QString& element() const { return static_cast<QmlPropGroupNode*>(parent())->element(); }
private:
enum Trool { Trool_True, Trool_False, Trool_Default };
diff --git a/tools/qdoc3/qmlcodemarker.cpp b/tools/qdoc3/qmlcodemarker.cpp
new file mode 100644
index 0000000..1062f9c
--- /dev/null
+++ b/tools/qdoc3/qmlcodemarker.cpp
@@ -0,0 +1,1175 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ cppcodemarker.cpp
+*/
+
+#include <qdebug.h>
+#include "atom.h"
+#include "cppcodemarker.h"
+#include "node.h"
+#include "text.h"
+#include "tree.h"
+
+QT_BEGIN_NAMESPACE
+
+static int insertTagAround(QString &result, int pos, int len, const QString &tagName,
+ const QString &attributes = QString())
+{
+ QString s;
+ //s.reserve(result.size() + tagName.size() * 2 + attributes.size() + 20);
+ s += result.midRef(0, pos);
+ s += QLatin1Char('<');
+ s += tagName;
+ if (!attributes.isEmpty()) {
+ s += QLatin1Char(' ');
+ s += attributes;
+ }
+ s += QLatin1Char('>');
+ s += result.midRef(pos, len);
+ s += QLatin1String("</");
+ s += tagName;
+ s += QLatin1Char('>');
+ s += result.midRef(pos + len);
+ int diff = s.length() - result.length();
+ result = s;
+ return diff;
+}
+
+/*!
+ The constructor does nothing.
+ */
+CppCodeMarker::CppCodeMarker()
+{
+ // nothing.
+}
+
+/*!
+ The destructor does nothing.
+ */
+CppCodeMarker::~CppCodeMarker()
+{
+ // nothing.
+}
+
+/*!
+ Returns true.
+ */
+bool CppCodeMarker::recognizeCode(const QString & /* code */)
+{
+ return true;
+}
+
+/*!
+ Returns true if \a ext is any of a list of file extensions
+ for the C++ language.
+ */
+bool CppCodeMarker::recognizeExtension(const QString& ext)
+{
+ return ext == "c" ||
+ ext == "c++" ||
+ ext == "cc" ||
+ ext == "cpp" ||
+ ext == "cxx" ||
+ ext == "ch" ||
+ ext == "h" ||
+ ext == "h++" ||
+ ext == "hh" ||
+ ext == "hpp" ||
+ ext == "hxx";
+}
+
+/*!
+ Returns true if \a lang is either "C" or "Cpp".
+ */
+bool CppCodeMarker::recognizeLanguage(const QString &lang)
+{
+ return lang == "C" || lang == "Cpp";
+}
+
+/*!
+ Returns the \a node name, or "()" if \a node is a
+ Node::Function node.
+ */
+QString CppCodeMarker::plainName(const Node *node)
+{
+ QString name = node->name();
+ if (node->type() == Node::Function)
+ name += "()";
+ return name;
+}
+
+QString CppCodeMarker::plainFullName(const Node *node, const Node *relative)
+{
+ if (node->name().isEmpty()) {
+ return "global";
+ }
+ else {
+ QString fullName;
+ for (;;) {
+ fullName.prepend(plainName(node));
+ if (node->parent() == relative || node->parent()->name().isEmpty())
+ break;
+ fullName.prepend("::");
+ node = node->parent();
+ }
+ return fullName;
+ }
+}
+
+QString CppCodeMarker::markedUpCode(const QString &code,
+ const Node *relative,
+ const QString &dirPath)
+{
+ return addMarkUp(protect(code), relative, dirPath);
+}
+
+QString CppCodeMarker::markedUpSynopsis(const Node *node,
+ const Node * /* relative */,
+ SynopsisStyle style)
+{
+ const int MaxEnumValues = 6;
+ const FunctionNode *func;
+ const PropertyNode *property;
+ const VariableNode *variable;
+ const EnumNode *enume;
+ const TypedefNode *typedeff;
+ QString synopsis;
+ QString extra;
+ QString name;
+
+ name = taggedNode(node);
+ if (style != Detailed)
+ name = linkTag(node, name);
+ name = "<@name>" + name + "</@name>";
+
+ if (style == Detailed && !node->parent()->name().isEmpty() &&
+ node->type() != Node::Property)
+ name.prepend(taggedNode(node->parent()) + "::");
+
+ switch (node->type()) {
+ case Node::Namespace:
+ synopsis = "namespace " + name;
+ break;
+ case Node::Class:
+ synopsis = "class " + name;
+ break;
+ case Node::Function:
+ func = (const FunctionNode *) node;
+ if (style != SeparateList && !func->returnType().isEmpty())
+ synopsis = typified(func->returnType()) + " ";
+ synopsis += name;
+ if (func->metaness() != FunctionNode::MacroWithoutParams) {
+ synopsis += " (";
+ if (!func->parameters().isEmpty()) {
+ synopsis += " ";
+ QList<Parameter>::ConstIterator p = func->parameters().begin();
+ while (p != func->parameters().end()) {
+ if (p != func->parameters().begin())
+ synopsis += ", ";
+ synopsis += typified((*p).leftType());
+ if (style != SeparateList && !(*p).name().isEmpty())
+ synopsis +=
+ " <@param>" + protect((*p).name()) + "</@param>";
+ synopsis += protect((*p).rightType());
+ if (style != SeparateList && !(*p).defaultValue().isEmpty())
+ synopsis += " = " + protect((*p).defaultValue());
+ ++p;
+ }
+ synopsis += " ";
+ }
+ synopsis += ")";
+ }
+ if (func->isConst())
+ synopsis += " const";
+
+ if (style == Summary || style == Accessors) {
+ if (func->virtualness() != FunctionNode::NonVirtual)
+ synopsis.prepend("virtual ");
+ if (func->virtualness() == FunctionNode::PureVirtual)
+ synopsis.append(" = 0");
+ }
+ else if (style == SeparateList) {
+ if (!func->returnType().isEmpty() && func->returnType() != "void")
+ synopsis += " : " + typified(func->returnType());
+ }
+ else {
+ QStringList bracketed;
+ if (func->isStatic()) {
+ bracketed += "static";
+ }
+ else if (func->virtualness() != FunctionNode::NonVirtual) {
+ if (func->virtualness() == FunctionNode::PureVirtual)
+ bracketed += "pure";
+ bracketed += "virtual";
+ }
+
+ if (func->access() == Node::Protected) {
+ bracketed += "protected";
+ }
+ else if (func->access() == Node::Private) {
+ bracketed += "private";
+ }
+
+ if (func->metaness() == FunctionNode::Signal) {
+ bracketed += "signal";
+ }
+ else if (func->metaness() == FunctionNode::Slot) {
+ bracketed += "slot";
+ }
+ if (!bracketed.isEmpty())
+ extra += " [" + bracketed.join(" ") + "]";
+ }
+ break;
+ case Node::Enum:
+ enume = static_cast<const EnumNode *>(node);
+ synopsis = "enum " + name;
+ if (style == Summary) {
+ synopsis += " { ";
+
+ QStringList documentedItems = enume->doc().enumItemNames();
+ if (documentedItems.isEmpty()) {
+ foreach (const EnumItem &item, enume->items())
+ documentedItems << item.name();
+ }
+ QStringList omitItems = enume->doc().omitEnumItemNames();
+ foreach (const QString &item, omitItems)
+ documentedItems.removeAll(item);
+
+ if (documentedItems.size() <= MaxEnumValues) {
+ for (int i = 0; i < documentedItems.size(); ++i) {
+ if (i != 0)
+ synopsis += ", ";
+ synopsis += documentedItems.at(i);
+ }
+ }
+ else {
+ for (int i = 0; i < documentedItems.size(); ++i) {
+ if (i < MaxEnumValues-2 || i == documentedItems.size()-1) {
+ if (i != 0)
+ synopsis += ", ";
+ synopsis += documentedItems.at(i);
+ }
+ else if (i == MaxEnumValues - 1) {
+ synopsis += ", ...";
+ }
+ }
+ }
+ if (!documentedItems.isEmpty())
+ synopsis += " ";
+ synopsis += "}";
+ }
+ break;
+ case Node::Typedef:
+ typedeff = static_cast<const TypedefNode *>(node);
+ if (typedeff->associatedEnum()) {
+ synopsis = "flags " + name;
+ }
+ else {
+ synopsis = "typedef " + name;
+ }
+ break;
+ case Node::Property:
+ property = static_cast<const PropertyNode *>(node);
+ synopsis = name + " : " + typified(property->qualifiedDataType());
+ break;
+ case Node::Variable:
+ variable = static_cast<const VariableNode *>(node);
+ if (style == SeparateList) {
+ synopsis = name + " : " + typified(variable->dataType());
+ }
+ else {
+ synopsis = typified(variable->leftType()) + " " +
+ name + protect(variable->rightType());
+ }
+ break;
+ default:
+ synopsis = name;
+ }
+
+ if (style == Summary) {
+ if (node->status() == Node::Preliminary) {
+ extra += " (preliminary)";
+ }
+ else if (node->status() == Node::Deprecated) {
+ extra += " (deprecated)";
+ }
+ else if (node->status() == Node::Obsolete) {
+ extra += " (obsolete)";
+ }
+ }
+
+ if (!extra.isEmpty()) {
+ extra.prepend("<@extra>");
+ extra.append("</@extra>");
+ }
+ return synopsis + extra;
+}
+
+#ifdef QDOC_QML
+/*!
+ */
+QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
+{
+ QString name = taggedQmlNode(node);
+ if (summary) {
+ name = linkTag(node,name);
+ }
+ name = "<@name>" + name + "</@name>";
+ QString synopsis = name;
+ if (node->type() == Node::QmlProperty) {
+ const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
+ synopsis += " : " + typified(pn->dataType());
+ }
+
+ QString extra;
+ if (summary) {
+ if (node->status() == Node::Preliminary) {
+ extra += " (preliminary)";
+ }
+ else if (node->status() == Node::Deprecated) {
+ extra += " (deprecated)";
+ }
+ else if (node->status() == Node::Obsolete) {
+ extra += " (obsolete)";
+ }
+ }
+
+ if (!extra.isEmpty()) {
+ extra.prepend("<@extra>");
+ extra.append("</@extra>");
+ }
+ return synopsis + extra;
+}
+#endif
+
+QString CppCodeMarker::markedUpName(const Node *node)
+{
+ QString name = linkTag(node, taggedNode(node));
+ if (node->type() == Node::Function)
+ name += "()";
+ return name;
+}
+
+QString CppCodeMarker::markedUpFullName(const Node *node, const Node *relative)
+{
+ if (node->name().isEmpty()) {
+ return "global";
+ }
+ else {
+ QString fullName;
+ for (;;) {
+ fullName.prepend(markedUpName(node));
+ if (node->parent() == relative || node->parent()->name().isEmpty())
+ break;
+ fullName.prepend("<@op>::</@op>");
+ node = node->parent();
+ }
+ return fullName;
+ }
+}
+
+QString CppCodeMarker::markedUpEnumValue(const QString &enumValue,
+ const Node *relative)
+{
+ const Node *node = relative->parent();
+ QString fullName;
+ while (node->parent()) {
+ fullName.prepend(markedUpName(node));
+ if (node->parent() == relative || node->parent()->name().isEmpty())
+ break;
+ fullName.prepend("<@op>::</@op>");
+ node = node->parent();
+ }
+ if (!fullName.isEmpty())
+ fullName.append("<@op>::</@op>");
+ fullName.append(enumValue);
+ return fullName;
+}
+
+QString CppCodeMarker::markedUpIncludes(const QStringList& includes)
+{
+ QString code;
+
+ QStringList::ConstIterator inc = includes.begin();
+ while (inc != includes.end()) {
+ code += "#include &lt;<@headerfile>" + *inc + "</@headerfile>&gt;\n";
+ ++inc;
+ }
+ return addMarkUp(code, 0, "");
+}
+
+QString CppCodeMarker::functionBeginRegExp(const QString& funcName)
+{
+ return "^" + QRegExp::escape(funcName) + "$";
+
+}
+
+QString CppCodeMarker::functionEndRegExp(const QString& /* funcName */)
+{
+ return "^\\}$";
+}
+
+#if 0
+ FastSection privateReimpFuncs(classe,
+ "Private Reimplemented Functions",
+ "private reimplemented function",
+ "private reimplemented functions");
+ FastSection protectedReimpFuncs(classe,
+ "Protected Reimplemented Functions",
+ "protected reimplemented function",
+ "protected reimplemented functions");
+ FastSection publicReimpFuncs(classe,
+ "Public Reimplemented Functions",
+ "public reimplemented function",
+ "public reimplemented functions");
+#endif
+
+QList<Section> CppCodeMarker::sections(const InnerNode *inner,
+ SynopsisStyle style,
+ Status status)
+{
+ QList<Section> sections;
+
+ if (inner->type() == Node::Class) {
+ const ClassNode *classe = static_cast<const ClassNode *>(inner);
+
+ if (style == Summary) {
+ FastSection privateFunctions(classe,
+ "Private Functions",
+ "private function",
+ "private functions");
+ FastSection privateSlots(classe, "Private Slots", "private slot", "private slots");
+ FastSection privateTypes(classe, "Private Types", "private type", "private types");
+ FastSection protectedFunctions(classe,
+ "Protected Functions",
+ "protected function",
+ "protected functions");
+ FastSection protectedSlots(classe,
+ "Protected Slots",
+ "protected slot",
+ "protected slots");
+ FastSection protectedTypes(classe,
+ "Protected Types",
+ "protected type",
+ "protected types");
+ FastSection protectedVariables(classe,
+ "Protected Variables",
+ "protected type",
+ "protected variables");
+ FastSection publicFunctions(classe,
+ "Public Functions",
+ "public function",
+ "public functions");
+ FastSection publicSignals(classe, "Signals", "signal", "signals");
+ FastSection publicSlots(classe, "Public Slots", "public slot", "public slots");
+ FastSection publicTypes(classe, "Public Types", "public type", "public types");
+ FastSection publicVariables(classe,
+ "Public Variables",
+ "public type",
+ "public variables");
+ FastSection properties(classe, "Properties", "property", "properties");
+ FastSection relatedNonMembers(classe,
+ "Related Non-Members",
+ "related non-member",
+ "related non-members");
+ FastSection staticPrivateMembers(classe,
+ "Static Private Members",
+ "static private member",
+ "static private members");
+ FastSection staticProtectedMembers(classe,
+ "Static Protected Members",
+ "static protected member",
+ "static protected members");
+ FastSection staticPublicMembers(classe,
+ "Static Public Members",
+ "static public member",
+ "static public members");
+ FastSection macros(inner, "Macros", "macro", "macros");
+
+ NodeList::ConstIterator r = classe->relatedNodes().begin();
+ while (r != classe->relatedNodes().end()) {
+ if ((*r)->type() == Node::Function) {
+ FunctionNode *func = static_cast<FunctionNode *>(*r);
+ if (func->isMacro())
+ insert(macros, *r, style, status);
+ else
+ insert(relatedNonMembers, *r, style, status);
+ }
+ else {
+ insert(relatedNonMembers, *r, style, status);
+ }
+ ++r;
+ }
+
+ QStack<const ClassNode *> stack;
+ stack.push(classe);
+
+ while (!stack.isEmpty()) {
+ const ClassNode *ancestorClass = stack.pop();
+
+ NodeList::ConstIterator c = ancestorClass->childNodes().begin();
+ while (c != ancestorClass->childNodes().end()) {
+ bool isSlot = false;
+ bool isSignal = false;
+ bool isStatic = false;
+ if ((*c)->type() == Node::Function) {
+ const FunctionNode *func = (const FunctionNode *) *c;
+ isSlot = (func->metaness() == FunctionNode::Slot);
+ isSignal = (func->metaness() == FunctionNode::Signal);
+ isStatic = func->isStatic();
+ }
+ else if ((*c)->type() == Node::Variable) {
+ const VariableNode *var = static_cast<const VariableNode *>(*c);
+ isStatic = var->isStatic();
+ }
+
+ switch ((*c)->access()) {
+ case Node::Public:
+ if (isSlot) {
+ insert(publicSlots, *c, style, status);
+ }
+ else if (isSignal) {
+ insert(publicSignals, *c, style, status);
+ }
+ else if (isStatic) {
+ if ((*c)->type() != Node::Variable
+ || !(*c)->doc().isEmpty())
+ insert(staticPublicMembers,*c,style,status);
+ }
+ else if ((*c)->type() == Node::Property) {
+ insert(properties, *c, style, status);
+ }
+ else if ((*c)->type() == Node::Variable) {
+ if (!(*c)->doc().isEmpty())
+ insert(publicVariables, *c, style, status);
+ }
+ else if ((*c)->type() == Node::Function) {
+ if (!insertReimpFunc(publicFunctions,*c,status))
+ insert(publicFunctions, *c, style, status);
+ }
+ else {
+ insert(publicTypes, *c, style, status);
+ }
+ break;
+ case Node::Protected:
+ if (isSlot) {
+ insert(protectedSlots, *c, style, status);
+ }
+ else if (isStatic) {
+ if ((*c)->type() != Node::Variable
+ || !(*c)->doc().isEmpty())
+ insert(staticProtectedMembers,*c,style,status);
+ }
+ else if ((*c)->type() == Node::Variable) {
+ if (!(*c)->doc().isEmpty())
+ insert(protectedVariables,*c,style,status);
+ }
+ else if ((*c)->type() == Node::Function) {
+ if (!insertReimpFunc(protectedFunctions,*c,status))
+ insert(protectedFunctions, *c, style, status);
+ }
+ else {
+ insert(protectedTypes, *c, style, status);
+ }
+ break;
+ case Node::Private:
+ if (isSlot) {
+ insert(privateSlots, *c, style, status);
+ }
+ else if (isStatic) {
+ if ((*c)->type() != Node::Variable
+ || !(*c)->doc().isEmpty())
+ insert(staticPrivateMembers,*c,style,status);
+ }
+ else if ((*c)->type() == Node::Function) {
+ if (!insertReimpFunc(privateFunctions,*c,status))
+ insert(privateFunctions, *c, style, status);
+ }
+ else {
+ insert(privateTypes,*c,style,status);
+ }
+ }
+ ++c;
+ }
+
+ QList<RelatedClass>::ConstIterator r =
+ ancestorClass->baseClasses().begin();
+ while (r != ancestorClass->baseClasses().end()) {
+ stack.prepend((*r).node);
+ ++r;
+ }
+ }
+
+ append(sections, publicTypes);
+ append(sections, properties);
+ append(sections, publicFunctions);
+ append(sections, publicSlots);
+ append(sections, publicSignals);
+ append(sections, publicVariables);
+ append(sections, staticPublicMembers);
+ append(sections, protectedTypes);
+ append(sections, protectedFunctions);
+ append(sections, protectedSlots);
+ append(sections, protectedVariables);
+ append(sections, staticProtectedMembers);
+ append(sections, privateTypes);
+ append(sections, privateFunctions);
+ append(sections, privateSlots);
+ append(sections, staticPrivateMembers);
+ append(sections, relatedNonMembers);
+ append(sections, macros);
+ }
+ else if (style == Detailed) {
+ FastSection memberFunctions(classe,"Member Function Documentation");
+ FastSection memberTypes(classe,"Member Type Documentation");
+ FastSection memberVariables(classe,"Member Variable Documentation");
+ FastSection properties(classe,"Property Documentation");
+ FastSection relatedNonMembers(classe,"Related Non-Members");
+ FastSection macros(classe,"Macro Documentation");
+
+ NodeList::ConstIterator r = classe->relatedNodes().begin();
+ while (r != classe->relatedNodes().end()) {
+ if ((*r)->type() == Node::Function) {
+ FunctionNode *func = static_cast<FunctionNode *>(*r);
+ if (func->isMacro())
+ insert(macros, *r, style, status);
+ else
+ insert(relatedNonMembers, *r, style, status);
+ }
+ else {
+ insert(relatedNonMembers, *r, style, status);
+ }
+ ++r;
+ }
+
+ NodeList::ConstIterator c = classe->childNodes().begin();
+ while (c != classe->childNodes().end()) {
+ if ((*c)->type() == Node::Enum ||
+ (*c)->type() == Node::Typedef) {
+ insert(memberTypes, *c, style, status);
+ }
+ else if ((*c)->type() == Node::Property) {
+ insert(properties, *c, style, status);
+ }
+ else if ((*c)->type() == Node::Variable) {
+ if (!(*c)->doc().isEmpty())
+ insert(memberVariables, *c, style, status);
+ }
+ else if ((*c)->type() == Node::Function) {
+ FunctionNode *function = static_cast<FunctionNode *>(*c);
+ if (!function->associatedProperty())
+ insert(memberFunctions, function, style, status);
+ }
+ ++c;
+ }
+
+ append(sections, memberTypes);
+ append(sections, properties);
+ append(sections, memberFunctions);
+ append(sections, memberVariables);
+ append(sections, relatedNonMembers);
+ append(sections, macros);
+ }
+ else {
+ FastSection all(classe);
+
+ QStack<const ClassNode *> stack;
+ stack.push(classe);
+
+ while (!stack.isEmpty()) {
+ const ClassNode *ancestorClass = stack.pop();
+
+ NodeList::ConstIterator c = ancestorClass->childNodes().begin();
+ while (c != ancestorClass->childNodes().end()) {
+ if ((*c)->access() != Node::Private &&
+ (*c)->type() != Node::Property)
+ insert(all, *c, style, status);
+ ++c;
+ }
+
+ QList<RelatedClass>::ConstIterator r =
+ ancestorClass->baseClasses().begin();
+ while (r != ancestorClass->baseClasses().end()) {
+ stack.prepend((*r).node);
+ ++r;
+ }
+ }
+ append(sections, all);
+ }
+ }
+ else {
+ if (style == Summary || style == Detailed) {
+ FastSection namespaces(inner,
+ "Namespaces",
+ "namespace",
+ "namespaces");
+ FastSection classes(inner,
+ "Classes",
+ "class",
+ "classes");
+ FastSection types(inner,
+ style == Summary ?
+ "Types" : "Type Documentation",
+ "type",
+ "types");
+ FastSection functions(inner,
+ style == Summary ?
+ "Functions" : "Function Documentation",
+ "function",
+ "functions");
+ FastSection macros(inner,
+ style == Summary ?
+ "Macros" : "Macro Documentation",
+ "macro",
+ "macros");
+
+ NodeList nodeList = inner->childNodes();
+ nodeList += inner->relatedNodes();
+
+ NodeList::ConstIterator n = nodeList.begin();
+ while (n != nodeList.end()) {
+ switch ((*n)->type()) {
+ case Node::Namespace:
+ insert(namespaces, *n, style, status);
+ break;
+ case Node::Class:
+ insert(classes, *n, style, status);
+ break;
+ case Node::Enum:
+ case Node::Typedef:
+ insert(types, *n, style, status);
+ break;
+ case Node::Function:
+ {
+ FunctionNode *func = static_cast<FunctionNode *>(*n);
+ if (func->isMacro())
+ insert(macros, *n, style, status);
+ else
+ insert(functions, *n, style, status);
+ }
+ break;
+ default:
+ ;
+ }
+ ++n;
+ }
+ append(sections, namespaces);
+ append(sections, classes);
+ append(sections, types);
+ append(sections, functions);
+ append(sections, macros);
+ }
+ }
+
+ return sections;
+}
+
+const Node *CppCodeMarker::resolveTarget(const QString &target,
+ const Tree *tree,
+ const Node *relative)
+{
+ if (target.endsWith("()")) {
+ const FunctionNode *func;
+ QString funcName = target;
+ funcName.chop(2);
+
+ QStringList path = funcName.split("::");
+ if ((func = tree->findFunctionNode(path,
+ relative,
+ Tree::SearchBaseClasses))
+ && func->metaness() != FunctionNode::MacroWithoutParams)
+ return func;
+ }
+ else if (target.contains("#")) {
+ // ### this doesn't belong here; get rid of TargetNode hack
+ int hashAt = target.indexOf("#");
+ QString link = target.left(hashAt);
+ QString ref = target.mid(hashAt + 1);
+ const Node *node;
+ if (link.isEmpty()) {
+ node = relative;
+ }
+ else {
+ QStringList path(link);
+ node = tree->findNode(path, tree->root(), Tree::SearchBaseClasses);
+ }
+ if (node && node->isInnerNode()) {
+ const Atom *atom = node->doc().body().firstAtom();
+ while (atom) {
+ if (atom->type() == Atom::Target && atom->string() == ref) {
+ Node *parentNode = const_cast<Node *>(node);
+ return new TargetNode(static_cast<InnerNode*>(parentNode),
+ ref);
+ }
+ atom = atom->next();
+ }
+ }
+ }
+ else {
+ QStringList path = target.split("::");
+ const Node *node;
+ if ((node = tree->findNode(path,
+ relative,
+ Tree::SearchBaseClasses |
+ Tree::SearchEnumValues |
+ Tree::NonFunction)))
+ return node;
+ }
+ return 0;
+}
+
+QString CppCodeMarker::addMarkUp(const QString& protectedCode,
+ const Node * /* relative */,
+ const QString& /* dirPath */)
+{
+ static QRegExp globalInclude("#include +&lt;([^<>&]+)&gt;");
+ static QRegExp yHasTypeX("(?:^|\n *)([a-zA-Z_][a-zA-Z_0-9]*)"
+ "(?:&lt;[^;{}]+&gt;)?(?: *(?:\\*|&amp;) *| +)"
+ "([a-zA-Z_][a-zA-Z_0-9]*)? *[,;()=]");
+ static QRegExp xNewY("([a-zA-Z_][a-zA-Z_0-9]*) *= *new +([a-zA-Z_0-9]+)");
+ static QRegExp xDotY("\\b([a-zA-Z_][a-zA-Z_0-9]*) *(?:\\.|-&gt;|,[ \n]*S(?:IGNAL|LOT)\\() *"
+ "([a-zA-Z_][a-zA-Z_0-9]*)(?= *\\()");
+ static QRegExp xIsStaticZOfY("[\n:;{(=] *(([a-zA-Z_0-9]+)::([a-zA-Z_0-9]+))(?= *\\()");
+ static QRegExp classX("[:,][ \n]*(?:p(?:ublic|r(?:otected|ivate))[ \n]+)?"
+ "([a-zA-Z_][a-zA-Z_0-9]*)");
+ static QRegExp globalX("[\n{()=] *([a-zA-Z_][a-zA-Z_0-9]*)[ \n]*\\(");
+ static QRegExp multiLineComment("/(?:( )?\\*(?:[^*]+|\\*(?! /))*\\*\\1/)");
+ multiLineComment.setMinimal(true);
+ static QRegExp singleLineComment("//(?!!)[^!\n]*");
+ static QRegExp preprocessor("(?:^|\n)(#[ \t]*(?:include|if|elif|endif|error|pragma|define"
+ "|warning)(?:(?:\\\\\n|\\n#)[^\n]*)*)");
+ static QRegExp literals("&quot;(?:[^\\\\&]|\\\\[^\n]|&(?!quot;))*&quot;"
+ "|'(?:[^\\\\]|\\\\(?:[^x0-9']|x[0-9a-f]{1,4}|[0-9]{1,3}))'");
+
+ QString result = protectedCode;
+ int pos;
+
+ if (!hurryUp()) {
+ /*
+ Mark global includes. For example:
+
+ #include &lt;<@headerfile>QString</@headerfile>
+ */
+ pos = 0;
+ while ((pos = result.indexOf(globalInclude, pos)) != -1)
+ pos += globalInclude.matchedLength()
+ + insertTagAround(result,
+ globalInclude.pos(1),
+ globalInclude.cap(1).length(),
+ "@headerfile");
+
+ /*
+ Look for variable definitions and similar constructs, mark
+ the data type, and remember the type of the variable.
+ */
+ QMap<QString, QSet<QString> > typesForVariable;
+ pos = 0;
+ while ((pos = yHasTypeX.indexIn(result, pos)) != -1) {
+ QString x = yHasTypeX.cap(1);
+ QString y = yHasTypeX.cap(2);
+
+ if (!y.isEmpty())
+ typesForVariable[y].insert(x);
+
+ /*
+ Without the minus one at the end, 'void member(Class
+ var)' would give 'member' as a variable of type 'void',
+ but would ignore 'Class var'. (### Is that true?)
+ */
+ pos += yHasTypeX.matchedLength()
+ + insertTagAround(result,
+ yHasTypeX.pos(1),
+ x.length(),
+ "@type") - 1;
+ }
+
+ /*
+ Do syntax highlighting of preprocessor directives.
+ */
+ pos = 0;
+ while ((pos = preprocessor.indexIn(result, pos)) != -1)
+ pos += preprocessor.matchedLength()
+ + insertTagAround(result,
+ preprocessor.pos(1),
+ preprocessor.cap(1).length(),
+ "@preprocessor");
+
+ /*
+ Deal with string and character literals.
+ */
+ pos = 0;
+ while ((pos = literals.indexIn(result, pos)) != -1)
+ pos += literals.matchedLength()
+ + insertTagAround(result,
+ pos,
+ literals.matchedLength(),
+ result.at(pos) ==
+ QLatin1Char(' ') ? "@string" : "@char");
+
+ /*
+ Look for 'var = new Class'.
+ */
+ pos = 0;
+ while ((pos = xNewY.indexIn(result, pos)) != -1) {
+ QString x = xNewY.cap(1);
+ QString y = xNewY.cap(2);
+ typesForVariable[x].insert(y);
+
+ pos += xNewY.matchedLength() + insertTagAround(result,
+ xNewY.pos(2),
+ y.length(),
+ "@type");
+ }
+
+ /*
+ Insert some stuff that cannot harm.
+ */
+ typesForVariable["qApp"].insert("QApplication");
+
+ /*
+ Add link to ': Class'.
+ */
+ pos = 0;
+ while ((pos = classX.indexIn(result, pos)) != -1)
+ pos += classX.matchedLength()
+ + insertTagAround(result,
+ classX.pos(1),
+ classX.cap(1).length(),
+ "@type") - 1;
+
+ /*
+ Find use of any of
+
+ var.method()
+ var->method()
+ var, SIGNAL(method())
+ var, SLOT(method()).
+ */
+ pos = 0;
+ while ((pos = xDotY.indexIn(result, pos)) != -1) {
+ QString x = xDotY.cap(1);
+ QString y = xDotY.cap(2);
+
+ QSet<QString> types = typesForVariable.value(x);
+ pos += xDotY.matchedLength()
+ + insertTagAround(result,
+ xDotY.pos(2),
+ xDotY.cap(2).length(),
+ "@func",
+ (types.count() == 1) ? "target=\""
+ + protect(*types.begin() + "::" + y)
+ + "()\"" : QString());
+ }
+
+ /*
+ Add link to 'Class::method()'.
+ */
+ pos = 0;
+ while ((pos = xIsStaticZOfY.indexIn(result, pos)) != -1) {
+ QString x = xIsStaticZOfY.cap(1);
+ QString z = xIsStaticZOfY.cap(3);
+
+ pos += insertTagAround(result,
+ xIsStaticZOfY.pos(3),
+ z.length(),
+ "@func",
+ "target=\"" + protect(x) + "()\"");
+ pos += insertTagAround(result,
+ xIsStaticZOfY.pos(2),
+ xIsStaticZOfY.cap(2).length(),
+ "@type");
+ pos += xIsStaticZOfY.matchedLength() - 1;
+ }
+
+ /*
+ Add link to 'globalFunction()'.
+ */
+ pos = 0;
+ while ((pos = globalX.indexIn(result, pos)) != -1) {
+ QString x = globalX.cap(1);
+ if (x != "QT_FORWARD_DECLARE_CLASS") {
+ pos += globalX.matchedLength()
+ + insertTagAround(result,
+ globalX.pos(1),
+ x.length(),
+ "@func",
+ "target=\"" + protect(x) + "()\"") - 1;
+ }
+ else
+ pos += globalX.matchedLength();
+ }
+ }
+
+ /*
+ Do syntax highlighting of comments. Also alter the code in a
+ minor way, so that we can include comments in documentation
+ comments.
+ */
+ pos = 0;
+ while (pos != -1) {
+ int mlpos;
+ int slpos;
+ int len;
+ slpos = singleLineComment.indexIn(result, pos);
+ mlpos = multiLineComment.indexIn(result, pos);
+
+ if (slpos == -1 && mlpos == -1)
+ break;
+
+ if (slpos == -1) {
+ pos = mlpos;
+ len = multiLineComment.matchedLength();
+ }
+ else if (mlpos == -1) {
+ pos = slpos;
+ len = singleLineComment.matchedLength();
+ }
+ else {
+ if (slpos < mlpos) {
+ pos = slpos;
+ len = singleLineComment.matchedLength();
+ }
+ else {
+ pos = mlpos;
+ len = multiLineComment.matchedLength();
+ }
+ }
+
+ if (result.at(pos + 1) == QLatin1Char(' ')) {
+ result.remove(pos + len - 2, 1);
+ result.remove(pos + 1, 1);
+ len -= 2;
+
+ forever {
+ int endcodePos = result.indexOf("\\ endcode", pos);
+ if (endcodePos == -1 || endcodePos >= pos + len)
+ break;
+ result.remove(endcodePos + 1, 1);
+ len -= 1;
+ }
+ }
+ pos += len + insertTagAround(result, pos, len, "@comment");
+ }
+
+ return result;
+}
+
+#ifdef QDOC_QML
+/*!
+ This function is for documenting QML properties. It returns
+ the list of documentation sections for the children of the
+ \a qmlClassNode.
+
+ Currently, it only handles QML property groups.
+ */
+QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode,
+ SynopsisStyle style)
+{
+ QList<Section> sections;
+ if (qmlClassNode) {
+ if (style == Summary) {
+ FastSection qmlproperties(qmlClassNode,
+ "Properties",
+ "property",
+ "properties");
+ FastSection qmlsignals(qmlClassNode,
+ "Signals",
+ "signal",
+ "signals");
+ FastSection qmlmethods(qmlClassNode,
+ "Methods",
+ "method",
+ "methods");
+
+ NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
+ while (c != qmlClassNode->childNodes().end()) {
+ if ((*c)->subType() == Node::QmlPropertyGroup) {
+ const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
+ NodeList::ConstIterator p = qpgn->childNodes().begin();
+ while (p != qpgn->childNodes().end()) {
+ if ((*p)->type() == Node::QmlProperty) {
+ insert(qmlproperties,*p,style,Okay);
+ }
+ ++p;
+ }
+ }
+ else if ((*c)->type() == Node::QmlSignal) {
+ insert(qmlsignals,*c,style,Okay);
+ }
+ else if ((*c)->type() == Node::QmlMethod) {
+ insert(qmlmethods,*c,style,Okay);
+ }
+ ++c;
+ }
+ append(sections,qmlproperties);
+ append(sections,qmlsignals);
+ append(sections,qmlmethods);
+ }
+ else if (style == Detailed) {
+ FastSection qmlproperties(qmlClassNode, "Property Documentation");
+ FastSection qmlsignals(qmlClassNode,"Signal Documentation");
+ FastSection qmlmethods(qmlClassNode,"Method Documentation");
+ NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
+ while (c != qmlClassNode->childNodes().end()) {
+ if ((*c)->subType() == Node::QmlPropertyGroup) {
+ insert(qmlproperties,*c,style,Okay);
+ }
+ else if ((*c)->type() == Node::QmlSignal) {
+ insert(qmlsignals,*c,style,Okay);
+ }
+ else if ((*c)->type() == Node::QmlMethod) {
+ insert(qmlmethods,*c,style,Okay);
+ }
+ ++c;
+ }
+ append(sections,qmlproperties);
+ append(sections,qmlsignals);
+ append(sections,qmlmethods);
+ }
+ }
+
+ return sections;
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/tools/qdoc3/qmlcodemarker.h b/tools/qdoc3/qmlcodemarker.h
new file mode 100644
index 0000000..8c83c04
--- /dev/null
+++ b/tools/qdoc3/qmlcodemarker.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ cppcodemarker.h
+*/
+
+#ifndef CPPCODEMARKER_H
+#define CPPCODEMARKER_H
+
+#include "codemarker.h"
+
+QT_BEGIN_NAMESPACE
+
+class CppCodeMarker : public CodeMarker
+{
+ public:
+ CppCodeMarker();
+ ~CppCodeMarker();
+
+ bool recognizeCode(const QString& code);
+ bool recognizeExtension(const QString& ext);
+ bool recognizeLanguage(const QString& lang);
+ QString plainName(const Node *node);
+ QString plainFullName(const Node *node, const Node *relative);
+ QString markedUpCode(const QString& code,
+ const Node *relative,
+ const QString& dirPath);
+ QString markedUpSynopsis(const Node *node,
+ const Node *relative,
+ SynopsisStyle style);
+#ifdef QDOC_QML
+ QString markedUpQmlItem(const Node *node, bool summary);
+#endif
+ QString markedUpName(const Node *node);
+ QString markedUpFullName(const Node *node, const Node *relative);
+ QString markedUpEnumValue(const QString &enumValue, const Node *relative);
+ QString markedUpIncludes(const QStringList& includes);
+ QString functionBeginRegExp(const QString& funcName);
+ QString functionEndRegExp(const QString& funcName);
+ QList<Section> sections(const InnerNode *innerNode,
+ SynopsisStyle style,
+ Status status);
+ QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
+ SynopsisStyle style);
+ const Node *resolveTarget(const QString& target,
+ const Tree *tree,
+ const Node *relative);
+
+private:
+ QString addMarkUp(const QString& protectedCode,
+ const Node *relative,
+ const QString& dirPath);
+};
+
+QT_END_NAMESPACE
+
+#endif