summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/declarative/contacts/Contact.qml5
-rw-r--r--demos/declarative/contacts/ContactField.qml2
-rw-r--r--demos/declarative/contacts/contacts.qml21
-rw-r--r--demos/declarative/flickr/content/ImageDetails.qml5
-rw-r--r--demos/declarative/flickr/flickr2.qml46
-rw-r--r--src/declarative/debugger/debugger.pri6
-rw-r--r--src/declarative/debugger/qmldebugger.cpp9
-rw-r--r--src/declarative/debugger/qmldebugger.h2
-rw-r--r--src/declarative/debugger/qmlpropertyview.cpp121
-rw-r--r--src/declarative/debugger/qmlpropertyview_p.h70
-rw-r--r--src/declarative/fx/qfxpathview.cpp59
-rw-r--r--src/declarative/fx/qfxpathview.h2
-rw-r--r--src/declarative/fx/qfxpathview_p.h21
-rw-r--r--src/declarative/fx/qfxvisualitemmodel.cpp28
-rw-r--r--src/declarative/fx/qfxvisualitemmodel.h7
-rw-r--r--src/declarative/qml/qmldom.cpp5
-rw-r--r--src/declarative/qml/qmldom.h2
-rw-r--r--tests/auto/declarative/qmldom/qmldom.pro2
-rw-r--r--tests/auto/declarative/qmldom/tst_qmldom.cpp25
-rw-r--r--tools/qmlviewer/main.cpp4
-rw-r--r--tools/qmlviewer/qmlviewer.cpp83
-rw-r--r--tools/qmlviewer/qmlviewer.h1
22 files changed, 439 insertions, 87 deletions
diff --git a/demos/declarative/contacts/Contact.qml b/demos/declarative/contacts/Contact.qml
index 342c356..7297fa6 100644
--- a/demos/declarative/contacts/Contact.qml
+++ b/demos/declarative/contacts/Contact.qml
@@ -52,6 +52,11 @@ Item {
}
]
+ function refresh() {
+ labelField.value = label;
+ emailField.value = email;
+ phoneField.value = phone;
+ }
function update() {
updateContactQuery.exec();
}
diff --git a/demos/declarative/contacts/ContactField.qml b/demos/declarative/contacts/ContactField.qml
index 3ce2c1a..cb319ae 100644
--- a/demos/declarative/contacts/ContactField.qml
+++ b/demos/declarative/contacts/ContactField.qml
@@ -5,7 +5,7 @@ Item {
property var label: "Name"
property var icon: "pics/phone.png"
property var value: ""
- onValueChanged: { fieldText.text=field.value }
+ onValueChanged: { fieldText.text = contactField.value }
RemoveButton {
id: removeButton
anchors.right: parent.right
diff --git a/demos/declarative/contacts/contacts.qml b/demos/declarative/contacts/contacts.qml
index ce5a2b5..4582bd1 100644
--- a/demos/declarative/contacts/contacts.qml
+++ b/demos/declarative/contacts/contacts.qml
@@ -39,9 +39,11 @@ Rect {
children: [
MouseRegion {
anchors.fill: parent
- onClicked: { Details.qml = 'Contact.qml';
+ onClicked: {
+ Details.qml = 'Contact.qml';
wrapper.state='opened';
- contacts.mode = 'edit'; }
+ contacts.mode = 'edit';
+ }
}
]
}
@@ -142,7 +144,7 @@ Rect {
anchors.right: parent.right
anchors.rightMargin: 5
icon: "pics/new.png"
- onClicked: { print("open new contact edit"); newContactItem.label = ''; newContactItem.phone = ''; newContactItem.email = ''; contacts.mode = 'new' }
+ onClicked: { newContactItem.refresh(); contacts.mode = 'new' }
opacity: contacts.mode == 'list' ? 1 : 0
}
Button {
@@ -174,10 +176,15 @@ Rect {
delegate: contactDelegate
focus: false
}
- Contact {
- id: newContactItem
+ FocusRealm {
+ id: newContactWrapper
anchors.fill: contactListView
opacity: 0
+ focus: contacts.mode == 'new'
+ Contact {
+ id: newContactItem
+ anchors.fill: parent
+ }
}
Connection {
sender: confirmEditButton
@@ -234,7 +241,7 @@ Rect {
]
}
KeyProxy {
- focus: true
+ focus: contacts.mode != 'new'
targets: { contacts.mode == "list" ? [searchBarWrapper, contactListView] : [contactListView]}
}
states: [
@@ -247,7 +254,7 @@ Rect {
value: 0
}
SetProperty {
- target: newContactItem
+ target: newContactWrapper
property: "opacity"
value: 1
}
diff --git a/demos/declarative/flickr/content/ImageDetails.qml b/demos/declarative/flickr/content/ImageDetails.qml
index 955f85d..6c354f6 100644
--- a/demos/declarative/flickr/content/ImageDetails.qml
+++ b/demos/declarative/flickr/content/ImageDetails.qml
@@ -60,8 +60,9 @@ Flipable {
text: "<b>Published:</b> " + Container.photoDate }
Text { id: TagsLabel; color: "white"; x: 220; anchors.top: Date.bottom;
text: Container.photoTags == "" ? "" : "<b>Tags:</b> " }
- Text { id: Tags; color: "white"; width: parent.width-x-20; anchors.left: TagsLabel.right; anchors.top: Date.bottom; elide: "ElideRight"
- text: Container.photoTags == "" ? "" : Container.photoTags }
+ Text { id: Tags; color: "white"; width: parent.width-x-20;
+ anchors.left: TagsLabel.right; anchors.top: Date.bottom;
+ elide: "ElideRight"; text: Container.photoTags }
ScrollBar { id: ScrollBar; x: 720; y: Flickable.y; width: 7; height: Flickable.height; opacity: 0;
flickableArea: Flickable; clip: true }
diff --git a/demos/declarative/flickr/flickr2.qml b/demos/declarative/flickr/flickr2.qml
index 4875fa4..3b1208c 100644
--- a/demos/declarative/flickr/flickr2.qml
+++ b/demos/declarative/flickr/flickr2.qml
@@ -143,29 +143,31 @@ Item {
]
transitions: [
Transition {
- fromState: "*"
- toState: "*"
+ fromState: "left"
+ toState: "right"
SequentialAnimation {
SetPropertyAction {
target: Wrapper
property: "moveToParent"
- value: Bounce
}
ParallelAnimation {
NumericAnimation {
target: Wrapper
- properties: "x"
+ properties: "x,y"
to: 0
- duration: 250
- }
- NumericAnimation {
- target: Wrapper
- properties: "y"
- to: 0
- easing: "easeInQuad"
- duration: 250
+ easing: "easeOutQuad"
+ duration: 350
}
}
+ }
+ },
+ Transition {
+ fromState: "right"
+ toState: "left"
+ SequentialAnimation {
+ PauseAnimation {
+ duration: Math.floor(index/7)*100
+ }
SetPropertyAction {
target: Wrapper
property: "moveToParent"
@@ -173,13 +175,7 @@ Item {
ParallelAnimation {
NumericAnimation {
target: Wrapper
- properties: "x"
- to: 0
- duration: 250
- }
- NumericAnimation {
- target: Wrapper
- properties: "y"
+ properties: "x,y"
to: 0
easing: "easeOutQuad"
duration: 250
@@ -203,14 +199,20 @@ Item {
GridView {
id: PhotoGridView; model: MyVisualModel.parts.leftBox
cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330; z: 1
+ cacheBuffer: 100
}
PathView {
id: PhotoPathView; model: MyVisualModel.parts.rightBox
y: 80; width: 800; height: 330; z: 1
+ pathItemCount: 10; snapPosition: 0.001
path: Path {
- startX: -50; startY: 40;
+ startX: -150; startY: 40;
+ PathPercent { value: 0 }
+ PathLine { x: -50; y: 40 }
+
+ PathPercent { value: 0.001 }
PathAttribute { name: "scale"; value: 1 }
PathAttribute { name: "angle"; value: -45 }
@@ -232,6 +234,10 @@ Item {
PathAttribute { name: "scale"; value: 1 }
PathAttribute { name: "angle"; value: -45 }
+
+ PathPercent { value: 0.999 }
+ PathLine { x: 950; y: 40 }
+ PathPercent { value: 1.0 }
}
}
diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri
index b88b7b3..31a1d5b 100644
--- a/src/declarative/debugger/debugger.pri
+++ b/src/declarative/debugger/debugger.pri
@@ -1,5 +1,7 @@
SOURCES += debugger/qmldebugger.cpp \
- debugger/qmldebuggerstatus.cpp
+ debugger/qmldebuggerstatus.cpp \
+ debugger/qmlpropertyview.cpp
HEADERS += debugger/qmldebugger.h \
- debugger/qmldebuggerstatus.h
+ debugger/qmldebuggerstatus.h \
+ debugger/qmlpropertyview_p.h
diff --git a/src/declarative/debugger/qmldebugger.cpp b/src/declarative/debugger/qmldebugger.cpp
index f232f02..634385b 100644
--- a/src/declarative/debugger/qmldebugger.cpp
+++ b/src/declarative/debugger/qmldebugger.cpp
@@ -57,9 +57,11 @@
#include <QtGui/qpushbutton.h>
#include <QtGui/qtablewidget.h>
#include <QtGui/qevent.h>
+#include <private/qmlpropertyview_p.h>
QmlDebugger::QmlDebugger(QWidget *parent)
-: QWidget(parent), m_tree(0), m_warnings(0), m_watchers(0), m_text(0)
+: QWidget(parent), m_tree(0), m_warnings(0), m_watchers(0), m_properties(0),
+ m_text(0)
{
QHBoxLayout *layout = new QHBoxLayout;
setLayout(layout);
@@ -97,6 +99,9 @@ QmlDebugger::QmlDebugger(QWidget *parent)
m_watchers->setSelectionMode(QTableWidget::NoSelection);
tabs->addTab(m_watchers, "Watchers");
+ m_properties = new QmlPropertyView(this);
+ tabs->addTab(m_properties, "Properties");
+
splitter->addWidget(tabs);
splitter->setStretchFactor(1, 2);
@@ -162,6 +167,8 @@ void QmlDebugger::itemClicked(QTreeWidgetItem *i)
debug->setSelectedState(true);
m_selectedItem = item->object;
}
+
+ m_properties->setObject(item->object);
}
if(item->url.scheme() == QLatin1String("file")) {
diff --git a/src/declarative/debugger/qmldebugger.h b/src/declarative/debugger/qmldebugger.h
index 8d2593d..35ff92c 100644
--- a/src/declarative/debugger/qmldebugger.h
+++ b/src/declarative/debugger/qmldebugger.h
@@ -57,6 +57,7 @@ class QTreeWidgetItem;
class QPlainTextEdit;
class QmlDebuggerItem;
class QTableWidget;
+class QmlPropertyView;
class QmlDebugger : public QWidget
{
Q_OBJECT
@@ -78,6 +79,7 @@ private:
QTreeWidget *m_tree;
QTreeWidget *m_warnings;
QTableWidget *m_watchers;
+ QmlPropertyView *m_properties;
QPlainTextEdit *m_text;
QPointer<QObject> m_object;
QList<QPair<quint32, QPair<int, QString> > > m_expressions;
diff --git a/src/declarative/debugger/qmlpropertyview.cpp b/src/declarative/debugger/qmlpropertyview.cpp
new file mode 100644
index 0000000..2434c58
--- /dev/null
+++ b/src/declarative/debugger/qmlpropertyview.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlpropertyview_p.h"
+#include <QtGui/qboxlayout.h>
+#include <QtGui/qtreewidget.h>
+#include <QtCore/qmetaobject.h>
+
+QmlPropertyView::QmlPropertyView(QWidget *parent)
+: QWidget(parent), m_tree(0)
+{
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ setLayout(layout);
+
+ m_tree = new QTreeWidget(this);
+ m_tree->setHeaderLabels(QStringList() << "Property" << "Value");
+
+ m_tree->setColumnCount(2);
+
+ layout->addWidget(m_tree);
+}
+
+class QmlPropertyViewItem : public QObject, public QTreeWidgetItem
+{
+Q_OBJECT
+public:
+ QmlPropertyViewItem(QTreeWidget *widget);
+
+ QObject *object;
+ QMetaProperty property;
+
+public slots:
+ void refresh();
+};
+
+QmlPropertyViewItem::QmlPropertyViewItem(QTreeWidget *widget)
+: QTreeWidgetItem(widget)
+{
+}
+
+void QmlPropertyViewItem::refresh()
+{
+ setText(1, property.read(object).toString());
+}
+
+void QmlPropertyView::setObject(QObject *object)
+{
+ m_object = object;
+
+ m_tree->clear();
+ if(!m_object)
+ return;
+
+ const QMetaObject *mo = object->metaObject();
+ for(int ii = 0; ii < mo->propertyCount(); ++ii) {
+ QmlPropertyViewItem *item = new QmlPropertyViewItem(m_tree);
+
+ QMetaProperty p = mo->property(ii);
+ item->object = object;
+ item->property = p;
+
+ item->setText(0, QLatin1String(p.name()));
+
+ static int refreshIdx = -1;
+ if(refreshIdx == -1)
+ refreshIdx = QmlPropertyViewItem::staticMetaObject.indexOfMethod("refresh()");
+
+ if(p.hasNotifySignal())
+ QMetaObject::connect(object, p.notifySignalIndex(),
+ item, refreshIdx);
+
+ item->refresh();
+ }
+}
+
+void QmlPropertyView::refresh()
+{
+ setObject(m_object);
+}
+
+#include "qmlpropertyview.moc"
diff --git a/src/declarative/debugger/qmlpropertyview_p.h b/src/declarative/debugger/qmlpropertyview_p.h
new file mode 100644
index 0000000..fce9941
--- /dev/null
+++ b/src/declarative/debugger/qmlpropertyview_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLPROPERTYVIEW_P_H
+#define QMLPROPERTYVIEW_P_H
+
+#include <QtGui/qwidget.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTreeWidget;
+class QmlPropertyView : public QWidget
+{
+ Q_OBJECT
+public:
+ QmlPropertyView(QWidget *parent = 0);
+
+ void setObject(QObject *);
+
+public slots:
+ void refresh();
+
+private:
+ QPointer<QObject> m_object;
+ QTreeWidget *m_tree;
+};
+
+QT_END_NAMESPACE
+
+#endif // QMLPROPERTYVIEW_P_H
+
diff --git a/src/declarative/fx/qfxpathview.cpp b/src/declarative/fx/qfxpathview.cpp
index 715ae5a..2b39d6e 100644
--- a/src/declarative/fx/qfxpathview.cpp
+++ b/src/declarative/fx/qfxpathview.cpp
@@ -145,7 +145,7 @@ QFxPathView::~QFxPathView()
QVariant QFxPathView::model() const
{
Q_D(const QFxPathView);
- return d->model ? d->model->model() : QVariant();
+ return d->modelVariant;
}
void QFxPathView::setModel(const QVariant &model)
@@ -154,13 +154,24 @@ void QFxPathView::setModel(const QVariant &model)
if (d->model) {
disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
+ disconnect(d->model, SIGNAL(itemCreated(int, QFxItem*)), this, SLOT(itemCreated(int,QFxItem*)));
+ for (int i=0; i<d->items.count(); i++){
+ QFxItem *p = d->items[i];
+ attachedProperties.remove(p);
+ d->model->release(p);
+ }
+ d->items.clear();
}
- if (QFxVisualItemModel *m = qvariant_cast<QFxVisualItemModel*>(model)) {
+
+ d->modelVariant = model;
+ QObject *object = qvariant_cast<QObject*>(model);
+ QFxVisualItemModel *vim = 0;
+ if (object && (vim = qobject_cast<QFxVisualItemModel *>(object))) {
if (d->ownModel) {
delete d->model;
d->ownModel = false;
}
- d->model = m;
+ d->model = vim;
} else {
if (!d->ownModel) {
d->model = new QFxVisualItemModel(qmlContext(this));
@@ -171,6 +182,7 @@ void QFxPathView::setModel(const QVariant &model)
if (d->model) {
connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
+ connect(d->model, SIGNAL(itemCreated(int, QFxItem*)), this, SLOT(itemCreated(int,QFxItem*)));
}
d->firstIndex = 0;
d->pathOffset = 0;
@@ -550,7 +562,7 @@ void QFxPathViewPrivate::regenerate()
}
items.clear();
- if (!model || model->count() <= 0 || !model->delegate() || !path)
+ if (!isValid())
return;
if (firstIndex >= model->count())
@@ -560,14 +572,14 @@ void QFxPathViewPrivate::regenerate()
int numItems = pathItems >= 0 ? pathItems : model->count();
for (int i=0; i < numItems && i < model->count(); ++i){
- QFxItem *item = model->item((i + firstIndex) % model->count());
- if (!item)
+ QFxItem *item = getItem((i + firstIndex) % model->count());
+ if (!item) {
+ qWarning() << "PathView: Cannot create item, index" << (i + firstIndex) % model->count();
return;
+ }
items.append(item);
item->setZ(i);
- item->setParent(q);
}
-
q->refill();
}
@@ -577,7 +589,6 @@ void QFxPathViewPrivate::updateItem(QFxItem *item, qreal percent)
foreach(const QString &attr, path->attributes())
static_cast<QFxPathViewAttached *>(obj)->setValue(attr.toLatin1(), path->attributeAt(attr, percent));
}
-
QPointF pf = path->pointAt(percent);
item->setX(pf.x() - item->width()*item->scale()/2);
item->setY(pf.y() - item->height()*item->scale()/2);
@@ -586,7 +597,7 @@ void QFxPathViewPrivate::updateItem(QFxItem *item, qreal percent)
void QFxPathView::refill()
{
Q_D(QFxPathView);
- if (!d->model || d->model->count() <= 0)
+ if (!d->isValid())
return;
QList<qreal> positions;
@@ -619,28 +630,28 @@ void QFxPathView::refill()
if (wrapIndex < d->items.count()/2){
while(wrapIndex-- >= 0){
QFxItem* p = d->items.takeFirst();
+ d->updateItem(p, 0.0);
attachedProperties.remove(p);
d->model->release(p);
d->firstIndex++;
d->firstIndex %= d->model->count();
int index = (d->firstIndex + d->items.count())%d->model->count();
- d->items << d->model->item(index);
+ d->items << d->getItem(index);
d->items.last()->setZ(wrapIndex);
- d->items.last()->setParent(this);
d->pathOffset++;
d->pathOffset=d->pathOffset % d->items.count();
}
} else {
while(wrapIndex++ < d->items.count()-1){
QFxItem* p = d->items.takeLast();
+ d->updateItem(p, 1.0);
attachedProperties.remove(p);
d->model->release(p);
d->firstIndex--;
if (d->firstIndex < 0)
d->firstIndex = d->model->count() - 1;
- d->items.prepend(d->model->item(d->firstIndex));
+ d->items.prepend(d->getItem(d->firstIndex));
d->items.first()->setZ(d->firstIndex);
- d->items.first()->setParent(this);
d->pathOffset--;
if (d->pathOffset < 0)
d->pathOffset = d->items.count() - 1;
@@ -658,11 +669,12 @@ void QFxPathView::itemsInserted(int modelIndex, int count)
{
//XXX support animated insertion
Q_D(QFxPathView);
+ if (!d->isValid())
+ return;
if (d->pathItems == -1) {
for (int i = 0; i < count; ++i) {
- QFxItem *item = d->model->item(modelIndex + i);
+ QFxItem *item = d->getItem(modelIndex + i);
item->setZ(modelIndex + i);
- item->setParent(this);
d->items.insert(modelIndex + i, item);
}
refill();
@@ -687,6 +699,8 @@ void QFxPathView::itemsRemoved(int modelIndex, int count)
{
//XXX support animated removal
Q_D(QFxPathView);
+ if (!d->isValid())
+ return;
if (d->pathItems == -1) {
for (int i = 0; i < count; ++i) {
QFxItem* p = d->items.takeAt(modelIndex);
@@ -719,6 +733,19 @@ void QFxPathView::itemsRemoved(int modelIndex, int count)
d->moveOffset.setValue(targetOffset);
}
+void QFxPathView::itemCreated(int index, QFxItem *item)
+{
+ Q_D(QFxPathView);
+ if (d->requestedIndex != index) {
+ item->setItemParent(this);
+ d->updateItem(item, index < d->firstIndex ? 0.0 : 1.0);
+ }
+}
+
+void QFxPathView::destroyingItem(QFxItem *item)
+{
+}
+
void QFxPathView::ticked()
{
Q_D(QFxPathView);
diff --git a/src/declarative/fx/qfxpathview.h b/src/declarative/fx/qfxpathview.h
index 23f2f07..0e1ac6f 100644
--- a/src/declarative/fx/qfxpathview.h
+++ b/src/declarative/fx/qfxpathview.h
@@ -115,6 +115,8 @@ private Q_SLOTS:
void ticked();
void itemsInserted(int index, int count);
void itemsRemoved(int index, int count);
+ void itemCreated(int index, QFxItem *item);
+ void destroyingItem(QFxItem *item);
protected:
QFxPathView(QFxPathViewPrivate &dd, QFxItem *parent);
diff --git a/src/declarative/fx/qfxpathview_p.h b/src/declarative/fx/qfxpathview_p.h
index a19d778..358daf6 100644
--- a/src/declarative/fx/qfxpathview_p.h
+++ b/src/declarative/fx/qfxpathview_p.h
@@ -77,7 +77,7 @@ public:
: path(0), currentIndex(0), startPc(0), lastDist(0)
, lastElapsed(0), stealMouse(false), ownModel(false), activeItem(0)
, snapPos(0), dragMargin(0), moveOffset(this, &QFxPathViewPrivate::setOffset)
- , firstIndex(0), pathItems(-1), pathOffset(0), model(0)
+ , firstIndex(0), pathItems(-1), pathOffset(0), requestedIndex(-1), model(0)
, moveReason(Other)
{
fixupOffsetEvent = QmlTimeLineEvent::timeLineEvent<QFxPathViewPrivate, &QFxPathViewPrivate::fixOffset>(&moveOffset, this);
@@ -92,6 +92,20 @@ public:
q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked()));
}
+ QFxItem *getItem(int modelIndex) {
+ Q_Q(QFxPathView);
+ requestedIndex = modelIndex;
+ QFxItem *item = model->item(modelIndex);
+ if (item)
+ item->setItemParent(q);
+ requestedIndex = -1;
+ return item;
+ }
+
+ bool isValid() const {
+ return model && model->count() > 0 && model->delegate() && path;
+ }
+
int calcCurrentIndex();
void updateCurrent();
void fixOffset();
@@ -108,8 +122,8 @@ public:
qreal lastDist;
int lastElapsed;
qreal _offset;
- int stealMouse : 1;
- int ownModel : 1;
+ bool stealMouse : 1;
+ bool ownModel : 1;
QTime lastPosTime;
QPointF lastPos;
QFxItem *activeItem;
@@ -121,6 +135,7 @@ public:
int firstIndex;
int pathItems;
int pathOffset;
+ int requestedIndex;
QList<QFxItem *> items;
QFxVisualItemModel *model;
QVariant modelVariant;
diff --git a/src/declarative/fx/qfxvisualitemmodel.cpp b/src/declarative/fx/qfxvisualitemmodel.cpp
index 7d0d7a5..9428281 100644
--- a/src/declarative/fx/qfxvisualitemmodel.cpp
+++ b/src/declarative/fx/qfxvisualitemmodel.cpp
@@ -336,6 +336,10 @@ void QFxVisualItemModel::setModel(const QVariant &model)
this, SIGNAL(itemsRemoved(int,int)));
QObject::disconnect(d->m_visualItemModel, SIGNAL(itemsMoved(int,int,int)),
this, SIGNAL(itemsMoved(int,int,int)));
+ QObject::disconnect(d->m_visualItemModel, SIGNAL(packageCreated(int,QmlPackage*)),
+ this, SLOT(_q_packageCreated(int,QmlPackage*)));
+ QObject::disconnect(d->m_visualItemModel, SIGNAL(destroyingPackage(QmlPackage*)),
+ this, SLOT(_q_destroyingPackage(QmlPackage*)));
d->m_visualItemModel = 0;
}
@@ -385,6 +389,10 @@ void QFxVisualItemModel::setModel(const QVariant &model)
this, SIGNAL(itemsRemoved(int,int)));
QObject::connect(d->m_visualItemModel, SIGNAL(itemsMoved(int,int,int)),
this, SIGNAL(itemsMoved(int,int,int)));
+ QObject::connect(d->m_visualItemModel, SIGNAL(packageCreated(int,QmlPackage*)),
+ this, SLOT(_q_packageCreated(int,QmlPackage*)));
+ QObject::connect(d->m_visualItemModel, SIGNAL(destroyingPackage(QmlPackage*)),
+ this, SLOT(_q_destroyingPackage(QmlPackage*)));
return;
}
if (!d->m_modelList)
@@ -397,6 +405,8 @@ void QFxVisualItemModel::setModel(const QVariant &model)
QmlComponent *QFxVisualItemModel::delegate() const
{
Q_D(const QFxVisualItemModel);
+ if (d->m_visualItemModel)
+ return d->m_visualItemModel->delegate();
return d->m_delegate;
}
@@ -404,7 +414,6 @@ void QFxVisualItemModel::setDelegate(QmlComponent *delegate)
{
Q_D(QFxVisualItemModel);
d->m_delegate = delegate;
-
if (d->modelCount())
emit itemsInserted(0, d->modelCount());
}
@@ -445,6 +454,7 @@ void QFxVisualItemModel::release(QFxItem *item)
item->setItemParent(0);
QObject *obj = item;
+ bool inPackage = false;
if (QmlPackage *package = d->m_packaged.value(item)) {
static_cast<QObject*>(item)->setParent(package);
d->m_packaged.remove(item);
@@ -454,6 +464,7 @@ void QFxVisualItemModel::release(QFxItem *item)
if (*iter == package)
return;
}
+ inPackage = true;
obj = package; // fall through and delete
}
@@ -461,6 +472,8 @@ void QFxVisualItemModel::release(QFxItem *item)
for (QHash<int, QObject *>::Iterator iter = d->m_cache.begin();
iter != d->m_cache.end(); ++iter) {
if (*iter == obj) {
+ if (inPackage)
+ emit destroyingPackage(qobject_cast<QmlPackage*>(obj));
delete obj;
d->m_cache.erase(iter);
return;
@@ -511,6 +524,7 @@ QFxItem *QFxVisualItemModel::item(int index, const QByteArray &viewId, bool comp
QObject *o = package->part(QLatin1String(viewId));
item = qobject_cast<QFxItem *>(o);
d->m_packaged[o] = package;
+ emit packageCreated(index, package);
}
}
@@ -688,6 +702,18 @@ void QFxVisualItemModel::_q_dataChanged(const QModelIndex &begin, const QModelIn
_q_itemsChanged(begin.row(), end.row() - begin.row() + 1, d->m_roles);
}
+void QFxVisualItemModel::_q_packageCreated(int index, QmlPackage *package)
+{
+ Q_D(QFxVisualItemModel);
+ emit itemCreated(index, qobject_cast<QFxItem*>(package->part(d->m_part)));
+}
+
+void QFxVisualItemModel::_q_destroyingPackage(QmlPackage *package)
+{
+ Q_D(QFxVisualItemModel);
+ emit destroyingItem(qobject_cast<QFxItem*>(package->part(d->m_part)));
+}
+
QML_DEFINE_TYPE(QFxVisualItemModel,VisualModel);
QT_END_NAMESPACE
diff --git a/src/declarative/fx/qfxvisualitemmodel.h b/src/declarative/fx/qfxvisualitemmodel.h
index 5ec42e9..33017e2 100644
--- a/src/declarative/fx/qfxvisualitemmodel.h
+++ b/src/declarative/fx/qfxvisualitemmodel.h
@@ -60,6 +60,7 @@ QT_MODULE(Declarative)
class QFxItem;
class QmlComponent;
+class QmlPackage;
class QFxVisualItemModelPrivate;
class QFxVisualItemModel : public QObject
{
@@ -98,6 +99,10 @@ Q_SIGNALS:
void itemsInserted(int index, int count);
void itemsRemoved(int index, int count);
void itemsMoved(int from, int to, int count);
+ void itemCreated(int index, QFxItem *item);
+ void packageCreated(int index, QmlPackage *package);
+ void destroyingItem(QFxItem *item);
+ void destroyingPackage(QmlPackage *package);
private Q_SLOTS:
void _q_itemsChanged(int, int, const QList<int> &);
@@ -107,6 +112,8 @@ private Q_SLOTS:
void _q_rowsInserted(const QModelIndex &,int,int);
void _q_rowsRemoved(const QModelIndex &,int,int);
void _q_dataChanged(const QModelIndex&,const QModelIndex&);
+ void _q_packageCreated(int index, QmlPackage *package);
+ void _q_destroyingPackage(QmlPackage *package);
private:
Q_DISABLE_COPY(QFxVisualItemModel)
diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp
index 689446b..a31be81 100644
--- a/src/declarative/qml/qmldom.cpp
+++ b/src/declarative/qml/qmldom.cpp
@@ -149,16 +149,15 @@ int QmlDomDocument::version() const
\sa QmlDomDocument::save() QmlDomDocument::loadError()
*/
-bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data)
+bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data, const QUrl &url)
{
Q_UNUSED(engine);
-
d->errors.clear();
QmlCompiledComponent component;
QmlCompiler compiler;
- QmlCompositeTypeData *td = ((QmlEnginePrivate *)QmlEnginePrivate::get(engine))->typeManager.getImmediate(data, QUrl());;
+ QmlCompositeTypeData *td = ((QmlEnginePrivate *)QmlEnginePrivate::get(engine))->typeManager.getImmediate(data, url);;
if(td->status == QmlCompositeTypeData::Error) {
d->errors = td->errors;
diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h
index daca888..f90fb08 100644
--- a/src/declarative/qml/qmldom.h
+++ b/src/declarative/qml/qmldom.h
@@ -73,7 +73,7 @@ public:
int version() const;
QList<QmlError> errors() const;
- bool load(QmlEngine *, const QByteArray &);
+ bool load(QmlEngine *, const QByteArray &, const QUrl & = QUrl());
QByteArray save() const;
QmlDomObject rootObject() const;
diff --git a/tests/auto/declarative/qmldom/qmldom.pro b/tests/auto/declarative/qmldom/qmldom.pro
index 5294cb4..d566354 100644
--- a/tests/auto/declarative/qmldom/qmldom.pro
+++ b/tests/auto/declarative/qmldom/qmldom.pro
@@ -1,3 +1,5 @@
load(qttest_p4)
contains(QT_CONFIG,declarative): QT += declarative
SOURCES += tst_qmldom.cpp
+
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/auto/declarative/qmldom/tst_qmldom.cpp b/tests/auto/declarative/qmldom/tst_qmldom.cpp
index 36d37f6..ca8929d 100644
--- a/tests/auto/declarative/qmldom/tst_qmldom.cpp
+++ b/tests/auto/declarative/qmldom/tst_qmldom.cpp
@@ -4,6 +4,7 @@
#include <QtDeclarative/qmldom.h>
#include <QtCore/QDebug>
+#include <QtCore/QFile>
class tst_qmldom : public QObject
{
@@ -15,6 +16,7 @@ private slots:
void loadSimple();
void loadProperties();
void loadChildObject();
+ void loadComposite();
void testValueSource();
@@ -30,7 +32,7 @@ void tst_qmldom::loadSimple()
QmlDomDocument document;
QVERIFY(document.load(&engine, qml));
- QVERIFY(document.loadError().isEmpty());
+ QVERIFY(document.errors().isEmpty());
QmlDomObject rootObject = document.rootObject();
QVERIFY(rootObject.isValid());
@@ -87,6 +89,27 @@ void tst_qmldom::loadChildObject()
QVERIFY(childItem.objectType() == "Item");
}
+void tst_qmldom::loadComposite()
+{
+ QFile file(SRCDIR "/top.qml");
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
+
+ QmlDomDocument document;
+ QVERIFY(document.load(&engine, file.readAll(), QUrl::fromLocalFile(file.fileName())));
+ QVERIFY(document.errors().isEmpty());
+
+ QmlDomObject rootItem = document.rootObject();
+ QVERIFY(rootItem.isValid());
+ QCOMPARE(rootItem.objectType(), QByteArray("MyComponent"));
+ QCOMPARE(rootItem.properties().size(), 2);
+
+ QmlDomProperty widthProperty = rootItem.property("width");
+ QVERIFY(widthProperty.value().isLiteral());
+
+ QmlDomProperty heightProperty = rootItem.property("height");
+ QVERIFY(heightProperty.value().isLiteral());
+}
+
void tst_qmldom::testValueSource()
{
QByteArray qml = "Rect { height: Follow { spring: 1.4; damping: .15; source: Math.min(Math.max(-130, value*2.2 - 130), 133); }}";
diff --git a/tools/qmlviewer/main.cpp b/tools/qmlviewer/main.cpp
index 3f74ef6..379fda9 100644
--- a/tools/qmlviewer/main.cpp
+++ b/tools/qmlviewer/main.cpp
@@ -26,7 +26,7 @@ void usage()
qWarning(" -v, -version ............................. display version");
qWarning(" -frameless ............................... run with no window frame");
qWarning(" -skin <qvfbskindir> ...................... run with a skin window frame");
- qWarning(" -recordfile <output> ..................... set output file");
+ qWarning(" -recordfile <output> ..................... set video recording file");
qWarning(" - ImageMagick 'convert' for GIF)");
qWarning(" - png file for raw frames");
qWarning(" - 'ffmpeg' for other formats");
@@ -69,7 +69,7 @@ int main(int argc, char ** argv)
int autorecord_from = 0;
int autorecord_to = 0;
QString dither = "none";
- QString recordfile = "animation.gif";
+ QString recordfile;
QString skin;
bool devkeys = false;
bool cache = false;
diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp
index 04054ec..8457972 100644
--- a/tools/qmlviewer/qmlviewer.cpp
+++ b/tools/qmlviewer/qmlviewer.cpp
@@ -31,6 +31,7 @@
#include <QFile>
#include <QFileInfo>
#include <QVBoxLayout>
+#include <QProgressDialog>
#include <QProcess>
#include <QMenuBar>
#include <QMenu>
@@ -86,15 +87,15 @@ void QmlViewer::createMenuBar()
fileMenu->addSeparator();
fileMenu->addAction(quitAction);
- /*QMenu *recordMenu = menuBar()->addMenu(tr("&Recording"));
+ QMenu *recordMenu = menuBar()->addMenu(tr("&Recording"));
- QAction *snapshotAction = new QAction(tr("&Take Snapsot"), this);
+ QAction *snapshotAction = new QAction(tr("&Take Snapsot\tF3"), this);
connect(snapshotAction, SIGNAL(triggered()), this, SLOT(takeSnapShot()));
recordMenu->addAction(snapshotAction);
- recordAction = new QAction(tr("&Start Recording Video"), this);
- connect(recordAction, SIGNAL(triggered()), this, SLOT(toggleRecording()));
- recordMenu->addAction(recordAction);*/
+ recordAction = new QAction(tr("Start Recording &Video\tF2"), this);
+ connect(recordAction, SIGNAL(triggered()), this, SLOT(toggleRecordingWithSelection()));
+ recordMenu->addAction(recordAction);
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
QAction *aboutAction = new QAction(tr("&About Qt..."), this);
@@ -111,13 +112,31 @@ void QmlViewer::takeSnapShot()
++snapshotcount;
}
+void QmlViewer::toggleRecordingWithSelection()
+{
+ if (!recordTimer.isActive()) {
+ QString fileName = QFileDialog::getSaveFileName(this, tr("Save Video File"), "", tr("Common Video files (*.avi *.mpeg *.mov);; GIF Animation (*.gif);; Individual PNG frames (*.png);; All ffmpeg formats (*.*)"));
+ if (fileName.isEmpty())
+ return;
+ if (!fileName.contains(QRegExp(".[^\\/]*$")))
+ fileName += ".avi";
+ setRecordFile(fileName);
+ }
+ toggleRecording();
+}
+
void QmlViewer::toggleRecording()
{
- bool recording = recordTimer.isActive();
- //recordAction->setText(recording ? tr("&Start Recording Video") : tr("&End Recording Video"));
- setRecording(!recording);
+ if (record_file.isEmpty()) {
+ toggleRecordingWithSelection();
+ return;
+ }
+ bool recording = !recordTimer.isActive();
+ recordAction->setText(recording ? tr("&Stop Recording Video\tF2") : tr("&Start Recording Video\tF2"));
+ setRecording(recording);
}
+
void QmlViewer::reload()
{
openQml(currentFileName);
@@ -389,6 +408,9 @@ void QmlViewer::setRecording(bool on)
frame_stream->close();
qDebug() << "Wrote" << record_file;
} else {
+ QProgressDialog progress(tr("Saving frames..."), tr("Cancel"), 0, frames.count()+10, this);
+ progress.setWindowModality(Qt::WindowModal);
+
int frame=0;
QStringList inputs;
qDebug() << "Saving frames...";
@@ -406,6 +428,9 @@ void QmlViewer::setRecording(bool on)
png_output = false;
}
foreach (QImage* img, frames) {
+ progress.setValue(progress.value()+1);
+ if (progress.wasCanceled())
+ break;
QString name;
name.sprintf(framename.toLocal8Bit(),frame++);
if (record_dither=="ordered")
@@ -420,31 +445,35 @@ void QmlViewer::setRecording(bool on)
delete img;
}
- if (png_output) {
- framename.replace(QRegExp("%\\d*."),"*");
- qDebug() << "Wrote frames" << framename;
- inputs.clear(); // don't remove them
- } else {
- // ImageMagick and gifsicle for GIF encoding
- QStringList args;
- args << "-delay" << QString::number(record_period/10);
- args << inputs;
- args << record_file;
- qDebug() << "Converting..." << record_file << "(this may take a while)";
- if (0!=QProcess::execute("convert", args)) {
- qWarning() << "Cannot run ImageMagick 'convert' - recorded frames not converted";
+ if (!progress.wasCanceled()) {
+ if (png_output) {
+ framename.replace(QRegExp("%\\d*."),"*");
+ qDebug() << "Wrote frames" << framename;
inputs.clear(); // don't remove them
- qDebug() << "Wrote frames tmp-frame*.png";
} else {
- if (record_file.right(4).toLower() == ".gif") {
- qDebug() << "Compressing..." << record_file;
- if (0!=QProcess::execute("gifsicle", QStringList() << "-O2" << "-o" << record_file << record_file))
- qWarning() << "Cannot run 'gifsicle' - not compressed";
+ // ImageMagick and gifsicle for GIF encoding
+ progress.setLabelText(tr("Converting frames to GIF file..."));
+ QStringList args;
+ args << "-delay" << QString::number(record_period/10);
+ args << inputs;
+ args << record_file;
+ qDebug() << "Converting..." << record_file << "(this may take a while)";
+ if (0!=QProcess::execute("convert", args)) {
+ qWarning() << "Cannot run ImageMagick 'convert' - recorded frames not converted";
+ inputs.clear(); // don't remove them
+ qDebug() << "Wrote frames tmp-frame*.png";
+ } else {
+ if (record_file.right(4).toLower() == ".gif") {
+ qDebug() << "Compressing..." << record_file;
+ if (0!=QProcess::execute("gifsicle", QStringList() << "-O2" << "-o" << record_file << record_file))
+ qWarning() << "Cannot run 'gifsicle' - not compressed";
+ }
+ qDebug() << "Wrote" << record_file;
}
- qDebug() << "Wrote" << record_file;
}
}
+ progress.setValue(progress.maximum()-1);
foreach (QString name, inputs)
QFile::remove(name);
diff --git a/tools/qmlviewer/qmlviewer.h b/tools/qmlviewer/qmlviewer.h
index 405e8d9..fc8a427 100644
--- a/tools/qmlviewer/qmlviewer.h
+++ b/tools/qmlviewer/qmlviewer.h
@@ -50,6 +50,7 @@ public slots:
void reload();
void takeSnapShot();
void toggleRecording();
+ void toggleRecordingWithSelection();
protected:
virtual void keyPressEvent(QKeyEvent *);