summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorBea Lam <bea.lam@nokia.com>2009-10-21 00:43:19 (GMT)
committerBea Lam <bea.lam@nokia.com>2009-10-21 00:43:19 (GMT)
commitf6b1582d726f97d8be4b30f0f6da2350220f27c5 (patch)
tree64bcea1b8b3cc8f94073a9e83b36b2b40ad990e8 /src/declarative
parent110c58a20f3158143d83ebea4f2ece4f7925f913 (diff)
parent7bd7f5ec6eb520b7d9940a24817b17132d9ed6a2 (diff)
downloadQt-f6b1582d726f97d8be4b30f0f6da2350220f27c5.zip
Qt-f6b1582d726f97d8be4b30f0f6da2350220f27c5.tar.gz
Qt-f6b1582d726f97d8be4b30f0f6da2350220f27c5.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/debugger/qmldebugclient.cpp2
-rw-r--r--src/declarative/extra/qmlfolderlistmodel.cpp105
-rw-r--r--src/declarative/extra/qmlfolderlistmodel.h19
-rw-r--r--src/declarative/extra/qmlfontloader.cpp4
-rw-r--r--src/declarative/fx/qfxgridview.h1
-rw-r--r--src/declarative/fx/qfxitem.cpp1
-rw-r--r--src/declarative/fx/qfxlistview.cpp2
-rw-r--r--src/declarative/fx/qfxlistview.h1
-rw-r--r--src/declarative/fx/qfxmouseregion.cpp1
-rw-r--r--src/declarative/fx/qfxpathview.h2
-rw-r--r--src/declarative/fx/qfxtext.cpp8
-rw-r--r--src/declarative/fx/qfxtextinput.cpp26
-rw-r--r--src/declarative/fx/qfxtextinput.h2
-rw-r--r--src/declarative/fx/qfxtextinput_p.h2
-rw-r--r--src/declarative/fx/qfxvisualitemmodel.h1
-rw-r--r--src/declarative/fx/qfxwebview.h1
-rw-r--r--src/declarative/qml/qml.h34
-rw-r--r--src/declarative/qml/qmlbasicscript.cpp11
-rw-r--r--src/declarative/qml/qmlbinding.cpp13
-rw-r--r--src/declarative/qml/qmlcompiler.cpp4
-rw-r--r--src/declarative/qml/qmlcomponent.h1
-rw-r--r--src/declarative/qml/qmlcontext.cpp2
-rw-r--r--src/declarative/qml/qmlcontextscriptclass.cpp18
-rw-r--r--src/declarative/qml/qmlcontextscriptclass_p.h3
-rw-r--r--src/declarative/qml/qmlcustomparser_p.h8
-rw-r--r--src/declarative/qml/qmlengine.cpp2
-rw-r--r--src/declarative/qml/qmlexpression.cpp49
-rw-r--r--src/declarative/qml/qmlexpression.h2
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp131
-rw-r--r--src/declarative/qml/qmlmetaproperty.h4
-rw-r--r--src/declarative/qml/qmlmetaproperty_p.h5
-rw-r--r--src/declarative/qml/qmlmetatype.cpp3
-rw-r--r--src/declarative/qml/qmlobjectscriptclass.cpp37
-rw-r--r--src/declarative/qml/qmlobjectscriptclass_p.h6
-rw-r--r--src/declarative/qml/qmlprivate.h27
-rw-r--r--src/declarative/qml/qmlrewrite.cpp73
-rw-r--r--src/declarative/qml/qmlrewrite_p.h22
-rw-r--r--src/declarative/qml/qmlsqldatabase.cpp4
-rw-r--r--src/declarative/util/qmlpackage.h1
-rw-r--r--src/declarative/util/qmlstate.cpp3
-rw-r--r--src/declarative/util/qmlstateoperations.cpp58
-rw-r--r--src/declarative/widgets/graphicslayouts.h2
42 files changed, 558 insertions, 143 deletions
diff --git a/src/declarative/debugger/qmldebugclient.cpp b/src/declarative/debugger/qmldebugclient.cpp
index d13de57..3171808 100644
--- a/src/declarative/debugger/qmldebugclient.cpp
+++ b/src/declarative/debugger/qmldebugclient.cpp
@@ -104,7 +104,7 @@ bool QmlDebugConnection::isConnected() const
class QmlDebugClientPrivate : public QObjectPrivate
{
- Q_DECLARE_PUBLIC(QmlDebugClient);
+ Q_DECLARE_PUBLIC(QmlDebugClient)
public:
QmlDebugClientPrivate();
diff --git a/src/declarative/extra/qmlfolderlistmodel.cpp b/src/declarative/extra/qmlfolderlistmodel.cpp
index bdea03f..0e5c275 100644
--- a/src/declarative/extra/qmlfolderlistmodel.cpp
+++ b/src/declarative/extra/qmlfolderlistmodel.cpp
@@ -43,6 +43,7 @@
#include <QDirModel>
#include <qdebug.h>
#include "qmlfolderlistmodel.h"
+#include <QtDeclarative/qmlcontext.h>
QT_BEGIN_NAMESPACE
@@ -51,7 +52,6 @@ class QmlFolderListModelPrivate : public QObjectPrivate
public:
QmlFolderListModelPrivate()
: sortField(QmlFolderListModel::Name), sortReversed(false), count(0) {
- folder = QDir::currentPath();
nameFilters << QLatin1String("*");
}
@@ -82,7 +82,7 @@ public:
}
QDirModel model;
- QString folder;
+ QUrl folder;
QStringList nameFilters;
QModelIndex folderIndex;
QmlFolderListModel::SortField sortField;
@@ -116,7 +116,7 @@ QmlFolderListModel::QmlFolderListModel(QObject *parent)
: QListModelInterface(*(new QmlFolderListModelPrivate), parent)
{
Q_D(QmlFolderListModel);
- d->model.setFilter(QDir::AllDirs | QDir::Files | QDir::Drives);
+ d->model.setFilter(QDir::AllDirs | QDir::Files | QDir::Drives | QDir::NoDotAndDotDot);
connect(&d->model, SIGNAL(rowsInserted(const QModelIndex&,int,int))
, this, SLOT(inserted(const QModelIndex&,int,int)));
connect(&d->model, SIGNAL(rowsRemoved(const QModelIndex&,int,int))
@@ -139,7 +139,7 @@ QHash<int,QVariant> QmlFolderListModel::data(int index, const QList<int> &roles)
QModelIndex modelIndex = d->model.index(index, 0, d->folderIndex);
if (modelIndex.isValid()) {
folderData[QDirModel::FileNameRole] = d->model.data(modelIndex, QDirModel::FileNameRole);
- folderData[QDirModel::FilePathRole] = d->model.data(modelIndex, QDirModel::FilePathRole);
+ folderData[QDirModel::FilePathRole] = QUrl::fromLocalFile(d->model.data(modelIndex, QDirModel::FilePathRole).toString());
}
return folderData;
@@ -175,19 +175,21 @@ QString QmlFolderListModel::toString(int role) const
\qmlproperty string FolderListModel::folder
The \a folder property holds the folder the model is currently providing.
+
+ It is a URL, but must be a file: or qrc: URL (or relative to such a URL).
*/
-QString QmlFolderListModel::folder() const
+QUrl QmlFolderListModel::folder() const
{
Q_D(const QmlFolderListModel);
return d->folder;
}
-void QmlFolderListModel::setFolder(const QString &folder)
+void QmlFolderListModel::setFolder(const QUrl &folder)
{
Q_D(QmlFolderListModel);
if (folder == d->folder)
return;
- QModelIndex index = d->model.index(folder);
+ QModelIndex index = d->model.index(folder.toLocalFile());
if (index.isValid() && d->model.isDir(index)) {
d->folder = folder;
QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
@@ -195,6 +197,17 @@ void QmlFolderListModel::setFolder(const QString &folder)
}
}
+QUrl QmlFolderListModel::parentFolder() const
+{
+ Q_D(const QmlFolderListModel);
+ int pos = d->folder.path().lastIndexOf(QLatin1Char('/'));
+ if (pos == -1)
+ return QUrl();
+ QUrl r = d->folder;
+ r.setPath(d->folder.path().left(pos));
+ return r;
+}
+
/*!
\qmlproperty list<string> FolderListModel::nameFilters
@@ -225,6 +238,9 @@ void QmlFolderListModel::setNameFilters(const QStringList &filters)
void QmlFolderListModel::componentComplete()
{
Q_D(QmlFolderListModel);
+ if (!d->folder.isValid() || !QDir().exists(d->folder.toLocalFile()))
+ setFolder(QUrl(QLatin1String("file://")+QDir::currentPath()));
+
if (!d->folderIndex.isValid())
QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
}
@@ -285,7 +301,7 @@ void QmlFolderListModel::refresh()
d->count = 0;
emit itemsRemoved(0, tmpCount);
}
- d->folderIndex = d->model.index(d->folder);
+ d->folderIndex = d->model.index(d->folder.toLocalFile());
d->count = d->model.rowCount(d->folderIndex);
if (d->count) {
emit itemsInserted(0, d->count);
@@ -318,6 +334,79 @@ void QmlFolderListModel::dataChanged(const QModelIndex &start, const QModelIndex
emit itemsChanged(start.row(), end.row() - start.row() + 1, roles());
}
+/*!
+ \qmlproperty bool FolderListModel::showDirs
+
+ If true (the default), directories are included in the model.
+
+ Note that the nameFilters are ignored for directories.
+*/
+bool QmlFolderListModel::showDirs() const
+{
+ Q_D(const QmlFolderListModel);
+ return d->model.filter() & QDir::AllDirs;
+}
+
+void QmlFolderListModel::setShowDirs(bool on)
+{
+ Q_D(QmlFolderListModel);
+ if (!(d->model.filter() & QDir::AllDirs) == !on)
+ return;
+ if (on)
+ d->model.setFilter(d->model.filter() | QDir::AllDirs | QDir::Drives);
+ else
+ d->model.setFilter(d->model.filter() & ~(QDir::AllDirs | QDir::Drives));
+}
+
+/*!
+ \qmlproperty bool FolderListModel::showDotAndDotDot
+
+ If true, the "." and ".." directories are included in the model.
+
+ The default is false.
+*/
+bool QmlFolderListModel::showDotAndDotDot() const
+{
+ Q_D(const QmlFolderListModel);
+ return !(d->model.filter() & QDir::NoDotAndDotDot);
+}
+
+void QmlFolderListModel::setShowDotAndDotDot(bool on)
+{
+ Q_D(QmlFolderListModel);
+ if (!(d->model.filter() & QDir::NoDotAndDotDot) == on)
+ return;
+ if (on)
+ d->model.setFilter(d->model.filter() & ~QDir::NoDotAndDotDot);
+ else
+ d->model.setFilter(d->model.filter() | QDir::NoDotAndDotDot);
+}
+
+/*!
+ \qmlproperty bool FolderListModel::showOnlyReadable
+
+ If true, only readable files and directories are shown.
+
+ The default is false.
+*/
+bool QmlFolderListModel::showOnlyReadable() const
+{
+ Q_D(const QmlFolderListModel);
+ return d->model.filter() & QDir::Readable;
+}
+
+void QmlFolderListModel::setShowOnlyReadable(bool on)
+{
+ Q_D(QmlFolderListModel);
+ if (!(d->model.filter() & QDir::Readable) == !on)
+ return;
+ if (on)
+ d->model.setFilter(d->model.filter() | QDir::Readable);
+ else
+ d->model.setFilter(d->model.filter() & ~QDir::Readable);
+}
+
+
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,FolderListModel,QmlFolderListModel)
QT_END_NAMESPACE
diff --git a/src/declarative/extra/qmlfolderlistmodel.h b/src/declarative/extra/qmlfolderlistmodel.h
index 24a3ac6..66e600b 100644
--- a/src/declarative/extra/qmlfolderlistmodel.h
+++ b/src/declarative/extra/qmlfolderlistmodel.h
@@ -60,10 +60,14 @@ class Q_DECLARATIVE_EXPORT QmlFolderListModel : public QListModelInterface, publ
Q_OBJECT
Q_INTERFACES(QmlParserStatus)
- Q_PROPERTY(QString folder READ folder WRITE setFolder NOTIFY folderChanged)
+ Q_PROPERTY(QUrl folder READ folder WRITE setFolder NOTIFY folderChanged)
+ Q_PROPERTY(QUrl parentFolder READ parentFolder NOTIFY folderChanged)
Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters)
Q_PROPERTY(SortField sortField READ sortField WRITE setSortField)
Q_PROPERTY(bool sortReversed READ sortReversed WRITE setSortReversed)
+ Q_PROPERTY(bool showDirs READ showDirs WRITE setShowDirs)
+ Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot)
+ Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable)
public:
QmlFolderListModel(QObject *parent = 0);
@@ -74,8 +78,10 @@ public:
virtual QList<int> roles() const;
virtual QString toString(int role) const;
- QString folder() const;
- void setFolder(const QString &folder);
+ QUrl folder() const;
+ void setFolder(const QUrl &folder);
+
+ QUrl parentFolder() const;
QStringList nameFilters() const;
void setNameFilters(const QStringList &filters);
@@ -92,6 +98,13 @@ public:
bool sortReversed() const;
void setSortReversed(bool rev);
+ bool showDirs() const;
+ void setShowDirs(bool);
+ bool showDotAndDotDot() const;
+ void setShowDotAndDotDot(bool);
+ bool showOnlyReadable() const;
+ void setShowOnlyReadable(bool);
+
Q_SIGNALS:
void folderChanged();
diff --git a/src/declarative/extra/qmlfontloader.cpp b/src/declarative/extra/qmlfontloader.cpp
index 4a447de..2193b68 100644
--- a/src/declarative/extra/qmlfontloader.cpp
+++ b/src/declarative/extra/qmlfontloader.cpp
@@ -75,13 +75,13 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,FontLoader,QmlFontLoader)
\brief This item allows using fonts by name or url.
Example:
- \code
+ \qml
FontLoader { id: FixedFont; name: "Courier" }
FontLoader { id: WebFont; source: "http://www.mysite.com/myfont.ttf" }
Text { text: "Fixed-size font"; font.family: FixedFont.name }
Text { text: "Fancy font"; font.family: WebFont.name }
- \endcode
+ \endqml
*/
QmlFontLoader::QmlFontLoader(QObject *parent)
: QObject(*(new QmlFontLoaderPrivate), parent)
diff --git a/src/declarative/fx/qfxgridview.h b/src/declarative/fx/qfxgridview.h
index 7f30f03..1c0a700 100644
--- a/src/declarative/fx/qfxgridview.h
+++ b/src/declarative/fx/qfxgridview.h
@@ -150,6 +150,7 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QFxGridView)
+QML_DECLARE_TYPEINFO(QFxGridView, QML_HAS_ATTACHED_PROPERTIES)
QT_END_HEADER
diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp
index 903fad7..bd94b8c 100644
--- a/src/declarative/fx/qfxitem.cpp
+++ b/src/declarative/fx/qfxitem.cpp
@@ -2860,6 +2860,7 @@ int QFxItemPrivate::restart(QTime &t)
QT_END_NAMESPACE
QML_DECLARE_TYPE(QFxKeysAttached)
+QML_DECLARE_TYPEINFO(QFxKeysAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Keys,QFxKeysAttached)
QML_DECLARE_TYPE(QFxKeyNavigationAttached)
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,KeyNavigation,QFxKeyNavigationAttached)
diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp
index 604d16b..4fb0ec1 100644
--- a/src/declarative/fx/qfxlistview.cpp
+++ b/src/declarative/fx/qfxlistview.cpp
@@ -166,7 +166,7 @@ public:
class QFxListViewPrivate : public QFxFlickablePrivate
{
- Q_DECLARE_PUBLIC(QFxListView);
+ Q_DECLARE_PUBLIC(QFxListView)
public:
QFxListViewPrivate()
diff --git a/src/declarative/fx/qfxlistview.h b/src/declarative/fx/qfxlistview.h
index 5a83604..1ff0e27 100644
--- a/src/declarative/fx/qfxlistview.h
+++ b/src/declarative/fx/qfxlistview.h
@@ -174,6 +174,7 @@ private Q_SLOTS:
QT_END_NAMESPACE
+QML_DECLARE_TYPEINFO(QFxListView, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QFxListView)
QT_END_HEADER
diff --git a/src/declarative/fx/qfxmouseregion.cpp b/src/declarative/fx/qfxmouseregion.cpp
index d3c776f..4b31fd4 100644
--- a/src/declarative/fx/qfxmouseregion.cpp
+++ b/src/declarative/fx/qfxmouseregion.cpp
@@ -440,6 +440,7 @@ void QFxMouseRegion::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
// If we don't accept hover, we need to reset containsMouse.
if (!acceptHoverEvents())
setHovered(false);
+ setKeepMouseGrab(false);
}
}
diff --git a/src/declarative/fx/qfxpathview.h b/src/declarative/fx/qfxpathview.h
index 3ee352a..c8c0ac0 100644
--- a/src/declarative/fx/qfxpathview.h
+++ b/src/declarative/fx/qfxpathview.h
@@ -132,7 +132,7 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QFxPathView)
-
+QML_DECLARE_TYPEINFO(QFxPathView, QML_HAS_ATTACHED_PROPERTIES)
QT_END_HEADER
#endif // QFXPATHVIEW_H
diff --git a/src/declarative/fx/qfxtext.cpp b/src/declarative/fx/qfxtext.cpp
index c26ed2c..4d02f0d 100644
--- a/src/declarative/fx/qfxtext.cpp
+++ b/src/declarative/fx/qfxtext.cpp
@@ -427,9 +427,13 @@ void QFxText::setTextFormat(TextFormat format)
This property cannot be used with wrap enabled or with rich text.
- Eliding can be ElideNone, ElideLeft, ElideMiddle, or ElideRight.
+ Eliding can be ElideNone (the default), ElideLeft, ElideMiddle, or ElideRight.
- ElideNone is the default.
+ If the text is a multi-length string, and the mode is not ElideNone,
+ the first string that fits will be used, otherwise the last will be elided.
+
+ Multi-length strings are ordered from longest to shortest, separated by the
+ Unicode "String Terminator" character U009C (write this in QML with "\\x9C").
*/
Qt::TextElideMode QFxText::elideMode() const
{
diff --git a/src/declarative/fx/qfxtextinput.cpp b/src/declarative/fx/qfxtextinput.cpp
index f5bf911..e9ddd3f 100644
--- a/src/declarative/fx/qfxtextinput.cpp
+++ b/src/declarative/fx/qfxtextinput.cpp
@@ -289,6 +289,18 @@ void QFxTextInput::setCursorPosition(int cp)
}
/*!
+ \internal
+
+ Returns a Rect which encompasses the cursor, but which may be larger than is
+ required. Ignores custom cursor delegates.
+*/
+QRect QFxTextInput::cursorRect() const
+{
+ Q_D(const QFxTextInput);
+ return d->control->cursorRect();
+}
+
+/*!
\qmlproperty int TextInput::selectionStart
The cursor position before the first character in the current selection.
@@ -489,17 +501,19 @@ void QFxTextInput::setCursorDelegate(QmlComponent* c)
{
Q_D(QFxTextInput);
d->cursorComponent = c;
- d->startCreatingCursor();
+ if(!c){
+ //note that the components are owned by something else
+ disconnect(d->control, SIGNAL(cursorPositionChanged(int, int)),
+ this, SLOT(moveCursor()));
+ delete d->cursorItem;
+ }else{
+ d->startCreatingCursor();
+ }
}
void QFxTextInputPrivate::startCreatingCursor()
{
Q_Q(QFxTextInput);
- if(!cursorComponent){
- q->disconnect(control, SIGNAL(cursorPositionChanged(int, int)),
- q, SLOT(moveCursor()));
- return;
- }
q->connect(control, SIGNAL(cursorPositionChanged(int, int)),
q, SLOT(moveCursor()));
if(cursorComponent->isReady()){
diff --git a/src/declarative/fx/qfxtextinput.h b/src/declarative/fx/qfxtextinput.h
index d5d0450..2540d41 100644
--- a/src/declarative/fx/qfxtextinput.h
+++ b/src/declarative/fx/qfxtextinput.h
@@ -131,6 +131,8 @@ public:
int cursorPosition() const;
void setCursorPosition(int cp);
+ QRect cursorRect() const;
+
int selectionStart() const;
void setSelectionStart(int);
diff --git a/src/declarative/fx/qfxtextinput_p.h b/src/declarative/fx/qfxtextinput_p.h
index a2b45bb..3978be4 100644
--- a/src/declarative/fx/qfxtextinput_p.h
+++ b/src/declarative/fx/qfxtextinput_p.h
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
class QFxTextInputPrivate : public QFxPaintedItemPrivate
{
- Q_DECLARE_PUBLIC(QFxTextInput);
+ Q_DECLARE_PUBLIC(QFxTextInput)
public:
QFxTextInputPrivate() : control(new QLineControl(QString())),
color((QRgb)0), style(QFxText::Normal),
diff --git a/src/declarative/fx/qfxvisualitemmodel.h b/src/declarative/fx/qfxvisualitemmodel.h
index f519a9e..5b613d8 100644
--- a/src/declarative/fx/qfxvisualitemmodel.h
+++ b/src/declarative/fx/qfxvisualitemmodel.h
@@ -192,6 +192,7 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QFxVisualModel)
QML_DECLARE_TYPE(QFxVisualItemModel)
+QML_DECLARE_TYPEINFO(QFxVisualItemModel, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QFxVisualDataModel)
QT_END_HEADER
diff --git a/src/declarative/fx/qfxwebview.h b/src/declarative/fx/qfxwebview.h
index f136e2d..a31b2b0 100644
--- a/src/declarative/fx/qfxwebview.h
+++ b/src/declarative/fx/qfxwebview.h
@@ -243,6 +243,7 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QFxWebView)
+QML_DECLARE_TYPEINFO(QFxWebView, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QAction)
QT_END_HEADER
diff --git a/src/declarative/qml/qml.h b/src/declarative/qml/qml.h
index 23f2f1e..818b4e7 100644
--- a/src/declarative/qml/qml.h
+++ b/src/declarative/qml/qml.h
@@ -72,8 +72,40 @@ QT_MODULE(Declarative)
#define QML_DECLARE_INTERFACE_HASMETATYPE(INTERFACE) \
QML_DECLARE_TYPE_HASMETATYPE(INTERFACE)
+enum { /* TYPEINFO flags */
+ QML_HAS_ATTACHED_PROPERTIES = 0x01,
+};
+
+#define QML_DECLARE_TYPEINFO(TYPE, FLAGS) \
+template <> \
+class QmlTypeInfo<TYPE > \
+{ \
+public: \
+ enum { \
+ hasAttachedProperties = (((FLAGS) & QML_HAS_ATTACHED_PROPERTIES) == QML_HAS_ATTACHED_PROPERTIES) \
+ }; \
+};
+
QT_BEGIN_NAMESPACE
+#if defined(Q_OS_SYMBIAN)
+#define QML_DEFINE_INTERFACE(INTERFACE) \
+ static int defineInterface##INTERFACE = qmlRegisterInterface<INTERFACE>(#INTERFACE);
+
+#define QML_DEFINE_EXTENDED_TYPE(URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MIN_TO, NAME, TYPE, EXTENSION) \
+ static int registerExtended##TYPE = qmlRegisterExtendedType<TYPE,EXTENSION>(#URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MIN_TO, #NAME, #TYPE);
+
+#define QML_DEFINE_TYPE(URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MIN_TO, NAME, TYPE) \
+ static int defineType##TYPE = qmlRegisterType<TYPE>(#URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MIN_TO, #NAME, #TYPE);
+
+#define QML_DEFINE_EXTENDED_NOCREATE_TYPE(TYPE, EXTENSION) \
+ static int registerExtendedNoCreate##TYPE = qmlRegisterExtendedType<TYPE,EXTENSION>(#TYPE);
+
+#define QML_DEFINE_NOCREATE_TYPE(TYPE) \
+ static int registerNoCreate##TYPE = qmlRegisterType<TYPE>(#TYPE);
+
+#else
+
#define QML_DEFINE_INTERFACE(INTERFACE) \
template<> QmlPrivate::InstanceType QmlPrivate::Define<INTERFACE *,0,0,0>::instance(qmlRegisterInterface<INTERFACE>(#INTERFACE));
@@ -89,6 +121,8 @@ QT_BEGIN_NAMESPACE
#define QML_DEFINE_NOCREATE_TYPE(TYPE) \
template<> QmlPrivate::InstanceType QmlPrivate::Define<TYPE *,0,0,0>::instance(qmlRegisterType<TYPE>(#TYPE));
+#endif
+
class QmlContext;
class QmlEngine;
Q_DECLARATIVE_EXPORT void qmlExecuteDeferred(QObject *);
diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp
index a0d749f..b7aac54 100644
--- a/src/declarative/qml/qmlbasicscript.cpp
+++ b/src/declarative/qml/qmlbasicscript.cpp
@@ -181,19 +181,24 @@ static QVariant fetch_value(QObject *o, int idx, int type)
break;
default:
{
+ // If the object is null, we extract the predicted type. While this isn't
+ // 100% reliable, in many cases it gives us better error messages if we
+ // assign this null-object to an incompatible property
if (QmlMetaType::isObject(type)) {
// NOTE: This assumes a cast to QObject does not alter the
// object pointer
QObject *val = 0;
void *args[] = { &val, 0 };
QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
- return QVariant::fromValue(val);
+ if (!val) return QVariant(type, &val);
+ else return QVariant::fromValue(val);
} else {
QVariant var = o->metaObject()->property(idx).read(o);
if (QmlMetaType::isObject(var.userType())) {
QObject *obj = 0;
obj = *(QObject **)var.data();
- var = QVariant::fromValue(obj);
+ if (!obj) var = QVariant(var.userType(), &obj);
+ else var = QVariant::fromValue(obj);
}
return var;
}
@@ -665,7 +670,7 @@ QVariant QmlBasicScript::run(QmlContext *context, QObject *me)
case ScriptInstruction::FetchConstant:
{
QVariant o = stack.pop();
- QObject *obj = qvariant_cast<QObject *>(o);
+ QObject *obj = *(QObject **)o.constData();
stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type));
if (obj && instr.constant.notify != 0)
diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp
index 6a70c1e..2b4e723 100644
--- a/src/declarative/qml/qmlbinding.cpp
+++ b/src/declarative/qml/qmlbinding.cpp
@@ -129,7 +129,18 @@ void QmlBinding::update(QmlMetaProperty::WriteFlags flags)
} else {
QVariant value = this->value();
- data->property.write(value, flags);
+ if (data->property.object() && !data->property.write(value, flags)) {
+ QString fileName = data->fileName;
+ int line = data->line;
+ if (fileName.isEmpty()) fileName = QLatin1String("<Unknown File>");
+
+ const char *valueType = 0;
+ if (value.userType() == QVariant::Invalid) valueType = "null";
+ else valueType = QMetaType::typeName(value.userType());
+ qWarning().nospace() << qPrintable(fileName) << ":" << line
+ << " Unable to assign " << valueType << " to "
+ << QMetaType::typeName(data->property.propertyType());
+ }
}
data->updating = false;
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index c744509..e2fd7cb 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -2039,7 +2039,7 @@ bool QmlCompiler::mergeDynamicMetaProperties(QmlParser::Object *obj)
return true;
}
-static QAtomicInt classIndexCounter;
+Q_GLOBAL_STATIC(QAtomicInt, classIndexCounter)
bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode)
{
@@ -2058,7 +2058,7 @@ bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode)
QByteArray newClassName = obj->metatype->className();
newClassName.append("_QML_");
- int idx = classIndexCounter.fetchAndAddRelaxed(1);
+ int idx = classIndexCounter()->fetchAndAddRelaxed(1);
newClassName.append(QByteArray::number(idx));
QMetaObjectBuilder builder;
diff --git a/src/declarative/qml/qmlcomponent.h b/src/declarative/qml/qmlcomponent.h
index dcf9347..7470f31 100644
--- a/src/declarative/qml/qmlcomponent.h
+++ b/src/declarative/qml/qmlcomponent.h
@@ -116,6 +116,7 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QmlComponent::Status)
QML_DECLARE_TYPE(QmlComponent)
+QML_DECLARE_TYPEINFO(QmlComponent, QML_HAS_ATTACHED_PROPERTIES)
QT_END_HEADER
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index 43a4741..31d4e1f 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -469,7 +469,7 @@ QUrl QmlContext::resolvedUrl(const QUrl &src)
}
/*!
- Explicitly sets the url resolveUrl() will use for relative references to \a baseUrl.
+ Explicitly sets the url resolvedUrl() will use for relative references to \a baseUrl.
Calling this function will override the url of the containing
component used by default.
diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp
index 939d008..4df23f0 100644
--- a/src/declarative/qml/qmlcontextscriptclass.cpp
+++ b/src/declarative/qml/qmlcontextscriptclass.cpp
@@ -99,10 +99,12 @@ QmlContextScriptClass::queryProperty(Object *object, const Identifier &name,
if (!bindContext)
return 0;
+ bool includeTypes = true;
while (bindContext) {
QScriptClass::QueryFlags rv =
- queryProperty(bindContext, scopeObject, name, flags);
+ queryProperty(bindContext, scopeObject, name, flags, includeTypes);
scopeObject = 0; // Only applies to the first context
+ includeTypes = false; // Only applies to the first context
if (rv) return rv;
bindContext = bindContext->parentContext();
}
@@ -113,7 +115,8 @@ QmlContextScriptClass::queryProperty(Object *object, const Identifier &name,
QScriptClass::QueryFlags
QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObject,
const Identifier &name,
- QScriptClass::QueryFlags flags)
+ QScriptClass::QueryFlags flags,
+ bool includeTypes)
{
QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
QmlContextPrivate *cp = QmlContextPrivate::get(bindContext);
@@ -124,7 +127,7 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje
return QScriptClass::HandlesReadAccess;
}
- if (cp->imports) {
+ if (includeTypes && cp->imports) {
QmlTypeNameCache::Data *data = cp->imports->data(name);
if (data) {
@@ -144,7 +147,7 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje
if (scopeObject) {
QScriptClass::QueryFlags rv =
- ep->objectClass->queryProperty(scopeObject, name, flags, 0);
+ ep->objectClass->queryProperty(scopeObject, name, flags, bindContext);
if (rv) {
lastScopeObject = scopeObject;
lastContext = bindContext;
@@ -154,7 +157,7 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje
for (int ii = 0; ii < cp->defaultObjects.count(); ++ii) {
QScriptClass::QueryFlags rv =
- ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, 0);
+ ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext);
if (rv) {
lastDefaultObject = ii;
@@ -225,9 +228,10 @@ void QmlContextScriptClass::setProperty(Object *object, const Identifier &name,
QmlContextPrivate *cp = QmlContextPrivate::get(bindContext);
if (lastScopeObject) {
- ep->objectClass->setProperty(lastScopeObject, name, value);
+ ep->objectClass->setProperty(lastScopeObject, name, value, bindContext);
} else {
- ep->objectClass->setProperty(cp->defaultObjects.at(lastDefaultObject), name, value);
+ ep->objectClass->setProperty(cp->defaultObjects.at(lastDefaultObject), name, value,
+ bindContext);
}
}
diff --git a/src/declarative/qml/qmlcontextscriptclass_p.h b/src/declarative/qml/qmlcontextscriptclass_p.h
index 126c8fe..95dff5b 100644
--- a/src/declarative/qml/qmlcontextscriptclass_p.h
+++ b/src/declarative/qml/qmlcontextscriptclass_p.h
@@ -80,7 +80,8 @@ protected:
private:
QScriptClass::QueryFlags queryProperty(QmlContext *, QObject *scopeObject,
const Identifier &,
- QScriptClass::QueryFlags flags);
+ QScriptClass::QueryFlags flags,
+ bool includeTypes);
QmlEngine *engine;
diff --git a/src/declarative/qml/qmlcustomparser_p.h b/src/declarative/qml/qmlcustomparser_p.h
index 5be0680..eb3e579 100644
--- a/src/declarative/qml/qmlcustomparser_p.h
+++ b/src/declarative/qml/qmlcustomparser_p.h
@@ -127,8 +127,14 @@ protected:
private:
QList<QmlError> exceptions;
};
-#define QML_DEFINE_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MAJ_TO, NAME, TYPE, CUSTOMTYPE) \
+
+#if defined(Q_OS_SYMBIAN)
+# define QML_DEFINE_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MAJ_TO, NAME, TYPE, CUSTOMTYPE) \
+ static int defineCustomType##NAME = qmlRegisterCustomType<TYPE>(#URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MAJ_TO, #NAME, #TYPE, new CUSTOMTYPE);
+#else
+# define QML_DEFINE_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MAJ_TO, NAME, TYPE, CUSTOMTYPE) \
template<> QmlPrivate::InstanceType QmlPrivate::Define<TYPE *,(VERSION_MAJ), (VERSION_MIN_FROM), (VERSION_MAJ_TO)>::instance(qmlRegisterCustomType<TYPE>(#URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MAJ_TO, #NAME, #TYPE, new CUSTOMTYPE));
+#endif
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index f0ecf1d..528e8c9 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -1099,7 +1099,7 @@ public:
int slash = type.indexOf('/');
if (slash >= 0) {
while (!s) {
- s = set.value(QString::fromLatin1(type.left(slash)));
+ s = set.value(QString::fromUtf8(type.left(slash)));
int nslash = type.indexOf('/',slash+1);
if (nslash > 0)
slash = nslash;
diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp
index e158621..b07ee4c 100644
--- a/src/declarative/qml/qmlexpression.cpp
+++ b/src/declarative/qml/qmlexpression.cpp
@@ -109,15 +109,21 @@ void QmlExpressionPrivate::init(QmlContext *ctxt, void *expr, QmlRefCount *rc,
QmlEngine *engine = ctxt->engine();
QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
+#ifndef Q_OS_SYMBIAN //XXX Why doesn't this work?
if (!dd->programs.at(progIdx)) {
- dd->programs[progIdx] =
+ dd->programs[progIdx] =
new QScriptProgram(scriptEngine->compile(data->expression, data->fileName, data->line));
}
+#endif
QScriptContext *scriptContext = scriptEngine->pushCleanContext();
scriptContext->pushScope(ep->contextClass->newContext(ctxt, me));
+#ifndef Q_OS_SYMBIAN
data->expressionFunction = scriptEngine->evaluate(*dd->programs[progIdx]);
+#else
+ data->expressionFunction = scriptEngine->evaluate(data->expression);
+#endif
data->expressionFunctionValid = true;
scriptEngine->popContext();
@@ -335,20 +341,17 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUnd
rv = QVariant::fromValue(list);
}
} else if (svalue.isObject() &&
- !svalue.isNumber() &&
- !svalue.isString() &&
- !svalue.isDate() &&
- !svalue.isError() &&
- !svalue.isFunction() &&
- !svalue.isNull() &&
- !svalue.isQMetaObject() &&
- !svalue.isQObject() &&
- !svalue.isRegExp()) {
-
+ ep->objectClass->scriptClass(svalue) == ep->objectClass) {
QObject *o = svalue.toQObject();
- if (o)
- return qVariantFromValue(o);
+ int type = QMetaType::QObjectStar;
+ // If the object is null, we extract the predicted type. While this isn't
+ // 100% reliable, in many cases it gives us better error messages if we
+ // assign this null-object to an incompatible property
+ if (!o) type = ep->objectClass->objectType(svalue);
+
+ return QVariant(type, &o);
}
+
if (rv.isNull())
rv = svalue.toVariant();
@@ -458,6 +461,26 @@ void QmlExpression::setTrackChange(bool trackChange)
}
/*!
+ Returns the source file URL for this expression. The source location must
+ have been previously set by calling setSourceLocation().
+*/
+QUrl QmlExpression::sourceFile() const
+{
+ Q_D(const QmlExpression);
+ return QUrl(d->data->fileName);
+}
+
+/*!
+ Returns the source file line number for this expression. The source location
+ must have been previously set by calling setSourceLocation().
+*/
+int QmlExpression::lineNumber() const
+{
+ Q_D(const QmlExpression);
+ return d->data->line;
+}
+
+/*!
Set the location of this expression to \a line of \a fileName. This information
is used by the script engine.
*/
diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h
index 169d096..96694d6 100644
--- a/src/declarative/qml/qmlexpression.h
+++ b/src/declarative/qml/qmlexpression.h
@@ -76,6 +76,8 @@ public:
bool trackChange() const;
void setTrackChange(bool);
+ QUrl sourceFile() const;
+ int lineNumber() const;
void setSourceLocation(const QUrl &fileName, int line);
QObject *scopeObject() const;
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index 86116c7..feedf13 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -768,13 +768,14 @@ bool QmlMetaPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int id
return status;
}
-void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value,
+bool QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value,
QmlMetaProperty::WriteFlags flags)
{
// Remove any existing bindings on this property
if (!(flags & QmlMetaProperty::DontRemoveBinding))
delete q->setBinding(0);
+ bool rv = false;
uint type = q->type();
if (type & QmlMetaProperty::ValueTypeProperty) {
QmlEnginePrivate *ep =
@@ -792,20 +793,23 @@ void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value,
QmlPropertyCache::Data data = core;
data.coreIndex = valueTypeCoreIdx;
data.propType = valueTypePropType;
- write(writeBack, data, value, context, flags);
+ rv = write(writeBack, data, value, context, flags);
writeBack->write(object, core.coreIndex, flags);
if (!ep) delete writeBack;
} else {
- write(object, core, value, context, flags);
+ rv = write(object, core, value, context, flags);
}
+
+ return rv;
}
-void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data &property,
- const QVariant &value, QmlContext *context, QmlMetaProperty::WriteFlags flags)
+bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data &property,
+ const QVariant &value, QmlContext *context,
+ QmlMetaProperty::WriteFlags flags)
{
int coreIdx = property.coreIndex;
int status = -1; //for dbus
@@ -820,14 +824,16 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
if (qFuzzyCompare(fractional, (double)0.0))
v.convert(QVariant::Int);
}
- writeEnumProperty(prop, coreIdx, object, v, flags);
-
- return;
+ return writeEnumProperty(prop, coreIdx, object, v, flags);
}
int t = property.propType;
int vt = value.userType();
+ QmlEnginePrivate *enginePriv = 0;
+ if (context && context->engine())
+ enginePriv = QmlEnginePrivate::get(context->engine());
+
if (t == QVariant::Url) {
QUrl u;
@@ -843,13 +849,14 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
found = true;
}
- if (found) {
- if (context && u.isRelative() && !u.isEmpty())
- u = context->baseUrl().resolved(u);
- int status = -1;
- void *argv[] = { &u, 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv);
- }
+ if (!found)
+ return false;
+
+ if (context && u.isRelative() && !u.isEmpty())
+ u = context->baseUrl().resolved(u);
+ int status = -1;
+ void *argv[] = { &u, 0, &status, &flags };
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv);
} else if (vt == t) {
@@ -863,29 +870,33 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
} else if (property.flags & QmlPropertyCache::Data::IsQObjectDerived) {
- QObject *o = QmlMetaType::toQObject(value);
-
const QMetaObject *valMo = 0;
+ if (enginePriv) valMo = enginePriv->rawMetaObjectForType(value.userType());
+ else valMo = QmlMetaType::rawMetaObjectForType(value.userType());
+
+ if (!valMo)
+ return false;
- if (o) {
+ QObject *o = *(QObject **)value.constData();
+ const QMetaObject *propMo = 0;
+ if (enginePriv) propMo = enginePriv->rawMetaObjectForType(t);
+ else propMo = QmlMetaType::rawMetaObjectForType(t);
- valMo = o->metaObject();
- const QMetaObject *propMo = QmlMetaType::rawMetaObjectForType(t);
-
- while (valMo) {
- if (equal(valMo, propMo))
- break;
- valMo = valMo->superClass();
- }
-
- }
-
- if (valMo || !o) {
+ if (o) valMo = o->metaObject();
+ if (canConvert(valMo, propMo)) {
void *args[] = { &o, 0, &status, &flags };
QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx,
args);
-
+ } else if (!o && canConvert(propMo, valMo)) {
+ // In the case of a null QObject, we assign the null if there is
+ // any change that the null variant type could be up or down cast to
+ // the property type.
+ void *args[] = { &o, 0, &status, &flags };
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx,
+ args);
+ } else {
+ return false;
}
} else if (property.flags & QmlPropertyCache::Data::IsQList) {
@@ -906,7 +917,6 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
} else if (vt == listType ||
value.userType() == listType) {
QVariant listVar = prop.read(object);
- QmlMetaType::clear(listVar);
QmlMetaType::append(listVar, value);
}
@@ -933,10 +943,8 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
objMo = objMo->superClass();
}
- if (!found) {
- qWarning() << "Unable to assign object to list";
- return;
- }
+ if (!found)
+ return false;
// NOTE: This assumes a cast to QObject does not alter
// the object pointer
@@ -952,35 +960,36 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
} else if ((uint)t >= QVariant::UserType && vt == QVariant::String) {
QmlMetaType::StringConverter con = QmlMetaType::customStringConverter(t);
- if (con) {
- QVariant v = con(value.toString());
- if (v.userType() == t) {
- void *a[] = { (void *)v.constData(), 0, &status, &flags};
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
- }
+ if (!con)
+ return false;
+
+ QVariant v = con(value.toString());
+ if (v.userType() == t) {
+ void *a[] = { (void *)v.constData(), 0, &status, &flags};
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
}
+ } else {
+ return false;
}
}
+
+ return true;
}
/*!
Set the property value to \a value.
*/
-void QmlMetaProperty::write(const QVariant &value) const
+bool QmlMetaProperty::write(const QVariant &value) const
{
- write(value, 0);
+ return write(value, 0);
}
-void QmlMetaProperty::write(const QVariant &value, QmlMetaProperty::WriteFlags flags) const
+bool QmlMetaProperty::write(const QVariant &value, QmlMetaProperty::WriteFlags flags) const
{
- if (!d->object)
- return;
-
- if (type() & Property && d->core.isValid()) {
-
- d->writeValueProperty(value, flags);
-
- }
+ if (d->object && type() & Property && d->core.isValid())
+ return d->writeValueProperty(value, flags);
+ else
+ return false;
}
/*!
@@ -1218,5 +1227,21 @@ bool QmlMetaPropertyPrivate::equal(const QMetaObject *lhs, const QMetaObject *rh
return lhs == rhs || (1 && lhs && rhs && lhs->d.stringdata == rhs->d.stringdata);
}
+/*!
+ Returns true if from inherits to.
+*/
+bool QmlMetaPropertyPrivate::canConvert(const QMetaObject *from, const QMetaObject *to)
+{
+ if (from && to == &QObject::staticMetaObject)
+ return true;
+
+ while (from) {
+ if (equal(from, to))
+ return true;
+ from = from->superClass();
+ }
+
+ return false;
+}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h
index b0ae28c..fcc020e 100644
--- a/src/declarative/qml/qmlmetaproperty.h
+++ b/src/declarative/qml/qmlmetaproperty.h
@@ -87,10 +87,10 @@ public:
QString name() const;
QVariant read() const;
- void write(const QVariant &) const;
+ bool write(const QVariant &) const;
enum WriteFlag { BypassInterceptor = 0x01, DontRemoveBinding = 0x02 };
Q_DECLARE_FLAGS(WriteFlags, WriteFlag)
- void write(const QVariant &, QmlMetaProperty::WriteFlags) const;
+ bool write(const QVariant &, QmlMetaProperty::WriteFlags) const;
bool hasChangedNotifier() const;
bool needsChangedNotifier() const;
diff --git a/src/declarative/qml/qmlmetaproperty_p.h b/src/declarative/qml/qmlmetaproperty_p.h
index 7288266..368ca30 100644
--- a/src/declarative/qml/qmlmetaproperty_p.h
+++ b/src/declarative/qml/qmlmetaproperty_p.h
@@ -97,9 +97,9 @@ public:
QmlMetaProperty::PropertyCategory propertyCategory() const;
QVariant readValueProperty();
- void writeValueProperty(const QVariant &, QmlMetaProperty::WriteFlags);
+ bool writeValueProperty(const QVariant &, QmlMetaProperty::WriteFlags);
static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags);
- static void write(QObject *, const QmlPropertyCache::Data &, const QVariant &, QmlContext *,
+ static bool write(QObject *, const QmlPropertyCache::Data &, const QVariant &, QmlContext *,
QmlMetaProperty::WriteFlags flags = 0);
static QmlAbstractBinding *setBinding(QObject *, const QmlPropertyCache::Data &, QmlAbstractBinding *,
QmlMetaProperty::WriteFlags flags = QmlMetaProperty::DontRemoveBinding);
@@ -108,6 +108,7 @@ public:
static quint32 saveProperty(int);
static bool equal(const QMetaObject *, const QMetaObject *);
+ static bool canConvert(const QMetaObject *from, const QMetaObject *to);
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp
index 5198f9f..1ab7aff 100644
--- a/src/declarative/qml/qmlmetatype.cpp
+++ b/src/declarative/qml/qmlmetatype.cpp
@@ -642,6 +642,9 @@ QVariant QmlMetaType::fromObject(QObject *obj, int typeId)
const QMetaObject *QmlMetaType::rawMetaObjectForType(int id)
{
+ if (id == QMetaType::QObjectStar)
+ return &QObject::staticMetaObject;
+
QReadLocker lock(metaTypeDataLock());
QmlMetaTypeData *data = metaTypeData();
diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp
index 122db51..a6edd3b 100644
--- a/src/declarative/qml/qmlobjectscriptclass.cpp
+++ b/src/declarative/qml/qmlobjectscriptclass.cpp
@@ -52,8 +52,9 @@
QT_BEGIN_NAMESPACE
struct ObjectData : public QScriptDeclarativeClass::Object {
- ObjectData(QObject *o) : object(o) {}
+ ObjectData(QObject *o, int t) : object(o), type(t) {}
QGuard<QObject> object;
+ int type;
};
/*
@@ -77,22 +78,22 @@ QmlObjectScriptClass::~QmlObjectScriptClass()
{
}
-QScriptValue QmlObjectScriptClass::newQObject(QObject *object)
+QScriptValue QmlObjectScriptClass::newQObject(QObject *object, int type)
{
QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
if (!object)
- return newObject(scriptEngine, this, new ObjectData(object));
+ return newObject(scriptEngine, this, new ObjectData(object, type));
QmlDeclarativeData *ddata = QmlDeclarativeData::get(object, true);
if (!ddata->scriptValue.isValid()) {
- ddata->scriptValue = newObject(scriptEngine, this, new ObjectData(object));
+ ddata->scriptValue = newObject(scriptEngine, this, new ObjectData(object, type));
return ddata->scriptValue;
} else if (ddata->scriptValue.engine() == QmlEnginePrivate::getScriptEngine(engine)) {
return ddata->scriptValue;
} else {
- return newObject(scriptEngine, this, new ObjectData(object));
+ return newObject(scriptEngine, this, new ObjectData(object, type));
}
}
@@ -101,6 +102,15 @@ QObject *QmlObjectScriptClass::toQObject(const QScriptValue &value) const
return value.toQObject();
}
+int QmlObjectScriptClass::objectType(const QScriptValue &value) const
+{
+ if (scriptClass(value) != this)
+ return QVariant::Invalid;
+
+ Object *o = object(value);
+ return ((ObjectData*)(o))->type;
+}
+
QScriptClass::QueryFlags
QmlObjectScriptClass::queryProperty(Object *object, const Identifier &name,
QScriptClass::QueryFlags flags)
@@ -224,7 +234,8 @@ QScriptValue QmlObjectScriptClass::property(QObject *obj, const Identifier &name
QObject *rv = 0;
void *args[] = { &rv, 0 };
QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args);
- return newQObject(rv);
+
+ return newQObject(rv, lastData->propType);
} else {
QVariant var = obj->metaObject()->property(lastData->coreIndex).read(obj);
return enginePriv->scriptValueFromVariant(var);
@@ -242,7 +253,8 @@ void QmlObjectScriptClass::setProperty(Object *object,
void QmlObjectScriptClass::setProperty(QObject *obj,
const Identifier &name,
- const QScriptValue &value)
+ const QScriptValue &value,
+ QmlContext *evalContext)
{
Q_UNUSED(name);
@@ -251,10 +263,19 @@ void QmlObjectScriptClass::setProperty(QObject *obj,
QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine);
+ if (!evalContext && context()) {
+ // Global object, QScriptContext activation object, QmlContext object
+ QScriptValue scopeNode = scopeChainValue(context(), -3);
+ Q_ASSERT(scopeNode.isValid());
+ Q_ASSERT(scriptClass(scopeNode) == enginePriv->contextClass);
+
+ evalContext = enginePriv->contextClass->contextFromValue(scopeNode);
+ }
+
// ### Can well known types be optimized?
QVariant v = QmlScriptClass::toVariant(engine, value);
delete QmlMetaPropertyPrivate::setBinding(obj, *lastData, 0);
- QmlMetaPropertyPrivate::write(obj, *lastData, v, enginePriv->currentExpression->context());
+ QmlMetaPropertyPrivate::write(obj, *lastData, v, evalContext);
}
QObject *QmlObjectScriptClass::toQObject(Object *object, bool *ok)
diff --git a/src/declarative/qml/qmlobjectscriptclass_p.h b/src/declarative/qml/qmlobjectscriptclass_p.h
index 3fcf009..7fb727e 100644
--- a/src/declarative/qml/qmlobjectscriptclass_p.h
+++ b/src/declarative/qml/qmlobjectscriptclass_p.h
@@ -70,8 +70,9 @@ public:
QmlObjectScriptClass(QmlEngine *);
~QmlObjectScriptClass();
- QScriptValue newQObject(QObject *);
+ QScriptValue newQObject(QObject *, int type = QMetaType::QObjectStar);
QObject *toQObject(const QScriptValue &) const;
+ int objectType(const QScriptValue &) const;
enum QueryMode { IncludeAttachedProperties, SkipAttachedProperties };
@@ -79,7 +80,8 @@ public:
QScriptClass::QueryFlags flags,
QmlContext *evalContext);
QScriptValue property(QObject *, const Identifier &);
- void setProperty(QObject *, const Identifier &name, const QScriptValue &);
+ void setProperty(QObject *, const Identifier &name, const QScriptValue &,
+ QmlContext *evalContext = 0);
protected:
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
diff --git a/src/declarative/qml/qmlprivate.h b/src/declarative/qml/qmlprivate.h
index e821759..3e1a7e0 100644
--- a/src/declarative/qml/qmlprivate.h
+++ b/src/declarative/qml/qmlprivate.h
@@ -56,6 +56,19 @@ QT_MODULE(Declarative)
typedef QObject *(*QmlAttachedPropertiesFunc)(QObject *);
+//template<typename T>
+//struct qml_hasAttached { static bool const value = false; };
+
+template <typename TYPE>
+class QmlTypeInfo
+{
+public:
+ enum {
+ hasAttachedProperties = 0
+ };
+};
+
+
namespace QmlPrivate
{
class ListInterface
@@ -101,11 +114,7 @@ namespace QmlPrivate
template<class From, class To>
struct StaticCastSelectorClass<From, To, sizeof(int)>
{
-#ifndef Q_OS_SYMBIAN
static inline int cast() { return (int)((intptr_t)static_cast<To *>((From *)0x10000000)) - 0x10000000; }
-#else
- static inline int cast() { return (int)(static_cast<To *>((From *)0x10000000)) - 0x10000000; }
-#endif
};
template<class From, class To>
@@ -135,6 +144,12 @@ namespace QmlPrivate
static bool const value = false;
}
};
+#elif defined(Q_OS_SYMBIAN)
+ template <typename T>
+ struct has_attachedPropertiesMember
+ {
+ static bool const value = QmlTypeInfo<T>::hasAttachedProperties;
+ };
#else
template <typename T>
class has_attachedPropertiesMember
@@ -147,8 +162,8 @@ namespace QmlPrivate
template <typename S>
static yes_type test(Selector<sizeof(&S::qmlAttachedProperties)>*);
- template <typename S>
- static no_type test(...);
+ template <typename S>
+ static no_type test(...);
public:
static bool const value = sizeof(test<T>(0)) == sizeof(yes_type);
diff --git a/src/declarative/qml/qmlrewrite.cpp b/src/declarative/qml/qmlrewrite.cpp
index a41b571..43b2529 100644
--- a/src/declarative/qml/qmlrewrite.cpp
+++ b/src/declarative/qml/qmlrewrite.cpp
@@ -71,6 +71,7 @@ QString RewriteBinding::rewrite(QString code, unsigned position,
TextWriter w;
_writer = &w;
_position = position;
+ _inLoop = 0;
accept(node);
@@ -111,12 +112,80 @@ bool RewriteBinding::visit(AST::Block *ast)
bool RewriteBinding::visit(AST::ExpressionStatement *ast)
{
- unsigned startOfExpressionStatement = ast->firstSourceLocation().begin() - _position;
- _writer->replace(startOfExpressionStatement, 0, QLatin1String("return "));
+ if (! _inLoop) {
+ unsigned startOfExpressionStatement = ast->firstSourceLocation().begin() - _position;
+ _writer->replace(startOfExpressionStatement, 0, QLatin1String("return "));
+ }
return false;
}
+bool RewriteBinding::visit(AST::DoWhileStatement *ast)
+{
+ ++_inLoop;
+ return true;
+}
+
+void RewriteBinding::endVisit(AST::DoWhileStatement *)
+{
+ --_inLoop;
+}
+
+bool RewriteBinding::visit(AST::WhileStatement *ast)
+{
+ ++_inLoop;
+ return true;
+}
+
+void RewriteBinding::endVisit(AST::WhileStatement *)
+{
+ --_inLoop;
+}
+
+bool RewriteBinding::visit(AST::ForStatement *ast)
+{
+ ++_inLoop;
+ return true;
+}
+
+void RewriteBinding::endVisit(AST::ForStatement *)
+{
+ --_inLoop;
+}
+
+bool RewriteBinding::visit(AST::LocalForStatement *ast)
+{
+ ++_inLoop;
+ return true;
+}
+
+void RewriteBinding::endVisit(AST::LocalForStatement *)
+{
+ --_inLoop;
+}
+
+bool RewriteBinding::visit(AST::ForEachStatement *ast)
+{
+ ++_inLoop;
+ return true;
+}
+
+void RewriteBinding::endVisit(AST::ForEachStatement *)
+{
+ --_inLoop;
+}
+
+bool RewriteBinding::visit(AST::LocalForEachStatement *ast)
+{
+ ++_inLoop;
+ return true;
+}
+
+void RewriteBinding::endVisit(AST::LocalForEachStatement *)
+{
+ --_inLoop;
+}
+
} // namespace QmlRewrite
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlrewrite_p.h b/src/declarative/qml/qmlrewrite_p.h
index b6fe017..59057d5 100644
--- a/src/declarative/qml/qmlrewrite_p.h
+++ b/src/declarative/qml/qmlrewrite_p.h
@@ -76,8 +76,30 @@ protected:
void accept(AST::Node *node);
QString rewrite(QString code, unsigned position, AST::Statement *node);
+
virtual bool visit(AST::Block *ast);
virtual bool visit(AST::ExpressionStatement *ast);
+
+ virtual bool visit(AST::DoWhileStatement *ast);
+ virtual void endVisit(AST::DoWhileStatement *ast);
+
+ virtual bool visit(AST::WhileStatement *ast);
+ virtual void endVisit(AST::WhileStatement *ast);
+
+ virtual bool visit(AST::ForStatement *ast);
+ virtual void endVisit(AST::ForStatement *ast);
+
+ virtual bool visit(AST::LocalForStatement *ast);
+ virtual void endVisit(AST::LocalForStatement *ast);
+
+ virtual bool visit(AST::ForEachStatement *ast);
+ virtual void endVisit(AST::ForEachStatement *ast);
+
+ virtual bool visit(AST::LocalForEachStatement *ast);
+ virtual void endVisit(AST::LocalForEachStatement *ast);
+
+private:
+ int _inLoop;
};
} // namespace QmlRewrite
diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp
index b132c55..4a5983d 100644
--- a/src/declarative/qml/qmlsqldatabase.cpp
+++ b/src/declarative/qml/qmlsqldatabase.cpp
@@ -312,6 +312,9 @@ static QScriptValue qmlsqldatabase_transaction(QScriptContext *context, QScriptE
}
+/*
+ Currently documented in doc/src/declarastive/globalobject.qdoc
+*/
static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine *engine)
{
QSqlDatabase database;
@@ -343,6 +346,7 @@ static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine *
ini.setValue(QLatin1String("Version"), dbversion);
ini.setValue(QLatin1String("Description"), dbdescription);
ini.setValue(QLatin1String("EstimatedSize"), dbestimatedsize);
+ ini.setValue(QLatin1String("DbType"), QLatin1String("QSQLITE"));
database.open();
}
diff --git a/src/declarative/util/qmlpackage.h b/src/declarative/util/qmlpackage.h
index 9f7a623..7cceaa7 100644
--- a/src/declarative/util/qmlpackage.h
+++ b/src/declarative/util/qmlpackage.h
@@ -81,6 +81,7 @@ public:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QmlPackage)
+QML_DECLARE_TYPEINFO(QmlPackage, QML_HAS_ATTACHED_PROPERTIES)
QT_END_HEADER
diff --git a/src/declarative/util/qmlstate.cpp b/src/declarative/util/qmlstate.cpp
index 98facd9..7e4e992 100644
--- a/src/declarative/util/qmlstate.cpp
+++ b/src/declarative/util/qmlstate.cpp
@@ -350,7 +350,6 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever
if (action.event) {
if (!action.event->isReversable())
continue;
- action.event->saveOriginals();
for (jj = 0; jj < d->revertList.count(); ++jj) {
ActionEvent *event = d->revertList.at(jj).event;
if (event && event->typeName() == action.event->typeName()) {
@@ -360,6 +359,8 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever
}
}
}
+ if (!found || action.event != d->revertList.at(jj).event)
+ action.event->saveOriginals();
} else {
action.fromBinding = action.property.binding();
diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp
index 07eb641..053cdc3 100644
--- a/src/declarative/util/qmlstateoperations.cpp
+++ b/src/declarative/util/qmlstateoperations.cpp
@@ -70,10 +70,11 @@ public:
void QmlParentChangePrivate::doChange(QFxItem *targetParent, QFxItem *stackBefore)
{
if (targetParent && target && target->parentItem()) {
- //### for backwards direction, we can just restore original x, y, scale, rotation
+ //### for backwards direction, can we just restore original x, y, scale, rotation
Q_Q(QmlParentChange);
- const QTransform &transform = target->itemTransform(targetParent);
- if (transform.type() >= QTransform::TxShear) {
+ bool ok;
+ const QTransform &transform = target->itemTransform(targetParent, &ok);
+ if (transform.type() >= QTransform::TxShear || !ok) {
qmlInfo(QObject::tr("Unable to preserve appearance under complex transform"), q);
}
@@ -82,25 +83,49 @@ void QmlParentChangePrivate::doChange(QFxItem *targetParent, QFxItem *stackBefor
if (transform.type() != QTransform::TxRotate) {
if (transform.m11() == transform.m22())
scale = transform.m11();
- else
+ else {
qmlInfo(QObject::tr("Unable to preserve appearance under non-uniform scale"), q);
+ ok = false;
+ }
} else if (transform.type() == QTransform::TxRotate) {
if (transform.m11() == transform.m22())
scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
- else
+ else {
qmlInfo(QObject::tr("Unable to preserve appearance under non-uniform scale"), q);
+ ok = false;
+ }
if (scale != 0)
rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
- else
+ else {
qmlInfo(QObject::tr("Unable to preserve appearance under scale of 0"), q);
+ ok = false;
+ }
}
+
+ qreal xt = transform.dx();
+ qreal yt = transform.dy();
+ if (target->transformOrigin() != QFxItem::TopLeft) {
+ qreal tempxt = target->transformOriginPoint().x();
+ qreal tempyt = target->transformOriginPoint().y();
+ QTransform t;
+ t.translate(-tempxt, -tempyt);
+ t.rotate(rotation);
+ t.scale(scale, scale);
+ t.translate(tempxt, tempyt);
+ QPointF offset = t.map(QPointF(0,0));
+ xt += offset.x();
+ yt += offset.y();
+ }
+
target->setParentItem(targetParent);
- //qDebug() << transform.dx() << transform.dy() << rotation << scale;
- target->setX(transform.dx());
- target->setY(transform.dy());
- target->setRotation(rotation);
- target->setScale(scale);
+ if (ok) {
+ //qDebug() << xt << yt << rotation << scale;
+ target->setX(xt);
+ target->setY(yt);
+ target->setRotation(rotation);
+ target->setScale(scale);
+ }
} else if (target) {
target->setParentItem(targetParent);
}
@@ -114,7 +139,16 @@ void QmlParentChangePrivate::doChange(QFxItem *targetParent, QFxItem *stackBefor
/*!
\preliminary
\qmlclass ParentChange
- \brief The ParentChange element allows you to reparent an object in a state.
+ \brief The ParentChange element allows you to reparent an Item in a state change.
+
+ ParentChange reparents an Item while preserving its visual appearance (position, rotation,
+ and scale) on screen. You can then specify a transition to move/rotate/scale the Item to
+ its final intended appearance.
+
+ ParentChange can only preserve visual appearance if no complex transforms are involved.
+ More specifically, it will not work if the transform property has been set for any
+ Items involved in the reparenting (defined as any Items in the common ancestor tree
+ for the original and new parent).
*/
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,ParentChange,QmlParentChange)
diff --git a/src/declarative/widgets/graphicslayouts.h b/src/declarative/widgets/graphicslayouts.h
index 863f846..45f1439 100644
--- a/src/declarative/widgets/graphicslayouts.h
+++ b/src/declarative/widgets/graphicslayouts.h
@@ -184,7 +184,9 @@ QML_DECLARE_INTERFACE(QGraphicsLayoutItem)
QML_DECLARE_INTERFACE(QGraphicsLayout)
QML_DECLARE_TYPE(QGraphicsLinearLayoutStretchItemObject)
QML_DECLARE_TYPE(QGraphicsLinearLayoutObject)
+QML_DECLARE_TYPEINFO(QGraphicsLinearLayoutObject, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QGraphicsGridLayoutObject)
+QML_DECLARE_TYPEINFO(QGraphicsGridLayoutObject, QML_HAS_ATTACHED_PROPERTIES)
QT_END_HEADER