summaryrefslogtreecommitdiffstats
path: root/src/plugins/qmltooling
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qmltooling')
-rw-r--r--src/plugins/qmltooling/declarativeobserver/declarativeobserver.pro53
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool.cpp200
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool_p.h121
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter.cpp284
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter_p.h126
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/colorpickertool.cpp131
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/colorpickertool_p.h99
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/editor.qrc24
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-24.pngbin0 -> 3440 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-hicontrast.pngbin0 -> 3192 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/color-picker.pngbin0 -> 3173 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/from-qml-24.pngbin0 -> 3395 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/from-qml.pngbin0 -> 3205 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/observermode-24.pngbin0 -> 1283 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/observermode.pngbin0 -> 3539 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/pause-24.pngbin0 -> 3307 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/pause.pngbin0 -> 3097 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/play-24.pngbin0 -> 3655 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/play.pngbin0 -> 3363 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/reload.pngbin0 -> 3418 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/resize_handle.pngbin0 -> 160 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/select-24.pngbin0 -> 3510 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee-24.pngbin0 -> 2891 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee.pngbin0 -> 2871 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/select.pngbin0 -> 3308 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/to-qml-24.pngbin0 -> 3407 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/to-qml.pngbin0 -> 3227 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/zoom-24.pngbin0 -> 3566 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/images/zoom.pngbin0 -> 3347 bytes
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/livelayeritem.cpp92
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/livelayeritem_p.h73
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator.cpp165
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator_p.h102
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator.cpp148
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator_p.h90
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle.cpp113
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle_p.h83
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool.cpp442
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool_p.h126
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator.cpp151
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator_p.h95
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar.cpp328
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar_p.h138
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool.cpp364
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool_p.h131
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem.cpp124
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem_p.h77
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox.cpp134
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox_p.h87
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp336
-rw-r--r--src/plugins/qmltooling/declarativeobserver/editor/zoomtool_p.h113
-rw-r--r--src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.cpp81
-rw-r--r--src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.h71
-rw-r--r--src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverprotocol.h145
-rw-r--r--src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver.cpp1167
-rw-r--r--src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p.h154
-rw-r--r--src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p_p.h165
-rw-r--r--src/plugins/qmltooling/declarativeobserver/qmlobserverconstants_p.h90
-rw-r--r--src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_ost/qmlostplugin.h1
-rw-r--r--src/plugins/qmltooling/qmldbg_ost/qostdevice.cpp42
-rw-r--r--src/plugins/qmltooling/qmldbg_ost/qostdevice.h4
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp15
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h2
-rw-r--r--src/plugins/qmltooling/qmltooling.pro2
65 files changed, 6490 insertions, 5 deletions
diff --git a/src/plugins/qmltooling/declarativeobserver/declarativeobserver.pro b/src/plugins/qmltooling/declarativeobserver/declarativeobserver.pro
new file mode 100644
index 0000000..bccabcb
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/declarativeobserver.pro
@@ -0,0 +1,53 @@
+TARGET = declarativeobserver
+QT += declarative
+
+include(../../qpluginbase.pri)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/qmltooling
+QTDIR_build:REQUIRES += "contains(QT_CONFIG, declarative)"
+
+SOURCES += \
+ qdeclarativeobserverplugin.cpp \
+ qdeclarativeviewobserver.cpp \
+ editor/abstractliveedittool.cpp \
+ editor/liveselectiontool.cpp \
+ editor/livelayeritem.cpp \
+ editor/livesingleselectionmanipulator.cpp \
+ editor/liverubberbandselectionmanipulator.cpp \
+ editor/liveselectionrectangle.cpp \
+ editor/liveselectionindicator.cpp \
+ editor/boundingrecthighlighter.cpp \
+ editor/subcomponenteditortool.cpp \
+ editor/subcomponentmasklayeritem.cpp \
+ editor/zoomtool.cpp \
+ editor/colorpickertool.cpp \
+ editor/qmltoolbar.cpp \
+ editor/toolbarcolorbox.cpp
+
+HEADERS += \
+ qdeclarativeobserverplugin.h \
+ qdeclarativeobserverprotocol.h \
+ qdeclarativeviewobserver_p.h \
+ qdeclarativeviewobserver_p_p.h \
+ qmlobserverconstants_p.h \
+ editor/abstractliveedittool_p.h \
+ editor/liveselectiontool_p.h \
+ editor/livelayeritem_p.h \
+ editor/livesingleselectionmanipulator_p.h \
+ editor/liverubberbandselectionmanipulator_p.h \
+ editor/liveselectionrectangle_p.h \
+ editor/liveselectionindicator_p.h \
+ editor/boundingrecthighlighter_p.h \
+ editor/subcomponenteditortool_p.h \
+ editor/subcomponentmasklayeritem_p.h \
+ editor/zoomtool_p.h \
+ editor/colorpickertool_p.h \
+ editor/qmltoolbar_p.h \
+ editor/toolbarcolorbox_p.h
+
+RESOURCES += editor/editor.qrc
+
+target.path += $$[QT_INSTALL_PLUGINS]/qmltooling
+INSTALLS += target
+
+symbian:TARGET.UID3=0x20031E90
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool.cpp
new file mode 100644
index 0000000..b3ed22e
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractliveedittool_p.h"
+#include "../qdeclarativeviewobserver_p_p.h"
+
+#include <QDeclarativeEngine>
+
+#include <QtDebug>
+#include <QGraphicsItem>
+#include <QDeclarativeItem>
+
+QT_BEGIN_NAMESPACE
+
+AbstractLiveEditTool::AbstractLiveEditTool(QDeclarativeViewObserver *editorView)
+ : QObject(editorView), m_observer(editorView)
+{
+}
+
+
+AbstractLiveEditTool::~AbstractLiveEditTool()
+{
+}
+
+QDeclarativeViewObserver *AbstractLiveEditTool::observer() const
+{
+ return m_observer;
+}
+
+QDeclarativeView *AbstractLiveEditTool::view() const
+{
+ return m_observer->declarativeView();
+}
+
+QGraphicsScene* AbstractLiveEditTool::scene() const
+{
+ return view()->scene();
+}
+
+void AbstractLiveEditTool::updateSelectedItems()
+{
+ selectedItemsChanged(items());
+}
+
+QList<QGraphicsItem*> AbstractLiveEditTool::items() const
+{
+ return observer()->selectedItems();
+}
+
+void AbstractLiveEditTool::enterContext(QGraphicsItem *itemToEnter)
+{
+ observer()->data->enterContext(itemToEnter);
+}
+
+bool AbstractLiveEditTool::topItemIsMovable(const QList<QGraphicsItem*> & itemList)
+{
+ QGraphicsItem *firstSelectableItem = topMovableGraphicsItem(itemList);
+ if (firstSelectableItem == 0)
+ return false;
+ if (toQDeclarativeItem(firstSelectableItem) != 0)
+ return true;
+
+ return false;
+
+}
+
+bool AbstractLiveEditTool::topSelectedItemIsMovable(const QList<QGraphicsItem*> &itemList)
+{
+ QList<QGraphicsItem*> selectedItems = observer()->selectedItems();
+
+ foreach (QGraphicsItem *item, itemList) {
+ QDeclarativeItem *declarativeItem = toQDeclarativeItem(item);
+ if (declarativeItem
+ && selectedItems.contains(declarativeItem)
+ /*&& (declarativeItem->qmlItemNode().hasShowContent() || selectNonContentItems)*/)
+ return true;
+ }
+
+ return false;
+
+}
+
+bool AbstractLiveEditTool::topItemIsResizeHandle(const QList<QGraphicsItem*> &/*itemList*/)
+{
+ return false;
+}
+
+QDeclarativeItem *AbstractLiveEditTool::toQDeclarativeItem(QGraphicsItem *item)
+{
+ return qobject_cast<QDeclarativeItem*>(item->toGraphicsObject());
+}
+
+QGraphicsItem *AbstractLiveEditTool::topMovableGraphicsItem(const QList<QGraphicsItem*> &itemList)
+{
+ foreach (QGraphicsItem *item, itemList) {
+ if (item->flags().testFlag(QGraphicsItem::ItemIsMovable))
+ return item;
+ }
+ return 0;
+}
+
+QDeclarativeItem *AbstractLiveEditTool::topMovableDeclarativeItem(const QList<QGraphicsItem*>
+ &itemList)
+{
+ foreach (QGraphicsItem *item, itemList) {
+ QDeclarativeItem *declarativeItem = toQDeclarativeItem(item);
+ if (declarativeItem /*&& (declarativeItem->qmlItemNode().hasShowContent())*/)
+ return declarativeItem;
+ }
+
+ return 0;
+}
+
+QList<QGraphicsObject*> AbstractLiveEditTool::toGraphicsObjectList(const QList<QGraphicsItem*>
+ &itemList)
+{
+ QList<QGraphicsObject*> gfxObjects;
+ foreach (QGraphicsItem *item, itemList) {
+ QGraphicsObject *obj = item->toGraphicsObject();
+ if (obj)
+ gfxObjects << obj;
+ }
+
+ return gfxObjects;
+}
+
+QString AbstractLiveEditTool::titleForItem(QGraphicsItem *item)
+{
+ QString className(QLatin1String("QGraphicsItem"));
+ QString objectStringId;
+
+ QString constructedName;
+
+ QGraphicsObject *gfxObject = item->toGraphicsObject();
+ if (gfxObject) {
+ className = QLatin1String(gfxObject->metaObject()->className());
+
+ className.remove(QRegExp(QLatin1String("_QMLTYPE_\\d+")));
+ className.remove(QRegExp(QLatin1String("_QML_\\d+")));
+ if (className.startsWith(QLatin1String("QDeclarative")))
+ className = className.remove(QLatin1String("QDeclarative"));
+
+ QDeclarativeItem *declarativeItem = qobject_cast<QDeclarativeItem*>(gfxObject);
+ if (declarativeItem) {
+ objectStringId = m_observer->idStringForObject(declarativeItem);
+ }
+
+ if (!objectStringId.isEmpty()) {
+ constructedName = objectStringId + QLatin1String(" (") + className + QLatin1Char(')');
+ } else {
+ if (!gfxObject->objectName().isEmpty()) {
+ constructedName = gfxObject->objectName() + QLatin1String(" (") + className + QLatin1Char(')');
+ } else {
+ constructedName = className;
+ }
+ }
+ }
+
+ return constructedName;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool_p.h b/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool_p.h
new file mode 100644
index 0000000..1dbc323
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTLIVEEDITTOOL_H
+#define ABSTRACTLIVEEDITTOOL_H
+
+#include <QtCore/QList>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+class QMouseEvent;
+class QGraphicsItem;
+class QDeclarativeItem;
+class QKeyEvent;
+class QGraphicsScene;
+class QGraphicsObject;
+class QWheelEvent;
+class QDeclarativeView;
+QT_END_NAMESPACE
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeViewObserver;
+
+class AbstractLiveEditTool : public QObject
+{
+ Q_OBJECT
+public:
+ AbstractLiveEditTool(QDeclarativeViewObserver *observer);
+
+ virtual ~AbstractLiveEditTool();
+
+ virtual void mousePressEvent(QMouseEvent *event) = 0;
+ virtual void mouseMoveEvent(QMouseEvent *event) = 0;
+ virtual void mouseReleaseEvent(QMouseEvent *event) = 0;
+ virtual void mouseDoubleClickEvent(QMouseEvent *event) = 0;
+
+ virtual void hoverMoveEvent(QMouseEvent *event) = 0;
+ virtual void wheelEvent(QWheelEvent *event) = 0;
+
+ virtual void keyPressEvent(QKeyEvent *event) = 0;
+ virtual void keyReleaseEvent(QKeyEvent *keyEvent) = 0;
+ virtual void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList) = 0;
+
+ virtual void clear() = 0;
+
+ void updateSelectedItems();
+ QList<QGraphicsItem*> items() const;
+
+ void enterContext(QGraphicsItem *itemToEnter);
+
+ bool topItemIsMovable(const QList<QGraphicsItem*> &itemList);
+ bool topItemIsResizeHandle(const QList<QGraphicsItem*> &itemList);
+ bool topSelectedItemIsMovable(const QList<QGraphicsItem*> &itemList);
+
+ QString titleForItem(QGraphicsItem *item);
+
+ static QList<QGraphicsObject*> toGraphicsObjectList(const QList<QGraphicsItem*> &itemList);
+ static QGraphicsItem* topMovableGraphicsItem(const QList<QGraphicsItem*> &itemList);
+ static QDeclarativeItem* topMovableDeclarativeItem(const QList<QGraphicsItem*> &itemList);
+ static QDeclarativeItem *toQDeclarativeItem(QGraphicsItem *item);
+
+protected:
+ virtual void selectedItemsChanged(const QList<QGraphicsItem*> &objectList) = 0;
+
+ QDeclarativeViewObserver *observer() const;
+ QDeclarativeView *view() const;
+ QGraphicsScene *scene() const;
+
+private:
+ QDeclarativeViewObserver *m_observer;
+ QList<QGraphicsItem*> m_itemList;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTLIVEEDITTOOL_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter.cpp b/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter.cpp
new file mode 100644
index 0000000..98dbc4f
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter.cpp
@@ -0,0 +1,284 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "boundingrecthighlighter_p.h"
+
+#include "../qdeclarativeviewobserver_p.h"
+#include "../qmlobserverconstants_p.h"
+
+#include <QtGui/QGraphicsPolygonItem>
+
+#include <QtCore/QTimer>
+#include <QtCore/QObject>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+const qreal AnimDelta = 0.025f;
+const int AnimInterval = 30;
+const int AnimFrames = 10;
+
+BoundingBox::BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parentItem,
+ QObject *parent)
+ : QObject(parent),
+ highlightedObject(itemToHighlight),
+ highlightPolygon(0),
+ highlightPolygonEdge(0)
+{
+ highlightPolygon = new BoundingBoxPolygonItem(parentItem);
+ highlightPolygonEdge = new BoundingBoxPolygonItem(parentItem);
+
+ highlightPolygon->setPen(QPen(QColor(0, 22, 159)));
+ highlightPolygonEdge->setPen(QPen(QColor(158, 199, 255)));
+
+ highlightPolygon->setFlag(QGraphicsItem::ItemIsSelectable, false);
+ highlightPolygonEdge->setFlag(QGraphicsItem::ItemIsSelectable, false);
+}
+
+BoundingBox::~BoundingBox()
+{
+ highlightedObject.clear();
+}
+
+BoundingBoxPolygonItem::BoundingBoxPolygonItem(QGraphicsItem *item) : QGraphicsPolygonItem(item)
+{
+ QPen pen;
+ pen.setColor(QColor(108, 141, 221));
+ pen.setWidth(1);
+ setPen(pen);
+}
+
+int BoundingBoxPolygonItem::type() const
+{
+ return Constants::EditorItemType;
+}
+
+BoundingRectHighlighter::BoundingRectHighlighter(QDeclarativeViewObserver *view) :
+ LiveLayerItem(view->declarativeView()->scene()),
+ m_view(view),
+ m_animFrame(0)
+{
+ m_animTimer = new QTimer(this);
+ m_animTimer->setInterval(AnimInterval);
+ connect(m_animTimer, SIGNAL(timeout()), SLOT(animTimeout()));
+}
+
+BoundingRectHighlighter::~BoundingRectHighlighter()
+{
+
+}
+
+void BoundingRectHighlighter::animTimeout()
+{
+ ++m_animFrame;
+ if (m_animFrame == AnimFrames) {
+ m_animTimer->stop();
+ }
+
+ qreal alpha = m_animFrame / float(AnimFrames);
+
+ foreach (BoundingBox *box, m_boxes) {
+ box->highlightPolygonEdge->setOpacity(alpha);
+ }
+}
+
+void BoundingRectHighlighter::clear()
+{
+ if (m_boxes.length()) {
+ m_animTimer->stop();
+
+ foreach (BoundingBox *box, m_boxes) {
+ freeBoundingBox(box);
+ }
+ }
+}
+
+BoundingBox *BoundingRectHighlighter::boxFor(QGraphicsObject *item) const
+{
+ foreach (BoundingBox *box, m_boxes) {
+ if (box->highlightedObject.data() == item) {
+ return box;
+ }
+ }
+ return 0;
+}
+
+void BoundingRectHighlighter::highlight(QList<QGraphicsObject*> items)
+{
+ if (items.isEmpty())
+ return;
+
+ bool animate = false;
+
+ QList<BoundingBox *> newBoxes;
+ foreach (QGraphicsObject *itemToHighlight, items) {
+ BoundingBox *box = boxFor(itemToHighlight);
+ if (!box) {
+ box = createBoundingBox(itemToHighlight);
+ animate = true;
+ }
+
+ newBoxes << box;
+ }
+ qSort(newBoxes);
+
+ if (newBoxes != m_boxes) {
+ clear();
+ m_boxes << newBoxes;
+ }
+
+ highlightAll(animate);
+}
+
+void BoundingRectHighlighter::highlight(QGraphicsObject* itemToHighlight)
+{
+ if (!itemToHighlight)
+ return;
+
+ bool animate = false;
+
+ BoundingBox *box = boxFor(itemToHighlight);
+ if (!box) {
+ box = createBoundingBox(itemToHighlight);
+ m_boxes << box;
+ animate = true;
+ qSort(m_boxes);
+ }
+
+ highlightAll(animate);
+}
+
+BoundingBox *BoundingRectHighlighter::createBoundingBox(QGraphicsObject *itemToHighlight)
+{
+ if (!m_freeBoxes.isEmpty()) {
+ BoundingBox *box = m_freeBoxes.last();
+ if (box->highlightedObject.isNull()) {
+ box->highlightedObject = itemToHighlight;
+ box->highlightPolygon->show();
+ box->highlightPolygonEdge->show();
+ m_freeBoxes.removeLast();
+ return box;
+ }
+ }
+
+ BoundingBox *box = new BoundingBox(itemToHighlight, this, this);
+
+ connect(itemToHighlight, SIGNAL(xChanged()), this, SLOT(refresh()));
+ connect(itemToHighlight, SIGNAL(yChanged()), this, SLOT(refresh()));
+ connect(itemToHighlight, SIGNAL(widthChanged()), this, SLOT(refresh()));
+ connect(itemToHighlight, SIGNAL(heightChanged()), this, SLOT(refresh()));
+ connect(itemToHighlight, SIGNAL(rotationChanged()), this, SLOT(refresh()));
+ connect(itemToHighlight, SIGNAL(destroyed(QObject*)), this, SLOT(itemDestroyed(QObject*)));
+
+ return box;
+}
+
+void BoundingRectHighlighter::removeBoundingBox(BoundingBox *box)
+{
+ delete box;
+ box = 0;
+}
+
+void BoundingRectHighlighter::freeBoundingBox(BoundingBox *box)
+{
+ if (!box->highlightedObject.isNull()) {
+ disconnect(box->highlightedObject.data(), SIGNAL(xChanged()), this, SLOT(refresh()));
+ disconnect(box->highlightedObject.data(), SIGNAL(yChanged()), this, SLOT(refresh()));
+ disconnect(box->highlightedObject.data(), SIGNAL(widthChanged()), this, SLOT(refresh()));
+ disconnect(box->highlightedObject.data(), SIGNAL(heightChanged()), this, SLOT(refresh()));
+ disconnect(box->highlightedObject.data(), SIGNAL(rotationChanged()), this, SLOT(refresh()));
+ }
+
+ box->highlightedObject.clear();
+ box->highlightPolygon->hide();
+ box->highlightPolygonEdge->hide();
+ m_boxes.removeOne(box);
+ m_freeBoxes << box;
+}
+
+void BoundingRectHighlighter::itemDestroyed(QObject *obj)
+{
+ foreach (BoundingBox *box, m_boxes) {
+ if (box->highlightedObject.data() == obj) {
+ freeBoundingBox(box);
+ break;
+ }
+ }
+}
+
+void BoundingRectHighlighter::highlightAll(bool animate)
+{
+ foreach (BoundingBox *box, m_boxes) {
+ if (box && box->highlightedObject.isNull()) {
+ // clear all highlights
+ clear();
+ return;
+ }
+ QGraphicsObject *item = box->highlightedObject.data();
+ QRectF itemAndChildRect = item->boundingRect() | item->childrenBoundingRect();
+
+ QPolygonF boundingRectInSceneSpace(item->mapToScene(itemAndChildRect));
+ QPolygonF boundingRectInLayerItemSpace = mapFromScene(boundingRectInSceneSpace);
+ QRectF bboxRect
+ = m_view->adjustToScreenBoundaries(boundingRectInLayerItemSpace.boundingRect());
+ QRectF edgeRect = bboxRect;
+ edgeRect.adjust(-1, -1, 1, 1);
+
+ box->highlightPolygon->setPolygon(QPolygonF(bboxRect));
+ box->highlightPolygonEdge->setPolygon(QPolygonF(edgeRect));
+
+ if (animate)
+ box->highlightPolygonEdge->setOpacity(0);
+ }
+
+ if (animate) {
+ m_animFrame = 0;
+ m_animTimer->start();
+ }
+}
+
+void BoundingRectHighlighter::refresh()
+{
+ if (!m_boxes.isEmpty())
+ highlightAll(true);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter_p.h b/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter_p.h
new file mode 100644
index 0000000..c1beed8
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BOUNDINGRECTHIGHLIGHTER_H
+#define BOUNDINGRECTHIGHLIGHTER_H
+
+#include "livelayeritem_p.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QWeakPointer>
+
+QT_FORWARD_DECLARE_CLASS(QGraphicsItem)
+QT_FORWARD_DECLARE_CLASS(QPainter)
+QT_FORWARD_DECLARE_CLASS(QWidget)
+QT_FORWARD_DECLARE_CLASS(QStyleOptionGraphicsItem)
+QT_FORWARD_DECLARE_CLASS(QTimer)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeViewObserver;
+class BoundingBox;
+
+class BoundingRectHighlighter : public LiveLayerItem
+{
+ Q_OBJECT
+public:
+ explicit BoundingRectHighlighter(QDeclarativeViewObserver *view);
+ ~BoundingRectHighlighter();
+ void clear();
+ void highlight(QList<QGraphicsObject*> items);
+ void highlight(QGraphicsObject* item);
+
+private slots:
+ void refresh();
+ void animTimeout();
+ void itemDestroyed(QObject *);
+
+private:
+ BoundingBox *boxFor(QGraphicsObject *item) const;
+ void highlightAll(bool animate);
+ BoundingBox *createBoundingBox(QGraphicsObject *itemToHighlight);
+ void removeBoundingBox(BoundingBox *box);
+ void freeBoundingBox(BoundingBox *box);
+
+private:
+ Q_DISABLE_COPY(BoundingRectHighlighter)
+
+ QDeclarativeViewObserver *m_view;
+ QList<BoundingBox* > m_boxes;
+ QList<BoundingBox* > m_freeBoxes;
+ QTimer *m_animTimer;
+ qreal m_animScale;
+ int m_animFrame;
+
+};
+
+class BoundingBox : public QObject
+{
+ Q_OBJECT
+public:
+ explicit BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parentItem,
+ QObject *parent = 0);
+ ~BoundingBox();
+ QWeakPointer<QGraphicsObject> highlightedObject;
+ QGraphicsPolygonItem *highlightPolygon;
+ QGraphicsPolygonItem *highlightPolygonEdge;
+
+private:
+ Q_DISABLE_COPY(BoundingBox)
+
+};
+
+class BoundingBoxPolygonItem : public QGraphicsPolygonItem
+{
+public:
+ explicit BoundingBoxPolygonItem(QGraphicsItem *item);
+ int type() const;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // BOUNDINGRECTHIGHLIGHTER_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool.cpp
new file mode 100644
index 0000000..a71e408
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "colorpickertool_p.h"
+
+#include "../qdeclarativeviewobserver_p.h"
+
+#include <QtGui/QMouseEvent>
+#include <QtGui/QKeyEvent>
+#include <QtCore/QRectF>
+#include <QtGui/QRgb>
+#include <QtGui/QImage>
+#include <QtGui/QApplication>
+#include <QtGui/QPalette>
+
+QT_BEGIN_NAMESPACE
+
+ColorPickerTool::ColorPickerTool(QDeclarativeViewObserver *view) :
+ AbstractLiveEditTool(view)
+{
+ m_selectedColor.setRgb(0,0,0);
+}
+
+ColorPickerTool::~ColorPickerTool()
+{
+
+}
+
+void ColorPickerTool::mousePressEvent(QMouseEvent * /*event*/)
+{
+}
+
+void ColorPickerTool::mouseMoveEvent(QMouseEvent *event)
+{
+ pickColor(event->pos());
+}
+
+void ColorPickerTool::mouseReleaseEvent(QMouseEvent *event)
+{
+ pickColor(event->pos());
+}
+
+void ColorPickerTool::mouseDoubleClickEvent(QMouseEvent * /*event*/)
+{
+}
+
+
+void ColorPickerTool::hoverMoveEvent(QMouseEvent * /*event*/)
+{
+}
+
+void ColorPickerTool::keyPressEvent(QKeyEvent * /*event*/)
+{
+}
+
+void ColorPickerTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/)
+{
+}
+void ColorPickerTool::wheelEvent(QWheelEvent * /*event*/)
+{
+}
+
+void ColorPickerTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
+{
+}
+
+void ColorPickerTool::clear()
+{
+ view()->setCursor(Qt::CrossCursor);
+}
+
+void ColorPickerTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/)
+{
+}
+
+void ColorPickerTool::pickColor(const QPoint &pos)
+{
+ QRgb fillColor = view()->backgroundBrush().color().rgb();
+ if (view()->backgroundBrush().style() == Qt::NoBrush)
+ fillColor = view()->palette().color(QPalette::Base).rgb();
+
+ QRectF target(0,0, 1, 1);
+ QRect source(pos.x(), pos.y(), 1, 1);
+ QImage img(1, 1, QImage::Format_ARGB32);
+ img.fill(fillColor);
+ QPainter painter(&img);
+ view()->render(&painter, target, source);
+ m_selectedColor = QColor::fromRgb(img.pixel(0, 0));
+
+ emit selectedColorChanged(m_selectedColor);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool_p.h b/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool_p.h
new file mode 100644
index 0000000..86a8893
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COLORPICKERTOOL_H
+#define COLORPICKERTOOL_H
+
+#include "abstractliveedittool_p.h"
+
+#include <QtGui/QColor>
+
+QT_FORWARD_DECLARE_CLASS(QPoint)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class ColorPickerTool : public AbstractLiveEditTool
+{
+ Q_OBJECT
+public:
+ explicit ColorPickerTool(QDeclarativeViewObserver *view);
+
+ virtual ~ColorPickerTool();
+
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+
+ void hoverMoveEvent(QMouseEvent *event);
+
+ void keyPressEvent(QKeyEvent *event);
+ void keyReleaseEvent(QKeyEvent *keyEvent);
+
+ void wheelEvent(QWheelEvent *event);
+
+ void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList);
+
+ void clear();
+
+signals:
+ void selectedColorChanged(const QColor &color);
+
+protected:
+
+ void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
+
+private:
+ void pickColor(const QPoint &pos);
+
+private:
+ QColor m_selectedColor;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // COLORPICKERTOOL_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/editor.qrc b/src/plugins/qmltooling/declarativeobserver/editor/editor.qrc
new file mode 100644
index 0000000..77744d5
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/editor.qrc
@@ -0,0 +1,24 @@
+<RCC>
+ <qresource prefix="/qml">
+ <file>images/resize_handle.png</file>
+ <file>images/select.png</file>
+ <file>images/select-marquee.png</file>
+ <file>images/color-picker.png</file>
+ <file>images/play.png</file>
+ <file>images/pause.png</file>
+ <file>images/from-qml.png</file>
+ <file>images/to-qml.png</file>
+ <file>images/color-picker-hicontrast.png</file>
+ <file>images/zoom.png</file>
+ <file>images/color-picker-24.png</file>
+ <file>images/from-qml-24.png</file>
+ <file>images/pause-24.png</file>
+ <file>images/play-24.png</file>
+ <file>images/to-qml-24.png</file>
+ <file>images/zoom-24.png</file>
+ <file>images/select-24.png</file>
+ <file>images/select-marquee-24.png</file>
+ <file>images/observermode.png</file>
+ <file>images/observermode-24.png</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-24.png
new file mode 100644
index 0000000..cff4721
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-24.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-hicontrast.png b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-hicontrast.png
new file mode 100644
index 0000000..b953d08
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-hicontrast.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker.png b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker.png
new file mode 100644
index 0000000..026c31b
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml-24.png
new file mode 100644
index 0000000..0ad21f3
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml-24.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml.png b/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml.png
new file mode 100644
index 0000000..666382c
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/observermode-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/observermode-24.png
new file mode 100644
index 0000000..5e74d86
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/observermode-24.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/observermode.png b/src/plugins/qmltooling/declarativeobserver/editor/images/observermode.png
new file mode 100644
index 0000000..daed21c
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/observermode.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/pause-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/pause-24.png
new file mode 100644
index 0000000..d9a2f6f
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/pause-24.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/pause.png b/src/plugins/qmltooling/declarativeobserver/editor/images/pause.png
new file mode 100644
index 0000000..114d89b
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/pause.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/play-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/play-24.png
new file mode 100644
index 0000000..e2b9fbc
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/play-24.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/play.png b/src/plugins/qmltooling/declarativeobserver/editor/images/play.png
new file mode 100644
index 0000000..011598a
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/play.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/reload.png b/src/plugins/qmltooling/declarativeobserver/editor/images/reload.png
new file mode 100644
index 0000000..7042bec
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/reload.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/resize_handle.png b/src/plugins/qmltooling/declarativeobserver/editor/images/resize_handle.png
new file mode 100644
index 0000000..2934f25
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/resize_handle.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/select-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/select-24.png
new file mode 100644
index 0000000..5388a9d
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/select-24.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee-24.png
new file mode 100644
index 0000000..0111dda
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee-24.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee.png b/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee.png
new file mode 100644
index 0000000..92fe40d
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/select.png b/src/plugins/qmltooling/declarativeobserver/editor/images/select.png
new file mode 100644
index 0000000..6722855
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/select.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml-24.png
new file mode 100644
index 0000000..b72450d
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml-24.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml.png b/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml.png
new file mode 100644
index 0000000..2ab951f
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/zoom-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/zoom-24.png
new file mode 100644
index 0000000..0346200
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/zoom-24.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/zoom.png b/src/plugins/qmltooling/declarativeobserver/editor/images/zoom.png
new file mode 100644
index 0000000..17f0da6
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/images/zoom.png
Binary files differ
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem.cpp b/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem.cpp
new file mode 100644
index 0000000..7b508a4
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "livelayeritem_p.h"
+
+#include "../qmlobserverconstants_p.h"
+
+#include <QGraphicsScene>
+
+QT_BEGIN_NAMESPACE
+
+LiveLayerItem::LiveLayerItem(QGraphicsScene* scene)
+ : QGraphicsObject()
+{
+ scene->addItem(this);
+ setZValue(1);
+ setFlag(QGraphicsItem::ItemIsMovable, false);
+}
+
+LiveLayerItem::~LiveLayerItem()
+{
+}
+
+void LiveLayerItem::paint(QPainter * /*painter*/, const QStyleOptionGraphicsItem * /*option*/,
+ QWidget * /*widget*/)
+{
+}
+
+int LiveLayerItem::type() const
+{
+ return Constants::EditorItemType;
+}
+
+QRectF LiveLayerItem::boundingRect() const
+{
+ return childrenBoundingRect();
+}
+
+QList<QGraphicsItem*> LiveLayerItem::findAllChildItems() const
+{
+ return findAllChildItems(this);
+}
+
+QList<QGraphicsItem*> LiveLayerItem::findAllChildItems(const QGraphicsItem *item) const
+{
+ QList<QGraphicsItem*> itemList(item->childItems());
+
+ foreach (QGraphicsItem *childItem, item->childItems())
+ itemList += findAllChildItems(childItem);
+
+ return itemList;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem_p.h b/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem_p.h
new file mode 100644
index 0000000..242e365
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LIVELAYERITEM_H
+#define LIVELAYERITEM_H
+
+#include <QtGui/QGraphicsObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class LiveLayerItem : public QGraphicsObject
+{
+public:
+ LiveLayerItem(QGraphicsScene *scene);
+ ~LiveLayerItem();
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget = 0);
+ QRectF boundingRect() const;
+ int type() const;
+
+ QList<QGraphicsItem*> findAllChildItems() const;
+
+protected:
+ QList<QGraphicsItem*> findAllChildItems(const QGraphicsItem *item) const;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // LIVELAYERITEM_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator.cpp b/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator.cpp
new file mode 100644
index 0000000..6c37ba5
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "liverubberbandselectionmanipulator_p.h"
+
+#include "../qdeclarativeviewobserver_p_p.h"
+
+#include <QtGui/QGraphicsItem>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+LiveRubberBandSelectionManipulator::LiveRubberBandSelectionManipulator(QGraphicsObject *layerItem,
+ QDeclarativeViewObserver *editorView)
+ : m_selectionRectangleElement(layerItem),
+ m_editorView(editorView),
+ m_beginFormEditorItem(0),
+ m_isActive(false)
+{
+ m_selectionRectangleElement.hide();
+}
+
+void LiveRubberBandSelectionManipulator::clear()
+{
+ m_selectionRectangleElement.clear();
+ m_isActive = false;
+ m_beginPoint = QPointF();
+ m_itemList.clear();
+ m_oldSelectionList.clear();
+}
+
+QGraphicsItem *LiveRubberBandSelectionManipulator::topFormEditorItem(const QList<QGraphicsItem*>
+ &itemList)
+{
+ if (itemList.isEmpty())
+ return 0;
+
+ return itemList.first();
+}
+
+void LiveRubberBandSelectionManipulator::begin(const QPointF &beginPoint)
+{
+ m_beginPoint = beginPoint;
+ m_selectionRectangleElement.setRect(m_beginPoint, m_beginPoint);
+ m_selectionRectangleElement.show();
+ m_isActive = true;
+ QDeclarativeViewObserverPrivate *observerPrivate
+ = QDeclarativeViewObserverPrivate::get(m_editorView);
+ m_beginFormEditorItem = topFormEditorItem(observerPrivate->selectableItems(beginPoint));
+ m_oldSelectionList = m_editorView->selectedItems();
+}
+
+void LiveRubberBandSelectionManipulator::update(const QPointF &updatePoint)
+{
+ m_selectionRectangleElement.setRect(m_beginPoint, updatePoint);
+}
+
+void LiveRubberBandSelectionManipulator::end()
+{
+ m_oldSelectionList.clear();
+ m_selectionRectangleElement.hide();
+ m_isActive = false;
+}
+
+void LiveRubberBandSelectionManipulator::select(SelectionType selectionType)
+{
+ QDeclarativeViewObserverPrivate *observerPrivate
+ = QDeclarativeViewObserverPrivate::get(m_editorView);
+ QList<QGraphicsItem*> itemList
+ = observerPrivate->selectableItems(m_selectionRectangleElement.rect(),
+ Qt::IntersectsItemShape);
+ QList<QGraphicsItem*> newSelectionList;
+
+ foreach (QGraphicsItem* item, itemList) {
+ if (item
+ && item->parentItem()
+ && !newSelectionList.contains(item)
+ //&& m_beginFormEditorItem->childItems().contains(item) // TODO activate this test
+ )
+ {
+ newSelectionList.append(item);
+ }
+ }
+
+ if (newSelectionList.isEmpty() && m_beginFormEditorItem)
+ newSelectionList.append(m_beginFormEditorItem);
+
+ QList<QGraphicsItem*> resultList;
+
+ switch (selectionType) {
+ case AddToSelection: {
+ resultList.append(m_oldSelectionList);
+ resultList.append(newSelectionList);
+ }
+ break;
+ case ReplaceSelection: {
+ resultList.append(newSelectionList);
+ }
+ break;
+ case RemoveFromSelection: {
+ QSet<QGraphicsItem*> oldSelectionSet(m_oldSelectionList.toSet());
+ QSet<QGraphicsItem*> newSelectionSet(newSelectionList.toSet());
+ resultList.append(oldSelectionSet.subtract(newSelectionSet).toList());
+ }
+ }
+
+ m_editorView->setSelectedItems(resultList);
+}
+
+
+void LiveRubberBandSelectionManipulator::setItems(const QList<QGraphicsItem*> &itemList)
+{
+ m_itemList = itemList;
+}
+
+QPointF LiveRubberBandSelectionManipulator::beginPoint() const
+{
+ return m_beginPoint;
+}
+
+bool LiveRubberBandSelectionManipulator::isActive() const
+{
+ return m_isActive;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator_p.h b/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator_p.h
new file mode 100644
index 0000000..8d15288
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RUBBERBANDSELECTIONMANIPULATOR_H
+#define RUBBERBANDSELECTIONMANIPULATOR_H
+
+#include "liveselectionrectangle_p.h"
+
+#include <QtCore/QPointF>
+
+QT_FORWARD_DECLARE_CLASS(QGraphicsItem)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeViewObserver;
+
+class LiveRubberBandSelectionManipulator
+{
+public:
+ enum SelectionType {
+ ReplaceSelection,
+ AddToSelection,
+ RemoveFromSelection
+ };
+
+ LiveRubberBandSelectionManipulator(QGraphicsObject *layerItem,
+ QDeclarativeViewObserver *editorView);
+
+ void setItems(const QList<QGraphicsItem*> &itemList);
+
+ void begin(const QPointF& beginPoint);
+ void update(const QPointF& updatePoint);
+ void end();
+
+ void clear();
+
+ void select(SelectionType selectionType);
+
+ QPointF beginPoint() const;
+
+ bool isActive() const;
+
+protected:
+ QGraphicsItem *topFormEditorItem(const QList<QGraphicsItem*> &itemList);
+
+private:
+ QList<QGraphicsItem*> m_itemList;
+ QList<QGraphicsItem*> m_oldSelectionList;
+ LiveSelectionRectangle m_selectionRectangleElement;
+ QPointF m_beginPoint;
+ QDeclarativeViewObserver *m_editorView;
+ QGraphicsItem *m_beginFormEditorItem;
+ bool m_isActive;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // RUBBERBANDSELECTIONMANIPULATOR_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator.cpp b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator.cpp
new file mode 100644
index 0000000..96e9dbf
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "liveselectionindicator_p.h"
+
+#include "../qdeclarativeviewobserver_p_p.h"
+#include "../qmlobserverconstants_p.h"
+
+#include <QtCore/QDebug>
+
+#include <QtGui/QGraphicsPolygonItem>
+#include <QtGui/QGraphicsObject>
+#include <QtGui/QGraphicsScene>
+#include <QtGui/QPen>
+
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+LiveSelectionIndicator::LiveSelectionIndicator(QDeclarativeViewObserver *editorView,
+ QGraphicsObject *layerItem)
+ : m_layerItem(layerItem), m_view(editorView)
+{
+}
+
+LiveSelectionIndicator::~LiveSelectionIndicator()
+{
+ clear();
+}
+
+void LiveSelectionIndicator::show()
+{
+ foreach (QGraphicsPolygonItem *item, m_indicatorShapeHash.values())
+ item->show();
+}
+
+void LiveSelectionIndicator::hide()
+{
+ foreach (QGraphicsPolygonItem *item, m_indicatorShapeHash.values())
+ item->hide();
+}
+
+void LiveSelectionIndicator::clear()
+{
+ if (!m_layerItem.isNull()) {
+ QHashIterator<QGraphicsItem*, QGraphicsPolygonItem *> iter(m_indicatorShapeHash);
+ while (iter.hasNext()) {
+ iter.next();
+ m_layerItem.data()->scene()->removeItem(iter.value());
+ delete iter.value();
+ }
+ }
+
+ m_indicatorShapeHash.clear();
+
+}
+
+QPolygonF LiveSelectionIndicator::addBoundingRectToPolygon(QGraphicsItem *item, QPolygonF &polygon)
+{
+ // ### remove this if statement when QTBUG-12172 gets fixed
+ if (item->boundingRect() != QRectF(0,0,0,0)) {
+ QPolygonF bounding = item->mapToScene(item->boundingRect());
+ if (bounding.isClosed()) //avoid crashes if there is an infinite scale.
+ polygon = polygon.united(bounding);
+ }
+
+ foreach (QGraphicsItem *child, item->childItems()) {
+ if (!QDeclarativeViewObserverPrivate::get(m_view)->isEditorItem(child))
+ addBoundingRectToPolygon(child, polygon);
+ }
+ return polygon;
+}
+
+void LiveSelectionIndicator::setItems(const QList<QWeakPointer<QGraphicsObject> > &itemList)
+{
+ clear();
+
+ // set selections to also all children if they are not editor items
+
+ foreach (const QWeakPointer<QGraphicsObject> &object, itemList) {
+ if (object.isNull())
+ continue;
+
+ QGraphicsItem *item = object.data();
+
+ QGraphicsPolygonItem *newSelectionIndicatorGraphicsItem
+ = new QGraphicsPolygonItem(m_layerItem.data());
+ if (!m_indicatorShapeHash.contains(item)) {
+ m_indicatorShapeHash.insert(item, newSelectionIndicatorGraphicsItem);
+
+ QPolygonF boundingShapeInSceneSpace;
+ addBoundingRectToPolygon(item, boundingShapeInSceneSpace);
+
+ QRectF boundingRect
+ = m_view->adjustToScreenBoundaries(boundingShapeInSceneSpace.boundingRect());
+ QPolygonF boundingRectInLayerItemSpace = m_layerItem.data()->mapFromScene(boundingRect);
+
+ QPen pen;
+ pen.setColor(QColor(108, 141, 221));
+ newSelectionIndicatorGraphicsItem->setData(Constants::EditorItemDataKey,
+ QVariant(true));
+ newSelectionIndicatorGraphicsItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
+ newSelectionIndicatorGraphicsItem->setPolygon(boundingRectInLayerItemSpace);
+ newSelectionIndicatorGraphicsItem->setPen(pen);
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator_p.h b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator_p.h
new file mode 100644
index 0000000..da95955
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LIVESELECTIONINDICATOR_H
+#define LIVESELECTIONINDICATOR_H
+
+#include <QtCore/QWeakPointer>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+class QGraphicsObject;
+class QGraphicsPolygonItem;
+class QGraphicsItem;
+class QPolygonF;
+QT_END_NAMESPACE
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeViewObserver;
+
+class LiveSelectionIndicator
+{
+public:
+ LiveSelectionIndicator(QDeclarativeViewObserver* editorView, QGraphicsObject *layerItem);
+ ~LiveSelectionIndicator();
+
+ void show();
+ void hide();
+
+ void clear();
+
+ void setItems(const QList<QWeakPointer<QGraphicsObject> > &itemList);
+
+private:
+ QPolygonF addBoundingRectToPolygon(QGraphicsItem *item, QPolygonF &polygon);
+
+private:
+ QHash<QGraphicsItem*, QGraphicsPolygonItem *> m_indicatorShapeHash;
+ QWeakPointer<QGraphicsObject> m_layerItem;
+ QDeclarativeViewObserver *m_view;
+
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // LIVESELECTIONINDICATOR_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle.cpp b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle.cpp
new file mode 100644
index 0000000..2a1d393
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "liveselectionrectangle_p.h"
+
+#include "../qmlobserverconstants_p.h"
+
+#include <QtGui/QPen>
+#include <QtGui/QGraphicsRectItem>
+#include <QtGui/QGraphicsObject>
+#include <QtGui/QGraphicsScene>
+
+#include <QtCore/QtDebug>
+
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+class SelectionRectShape : public QGraphicsRectItem
+{
+public:
+ SelectionRectShape(QGraphicsItem *parent = 0) : QGraphicsRectItem(parent) {}
+ int type() const { return Constants::EditorItemType; }
+};
+
+LiveSelectionRectangle::LiveSelectionRectangle(QGraphicsObject *layerItem)
+ : m_controlShape(new SelectionRectShape(layerItem)),
+ m_layerItem(layerItem)
+{
+ m_controlShape->setPen(QPen(Qt::black));
+ m_controlShape->setBrush(QColor(128, 128, 128, 50));
+}
+
+LiveSelectionRectangle::~LiveSelectionRectangle()
+{
+ if (m_layerItem)
+ m_layerItem.data()->scene()->removeItem(m_controlShape);
+}
+
+void LiveSelectionRectangle::clear()
+{
+ hide();
+}
+void LiveSelectionRectangle::show()
+{
+ m_controlShape->show();
+}
+
+void LiveSelectionRectangle::hide()
+{
+ m_controlShape->hide();
+}
+
+QRectF LiveSelectionRectangle::rect() const
+{
+ return m_controlShape->mapFromScene(m_controlShape->rect()).boundingRect();
+}
+
+void LiveSelectionRectangle::setRect(const QPointF &firstPoint,
+ const QPointF &secondPoint)
+{
+ double firstX = std::floor(firstPoint.x()) + 0.5;
+ double firstY = std::floor(firstPoint.y()) + 0.5;
+ double secondX = std::floor(secondPoint.x()) + 0.5;
+ double secondY = std::floor(secondPoint.y()) + 0.5;
+ QPointF topLeftPoint(firstX < secondX ? firstX : secondX,
+ firstY < secondY ? firstY : secondY);
+ QPointF bottomRightPoint(firstX > secondX ? firstX : secondX,
+ firstY > secondY ? firstY : secondY);
+
+ QRectF rect(topLeftPoint, bottomRightPoint);
+ m_controlShape->setRect(rect);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle_p.h b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle_p.h
new file mode 100644
index 0000000..d1bed72
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LIVESELECTIONRECTANGLE_H
+#define LIVESELECTIONRECTANGLE_H
+
+#include <QtCore/QWeakPointer>
+
+QT_FORWARD_DECLARE_CLASS(QGraphicsObject)
+QT_FORWARD_DECLARE_CLASS(QGraphicsRectItem)
+QT_FORWARD_DECLARE_CLASS(QPointF)
+QT_FORWARD_DECLARE_CLASS(QRectF)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class LiveSelectionRectangle
+{
+public:
+ LiveSelectionRectangle(QGraphicsObject *layerItem);
+ ~LiveSelectionRectangle();
+
+ void show();
+ void hide();
+
+ void clear();
+
+ void setRect(const QPointF &firstPoint,
+ const QPointF &secondPoint);
+
+ QRectF rect() const;
+
+private:
+ QGraphicsRectItem *m_controlShape;
+ QWeakPointer<QGraphicsObject> m_layerItem;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // LIVESELECTIONRECTANGLE_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool.cpp
new file mode 100644
index 0000000..d85926e
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool.cpp
@@ -0,0 +1,442 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "liveselectiontool_p.h"
+#include "livelayeritem_p.h"
+
+#include "../qdeclarativeviewobserver_p_p.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QWheelEvent>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QClipboard>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+#include <QtGui/QGraphicsObject>
+
+#include <QtDeclarative/QDeclarativeItem>
+#include <QtDeclarative/QDeclarativeEngine>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+LiveSelectionTool::LiveSelectionTool(QDeclarativeViewObserver *editorView) :
+ AbstractLiveEditTool(editorView),
+ m_rubberbandSelectionMode(false),
+ m_rubberbandSelectionManipulator(
+ QDeclarativeViewObserverPrivate::get(editorView)->manipulatorLayer, editorView),
+ m_singleSelectionManipulator(editorView),
+ m_selectionIndicator(editorView,
+ QDeclarativeViewObserverPrivate::get(editorView)->manipulatorLayer),
+ //m_resizeIndicator(editorView->manipulatorLayer()),
+ m_selectOnlyContentItems(true)
+{
+
+}
+
+LiveSelectionTool::~LiveSelectionTool()
+{
+}
+
+void LiveSelectionTool::setRubberbandSelectionMode(bool value)
+{
+ m_rubberbandSelectionMode = value;
+}
+
+LiveSingleSelectionManipulator::SelectionType LiveSelectionTool::getSelectionType(Qt::KeyboardModifiers
+ modifiers)
+{
+ LiveSingleSelectionManipulator::SelectionType selectionType
+ = LiveSingleSelectionManipulator::ReplaceSelection;
+ if (modifiers.testFlag(Qt::ControlModifier)) {
+ selectionType = LiveSingleSelectionManipulator::RemoveFromSelection;
+ } else if (modifiers.testFlag(Qt::ShiftModifier)) {
+ selectionType = LiveSingleSelectionManipulator::AddToSelection;
+ }
+ return selectionType;
+}
+
+bool LiveSelectionTool::alreadySelected(const QList<QGraphicsItem*> &itemList) const
+{
+ QDeclarativeViewObserverPrivate *observerPrivate
+ = QDeclarativeViewObserverPrivate::get(observer());
+ const QList<QGraphicsItem*> selectedItems = observerPrivate->selectedItems();
+
+ if (selectedItems.isEmpty())
+ return false;
+
+ foreach (QGraphicsItem *item, itemList)
+ if (selectedItems.contains(item))
+ return true;
+
+ return false;
+}
+
+void LiveSelectionTool::mousePressEvent(QMouseEvent *event)
+{
+ QDeclarativeViewObserverPrivate *observerPrivate
+ = QDeclarativeViewObserverPrivate::get(observer());
+ QList<QGraphicsItem*> itemList = observerPrivate->selectableItems(event->pos());
+ LiveSingleSelectionManipulator::SelectionType selectionType = getSelectionType(event->modifiers());
+
+ if (event->buttons() & Qt::LeftButton) {
+ m_mousePressTimer.start();
+
+ if (m_rubberbandSelectionMode) {
+ m_rubberbandSelectionManipulator.begin(event->pos());
+ } else {
+ m_singleSelectionManipulator.begin(event->pos());
+ m_singleSelectionManipulator.select(selectionType, m_selectOnlyContentItems);
+ }
+ } else if (event->buttons() & Qt::RightButton) {
+ createContextMenu(itemList, event->globalPos());
+ }
+}
+
+void LiveSelectionTool::createContextMenu(QList<QGraphicsItem*> itemList, QPoint globalPos)
+{
+ if (!QDeclarativeViewObserverPrivate::get(observer())->mouseInsideContextItem())
+ return;
+
+ QMenu contextMenu;
+ connect(&contextMenu, SIGNAL(hovered(QAction*)),
+ this, SLOT(contextMenuElementHovered(QAction*)));
+
+ m_contextMenuItemList = itemList;
+
+ contextMenu.addAction(tr("Items"));
+ contextMenu.addSeparator();
+ int shortcutKey = Qt::Key_1;
+ bool addKeySequence = true;
+ int i = 0;
+
+ foreach (QGraphicsItem * const item, itemList) {
+ QString itemTitle = titleForItem(item);
+ QAction *elementAction = contextMenu.addAction(itemTitle, this,
+ SLOT(contextMenuElementSelected()));
+
+ if (observer()->selectedItems().contains(item)) {
+ QFont boldFont = elementAction->font();
+ boldFont.setBold(true);
+ elementAction->setFont(boldFont);
+ }
+
+ elementAction->setData(i);
+ if (addKeySequence)
+ elementAction->setShortcut(QKeySequence(shortcutKey));
+
+ shortcutKey++;
+ if (shortcutKey > Qt::Key_9)
+ addKeySequence = false;
+
+ ++i;
+ }
+ // add root item separately
+ // QString itemTitle = QString(tr("%1")).arg(titleForItem(view()->currentRootItem()));
+ // contextMenu.addAction(itemTitle, this, SLOT(contextMenuElementSelected()));
+ // m_contextMenuItemList.append(view()->currentRootItem());
+
+ contextMenu.exec(globalPos);
+ m_contextMenuItemList.clear();
+}
+
+void LiveSelectionTool::contextMenuElementSelected()
+{
+ QAction *senderAction = static_cast<QAction*>(sender());
+ int itemListIndex = senderAction->data().toInt();
+ if (itemListIndex >= 0 && itemListIndex < m_contextMenuItemList.length()) {
+
+ QPointF updatePt(0, 0);
+ QGraphicsItem *item = m_contextMenuItemList.at(itemListIndex);
+ m_singleSelectionManipulator.begin(updatePt);
+ m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::InvertSelection,
+ QList<QGraphicsItem*>() << item,
+ false);
+ m_singleSelectionManipulator.end(updatePt);
+ enterContext(item);
+ }
+}
+
+void LiveSelectionTool::contextMenuElementHovered(QAction *action)
+{
+ int itemListIndex = action->data().toInt();
+ if (itemListIndex >= 0 && itemListIndex < m_contextMenuItemList.length()) {
+ QGraphicsObject *item = m_contextMenuItemList.at(itemListIndex)->toGraphicsObject();
+ QDeclarativeViewObserverPrivate::get(observer())->highlight(item);
+ }
+}
+
+void LiveSelectionTool::mouseMoveEvent(QMouseEvent *event)
+{
+ if (m_singleSelectionManipulator.isActive()) {
+ QPointF mouseMovementVector = m_singleSelectionManipulator.beginPoint() - event->pos();
+
+ if ((mouseMovementVector.toPoint().manhattanLength() > Constants::DragStartDistance)
+ && (m_mousePressTimer.elapsed() > Constants::DragStartTime))
+ {
+ m_singleSelectionManipulator.end(event->pos());
+ //view()->changeToMoveTool(m_singleSelectionManipulator.beginPoint());
+ return;
+ }
+ } else if (m_rubberbandSelectionManipulator.isActive()) {
+ QPointF mouseMovementVector = m_rubberbandSelectionManipulator.beginPoint() - event->pos();
+
+ if ((mouseMovementVector.toPoint().manhattanLength() > Constants::DragStartDistance)
+ && (m_mousePressTimer.elapsed() > Constants::DragStartTime)) {
+ m_rubberbandSelectionManipulator.update(event->pos());
+
+ if (event->modifiers().testFlag(Qt::ControlModifier))
+ m_rubberbandSelectionManipulator.select(
+ LiveRubberBandSelectionManipulator::RemoveFromSelection);
+ else if (event->modifiers().testFlag(Qt::ShiftModifier))
+ m_rubberbandSelectionManipulator.select(
+ LiveRubberBandSelectionManipulator::AddToSelection);
+ else
+ m_rubberbandSelectionManipulator.select(
+ LiveRubberBandSelectionManipulator::ReplaceSelection);
+ }
+ }
+}
+
+void LiveSelectionTool::hoverMoveEvent(QMouseEvent * event)
+{
+// ### commented out until move tool is re-enabled
+// QList<QGraphicsItem*> itemList = view()->items(event->pos());
+// if (!itemList.isEmpty() && !m_rubberbandSelectionMode) {
+//
+// foreach (QGraphicsItem *item, itemList) {
+// if (item->type() == Constants::ResizeHandleItemType) {
+// ResizeHandleItem* resizeHandle = ResizeHandleItem::fromGraphicsItem(item);
+// if (resizeHandle)
+// view()->changeTool(Constants::ResizeToolMode);
+// return;
+// }
+// }
+// if (topSelectedItemIsMovable(itemList))
+// view()->changeTool(Constants::MoveToolMode);
+// }
+ QDeclarativeViewObserverPrivate *observerPrivate
+ = QDeclarativeViewObserverPrivate::get(observer());
+
+ QList<QGraphicsItem*> selectableItemList = observerPrivate->selectableItems(event->pos());
+ if (!selectableItemList.isEmpty()) {
+ QGraphicsObject *item = selectableItemList.first()->toGraphicsObject();
+ if (item)
+ QDeclarativeViewObserverPrivate::get(observer())->highlight(item);
+
+ return;
+ }
+
+ QDeclarativeViewObserverPrivate::get(observer())->clearHighlight();
+}
+
+void LiveSelectionTool::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (m_singleSelectionManipulator.isActive()) {
+ m_singleSelectionManipulator.end(event->pos());
+ }
+ else if (m_rubberbandSelectionManipulator.isActive()) {
+
+ QPointF mouseMovementVector = m_rubberbandSelectionManipulator.beginPoint() - event->pos();
+ if (mouseMovementVector.toPoint().manhattanLength() < Constants::DragStartDistance) {
+ m_singleSelectionManipulator.begin(event->pos());
+
+ if (event->modifiers().testFlag(Qt::ControlModifier))
+ m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::RemoveFromSelection,
+ m_selectOnlyContentItems);
+ else if (event->modifiers().testFlag(Qt::ShiftModifier))
+ m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::AddToSelection,
+ m_selectOnlyContentItems);
+ else
+ m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::InvertSelection,
+ m_selectOnlyContentItems);
+
+ m_singleSelectionManipulator.end(event->pos());
+ } else {
+ m_rubberbandSelectionManipulator.update(event->pos());
+
+ if (event->modifiers().testFlag(Qt::ControlModifier))
+ m_rubberbandSelectionManipulator.select(
+ LiveRubberBandSelectionManipulator::RemoveFromSelection);
+ else if (event->modifiers().testFlag(Qt::ShiftModifier))
+ m_rubberbandSelectionManipulator.select(
+ LiveRubberBandSelectionManipulator::AddToSelection);
+ else
+ m_rubberbandSelectionManipulator.select(
+ LiveRubberBandSelectionManipulator::ReplaceSelection);
+
+ m_rubberbandSelectionManipulator.end();
+ }
+ }
+}
+
+void LiveSelectionTool::mouseDoubleClickEvent(QMouseEvent * /*event*/)
+{
+}
+
+void LiveSelectionTool::keyPressEvent(QKeyEvent *event)
+{
+ switch (event->key()) {
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ // disabled for now, cannot move stuff yet.
+ //view()->changeTool(Constants::MoveToolMode);
+ //view()->currentTool()->keyPressEvent(event);
+ break;
+ }
+}
+
+void LiveSelectionTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/)
+{
+
+}
+
+void LiveSelectionTool::wheelEvent(QWheelEvent *event)
+{
+ if (event->orientation() == Qt::Horizontal || m_rubberbandSelectionMode)
+ return;
+
+ QDeclarativeViewObserverPrivate *observerPrivate
+ = QDeclarativeViewObserverPrivate::get(observer());
+ QList<QGraphicsItem*> itemList = observerPrivate->selectableItems(event->pos());
+
+ if (itemList.isEmpty())
+ return;
+
+ int selectedIdx = 0;
+ if (!observer()->selectedItems().isEmpty()) {
+ selectedIdx = itemList.indexOf(observer()->selectedItems().first());
+ if (selectedIdx >= 0) {
+ if (event->delta() > 0) {
+ selectedIdx++;
+ if (selectedIdx == itemList.length())
+ selectedIdx = 0;
+ } else if (event->delta() < 0) {
+ selectedIdx--;
+ if (selectedIdx == -1)
+ selectedIdx = itemList.length() - 1;
+ }
+ } else {
+ selectedIdx = 0;
+ }
+ }
+
+ QPointF updatePt(0, 0);
+ m_singleSelectionManipulator.begin(updatePt);
+ m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::ReplaceSelection,
+ QList<QGraphicsItem*>() << itemList.at(selectedIdx),
+ false);
+ m_singleSelectionManipulator.end(updatePt);
+
+}
+
+void LiveSelectionTool::setSelectOnlyContentItems(bool selectOnlyContentItems)
+{
+ m_selectOnlyContentItems = selectOnlyContentItems;
+}
+
+void LiveSelectionTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
+{
+}
+
+void LiveSelectionTool::clear()
+{
+ view()->setCursor(Qt::ArrowCursor);
+ m_rubberbandSelectionManipulator.clear(),
+ m_singleSelectionManipulator.clear();
+ m_selectionIndicator.clear();
+ //m_resizeIndicator.clear();
+}
+
+void LiveSelectionTool::selectedItemsChanged(const QList<QGraphicsItem*> &itemList)
+{
+ foreach (const QWeakPointer<QGraphicsObject> &obj, m_selectedItemList) {
+ if (!obj.isNull()) {
+ disconnect(obj.data(), SIGNAL(xChanged()), this, SLOT(repaintBoundingRects()));
+ disconnect(obj.data(), SIGNAL(yChanged()), this, SLOT(repaintBoundingRects()));
+ disconnect(obj.data(), SIGNAL(widthChanged()), this, SLOT(repaintBoundingRects()));
+ disconnect(obj.data(), SIGNAL(heightChanged()), this, SLOT(repaintBoundingRects()));
+ disconnect(obj.data(), SIGNAL(rotationChanged()), this, SLOT(repaintBoundingRects()));
+ }
+ }
+
+ QList<QGraphicsObject*> objects = toGraphicsObjectList(itemList);
+ m_selectedItemList.clear();
+
+ foreach (QGraphicsObject *obj, objects) {
+ m_selectedItemList.append(obj);
+ connect(obj, SIGNAL(xChanged()), this, SLOT(repaintBoundingRects()));
+ connect(obj, SIGNAL(yChanged()), this, SLOT(repaintBoundingRects()));
+ connect(obj, SIGNAL(widthChanged()), this, SLOT(repaintBoundingRects()));
+ connect(obj, SIGNAL(heightChanged()), this, SLOT(repaintBoundingRects()));
+ connect(obj, SIGNAL(rotationChanged()), this, SLOT(repaintBoundingRects()));
+ }
+
+ m_selectionIndicator.setItems(m_selectedItemList);
+ //m_resizeIndicator.setItems(toGraphicsObjectList(itemList));
+}
+
+void LiveSelectionTool::repaintBoundingRects()
+{
+ m_selectionIndicator.setItems(m_selectedItemList);
+}
+
+void LiveSelectionTool::selectUnderPoint(QMouseEvent *event)
+{
+ m_singleSelectionManipulator.begin(event->pos());
+
+ if (event->modifiers().testFlag(Qt::ControlModifier))
+ m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::RemoveFromSelection,
+ m_selectOnlyContentItems);
+ else if (event->modifiers().testFlag(Qt::ShiftModifier))
+ m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::AddToSelection,
+ m_selectOnlyContentItems);
+ else
+ m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::InvertSelection,
+ m_selectOnlyContentItems);
+
+ m_singleSelectionManipulator.end(event->pos());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool_p.h b/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool_p.h
new file mode 100644
index 0000000..3daac3d
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LIVESELECTIONTOOL_H
+#define LIVESELECTIONTOOL_H
+
+#include "abstractliveedittool_p.h"
+#include "liverubberbandselectionmanipulator_p.h"
+#include "livesingleselectionmanipulator_p.h"
+#include "liveselectionindicator_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QTime>
+
+QT_FORWARD_DECLARE_CLASS(QGraphicsItem)
+QT_FORWARD_DECLARE_CLASS(QMouseEvent)
+QT_FORWARD_DECLARE_CLASS(QKeyEvent)
+QT_FORWARD_DECLARE_CLASS(QAction)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class LiveSelectionTool : public AbstractLiveEditTool
+{
+ Q_OBJECT
+
+public:
+ LiveSelectionTool(QDeclarativeViewObserver* editorView);
+ ~LiveSelectionTool();
+
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void hoverMoveEvent(QMouseEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void keyReleaseEvent(QKeyEvent *keyEvent);
+ void wheelEvent(QWheelEvent *event);
+
+ void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList);
+// QVariant itemChange(const QList<QGraphicsItem*> &itemList,
+// QGraphicsItem::GraphicsItemChange change,
+// const QVariant &value );
+
+// void update();
+
+ void clear();
+
+ void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
+
+ void selectUnderPoint(QMouseEvent *event);
+
+ void setSelectOnlyContentItems(bool selectOnlyContentItems);
+
+ void setRubberbandSelectionMode(bool value);
+
+private slots:
+ void contextMenuElementSelected();
+ void contextMenuElementHovered(QAction *action);
+ void repaintBoundingRects();
+
+private:
+ void createContextMenu(QList<QGraphicsItem*> itemList, QPoint globalPos);
+ LiveSingleSelectionManipulator::SelectionType getSelectionType(Qt::KeyboardModifiers modifiers);
+ bool alreadySelected(const QList<QGraphicsItem*> &itemList) const;
+
+private:
+ bool m_rubberbandSelectionMode;
+ LiveRubberBandSelectionManipulator m_rubberbandSelectionManipulator;
+ LiveSingleSelectionManipulator m_singleSelectionManipulator;
+ LiveSelectionIndicator m_selectionIndicator;
+ //ResizeIndicator m_resizeIndicator;
+ QTime m_mousePressTimer;
+ bool m_selectOnlyContentItems;
+
+ QList<QWeakPointer<QGraphicsObject> > m_selectedItemList;
+
+ QList<QGraphicsItem*> m_contextMenuItemList;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // LIVESELECTIONTOOL_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator.cpp b/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator.cpp
new file mode 100644
index 0000000..e753b64
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "livesingleselectionmanipulator_p.h"
+
+#include "../qdeclarativeviewobserver_p_p.h"
+
+#include <QtDebug>
+
+QT_BEGIN_NAMESPACE
+
+LiveSingleSelectionManipulator::LiveSingleSelectionManipulator(QDeclarativeViewObserver *editorView)
+ : m_editorView(editorView),
+ m_isActive(false)
+{
+}
+
+
+void LiveSingleSelectionManipulator::begin(const QPointF &beginPoint)
+{
+ m_beginPoint = beginPoint;
+ m_isActive = true;
+ m_oldSelectionList = QDeclarativeViewObserverPrivate::get(m_editorView)->selectedItems();
+}
+
+void LiveSingleSelectionManipulator::update(const QPointF &/*updatePoint*/)
+{
+ m_oldSelectionList.clear();
+}
+
+void LiveSingleSelectionManipulator::clear()
+{
+ m_beginPoint = QPointF();
+ m_oldSelectionList.clear();
+}
+
+
+void LiveSingleSelectionManipulator::end(const QPointF &/*updatePoint*/)
+{
+ m_oldSelectionList.clear();
+ m_isActive = false;
+}
+
+void LiveSingleSelectionManipulator::select(SelectionType selectionType,
+ const QList<QGraphicsItem*> &items,
+ bool /*selectOnlyContentItems*/)
+{
+ QGraphicsItem *selectedItem = 0;
+
+ foreach (QGraphicsItem* item, items)
+ {
+ //FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
+ if (item
+ /*&& !formEditorItem->qmlItemNode().isRootNode()
+ && (formEditorItem->qmlItemNode().hasShowContent() || !selectOnlyContentItems)*/)
+ {
+ selectedItem = item;
+ break;
+ }
+ }
+
+ QList<QGraphicsItem*> resultList;
+
+ switch (selectionType) {
+ case AddToSelection: {
+ resultList.append(m_oldSelectionList);
+ if (selectedItem && !m_oldSelectionList.contains(selectedItem))
+ resultList.append(selectedItem);
+ }
+ break;
+ case ReplaceSelection: {
+ if (selectedItem)
+ resultList.append(selectedItem);
+ }
+ break;
+ case RemoveFromSelection: {
+ resultList.append(m_oldSelectionList);
+ if (selectedItem)
+ resultList.removeAll(selectedItem);
+ }
+ break;
+ case InvertSelection: {
+ if (selectedItem
+ && !m_oldSelectionList.contains(selectedItem))
+ {
+ resultList.append(selectedItem);
+ }
+ }
+ }
+
+ m_editorView->setSelectedItems(resultList);
+}
+
+void LiveSingleSelectionManipulator::select(SelectionType selectionType, bool selectOnlyContentItems)
+{
+ QDeclarativeViewObserverPrivate *observerPrivate =
+ QDeclarativeViewObserverPrivate::get(m_editorView);
+ QList<QGraphicsItem*> itemList = observerPrivate->selectableItems(m_beginPoint);
+ select(selectionType, itemList, selectOnlyContentItems);
+}
+
+
+bool LiveSingleSelectionManipulator::isActive() const
+{
+ return m_isActive;
+}
+
+QPointF LiveSingleSelectionManipulator::beginPoint() const
+{
+ return m_beginPoint;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator_p.h b/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator_p.h
new file mode 100644
index 0000000..68329e5
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LIVESINGLESELECTIONMANIPULATOR_H
+#define LIVESINGLESELECTIONMANIPULATOR_H
+
+#include <QtCore/QPointF>
+#include <QtCore/QList>
+
+QT_FORWARD_DECLARE_CLASS(QGraphicsItem)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeViewObserver;
+
+class LiveSingleSelectionManipulator
+{
+public:
+ LiveSingleSelectionManipulator(QDeclarativeViewObserver *editorView);
+
+ enum SelectionType {
+ ReplaceSelection,
+ AddToSelection,
+ RemoveFromSelection,
+ InvertSelection
+ };
+
+ void begin(const QPointF& beginPoint);
+ void update(const QPointF& updatePoint);
+ void end(const QPointF& updatePoint);
+
+ void select(SelectionType selectionType, const QList<QGraphicsItem*> &items,
+ bool selectOnlyContentItems);
+ void select(SelectionType selectionType, bool selectOnlyContentItems);
+
+ void clear();
+
+ QPointF beginPoint() const;
+
+ bool isActive() const;
+
+private:
+ QList<QGraphicsItem*> m_oldSelectionList;
+ QPointF m_beginPoint;
+ QDeclarativeViewObserver *m_editorView;
+ bool m_isActive;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // LIVESINGLESELECTIONMANIPULATOR_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar.cpp b/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar.cpp
new file mode 100644
index 0000000..359e9ef
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar.cpp
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmltoolbar_p.h"
+#include "toolbarcolorbox_p.h"
+
+#include <QtGui/QLabel>
+#include <QtGui/QIcon>
+#include <QtGui/QAction>
+#include <QtGui/QMenu>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+QmlToolBar::QmlToolBar(QWidget *parent)
+ : QToolBar(parent)
+ , m_emitSignals(true)
+ , m_paused(false)
+ , m_animationSpeed(1.0f)
+ , ui(new Ui)
+{
+ ui->playIcon = QIcon(QLatin1String(":/qml/images/play-24.png"));
+ ui->pauseIcon = QIcon(QLatin1String(":/qml/images/pause-24.png"));
+
+ ui->designmode = new QAction(QIcon(QLatin1String(":/qml/images/observermode-24.png")),
+ tr("Observer Mode"), this);
+ ui->play = new QAction(ui->pauseIcon, tr("Play/Pause Animations"), this);
+ ui->select = new QAction(QIcon(QLatin1String(":/qml/images/select-24.png")), tr("Select"), this);
+ ui->selectMarquee = new QAction(QIcon(QLatin1String(":/qml/images/select-marquee-24.png")),
+ tr("Select (Marquee)"), this);
+ ui->zoom = new QAction(QIcon(QLatin1String(":/qml/images/zoom-24.png")), tr("Zoom"), this);
+ ui->colorPicker = new QAction(QIcon(QLatin1String(":/qml/images/color-picker-24.png")),
+ tr("Color Picker"), this);
+ ui->toQml = new QAction(QIcon(QLatin1String(":/qml/images/to-qml-24.png")),
+ tr("Apply Changes to QML Viewer"), this);
+ ui->fromQml = new QAction(QIcon(QLatin1String(":/qml/images/from-qml-24.png")),
+ tr("Apply Changes to Document"), this);
+ ui->designmode->setCheckable(true);
+ ui->designmode->setChecked(false);
+
+ ui->play->setCheckable(false);
+ ui->select->setCheckable(true);
+ ui->selectMarquee->setCheckable(true);
+ ui->zoom->setCheckable(true);
+ ui->colorPicker->setCheckable(true);
+
+ setWindowTitle(tr("Tools"));
+
+ addAction(ui->designmode);
+ addAction(ui->play);
+ addSeparator();
+
+ addAction(ui->select);
+ // disabled because multi selection does not do anything useful without design mode
+ //addAction(ui->selectMarquee);
+ addSeparator();
+ addAction(ui->zoom);
+ addAction(ui->colorPicker);
+ //addAction(ui->fromQml);
+
+ ui->colorBox = new ToolBarColorBox(this);
+ ui->colorBox->setMinimumSize(24, 24);
+ ui->colorBox->setMaximumSize(28, 28);
+ ui->colorBox->setColor(Qt::black);
+ addWidget(ui->colorBox);
+
+ setWindowFlags(Qt::Tool);
+
+ QMenu *playSpeedMenu = new QMenu(this);
+ ui->playSpeedMenuActions = new QActionGroup(this);
+ ui->playSpeedMenuActions->setExclusive(true);
+
+ QAction *speedAction = playSpeedMenu->addAction(tr("1x"), this, SLOT(changeAnimationSpeed()));
+ speedAction->setCheckable(true);
+ speedAction->setChecked(true);
+ speedAction->setData(1.0f);
+ ui->playSpeedMenuActions->addAction(speedAction);
+
+ speedAction = playSpeedMenu->addAction(tr("0.5x"), this, SLOT(changeAnimationSpeed()));
+ speedAction->setCheckable(true);
+ speedAction->setData(2.0f);
+ ui->playSpeedMenuActions->addAction(speedAction);
+
+ speedAction = playSpeedMenu->addAction(tr("0.25x"), this, SLOT(changeAnimationSpeed()));
+ speedAction->setCheckable(true);
+ speedAction->setData(4.0f);
+ ui->playSpeedMenuActions->addAction(speedAction);
+
+ speedAction = playSpeedMenu->addAction(tr("0.125x"), this, SLOT(changeAnimationSpeed()));
+ speedAction->setCheckable(true);
+ speedAction->setData(8.0f);
+ ui->playSpeedMenuActions->addAction(speedAction);
+
+ speedAction = playSpeedMenu->addAction(tr("0.1x"), this, SLOT(changeAnimationSpeed()));
+ speedAction->setCheckable(true);
+ speedAction->setData(10.0f);
+ ui->playSpeedMenuActions->addAction(speedAction);
+
+ ui->play->setMenu(playSpeedMenu);
+
+ connect(ui->designmode, SIGNAL(toggled(bool)), SLOT(setDesignModeBehaviorOnClick(bool)));
+
+ connect(ui->colorPicker, SIGNAL(triggered()), SLOT(activateColorPickerOnClick()));
+
+ connect(ui->play, SIGNAL(triggered()), SLOT(activatePlayOnClick()));
+
+ connect(ui->zoom, SIGNAL(triggered()), SLOT(activateZoomOnClick()));
+ connect(ui->colorPicker, SIGNAL(triggered()), SLOT(activateColorPickerOnClick()));
+ connect(ui->select, SIGNAL(triggered()), SLOT(activateSelectToolOnClick()));
+ connect(ui->selectMarquee, SIGNAL(triggered()), SLOT(activateMarqueeSelectToolOnClick()));
+
+ connect(ui->toQml, SIGNAL(triggered()), SLOT(activateToQml()));
+ connect(ui->fromQml, SIGNAL(triggered()), SLOT(activateFromQml()));
+}
+
+QmlToolBar::~QmlToolBar()
+{
+ delete ui;
+}
+
+void QmlToolBar::activateColorPicker()
+{
+ m_emitSignals = false;
+ activateColorPickerOnClick();
+ m_emitSignals = true;
+}
+
+void QmlToolBar::activateSelectTool()
+{
+ m_emitSignals = false;
+ activateSelectToolOnClick();
+ m_emitSignals = true;
+}
+
+void QmlToolBar::activateMarqueeSelectTool()
+{
+ m_emitSignals = false;
+ activateMarqueeSelectToolOnClick();
+ m_emitSignals = true;
+}
+
+void QmlToolBar::activateZoom()
+{
+ m_emitSignals = false;
+ activateZoomOnClick();
+ m_emitSignals = true;
+}
+
+void QmlToolBar::setAnimationSpeed(qreal slowDownFactor)
+{
+ if (m_animationSpeed == slowDownFactor)
+ return;
+
+ m_emitSignals = false;
+ m_animationSpeed = slowDownFactor;
+
+ foreach (QAction *action, ui->playSpeedMenuActions->actions()) {
+ if (action->data().toReal() == slowDownFactor) {
+ action->setChecked(true);
+ break;
+ }
+ }
+
+ m_emitSignals = true;
+}
+
+void QmlToolBar::setAnimationPaused(bool paused)
+{
+ if (m_paused == paused)
+ return;
+
+ m_paused = paused;
+ updatePlayAction();
+}
+
+void QmlToolBar::changeAnimationSpeed()
+{
+ QAction *action = qobject_cast<QAction*>(sender());
+ m_animationSpeed = action->data().toReal();
+ emit animationSpeedChanged(m_animationSpeed);
+}
+
+void QmlToolBar::setDesignModeBehavior(bool inDesignMode)
+{
+ m_emitSignals = false;
+ ui->designmode->setChecked(inDesignMode);
+ setDesignModeBehaviorOnClick(inDesignMode);
+ m_emitSignals = true;
+}
+
+void QmlToolBar::setDesignModeBehaviorOnClick(bool checked)
+{
+ ui->select->setEnabled(checked);
+ ui->selectMarquee->setEnabled(checked);
+ ui->zoom->setEnabled(checked);
+ ui->colorPicker->setEnabled(checked);
+ ui->toQml->setEnabled(checked);
+ ui->fromQml->setEnabled(checked);
+
+ if (m_emitSignals)
+ emit designModeBehaviorChanged(checked);
+}
+
+void QmlToolBar::setColorBoxColor(const QColor &color)
+{
+ ui->colorBox->setColor(color);
+}
+
+void QmlToolBar::activatePlayOnClick()
+{
+ m_paused = !m_paused;
+ emit animationPausedChanged(m_paused);
+ updatePlayAction();
+}
+
+void QmlToolBar::updatePlayAction()
+{
+ ui->play->setIcon(m_paused ? ui->playIcon : ui->pauseIcon);
+}
+
+void QmlToolBar::activateColorPickerOnClick()
+{
+ ui->zoom->setChecked(false);
+ ui->select->setChecked(false);
+ ui->selectMarquee->setChecked(false);
+
+ ui->colorPicker->setChecked(true);
+ if (m_activeTool != Constants::ColorPickerMode) {
+ m_activeTool = Constants::ColorPickerMode;
+ if (m_emitSignals)
+ emit colorPickerSelected();
+ }
+}
+
+void QmlToolBar::activateSelectToolOnClick()
+{
+ ui->zoom->setChecked(false);
+ ui->selectMarquee->setChecked(false);
+ ui->colorPicker->setChecked(false);
+
+ ui->select->setChecked(true);
+ if (m_activeTool != Constants::SelectionToolMode) {
+ m_activeTool = Constants::SelectionToolMode;
+ if (m_emitSignals)
+ emit selectToolSelected();
+ }
+}
+
+void QmlToolBar::activateMarqueeSelectToolOnClick()
+{
+ ui->zoom->setChecked(false);
+ ui->select->setChecked(false);
+ ui->colorPicker->setChecked(false);
+
+ ui->selectMarquee->setChecked(true);
+ if (m_activeTool != Constants::MarqueeSelectionToolMode) {
+ m_activeTool = Constants::MarqueeSelectionToolMode;
+ if (m_emitSignals)
+ emit marqueeSelectToolSelected();
+ }
+}
+
+void QmlToolBar::activateZoomOnClick()
+{
+ ui->select->setChecked(false);
+ ui->selectMarquee->setChecked(false);
+ ui->colorPicker->setChecked(false);
+
+ ui->zoom->setChecked(true);
+ if (m_activeTool != Constants::ZoomMode) {
+ m_activeTool = Constants::ZoomMode;
+ if (m_emitSignals)
+ emit zoomToolSelected();
+ }
+}
+
+void QmlToolBar::activateFromQml()
+{
+ if (m_emitSignals)
+ emit applyChangesFromQmlFileSelected();
+}
+
+void QmlToolBar::activateToQml()
+{
+ if (m_emitSignals)
+ emit applyChangesToQmlFileSelected();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar_p.h b/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar_p.h
new file mode 100644
index 0000000..459eafd
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLTOOLBAR_H
+#define QMLTOOLBAR_H
+
+#include <QtGui/QToolBar>
+#include <QtGui/QIcon>
+
+#include "../qmlobserverconstants_p.h"
+
+QT_FORWARD_DECLARE_CLASS(QActionGroup)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class ToolBarColorBox;
+
+class QmlToolBar : public QToolBar
+{
+ Q_OBJECT
+
+public:
+ explicit QmlToolBar(QWidget *parent = 0);
+ ~QmlToolBar();
+
+public slots:
+ void setDesignModeBehavior(bool inDesignMode);
+ void setColorBoxColor(const QColor &color);
+ void activateColorPicker();
+ void activateSelectTool();
+ void activateMarqueeSelectTool();
+ void activateZoom();
+
+ void setAnimationSpeed(qreal slowDownFactor);
+ void setAnimationPaused(bool paused);
+
+signals:
+ void animationSpeedChanged(qreal factor);
+ void animationPausedChanged(bool paused);
+
+ void designModeBehaviorChanged(bool inDesignMode);
+ void colorPickerSelected();
+ void selectToolSelected();
+ void marqueeSelectToolSelected();
+ void zoomToolSelected();
+
+ void applyChangesToQmlFileSelected();
+ void applyChangesFromQmlFileSelected();
+
+private slots:
+ void setDesignModeBehaviorOnClick(bool inDesignMode);
+ void activatePlayOnClick();
+ void activateColorPickerOnClick();
+ void activateSelectToolOnClick();
+ void activateMarqueeSelectToolOnClick();
+ void activateZoomOnClick();
+
+ void activateFromQml();
+ void activateToQml();
+
+ void changeAnimationSpeed();
+
+ void updatePlayAction();
+
+private:
+ class Ui {
+ public:
+ QAction *designmode;
+ QAction *play;
+ QAction *select;
+ QAction *selectMarquee;
+ QAction *zoom;
+ QAction *colorPicker;
+ QAction *toQml;
+ QAction *fromQml;
+ QIcon playIcon;
+ QIcon pauseIcon;
+ ToolBarColorBox *colorBox;
+
+ QActionGroup *playSpeedMenuActions;
+ };
+
+ bool m_emitSignals;
+ bool m_paused;
+ qreal m_animationSpeed;
+
+ Constants::DesignTool m_activeTool;
+
+ Ui *ui;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLTOOLBAR_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool.cpp
new file mode 100644
index 0000000..ab77296
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool.cpp
@@ -0,0 +1,364 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "subcomponenteditortool_p.h"
+#include "subcomponentmasklayeritem_p.h"
+#include "livelayeritem_p.h"
+
+#include "../qdeclarativeviewobserver_p_p.h"
+
+#include <QtGui/QGraphicsItem>
+#include <QtGui/QGraphicsObject>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QKeyEvent>
+
+#include <QtCore/QTimer>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+const qreal MaxOpacity = 0.5f;
+
+SubcomponentEditorTool::SubcomponentEditorTool(QDeclarativeViewObserver *view)
+ : AbstractLiveEditTool(view),
+ m_animIncrement(0.05f),
+ m_animTimer(new QTimer(this))
+{
+ QDeclarativeViewObserverPrivate *observerPrivate =
+ QDeclarativeViewObserverPrivate::get(view);
+ m_mask = new SubcomponentMaskLayerItem(view, observerPrivate->manipulatorLayer);
+ connect(m_animTimer, SIGNAL(timeout()), SLOT(animate()));
+ m_animTimer->setInterval(20);
+}
+
+SubcomponentEditorTool::~SubcomponentEditorTool()
+{
+
+}
+
+void SubcomponentEditorTool::mousePressEvent(QMouseEvent * /*event*/)
+{
+
+}
+
+void SubcomponentEditorTool::mouseMoveEvent(QMouseEvent * /*event*/)
+{
+
+}
+
+bool SubcomponentEditorTool::containsCursor(const QPoint &mousePos) const
+{
+ if (!m_currentContext.size())
+ return false;
+
+ QPointF scenePos = view()->mapToScene(mousePos);
+ QRectF itemRect = m_currentContext.top()->boundingRect()
+ | m_currentContext.top()->childrenBoundingRect();
+ QRectF polyRect = m_currentContext.top()->mapToScene(itemRect).boundingRect();
+
+ return polyRect.contains(scenePos);
+}
+
+void SubcomponentEditorTool::mouseReleaseEvent(QMouseEvent * /*event*/)
+{
+
+}
+
+void SubcomponentEditorTool::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (event->buttons() & Qt::LeftButton
+ && !containsCursor(event->pos())
+ && m_currentContext.size() > 1)
+ {
+ aboutToPopContext();
+ }
+}
+
+void SubcomponentEditorTool::hoverMoveEvent(QMouseEvent *event)
+{
+ if (!containsCursor(event->pos()) && m_currentContext.size() > 1) {
+ QDeclarativeViewObserverPrivate::get(observer())->clearHighlight();
+ }
+}
+
+void SubcomponentEditorTool::wheelEvent(QWheelEvent * /*event*/)
+{
+
+}
+
+void SubcomponentEditorTool::keyPressEvent(QKeyEvent * /*event*/)
+{
+
+}
+
+void SubcomponentEditorTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/)
+{
+
+}
+
+void SubcomponentEditorTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
+{
+
+}
+
+void SubcomponentEditorTool::animate()
+{
+ if (m_animIncrement > 0) {
+ if (m_mask->opacity() + m_animIncrement < MaxOpacity) {
+ m_mask->setOpacity(m_mask->opacity() + m_animIncrement);
+ } else {
+ m_animTimer->stop();
+ m_mask->setOpacity(MaxOpacity);
+ }
+ } else {
+ if (m_mask->opacity() + m_animIncrement > 0) {
+ m_mask->setOpacity(m_mask->opacity() + m_animIncrement);
+ } else {
+ m_animTimer->stop();
+ m_mask->setOpacity(0);
+ popContext();
+ emit contextPathChanged(m_path);
+ }
+ }
+
+}
+
+void SubcomponentEditorTool::clear()
+{
+ m_currentContext.clear();
+ m_mask->setCurrentItem(0);
+ m_animTimer->stop();
+ m_mask->hide();
+ m_path.clear();
+
+ emit contextPathChanged(m_path);
+ emit cleared();
+}
+
+void SubcomponentEditorTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/)
+{
+
+}
+
+void SubcomponentEditorTool::setCurrentItem(QGraphicsItem* contextItem)
+{
+ if (!contextItem)
+ return;
+
+ QGraphicsObject *gfxObject = contextItem->toGraphicsObject();
+ if (!gfxObject)
+ return;
+
+ //QString parentClassName = gfxObject->metaObject()->className();
+ //if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+")))
+
+ bool containsSelectableItems = false;
+ foreach (QGraphicsItem *item, gfxObject->childItems()) {
+ if (item->type() == Constants::EditorItemType
+ || item->type() == Constants::ResizeHandleItemType)
+ {
+ continue;
+ }
+ containsSelectableItems = true;
+ break;
+ }
+
+ if (containsSelectableItems) {
+ m_mask->setCurrentItem(gfxObject);
+ m_mask->setOpacity(0);
+ m_mask->show();
+ m_animIncrement = 0.05f;
+ m_animTimer->start();
+
+ QDeclarativeViewObserverPrivate::get(observer())->clearHighlight();
+ observer()->setSelectedItems(QList<QGraphicsItem*>());
+
+ pushContext(gfxObject);
+ }
+}
+
+QGraphicsItem *SubcomponentEditorTool::firstChildOfContext(QGraphicsItem *item) const
+{
+ if (!item)
+ return 0;
+
+ if (isDirectChildOfContext(item))
+ return item;
+
+ QGraphicsItem *parent = item->parentItem();
+ while (parent) {
+ if (isDirectChildOfContext(parent))
+ return parent;
+ parent = parent->parentItem();
+ }
+
+ return 0;
+}
+
+bool SubcomponentEditorTool::isChildOfContext(QGraphicsItem *item) const
+{
+ return (firstChildOfContext(item) != 0);
+}
+
+bool SubcomponentEditorTool::isDirectChildOfContext(QGraphicsItem *item) const
+{
+ return (item->parentItem() == m_currentContext.top());
+}
+
+bool SubcomponentEditorTool::itemIsChildOfQmlSubComponent(QGraphicsItem *item) const
+{
+ if (item->parentItem() && item->parentItem() != m_currentContext.top()) {
+ QGraphicsObject *parent = item->parentItem()->toGraphicsObject();
+ QString parentClassName = QLatin1String(parent->metaObject()->className());
+
+ if (parentClassName.contains(QRegExp(QLatin1String("_QMLTYPE_\\d+")))) {
+ return true;
+ } else {
+ return itemIsChildOfQmlSubComponent(parent);
+ }
+ }
+
+ return false;
+}
+
+void SubcomponentEditorTool::pushContext(QGraphicsObject *contextItem)
+{
+ connect(contextItem, SIGNAL(destroyed(QObject*)), this, SLOT(contextDestroyed(QObject*)));
+ connect(contextItem, SIGNAL(xChanged()), this, SLOT(resizeMask()));
+ connect(contextItem, SIGNAL(yChanged()), this, SLOT(resizeMask()));
+ connect(contextItem, SIGNAL(widthChanged()), this, SLOT(resizeMask()));
+ connect(contextItem, SIGNAL(heightChanged()), this, SLOT(resizeMask()));
+ connect(contextItem, SIGNAL(rotationChanged()), this, SLOT(resizeMask()));
+
+ m_currentContext.push(contextItem);
+ QString title = titleForItem(contextItem);
+ emit contextPushed(title);
+
+ m_path << title;
+ emit contextPathChanged(m_path);
+}
+
+void SubcomponentEditorTool::aboutToPopContext()
+{
+ if (m_currentContext.size() > 2) {
+ popContext();
+ emit contextPathChanged(m_path);
+ } else {
+ m_animIncrement = -0.05f;
+ m_animTimer->start();
+ }
+}
+
+QGraphicsObject *SubcomponentEditorTool::popContext()
+{
+ QGraphicsObject *popped = m_currentContext.pop();
+ m_path.removeLast();
+
+ emit contextPopped();
+
+ disconnect(popped, SIGNAL(xChanged()), this, SLOT(resizeMask()));
+ disconnect(popped, SIGNAL(yChanged()), this, SLOT(resizeMask()));
+ disconnect(popped, SIGNAL(scaleChanged()), this, SLOT(resizeMask()));
+ disconnect(popped, SIGNAL(widthChanged()), this, SLOT(resizeMask()));
+ disconnect(popped, SIGNAL(heightChanged()), this, SLOT(resizeMask()));
+
+ if (m_currentContext.size() > 1) {
+ QGraphicsObject *item = m_currentContext.top();
+ m_mask->setCurrentItem(item);
+ m_mask->setOpacity(MaxOpacity);
+ m_mask->setVisible(true);
+ } else {
+ m_mask->setVisible(false);
+ }
+
+ return popped;
+}
+
+void SubcomponentEditorTool::resizeMask()
+{
+ QGraphicsObject *item = m_currentContext.top();
+ m_mask->setCurrentItem(item);
+}
+
+QGraphicsObject *SubcomponentEditorTool::currentRootItem() const
+{
+ return m_currentContext.top();
+}
+
+void SubcomponentEditorTool::contextDestroyed(QObject *contextToDestroy)
+{
+ disconnect(contextToDestroy, SIGNAL(destroyed(QObject*)),
+ this, SLOT(contextDestroyed(QObject*)));
+
+ // pop out the whole context - it might not be safe anymore.
+ while (m_currentContext.size() > 1) {
+ m_currentContext.pop();
+ m_path.removeLast();
+ emit contextPopped();
+ }
+ m_mask->setVisible(false);
+
+ emit contextPathChanged(m_path);
+}
+
+QGraphicsObject *SubcomponentEditorTool::setContext(int contextIndex)
+{
+ Q_ASSERT(contextIndex >= 0);
+
+ // sometimes we have to delete the context while user was still clicking around,
+ // so just bail out.
+ if (contextIndex >= m_currentContext.size() -1)
+ return 0;
+
+ while (m_currentContext.size() - 1 > contextIndex) {
+ popContext();
+ }
+ emit contextPathChanged(m_path);
+
+ return m_currentContext.top();
+}
+
+int SubcomponentEditorTool::contextIndex() const
+{
+ return m_currentContext.size() - 1;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool_p.h b/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool_p.h
new file mode 100644
index 0000000..15217eb
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SUBCOMPONENTEDITORTOOL_H
+#define SUBCOMPONENTEDITORTOOL_H
+
+#include "abstractliveedittool_p.h"
+
+#include <QtCore/QStack>
+#include <QtCore/QStringList>
+
+QT_FORWARD_DECLARE_CLASS(QGraphicsObject)
+QT_FORWARD_DECLARE_CLASS(QPoint)
+QT_FORWARD_DECLARE_CLASS(QTimer)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class SubcomponentMaskLayerItem;
+
+class SubcomponentEditorTool : public AbstractLiveEditTool
+{
+ Q_OBJECT
+
+public:
+ SubcomponentEditorTool(QDeclarativeViewObserver *view);
+ ~SubcomponentEditorTool();
+
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+
+ void hoverMoveEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent *event);
+
+ void keyPressEvent(QKeyEvent *event);
+ void keyReleaseEvent(QKeyEvent *keyEvent);
+ void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList);
+
+ void clear();
+
+ bool containsCursor(const QPoint &mousePos) const;
+ bool itemIsChildOfQmlSubComponent(QGraphicsItem *item) const;
+
+ bool isChildOfContext(QGraphicsItem *item) const;
+ bool isDirectChildOfContext(QGraphicsItem *item) const;
+ QGraphicsItem *firstChildOfContext(QGraphicsItem *item) const;
+
+ void setCurrentItem(QGraphicsItem *contextObject);
+
+ void pushContext(QGraphicsObject *contextItem);
+
+ QGraphicsObject *currentRootItem() const;
+ QGraphicsObject *setContext(int contextIndex);
+ int contextIndex() const;
+
+signals:
+ void exitContextRequested();
+ void cleared();
+ void contextPushed(const QString &contextTitle);
+ void contextPopped();
+ void contextPathChanged(const QStringList &path);
+
+protected:
+ void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
+
+private slots:
+ void animate();
+ void contextDestroyed(QObject *context);
+ void resizeMask();
+
+private:
+ QGraphicsObject *popContext();
+ void aboutToPopContext();
+
+private:
+ QStack<QGraphicsObject *> m_currentContext;
+ QStringList m_path;
+
+ qreal m_animIncrement;
+ SubcomponentMaskLayerItem *m_mask;
+ QTimer *m_animTimer;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // SUBCOMPONENTEDITORTOOL_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem.cpp b/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem.cpp
new file mode 100644
index 0000000..15d2a2c
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "subcomponentmasklayeritem_p.h"
+
+#include "../qmlobserverconstants_p.h"
+#include "../qdeclarativeviewobserver_p.h"
+
+#include <QtGui/QPolygonF>
+
+QT_BEGIN_NAMESPACE
+
+SubcomponentMaskLayerItem::SubcomponentMaskLayerItem(QDeclarativeViewObserver *observer,
+ QGraphicsItem *parentItem) :
+ QGraphicsPolygonItem(parentItem),
+ m_observer(observer),
+ m_currentItem(0),
+ m_borderRect(new QGraphicsRectItem(this))
+{
+ m_borderRect->setRect(0,0,0,0);
+ m_borderRect->setPen(QPen(QColor(60, 60, 60), 1));
+ m_borderRect->setData(Constants::EditorItemDataKey, QVariant(true));
+
+ setBrush(QBrush(QColor(160,160,160)));
+ setPen(Qt::NoPen);
+}
+
+int SubcomponentMaskLayerItem::type() const
+{
+ return Constants::EditorItemType;
+}
+
+static QRectF resizeRect(const QRectF &newRect, const QRectF &oldRect)
+{
+ QRectF result = newRect;
+ if (oldRect.left() < newRect.left())
+ result.setLeft(oldRect.left());
+
+ if (oldRect.top() < newRect.top())
+ result.setTop(oldRect.top());
+
+ if (oldRect.right() > newRect.right())
+ result.setRight(oldRect.right());
+
+ if (oldRect.bottom() > newRect.bottom())
+ result.setBottom(oldRect.bottom());
+
+ return result;
+}
+
+
+void SubcomponentMaskLayerItem::setCurrentItem(QGraphicsItem *item)
+{
+ QGraphicsItem *prevItem = m_currentItem;
+ m_currentItem = item;
+
+ if (!m_currentItem)
+ return;
+
+ QPolygonF viewPoly(QRectF(m_observer->declarativeView()->rect()));
+ viewPoly = m_observer->declarativeView()->mapToScene(viewPoly.toPolygon());
+
+ QRectF itemRect = item->boundingRect() | item->childrenBoundingRect();
+ QPolygonF itemPoly(itemRect);
+ itemPoly = item->mapToScene(itemPoly);
+
+ // if updating the same item as before, resize the rectangle only bigger, not smaller.
+ if (prevItem == item && prevItem != 0) {
+ m_itemPolyRect = resizeRect(itemPoly.boundingRect(), m_itemPolyRect);
+ } else {
+ m_itemPolyRect = itemPoly.boundingRect();
+ }
+ QRectF borderRect = m_itemPolyRect;
+ borderRect.adjust(-1, -1, 1, 1);
+ m_borderRect->setRect(borderRect);
+
+ itemPoly = viewPoly.subtracted(QPolygonF(m_itemPolyRect));
+ setPolygon(itemPoly);
+}
+
+QGraphicsItem *SubcomponentMaskLayerItem::currentItem() const
+{
+ return m_currentItem;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem_p.h b/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem_p.h
new file mode 100644
index 0000000..e0b892d
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SUBCOMPONENTMASKLAYERITEM_H
+#define SUBCOMPONENTMASKLAYERITEM_H
+
+#include <QtGui/QGraphicsPolygonItem>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeViewObserver;
+
+class SubcomponentMaskLayerItem : public QGraphicsPolygonItem
+{
+public:
+ explicit SubcomponentMaskLayerItem(QDeclarativeViewObserver *observer,
+ QGraphicsItem *parentItem = 0);
+ int type() const;
+ void setCurrentItem(QGraphicsItem *item);
+ void setBoundingBox(const QRectF &boundingBox);
+ QGraphicsItem *currentItem() const;
+ QRectF itemRect() const;
+
+private:
+ QDeclarativeViewObserver *m_observer;
+ QGraphicsItem *m_currentItem;
+ QGraphicsRectItem *m_borderRect;
+ QRectF m_itemPolyRect;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // SUBCOMPONENTMASKLAYERITEM_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox.cpp b/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox.cpp
new file mode 100644
index 0000000..35582fb
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "toolbarcolorbox_p.h"
+
+#include "../qmlobserverconstants_p.h"
+
+#include <QtGui/QPixmap>
+#include <QtGui/QPainter>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QClipboard>
+#include <QtGui/QApplication>
+#include <QtGui/QColorDialog>
+#include <QtGui/QDrag>
+
+#include <QtCore/QMimeData>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+ToolBarColorBox::ToolBarColorBox(QWidget *parent) :
+ QLabel(parent)
+{
+ m_copyHexColor = new QAction(QIcon(QLatin1String(":/qml/images/color-picker-hicontrast.png")),
+ tr("Copy Color"), this);
+ connect(m_copyHexColor, SIGNAL(triggered()), SLOT(copyColorToClipboard()));
+ setScaledContents(false);
+}
+
+void ToolBarColorBox::setColor(const QColor &color)
+{
+ m_color = color;
+
+ QPixmap pix = createDragPixmap(width());
+ setPixmap(pix);
+ update();
+}
+
+void ToolBarColorBox::mousePressEvent(QMouseEvent *event)
+{
+ m_dragBeginPoint = event->pos();
+ m_dragStarted = false;
+}
+
+void ToolBarColorBox::mouseMoveEvent(QMouseEvent *event)
+{
+
+ if (event->buttons() & Qt::LeftButton
+ && (QPoint(event->pos() - m_dragBeginPoint).manhattanLength()
+ > Constants::DragStartDistance)
+ && !m_dragStarted)
+ {
+ m_dragStarted = true;
+ QDrag *drag = new QDrag(this);
+ QMimeData *mimeData = new QMimeData;
+
+ mimeData->setText(m_color.name());
+ drag->setMimeData(mimeData);
+ drag->setPixmap(createDragPixmap());
+
+ drag->exec();
+ }
+}
+
+QPixmap ToolBarColorBox::createDragPixmap(int size) const
+{
+ QPixmap pix(size, size);
+ QPainter p(&pix);
+
+ QColor borderColor1 = QColor(143, 143 ,143);
+ QColor borderColor2 = QColor(43, 43, 43);
+
+ p.setBrush(QBrush(m_color));
+ p.setPen(QPen(QBrush(borderColor2),1));
+
+ p.fillRect(0, 0, size, size, borderColor1);
+ p.drawRect(1,1, size - 3, size - 3);
+ return pix;
+}
+
+void ToolBarColorBox::contextMenuEvent(QContextMenuEvent *ev)
+{
+ QMenu contextMenu;
+ contextMenu.addAction(m_copyHexColor);
+ contextMenu.exec(ev->globalPos());
+}
+
+void ToolBarColorBox::copyColorToClipboard()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ clipboard->setText(m_color.name());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox_p.h b/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox_p.h
new file mode 100644
index 0000000..d4914fa
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOOLBARCOLORBOX_H
+#define TOOLBARCOLORBOX_H
+
+#include <QtGui/QLabel>
+#include <QtGui/QColor>
+#include <QtCore/QPoint>
+
+QT_FORWARD_DECLARE_CLASS(QContextMenuEvent)
+QT_FORWARD_DECLARE_CLASS(QAction)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class ToolBarColorBox : public QLabel
+{
+ Q_OBJECT
+
+public:
+ explicit ToolBarColorBox(QWidget *parent = 0);
+ void setColor(const QColor &color);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *ev);
+ void mousePressEvent(QMouseEvent *ev);
+ void mouseMoveEvent(QMouseEvent *ev);
+private slots:
+ void copyColorToClipboard();
+
+private:
+ QPixmap createDragPixmap(int size = 24) const;
+
+private:
+ bool m_dragStarted;
+ QPoint m_dragBeginPoint;
+ QAction *m_copyHexColor;
+ QColor m_color;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // TOOLBARCOLORBOX_H
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp
new file mode 100644
index 0000000..b70cda5
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp
@@ -0,0 +1,336 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "zoomtool_p.h"
+
+#include "../qdeclarativeviewobserver_p_p.h"
+
+#include <QtGui/QMouseEvent>
+#include <QtGui/QWheelEvent>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+
+#include <QtCore/QRectF>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+ZoomTool::ZoomTool(QDeclarativeViewObserver *view) :
+ AbstractLiveEditTool(view),
+ m_rubberbandManipulator(),
+ m_smoothZoomMultiplier(0.05f),
+ m_currentScale(1.0f)
+{
+ m_zoomTo100Action = new QAction(tr("Zoom to &100%"), this);
+ m_zoomInAction = new QAction(tr("Zoom In"), this);
+ m_zoomOutAction = new QAction(tr("Zoom Out"), this);
+ m_zoomInAction->setShortcut(QKeySequence(Qt::Key_Plus));
+ m_zoomOutAction->setShortcut(QKeySequence(Qt::Key_Minus));
+
+
+ LiveLayerItem *layerItem = QDeclarativeViewObserverPrivate::get(view)->manipulatorLayer;
+ QGraphicsObject *layerObject = reinterpret_cast<QGraphicsObject *>(layerItem);
+ m_rubberbandManipulator = new LiveRubberBandSelectionManipulator(layerObject, view);
+
+
+ connect(m_zoomTo100Action, SIGNAL(triggered()), SLOT(zoomTo100()));
+ connect(m_zoomInAction, SIGNAL(triggered()), SLOT(zoomIn()));
+ connect(m_zoomOutAction, SIGNAL(triggered()), SLOT(zoomOut()));
+}
+
+ZoomTool::~ZoomTool()
+{
+ delete m_rubberbandManipulator;
+}
+
+void ZoomTool::mousePressEvent(QMouseEvent *event)
+{
+ m_mousePos = event->pos();
+
+ QPointF scenePos = view()->mapToScene(event->pos());
+
+ if (event->buttons() & Qt::RightButton) {
+ QMenu contextMenu;
+ contextMenu.addAction(m_zoomTo100Action);
+ contextMenu.addSeparator();
+ contextMenu.addAction(m_zoomInAction);
+ contextMenu.addAction(m_zoomOutAction);
+ contextMenu.exec(event->globalPos());
+ } else if (event->buttons() & Qt::LeftButton) {
+ m_dragBeginPos = scenePos;
+ m_dragStarted = false;
+ }
+}
+
+void ZoomTool::mouseMoveEvent(QMouseEvent *event)
+{
+ m_mousePos = event->pos();
+
+ QPointF scenePos = view()->mapToScene(event->pos());
+
+ if (event->buttons() & Qt::LeftButton
+ && (QPointF(scenePos - m_dragBeginPos).manhattanLength()
+ > Constants::DragStartDistance / 3)
+ && !m_dragStarted)
+ {
+ m_dragStarted = true;
+ m_rubberbandManipulator->begin(m_dragBeginPos);
+ return;
+ }
+
+ if (m_dragStarted)
+ m_rubberbandManipulator->update(scenePos);
+
+}
+
+void ZoomTool::mouseReleaseEvent(QMouseEvent *event)
+{
+ m_mousePos = event->pos();
+ QPointF scenePos = view()->mapToScene(event->pos());
+
+ if (m_dragStarted) {
+ m_rubberbandManipulator->end();
+
+ int x1 = qMin(scenePos.x(), m_rubberbandManipulator->beginPoint().x());
+ int x2 = qMax(scenePos.x(), m_rubberbandManipulator->beginPoint().x());
+ int y1 = qMin(scenePos.y(), m_rubberbandManipulator->beginPoint().y());
+ int y2 = qMax(scenePos.y(), m_rubberbandManipulator->beginPoint().y());
+
+ QPointF scenePosTopLeft = QPoint(x1, y1);
+ QPointF scenePosBottomRight = QPoint(x2, y2);
+
+ QRectF sceneArea(scenePosTopLeft, scenePosBottomRight);
+
+ m_currentScale = qMin(view()->rect().width() / sceneArea.width(),
+ view()->rect().height() / sceneArea.height());
+
+
+ QTransform transform;
+ transform.scale(m_currentScale, m_currentScale);
+
+ view()->setTransform(transform);
+ view()->setSceneRect(sceneArea);
+ } else {
+ Qt::KeyboardModifier modifierKey = Qt::ControlModifier;
+#ifdef Q_WS_MAC
+ modifierKey = Qt::AltModifier;
+#endif
+ if (event->modifiers() & modifierKey) {
+ zoomOut();
+ } else {
+ zoomIn();
+ }
+ }
+}
+
+void ZoomTool::zoomIn()
+{
+ m_currentScale = nextZoomScale(ZoomIn);
+ scaleView(view()->mapToScene(m_mousePos));
+}
+
+void ZoomTool::zoomOut()
+{
+ m_currentScale = nextZoomScale(ZoomOut);
+ scaleView(view()->mapToScene(m_mousePos));
+}
+
+void ZoomTool::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ m_mousePos = event->pos();
+}
+
+
+void ZoomTool::hoverMoveEvent(QMouseEvent *event)
+{
+ m_mousePos = event->pos();
+}
+
+
+void ZoomTool::keyPressEvent(QKeyEvent * /*event*/)
+{
+}
+
+void ZoomTool::wheelEvent(QWheelEvent *event)
+{
+ if (event->orientation() != Qt::Vertical)
+ return;
+
+ Qt::KeyboardModifier smoothZoomModifier = Qt::ControlModifier;
+ if (event->modifiers() & smoothZoomModifier) {
+ int numDegrees = event->delta() / 8;
+ m_currentScale += m_smoothZoomMultiplier * (numDegrees / 15.0f);
+
+ scaleView(view()->mapToScene(m_mousePos));
+
+ } else if (!event->modifiers()) {
+ if (event->delta() > 0) {
+ m_currentScale = nextZoomScale(ZoomIn);
+ } else if (event->delta() < 0) {
+ m_currentScale = nextZoomScale(ZoomOut);
+ }
+ scaleView(view()->mapToScene(m_mousePos));
+ }
+}
+
+void ZoomTool::keyReleaseEvent(QKeyEvent *event)
+{
+ switch (event->key()) {
+ case Qt::Key_Plus:
+ zoomIn();
+ break;
+ case Qt::Key_Minus:
+ zoomOut();
+ break;
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ {
+ m_currentScale = ((event->key() - Qt::Key_0) * 1.0f);
+ scaleView(view()->mapToScene(m_mousePos)); // view()->mapToScene(view()->rect().center())
+ break;
+ }
+
+ default:
+ break;
+ }
+
+}
+
+void ZoomTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
+{
+}
+
+void ZoomTool::clear()
+{
+ view()->setCursor(Qt::ArrowCursor);
+}
+
+void ZoomTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/)
+{
+}
+
+void ZoomTool::scaleView(const QPointF &centerPos)
+{
+
+ QTransform transform;
+ transform.scale(m_currentScale, m_currentScale);
+ view()->setTransform(transform);
+
+ QPointF adjustedCenterPos = centerPos;
+ QSize rectSize(view()->rect().width() / m_currentScale,
+ view()->rect().height() / m_currentScale);
+
+ QRectF sceneRect;
+ if (qAbs(m_currentScale - 1.0f) < Constants::ZoomSnapDelta) {
+ adjustedCenterPos.rx() = rectSize.width() / 2;
+ adjustedCenterPos.ry() = rectSize.height() / 2;
+ }
+
+ if (m_currentScale < 1.0f) {
+ adjustedCenterPos.rx() = rectSize.width() / 2;
+ adjustedCenterPos.ry() = rectSize.height() / 2;
+ sceneRect.setRect(view()->rect().width() / 2 -rectSize.width() / 2,
+ view()->rect().height() / 2 -rectSize.height() / 2,
+ rectSize.width(),
+ rectSize.height());
+ } else {
+ sceneRect.setRect(adjustedCenterPos.x() - rectSize.width() / 2,
+ adjustedCenterPos.y() - rectSize.height() / 2,
+ rectSize.width(),
+ rectSize.height());
+ }
+
+ view()->setSceneRect(sceneRect);
+}
+
+void ZoomTool::zoomTo100()
+{
+ m_currentScale = 1.0f;
+ scaleView(view()->mapToScene(view()->rect().center()));
+}
+
+qreal ZoomTool::nextZoomScale(ZoomDirection direction) const
+{
+ static QList<qreal> zoomScales =
+ QList<qreal>()
+ << 0.125f
+ << 1.0f / 6.0f
+ << 0.25f
+ << 1.0f / 3.0f
+ << 0.5f
+ << 2.0f / 3.0f
+ << 1.0f
+ << 2.0f
+ << 3.0f
+ << 4.0f
+ << 5.0f
+ << 6.0f
+ << 7.0f
+ << 8.0f
+ << 12.0f
+ << 16.0f
+ << 32.0f
+ << 48.0f;
+
+ if (direction == ZoomIn) {
+ for (int i = 0; i < zoomScales.length(); ++i) {
+ if (zoomScales[i] > m_currentScale || i == zoomScales.length() - 1)
+ return zoomScales[i];
+ }
+ } else {
+ for (int i = zoomScales.length() - 1; i >= 0; --i) {
+ if (zoomScales[i] < m_currentScale || i == 0)
+ return zoomScales[i];
+ }
+ }
+
+ return 1.0f;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/declarativeobserver/editor/zoomtool_p.h b/src/plugins/qmltooling/declarativeobserver/editor/zoomtool_p.h
new file mode 100644
index 0000000..6734cf9
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/editor/zoomtool_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ZOOMTOOL_H
+#define ZOOMTOOL_H
+
+#include "abstractliveedittool_p.h"
+#include "liverubberbandselectionmanipulator_p.h"
+
+QT_FORWARD_DECLARE_CLASS(QAction)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class ZoomTool : public AbstractLiveEditTool
+{
+ Q_OBJECT
+
+public:
+ enum ZoomDirection {
+ ZoomIn,
+ ZoomOut
+ };
+
+ explicit ZoomTool(QDeclarativeViewObserver *view);
+
+ virtual ~ZoomTool();
+
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+
+ void hoverMoveEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent *event);
+
+ void keyPressEvent(QKeyEvent *event);
+ void keyReleaseEvent(QKeyEvent *keyEvent);
+ void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList);
+
+ void clear();
+
+protected:
+ void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
+
+private slots:
+ void zoomTo100();
+ void zoomIn();
+ void zoomOut();
+
+private:
+ qreal nextZoomScale(ZoomDirection direction) const;
+ void scaleView(const QPointF &centerPos);
+
+private:
+ bool m_dragStarted;
+ QPoint m_mousePos; // in view coords
+ QPointF m_dragBeginPos;
+ QAction *m_zoomTo100Action;
+ QAction *m_zoomInAction;
+ QAction *m_zoomOutAction;
+ LiveRubberBandSelectionManipulator *m_rubberbandManipulator;
+
+ qreal m_smoothZoomMultiplier;
+ qreal m_currentScale;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ZOOMTOOL_H
diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.cpp b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.cpp
new file mode 100644
index 0000000..458b7ef
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativeobserverplugin.h"
+
+#include "qdeclarativeviewobserver_p.h"
+
+#include <QtCore/qplugin.h>
+#include <QtDeclarative/private/qdeclarativeobserverservice_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QDeclarativeObserverPlugin::QDeclarativeObserverPlugin() :
+ m_observer(0)
+{
+}
+
+QDeclarativeObserverPlugin::~QDeclarativeObserverPlugin()
+{
+ delete m_observer;
+}
+
+void QDeclarativeObserverPlugin::activate()
+{
+ QDeclarativeObserverService *service = QDeclarativeObserverService::instance();
+ QList<QDeclarativeView*> views = service->views();
+ if (views.isEmpty())
+ return;
+
+ // TODO: Support multiple views
+ QDeclarativeView *view = service->views().at(0);
+ m_observer = new QDeclarativeViewObserver(view, view);
+}
+
+void QDeclarativeObserverPlugin::deactivate()
+{
+ delete m_observer;
+}
+
+Q_EXPORT_PLUGIN2(declarativeobserver, QDeclarativeObserverPlugin)
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.h b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.h
new file mode 100644
index 0000000..82d3dbc
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEOBSERVERPLUGIN_H
+#define QDECLARATIVEOBSERVERPLUGIN_H
+
+#include <QtCore/QPointer>
+#include <QtDeclarative/private/qdeclarativeobserverinterface_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeViewObserver;
+
+class QDeclarativeObserverPlugin : public QObject, public QDeclarativeObserverInterface
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QDeclarativeObserverPlugin)
+ Q_INTERFACES(QDeclarativeObserverInterface)
+
+public:
+ QDeclarativeObserverPlugin();
+ ~QDeclarativeObserverPlugin();
+
+ void activate();
+ void deactivate();
+
+private:
+ QPointer<QDeclarativeViewObserver> m_observer;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEOBSERVERPLUGIN_H
diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverprotocol.h b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverprotocol.h
new file mode 100644
index 0000000..eb46693
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverprotocol.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEOBSERVERPROTOCOL_H
+#define QDECLARATIVEOBSERVERPROTOCOL_H
+
+#include <QtCore/QDebug>
+#include <QtCore/QMetaType>
+#include <QtCore/QMetaEnum>
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class ObserverProtocol : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(Message Tool)
+
+public:
+ enum Message {
+ AnimationSpeedChanged = 0,
+ AnimationPausedChanged = 19, // highest value
+ ChangeTool = 1,
+ ClearComponentCache = 2,
+ ColorChanged = 3,
+ ContextPathUpdated = 4,
+ CreateObject = 5,
+ CurrentObjectsChanged = 6,
+ DestroyObject = 7,
+ MoveObject = 8,
+ ObjectIdList = 9,
+ Reload = 10,
+ Reloaded = 11,
+ SetAnimationSpeed = 12,
+ SetAnimationPaused = 18,
+ SetContextPathIdx = 13,
+ SetCurrentObjects = 14,
+ SetDesignMode = 15,
+ ShowAppOnTop = 16,
+ ToolChanged = 17
+ };
+
+ enum Tool {
+ ColorPickerTool,
+ SelectMarqueeTool,
+ SelectTool,
+ ZoomTool
+ };
+
+ static inline QString toString(Message message)
+ {
+ return QLatin1String(staticMetaObject.enumerator(0).valueToKey(message));
+ }
+
+ static inline QString toString(Tool tool)
+ {
+ return QLatin1String(staticMetaObject.enumerator(1).valueToKey(tool));
+ }
+};
+
+inline QDataStream & operator<< (QDataStream &stream, ObserverProtocol::Message message)
+{
+ return stream << static_cast<quint32>(message);
+}
+
+inline QDataStream & operator>> (QDataStream &stream, ObserverProtocol::Message &message)
+{
+ quint32 i;
+ stream >> i;
+ message = static_cast<ObserverProtocol::Message>(i);
+ return stream;
+}
+
+inline QDebug operator<< (QDebug dbg, ObserverProtocol::Message message)
+{
+ dbg << ObserverProtocol::toString(message);
+ return dbg;
+}
+
+inline QDataStream & operator<< (QDataStream &stream, ObserverProtocol::Tool tool)
+{
+ return stream << static_cast<quint32>(tool);
+}
+
+inline QDataStream & operator>> (QDataStream &stream, ObserverProtocol::Tool &tool)
+{
+ quint32 i;
+ stream >> i;
+ tool = static_cast<ObserverProtocol::Tool>(i);
+ return stream;
+}
+
+inline QDebug operator<< (QDebug dbg, ObserverProtocol::Tool tool)
+{
+ dbg << ObserverProtocol::toString(tool);
+ return dbg;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEOBSERVERPROTOCOL_H
diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver.cpp b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver.cpp
new file mode 100644
index 0000000..2286990
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver.cpp
@@ -0,0 +1,1167 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "QtDeclarative/private/qdeclarativeobserverservice_p.h"
+#include "QtDeclarative/private/qdeclarativedebughelper_p.h"
+
+#include "qdeclarativeviewobserver_p.h"
+#include "qdeclarativeviewobserver_p_p.h"
+#include "qdeclarativeobserverprotocol.h"
+
+#include "editor/liveselectiontool_p.h"
+#include "editor/zoomtool_p.h"
+#include "editor/colorpickertool_p.h"
+#include "editor/livelayeritem_p.h"
+#include "editor/boundingrecthighlighter_p.h"
+#include "editor/subcomponenteditortool_p.h"
+#include "editor/qmltoolbar_p.h"
+
+#include <QtDeclarative/QDeclarativeItem>
+#include <QtDeclarative/QDeclarativeEngine>
+#include <QtDeclarative/QDeclarativeContext>
+#include <QtDeclarative/QDeclarativeExpression>
+#include <QtGui/QWidget>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QGraphicsObject>
+#include <QtGui/QApplication>
+#include <QtCore/QSettings>
+
+static inline void initEditorResource() { Q_INIT_RESOURCE(editor); }
+
+QT_BEGIN_NAMESPACE
+
+const char * const KEY_TOOLBOX_GEOMETRY = "toolBox/geometry";
+
+const int SceneChangeUpdateInterval = 5000;
+
+
+class ToolBox : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ToolBox(QWidget *parent = 0);
+ ~ToolBox();
+
+ QmlToolBar *toolBar() const { return m_toolBar; }
+
+private:
+ QSettings m_settings;
+ QmlToolBar *m_toolBar;
+};
+
+ToolBox::ToolBox(QWidget *parent)
+ : QWidget(parent, Qt::Tool)
+ , m_settings(QLatin1String("Nokia"), QLatin1String("QmlObserver"), this)
+ , m_toolBar(new QmlToolBar)
+{
+ setWindowFlags((windowFlags() & ~Qt::WindowCloseButtonHint) | Qt::CustomizeWindowHint);
+ setWindowTitle(tr("Qt Quick Toolbox"));
+
+ QVBoxLayout *verticalLayout = new QVBoxLayout;
+ verticalLayout->setMargin(0);
+ verticalLayout->addWidget(m_toolBar);
+ setLayout(verticalLayout);
+
+ restoreGeometry(m_settings.value(QLatin1String(KEY_TOOLBOX_GEOMETRY)).toByteArray());
+}
+
+ToolBox::~ToolBox()
+{
+ m_settings.setValue(QLatin1String(KEY_TOOLBOX_GEOMETRY), saveGeometry());
+}
+
+
+QDeclarativeViewObserverPrivate::QDeclarativeViewObserverPrivate(QDeclarativeViewObserver *q) :
+ q(q),
+ designModeBehavior(false),
+ showAppOnTop(false),
+ animationPaused(false),
+ slowDownFactor(1.0f),
+ toolBox(0)
+{
+}
+
+QDeclarativeViewObserverPrivate::~QDeclarativeViewObserverPrivate()
+{
+}
+
+QDeclarativeViewObserver::QDeclarativeViewObserver(QDeclarativeView *view,
+ QObject *parent) :
+ QObject(parent),
+ data(new QDeclarativeViewObserverPrivate(this))
+{
+ initEditorResource();
+
+ data->view = view;
+ data->manipulatorLayer = new LiveLayerItem(view->scene());
+ data->selectionTool = new LiveSelectionTool(this);
+ data->zoomTool = new ZoomTool(this);
+ data->colorPickerTool = new ColorPickerTool(this);
+ data->boundingRectHighlighter = new BoundingRectHighlighter(this);
+ data->subcomponentEditorTool = new SubcomponentEditorTool(this);
+ data->currentTool = data->selectionTool;
+
+ // to capture ChildRemoved event when viewport changes
+ data->view->installEventFilter(this);
+
+ data->setViewport(data->view->viewport());
+
+ data->debugService = QDeclarativeObserverService::instance();
+ connect(data->debugService, SIGNAL(gotMessage(QByteArray)),
+ this, SLOT(handleMessage(QByteArray)));
+
+ connect(data->view, SIGNAL(statusChanged(QDeclarativeView::Status)),
+ data.data(), SLOT(_q_onStatusChanged(QDeclarativeView::Status)));
+
+ connect(data->colorPickerTool, SIGNAL(selectedColorChanged(QColor)),
+ SIGNAL(selectedColorChanged(QColor)));
+ connect(data->colorPickerTool, SIGNAL(selectedColorChanged(QColor)),
+ this, SLOT(sendColorChanged(QColor)));
+
+ connect(data->subcomponentEditorTool, SIGNAL(cleared()), SIGNAL(inspectorContextCleared()));
+ connect(data->subcomponentEditorTool, SIGNAL(contextPushed(QString)),
+ SIGNAL(inspectorContextPushed(QString)));
+ connect(data->subcomponentEditorTool, SIGNAL(contextPopped()),
+ SIGNAL(inspectorContextPopped()));
+ connect(data->subcomponentEditorTool, SIGNAL(contextPathChanged(QStringList)),
+ this, SLOT(sendContextPathUpdated(QStringList)));
+
+ data->_q_changeToSingleSelectTool();
+}
+
+QDeclarativeViewObserver::~QDeclarativeViewObserver()
+{
+}
+
+void QDeclarativeViewObserver::setObserverContext(int contextIndex)
+{
+ if (data->subcomponentEditorTool->contextIndex() != contextIndex) {
+ QGraphicsObject *object = data->subcomponentEditorTool->setContext(contextIndex);
+ if (object)
+ setSelectedItems(QList<QGraphicsItem*>() << object);
+ }
+}
+
+void QDeclarativeViewObserverPrivate::_q_setToolBoxVisible(bool visible)
+{
+#if !defined(Q_OS_SYMBIAN) && !defined(Q_WS_MAEMO_5) && !defined(Q_WS_SIMULATOR)
+ if (!toolBox && visible)
+ createToolBox();
+ if (toolBox)
+ toolBox->setVisible(visible);
+#else
+ Q_UNUSED(visible)
+#endif
+}
+
+void QDeclarativeViewObserverPrivate::_q_reloadView()
+{
+ subcomponentEditorTool->clear();
+ clearHighlight();
+ emit q->reloadRequested();
+}
+
+void QDeclarativeViewObserverPrivate::setViewport(QWidget *widget)
+{
+ if (viewport.data() == widget)
+ return;
+
+ if (viewport)
+ viewport.data()->removeEventFilter(q);
+
+ viewport = widget;
+ if (viewport) {
+ // make sure we get mouse move events
+ viewport.data()->setMouseTracking(true);
+ viewport.data()->installEventFilter(q);
+ }
+}
+
+void QDeclarativeViewObserverPrivate::clearEditorItems()
+{
+ clearHighlight();
+ setSelectedItems(QList<QGraphicsItem*>());
+}
+
+bool QDeclarativeViewObserver::eventFilter(QObject *obj, QEvent *event)
+{
+ if (obj == data->view) {
+ // Event from view
+ if (event->type() == QEvent::ChildRemoved) {
+ // Might mean that viewport has changed
+ if (data->view->viewport() != data->viewport.data())
+ data->setViewport(data->view->viewport());
+ }
+ return QObject::eventFilter(obj, event);
+ }
+
+ // Event from viewport
+ switch (event->type()) {
+ case QEvent::Leave: {
+ if (leaveEvent(event))
+ return true;
+ break;
+ }
+ case QEvent::MouseButtonPress: {
+ if (mousePressEvent(static_cast<QMouseEvent*>(event)))
+ return true;
+ break;
+ }
+ case QEvent::MouseMove: {
+ if (mouseMoveEvent(static_cast<QMouseEvent*>(event)))
+ return true;
+ break;
+ }
+ case QEvent::MouseButtonRelease: {
+ if (mouseReleaseEvent(static_cast<QMouseEvent*>(event)))
+ return true;
+ break;
+ }
+ case QEvent::KeyPress: {
+ if (keyPressEvent(static_cast<QKeyEvent*>(event)))
+ return true;
+ break;
+ }
+ case QEvent::KeyRelease: {
+ if (keyReleaseEvent(static_cast<QKeyEvent*>(event)))
+ return true;
+ break;
+ }
+ case QEvent::MouseButtonDblClick: {
+ if (mouseDoubleClickEvent(static_cast<QMouseEvent*>(event)))
+ return true;
+ break;
+ }
+ case QEvent::Wheel: {
+ if (wheelEvent(static_cast<QWheelEvent*>(event)))
+ return true;
+ break;
+ }
+ default: {
+ break;
+ }
+ } //switch
+
+ // standard event processing
+ return QObject::eventFilter(obj, event);
+}
+
+bool QDeclarativeViewObserver::leaveEvent(QEvent * /*event*/)
+{
+ if (!data->designModeBehavior)
+ return false;
+ data->clearHighlight();
+ return true;
+}
+
+bool QDeclarativeViewObserver::mousePressEvent(QMouseEvent *event)
+{
+ if (!data->designModeBehavior)
+ return false;
+ data->cursorPos = event->pos();
+ data->currentTool->mousePressEvent(event);
+ return true;
+}
+
+bool QDeclarativeViewObserver::mouseMoveEvent(QMouseEvent *event)
+{
+ if (!data->designModeBehavior) {
+ data->clearEditorItems();
+ return false;
+ }
+ data->cursorPos = event->pos();
+
+ QList<QGraphicsItem*> selItems = data->selectableItems(event->pos());
+ if (!selItems.isEmpty()) {
+ declarativeView()->setToolTip(data->currentTool->titleForItem(selItems.first()));
+ } else {
+ declarativeView()->setToolTip(QString());
+ }
+ if (event->buttons()) {
+ data->subcomponentEditorTool->mouseMoveEvent(event);
+ data->currentTool->mouseMoveEvent(event);
+ } else {
+ data->subcomponentEditorTool->hoverMoveEvent(event);
+ data->currentTool->hoverMoveEvent(event);
+ }
+ return true;
+}
+
+bool QDeclarativeViewObserver::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (!data->designModeBehavior)
+ return false;
+ data->subcomponentEditorTool->mouseReleaseEvent(event);
+
+ data->cursorPos = event->pos();
+ data->currentTool->mouseReleaseEvent(event);
+ return true;
+}
+
+bool QDeclarativeViewObserver::keyPressEvent(QKeyEvent *event)
+{
+ if (!data->designModeBehavior)
+ return false;
+
+ data->currentTool->keyPressEvent(event);
+ return true;
+}
+
+bool QDeclarativeViewObserver::keyReleaseEvent(QKeyEvent *event)
+{
+ if (!data->designModeBehavior)
+ return false;
+
+ switch (event->key()) {
+ case Qt::Key_V:
+ data->_q_changeToSingleSelectTool();
+ break;
+// disabled because multiselection does not do anything useful without design mode
+// case Qt::Key_M:
+// data->_q_changeToMarqueeSelectTool();
+// break;
+ case Qt::Key_I:
+ data->_q_changeToColorPickerTool();
+ break;
+ case Qt::Key_Z:
+ data->_q_changeToZoomTool();
+ break;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ if (!data->selectedItems().isEmpty())
+ data->subcomponentEditorTool->setCurrentItem(data->selectedItems().first());
+ break;
+ case Qt::Key_Space:
+ setAnimationPaused(!data->animationPaused);
+ break;
+ default:
+ break;
+ }
+
+ data->currentTool->keyReleaseEvent(event);
+ return true;
+}
+
+void QDeclarativeViewObserverPrivate::_q_createQmlObject(const QString &qml, QObject *parent,
+ const QStringList &importList,
+ const QString &filename)
+{
+ if (!parent)
+ return;
+
+ QString imports;
+ foreach (const QString &s, importList) {
+ imports += s;
+ imports += QLatin1Char('\n');
+ }
+
+ QDeclarativeContext *parentContext = view->engine()->contextForObject(parent);
+ QDeclarativeComponent component(view->engine(), q);
+ QByteArray constructedQml = QString(imports + qml).toLatin1();
+
+ component.setData(constructedQml, QUrl::fromLocalFile(filename));
+ QObject *newObject = component.create(parentContext);
+ if (newObject) {
+ newObject->setParent(parent);
+ QDeclarativeItem *parentItem = qobject_cast<QDeclarativeItem*>(parent);
+ QDeclarativeItem *newItem = qobject_cast<QDeclarativeItem*>(newObject);
+ if (parentItem && newItem)
+ newItem->setParentItem(parentItem);
+ }
+}
+
+void QDeclarativeViewObserverPrivate::_q_reparentQmlObject(QObject *object, QObject *newParent)
+{
+ if (!newParent)
+ return;
+
+ object->setParent(newParent);
+ QDeclarativeItem *newParentItem = qobject_cast<QDeclarativeItem*>(newParent);
+ QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(object);
+ if (newParentItem && item)
+ item->setParentItem(newParentItem);
+}
+
+void QDeclarativeViewObserverPrivate::_q_clearComponentCache()
+{
+ view->engine()->clearComponentCache();
+}
+
+void QDeclarativeViewObserverPrivate::_q_removeFromSelection(QObject *obj)
+{
+ QList<QGraphicsItem*> items = selectedItems();
+ if (QGraphicsItem *item = qobject_cast<QGraphicsObject*>(obj))
+ items.removeOne(item);
+ setSelectedItems(items);
+}
+
+QGraphicsItem *QDeclarativeViewObserverPrivate::currentRootItem() const
+{
+ return subcomponentEditorTool->currentRootItem();
+}
+
+bool QDeclarativeViewObserver::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (!data->designModeBehavior)
+ return false;
+
+ if (data->currentToolMode != Constants::SelectionToolMode
+ && data->currentToolMode != Constants::MarqueeSelectionToolMode)
+ return true;
+
+ QGraphicsItem *itemToEnter = 0;
+ QList<QGraphicsItem*> itemList = data->view->items(event->pos());
+ data->filterForSelection(itemList);
+
+ if (data->selectedItems().isEmpty() && !itemList.isEmpty()) {
+ itemToEnter = itemList.first();
+ } else if (!data->selectedItems().isEmpty() && !itemList.isEmpty()) {
+ itemToEnter = itemList.first();
+ }
+
+ if (itemToEnter)
+ itemToEnter = data->subcomponentEditorTool->firstChildOfContext(itemToEnter);
+
+ data->subcomponentEditorTool->setCurrentItem(itemToEnter);
+ data->subcomponentEditorTool->mouseDoubleClickEvent(event);
+
+ if ((event->buttons() & Qt::LeftButton) && itemToEnter) {
+ if (QGraphicsObject *objectToEnter = itemToEnter->toGraphicsObject())
+ setSelectedItems(QList<QGraphicsItem*>() << objectToEnter);
+ }
+
+ return true;
+}
+
+bool QDeclarativeViewObserver::wheelEvent(QWheelEvent *event)
+{
+ if (!data->designModeBehavior)
+ return false;
+ data->currentTool->wheelEvent(event);
+ return true;
+}
+
+void QDeclarativeViewObserverPrivate::enterContext(QGraphicsItem *itemToEnter)
+{
+ QGraphicsItem *itemUnderCurrentContext = itemToEnter;
+ if (itemUnderCurrentContext)
+ itemUnderCurrentContext = subcomponentEditorTool->firstChildOfContext(itemToEnter);
+
+ if (itemUnderCurrentContext)
+ subcomponentEditorTool->setCurrentItem(itemToEnter);
+}
+
+void QDeclarativeViewObserver::setDesignModeBehavior(bool value)
+{
+ emit designModeBehaviorChanged(value);
+
+ if (data->toolBox)
+ data->toolBox->toolBar()->setDesignModeBehavior(value);
+ sendDesignModeBehavior(value);
+
+ data->designModeBehavior = value;
+ if (data->subcomponentEditorTool) {
+ data->subcomponentEditorTool->clear();
+ data->clearHighlight();
+ data->setSelectedItems(QList<QGraphicsItem*>());
+
+ if (data->view->rootObject())
+ data->subcomponentEditorTool->pushContext(data->view->rootObject());
+ }
+
+ if (!data->designModeBehavior)
+ data->clearEditorItems();
+}
+
+bool QDeclarativeViewObserver::designModeBehavior()
+{
+ return data->designModeBehavior;
+}
+
+bool QDeclarativeViewObserver::showAppOnTop() const
+{
+ return data->showAppOnTop;
+}
+
+void QDeclarativeViewObserver::setShowAppOnTop(bool appOnTop)
+{
+ if (data->view) {
+ QWidget *window = data->view->window();
+ Qt::WindowFlags flags = window->windowFlags();
+ if (appOnTop)
+ flags |= Qt::WindowStaysOnTopHint;
+ else
+ flags &= ~Qt::WindowStaysOnTopHint;
+
+ window->setWindowFlags(flags);
+ window->show();
+ }
+
+ data->showAppOnTop = appOnTop;
+ sendShowAppOnTop(appOnTop);
+
+ emit showAppOnTopChanged(appOnTop);
+}
+
+void QDeclarativeViewObserverPrivate::changeTool(Constants::DesignTool tool,
+ Constants::ToolFlags /*flags*/)
+{
+ switch (tool) {
+ case Constants::SelectionToolMode:
+ _q_changeToSingleSelectTool();
+ break;
+ case Constants::NoTool:
+ default:
+ currentTool = 0;
+ break;
+ }
+}
+
+void QDeclarativeViewObserverPrivate::setSelectedItemsForTools(QList<QGraphicsItem *> items)
+{
+ foreach (const QWeakPointer<QGraphicsObject> &obj, currentSelection) {
+ if (QGraphicsItem *item = obj.data()) {
+ if (!items.contains(item)) {
+ QObject::disconnect(obj.data(), SIGNAL(destroyed(QObject*)),
+ this, SLOT(_q_removeFromSelection(QObject*)));
+ currentSelection.removeOne(obj);
+ }
+ }
+ }
+
+ foreach (QGraphicsItem *item, items) {
+ if (item) {
+ if (QGraphicsObject *obj = item->toGraphicsObject()) {
+ QObject::connect(obj, SIGNAL(destroyed(QObject*)),
+ this, SLOT(_q_removeFromSelection(QObject*)));
+ currentSelection.append(obj);
+ }
+ }
+ }
+
+ currentTool->updateSelectedItems();
+}
+
+void QDeclarativeViewObserverPrivate::setSelectedItems(QList<QGraphicsItem *> items)
+{
+ QList<QWeakPointer<QGraphicsObject> > oldList = currentSelection;
+ setSelectedItemsForTools(items);
+ if (oldList != currentSelection) {
+ QList<QObject*> objectList;
+ foreach (const QWeakPointer<QGraphicsObject> &graphicsObject, currentSelection) {
+ if (graphicsObject)
+ objectList << graphicsObject.data();
+ }
+
+ q->sendCurrentObjects(objectList);
+ }
+}
+
+QList<QGraphicsItem *> QDeclarativeViewObserverPrivate::selectedItems() const
+{
+ QList<QGraphicsItem *> selection;
+ foreach (const QWeakPointer<QGraphicsObject> &selectedObject, currentSelection) {
+ if (selectedObject.data())
+ selection << selectedObject.data();
+ }
+
+ return selection;
+}
+
+void QDeclarativeViewObserver::setSelectedItems(QList<QGraphicsItem *> items)
+{
+ data->setSelectedItems(items);
+}
+
+QList<QGraphicsItem *> QDeclarativeViewObserver::selectedItems() const
+{
+ return data->selectedItems();
+}
+
+QDeclarativeView *QDeclarativeViewObserver::declarativeView()
+{
+ return data->view;
+}
+
+void QDeclarativeViewObserverPrivate::clearHighlight()
+{
+ boundingRectHighlighter->clear();
+}
+
+void QDeclarativeViewObserverPrivate::highlight(QGraphicsObject * item, ContextFlags flags)
+{
+ highlight(QList<QGraphicsObject*>() << item, flags);
+}
+
+void QDeclarativeViewObserverPrivate::highlight(QList<QGraphicsObject *> items, ContextFlags flags)
+{
+ if (items.isEmpty())
+ return;
+
+ QList<QGraphicsObject*> objectList;
+ foreach (QGraphicsItem *item, items) {
+ QGraphicsItem *child = item;
+ if (flags & ContextSensitive)
+ child = subcomponentEditorTool->firstChildOfContext(item);
+
+ if (child) {
+ QGraphicsObject *childObject = child->toGraphicsObject();
+ if (childObject)
+ objectList << childObject;
+ }
+ }
+
+ boundingRectHighlighter->highlight(objectList);
+}
+
+bool QDeclarativeViewObserverPrivate::mouseInsideContextItem() const
+{
+ return subcomponentEditorTool->containsCursor(cursorPos.toPoint());
+}
+
+QList<QGraphicsItem*> QDeclarativeViewObserverPrivate::selectableItems(
+ const QPointF &scenePos) const
+{
+ QList<QGraphicsItem*> itemlist = view->scene()->items(scenePos);
+ return filterForCurrentContext(itemlist);
+}
+
+QList<QGraphicsItem*> QDeclarativeViewObserverPrivate::selectableItems(const QPoint &pos) const
+{
+ QList<QGraphicsItem*> itemlist = view->items(pos);
+ return filterForCurrentContext(itemlist);
+}
+
+QList<QGraphicsItem*> QDeclarativeViewObserverPrivate::selectableItems(
+ const QRectF &sceneRect, Qt::ItemSelectionMode selectionMode) const
+{
+ QList<QGraphicsItem*> itemlist = view->scene()->items(sceneRect, selectionMode);
+
+ return filterForCurrentContext(itemlist);
+}
+
+void QDeclarativeViewObserverPrivate::_q_changeToSingleSelectTool()
+{
+ currentToolMode = Constants::SelectionToolMode;
+ selectionTool->setRubberbandSelectionMode(false);
+
+ changeToSelectTool();
+
+ emit q->selectToolActivated();
+ q->sendCurrentTool(Constants::SelectionToolMode);
+}
+
+void QDeclarativeViewObserverPrivate::changeToSelectTool()
+{
+ if (currentTool == selectionTool)
+ return;
+
+ currentTool->clear();
+ currentTool = selectionTool;
+ currentTool->clear();
+ currentTool->updateSelectedItems();
+}
+
+void QDeclarativeViewObserverPrivate::_q_changeToMarqueeSelectTool()
+{
+ changeToSelectTool();
+ currentToolMode = Constants::MarqueeSelectionToolMode;
+ selectionTool->setRubberbandSelectionMode(true);
+
+ emit q->marqueeSelectToolActivated();
+ q->sendCurrentTool(Constants::MarqueeSelectionToolMode);
+}
+
+void QDeclarativeViewObserverPrivate::_q_changeToZoomTool()
+{
+ currentToolMode = Constants::ZoomMode;
+ currentTool->clear();
+ currentTool = zoomTool;
+ currentTool->clear();
+
+ emit q->zoomToolActivated();
+ q->sendCurrentTool(Constants::ZoomMode);
+}
+
+void QDeclarativeViewObserverPrivate::_q_changeToColorPickerTool()
+{
+ if (currentTool == colorPickerTool)
+ return;
+
+ currentToolMode = Constants::ColorPickerMode;
+ currentTool->clear();
+ currentTool = colorPickerTool;
+ currentTool->clear();
+
+ emit q->colorPickerActivated();
+ q->sendCurrentTool(Constants::ColorPickerMode);
+}
+
+void QDeclarativeViewObserverPrivate::_q_changeContextPathIndex(int index)
+{
+ subcomponentEditorTool->setContext(index);
+}
+
+void QDeclarativeViewObserver::setAnimationSpeed(qreal slowDownFactor)
+{
+ Q_ASSERT(slowDownFactor > 0);
+ if (data->slowDownFactor == slowDownFactor)
+ return;
+
+ animationSpeedChangeRequested(slowDownFactor);
+ sendAnimationSpeed(slowDownFactor);
+}
+
+void QDeclarativeViewObserver::setAnimationPaused(bool paused)
+{
+ if (data->animationPaused == paused)
+ return;
+
+ animationPausedChangeRequested(paused);
+ sendAnimationPaused(paused);
+}
+
+void QDeclarativeViewObserver::animationSpeedChangeRequested(qreal factor)
+{
+ if (data->slowDownFactor != factor) {
+ data->slowDownFactor = factor;
+ emit animationSpeedChanged(factor);
+ }
+
+ const float effectiveFactor = data->animationPaused ? 0 : factor;
+ QDeclarativeDebugHelper::setAnimationSlowDownFactor(effectiveFactor);
+}
+
+void QDeclarativeViewObserver::animationPausedChangeRequested(bool paused)
+{
+ if (data->animationPaused != paused) {
+ data->animationPaused = paused;
+ emit animationPausedChanged(paused);
+ }
+
+ const float effectiveFactor = paused ? 0 : data->slowDownFactor;
+ QDeclarativeDebugHelper::setAnimationSlowDownFactor(effectiveFactor);
+}
+
+
+void QDeclarativeViewObserverPrivate::_q_applyChangesFromClient()
+{
+}
+
+
+QList<QGraphicsItem*> QDeclarativeViewObserverPrivate::filterForSelection(
+ QList<QGraphicsItem*> &itemlist) const
+{
+ foreach (QGraphicsItem *item, itemlist) {
+ if (isEditorItem(item) || !subcomponentEditorTool->isChildOfContext(item))
+ itemlist.removeOne(item);
+ }
+
+ return itemlist;
+}
+
+QList<QGraphicsItem*> QDeclarativeViewObserverPrivate::filterForCurrentContext(
+ QList<QGraphicsItem*> &itemlist) const
+{
+ foreach (QGraphicsItem *item, itemlist) {
+
+ if (isEditorItem(item) || !subcomponentEditorTool->isDirectChildOfContext(item)) {
+
+ // if we're a child, but not directly, replace with the parent that is directly in context.
+ if (QGraphicsItem *contextParent = subcomponentEditorTool->firstChildOfContext(item)) {
+ if (contextParent != item) {
+ if (itemlist.contains(contextParent)) {
+ itemlist.removeOne(item);
+ } else {
+ itemlist.replace(itemlist.indexOf(item), contextParent);
+ }
+ }
+ } else {
+ itemlist.removeOne(item);
+ }
+ }
+ }
+
+ return itemlist;
+}
+
+bool QDeclarativeViewObserverPrivate::isEditorItem(QGraphicsItem *item) const
+{
+ return (item->type() == Constants::EditorItemType
+ || item->type() == Constants::ResizeHandleItemType
+ || item->data(Constants::EditorItemDataKey).toBool());
+}
+
+void QDeclarativeViewObserverPrivate::_q_onStatusChanged(QDeclarativeView::Status status)
+{
+ if (status == QDeclarativeView::Ready) {
+ if (view->rootObject()) {
+ if (subcomponentEditorTool->contextIndex() != -1)
+ subcomponentEditorTool->clear();
+ subcomponentEditorTool->pushContext(view->rootObject());
+ }
+ q->sendReloaded();
+ }
+}
+
+void QDeclarativeViewObserverPrivate::_q_onCurrentObjectsChanged(QList<QObject*> objects)
+{
+ QList<QGraphicsItem*> items;
+ QList<QGraphicsObject*> gfxObjects;
+ foreach (QObject *obj, objects) {
+ QDeclarativeItem* declarativeItem = qobject_cast<QDeclarativeItem*>(obj);
+ if (declarativeItem) {
+ items << declarativeItem;
+ if (QGraphicsObject *gfxObj = declarativeItem->toGraphicsObject())
+ gfxObjects << gfxObj;
+ }
+ }
+ if (designModeBehavior) {
+ setSelectedItemsForTools(items);
+ clearHighlight();
+ highlight(gfxObjects, QDeclarativeViewObserverPrivate::IgnoreContext);
+ }
+}
+
+// adjusts bounding boxes on edges of screen to be visible
+QRectF QDeclarativeViewObserver::adjustToScreenBoundaries(const QRectF &boundingRectInSceneSpace)
+{
+ int marginFromEdge = 1;
+ QRectF boundingRect(boundingRectInSceneSpace);
+ if (qAbs(boundingRect.left()) - 1 < 2)
+ boundingRect.setLeft(marginFromEdge);
+
+ QRect rect = data->view->rect();
+
+ if (boundingRect.right() >= rect.right())
+ boundingRect.setRight(rect.right() - marginFromEdge);
+
+ if (qAbs(boundingRect.top()) - 1 < 2)
+ boundingRect.setTop(marginFromEdge);
+
+ if (boundingRect.bottom() >= rect.bottom())
+ boundingRect.setBottom(rect.bottom() - marginFromEdge);
+
+ return boundingRect;
+}
+
+void QDeclarativeViewObserverPrivate::createToolBox()
+{
+ toolBox = new ToolBox(q->declarativeView());
+
+ QmlToolBar *toolBar = toolBox->toolBar();
+
+ QObject::connect(q, SIGNAL(selectedColorChanged(QColor)),
+ toolBar, SLOT(setColorBoxColor(QColor)));
+
+ QObject::connect(q, SIGNAL(designModeBehaviorChanged(bool)),
+ toolBar, SLOT(setDesignModeBehavior(bool)));
+
+ QObject::connect(toolBar, SIGNAL(designModeBehaviorChanged(bool)),
+ q, SLOT(setDesignModeBehavior(bool)));
+ QObject::connect(toolBar, SIGNAL(animationSpeedChanged(qreal)), q, SLOT(setAnimationSpeed(qreal)));
+ QObject::connect(toolBar, SIGNAL(animationPausedChanged(bool)), q, SLOT(setAnimationPaused(bool)));
+ QObject::connect(toolBar, SIGNAL(colorPickerSelected()), this, SLOT(_q_changeToColorPickerTool()));
+ QObject::connect(toolBar, SIGNAL(zoomToolSelected()), this, SLOT(_q_changeToZoomTool()));
+ QObject::connect(toolBar, SIGNAL(selectToolSelected()), this, SLOT(_q_changeToSingleSelectTool()));
+ QObject::connect(toolBar, SIGNAL(marqueeSelectToolSelected()),
+ this, SLOT(_q_changeToMarqueeSelectTool()));
+
+ QObject::connect(toolBar, SIGNAL(applyChangesFromQmlFileSelected()),
+ this, SLOT(_q_applyChangesFromClient()));
+
+ QObject::connect(q, SIGNAL(animationSpeedChanged(qreal)), toolBar, SLOT(setAnimationSpeed(qreal)));
+ QObject::connect(q, SIGNAL(animationPausedChanged(bool)), toolBar, SLOT(setAnimationPaused(bool)));
+
+ QObject::connect(q, SIGNAL(selectToolActivated()), toolBar, SLOT(activateSelectTool()));
+
+ // disabled features
+ //connect(d->m_toolBar, SIGNAL(applyChangesToQmlFileSelected()), SLOT(applyChangesToClient()));
+ //connect(q, SIGNAL(resizeToolActivated()), d->m_toolBar, SLOT(activateSelectTool()));
+ //connect(q, SIGNAL(moveToolActivated()), d->m_toolBar, SLOT(activateSelectTool()));
+
+ QObject::connect(q, SIGNAL(colorPickerActivated()), toolBar, SLOT(activateColorPicker()));
+ QObject::connect(q, SIGNAL(zoomToolActivated()), toolBar, SLOT(activateZoom()));
+ QObject::connect(q, SIGNAL(marqueeSelectToolActivated()),
+ toolBar, SLOT(activateMarqueeSelectTool()));
+}
+
+void QDeclarativeViewObserver::handleMessage(const QByteArray &message)
+{
+ QDataStream ds(message);
+
+ ObserverProtocol::Message type;
+ ds >> type;
+
+ switch (type) {
+ case ObserverProtocol::SetCurrentObjects: {
+ int itemCount = 0;
+ ds >> itemCount;
+
+ QList<QObject*> selectedObjects;
+ for (int i = 0; i < itemCount; ++i) {
+ int debugId = -1;
+ ds >> debugId;
+ QObject *obj = QDeclarativeDebugService::objectForId(debugId);
+
+ if (obj)
+ selectedObjects << obj;
+ }
+
+ data->_q_onCurrentObjectsChanged(selectedObjects);
+ break;
+ }
+ case ObserverProtocol::Reload: {
+ data->_q_reloadView();
+ break;
+ }
+ case ObserverProtocol::SetAnimationSpeed: {
+ qreal speed;
+ ds >> speed;
+ animationSpeedChangeRequested(speed);
+ break;
+ }
+ case ObserverProtocol::SetAnimationPaused: {
+ bool paused;
+ ds >> paused;
+ animationPausedChangeRequested(paused);
+ break;
+ }
+ case ObserverProtocol::ChangeTool: {
+ ObserverProtocol::Tool tool;
+ ds >> tool;
+ switch (tool) {
+ case ObserverProtocol::ColorPickerTool:
+ data->_q_changeToColorPickerTool();
+ break;
+ case ObserverProtocol::SelectTool:
+ data->_q_changeToSingleSelectTool();
+ break;
+ case ObserverProtocol::SelectMarqueeTool:
+ data->_q_changeToMarqueeSelectTool();
+ break;
+ case ObserverProtocol::ZoomTool:
+ data->_q_changeToZoomTool();
+ break;
+ default:
+ qWarning() << "Warning: Unhandled tool:" << tool;
+ }
+ break;
+ }
+ case ObserverProtocol::SetDesignMode: {
+ bool inDesignMode;
+ ds >> inDesignMode;
+ setDesignModeBehavior(inDesignMode);
+ break;
+ }
+ case ObserverProtocol::ShowAppOnTop: {
+ bool showOnTop;
+ ds >> showOnTop;
+ setShowAppOnTop(showOnTop);
+ break;
+ }
+ case ObserverProtocol::CreateObject: {
+ QString qml;
+ int parentId;
+ QString filename;
+ QStringList imports;
+ ds >> qml >> parentId >> imports >> filename;
+ data->_q_createQmlObject(qml, QDeclarativeDebugService::objectForId(parentId),
+ imports, filename);
+ break;
+ }
+ case ObserverProtocol::DestroyObject: {
+ int debugId;
+ ds >> debugId;
+ if (QObject* obj = QDeclarativeDebugService::objectForId(debugId))
+ obj->deleteLater();
+ break;
+ }
+ case ObserverProtocol::MoveObject: {
+ int debugId, newParent;
+ ds >> debugId >> newParent;
+ data->_q_reparentQmlObject(QDeclarativeDebugService::objectForId(debugId),
+ QDeclarativeDebugService::objectForId(newParent));
+ break;
+ }
+ case ObserverProtocol::ObjectIdList: {
+ int itemCount;
+ ds >> itemCount;
+ data->stringIdForObjectId.clear();
+ for (int i = 0; i < itemCount; ++i) {
+ int itemDebugId;
+ QString itemIdString;
+ ds >> itemDebugId
+ >> itemIdString;
+
+ data->stringIdForObjectId.insert(itemDebugId, itemIdString);
+ }
+ break;
+ }
+ case ObserverProtocol::SetContextPathIdx: {
+ int contextPathIndex;
+ ds >> contextPathIndex;
+ data->_q_changeContextPathIndex(contextPathIndex);
+ break;
+ }
+ case ObserverProtocol::ClearComponentCache: {
+ data->_q_clearComponentCache();
+ break;
+ }
+ default:
+ qWarning() << "Warning: Not handling message:" << type;
+ }
+}
+
+void QDeclarativeViewObserver::sendDesignModeBehavior(bool inDesignMode)
+{
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+
+ ds << ObserverProtocol::SetDesignMode
+ << inDesignMode;
+
+ data->debugService->sendMessage(message);
+}
+
+void QDeclarativeViewObserver::sendCurrentObjects(QList<QObject*> objects)
+{
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+
+ ds << ObserverProtocol::CurrentObjectsChanged
+ << objects.length();
+
+ foreach (QObject *object, objects) {
+ int id = QDeclarativeDebugService::idForObject(object);
+ ds << id;
+ }
+
+ data->debugService->sendMessage(message);
+}
+
+void QDeclarativeViewObserver::sendCurrentTool(Constants::DesignTool toolId)
+{
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+
+ ds << ObserverProtocol::ToolChanged
+ << toolId;
+
+ data->debugService->sendMessage(message);
+}
+
+void QDeclarativeViewObserver::sendAnimationSpeed(qreal slowDownFactor)
+{
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+
+ ds << ObserverProtocol::AnimationSpeedChanged
+ << slowDownFactor;
+
+ data->debugService->sendMessage(message);
+}
+
+void QDeclarativeViewObserver::sendAnimationPaused(bool paused)
+{
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+
+ ds << ObserverProtocol::AnimationPausedChanged
+ << paused;
+
+ data->debugService->sendMessage(message);
+}
+
+void QDeclarativeViewObserver::sendReloaded()
+{
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+
+ ds << ObserverProtocol::Reloaded;
+
+ data->debugService->sendMessage(message);
+}
+
+void QDeclarativeViewObserver::sendShowAppOnTop(bool showAppOnTop)
+{
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+
+ ds << ObserverProtocol::ShowAppOnTop << showAppOnTop;
+
+ data->debugService->sendMessage(message);
+}
+
+void QDeclarativeViewObserver::sendColorChanged(const QColor &color)
+{
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+
+ ds << ObserverProtocol::ColorChanged
+ << color;
+
+ data->debugService->sendMessage(message);
+}
+
+void QDeclarativeViewObserver::sendContextPathUpdated(const QStringList &contextPath)
+{
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+
+ ds << ObserverProtocol::ContextPathUpdated
+ << contextPath;
+
+ data->debugService->sendMessage(message);
+}
+
+QString QDeclarativeViewObserver::idStringForObject(QObject *obj) const
+{
+ int id = QDeclarativeDebugService::idForObject(obj);
+ QString idString = data->stringIdForObjectId.value(id, QString());
+ return idString;
+}
+
+QT_END_NAMESPACE
+
+#include "qdeclarativeviewobserver.moc"
diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p.h b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p.h
new file mode 100644
index 0000000..6e986c2
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEVIEWOBSERVER_P_H
+#define QDECLARATIVEVIEWOBSERVER_P_H
+
+#include <private/qdeclarativeglobal_p.h>
+#include "qmlobserverconstants_p.h"
+
+#include <QtCore/QScopedPointer>
+#include <QtDeclarative/QDeclarativeView>
+
+QT_FORWARD_DECLARE_CLASS(QDeclarativeItem)
+QT_FORWARD_DECLARE_CLASS(QMouseEvent)
+QT_FORWARD_DECLARE_CLASS(QToolBar)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeViewObserverPrivate;
+
+class QDeclarativeViewObserver : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QDeclarativeViewObserver(QDeclarativeView *view, QObject *parent = 0);
+ ~QDeclarativeViewObserver();
+
+ void setSelectedItems(QList<QGraphicsItem *> items);
+ QList<QGraphicsItem *> selectedItems() const;
+
+ QDeclarativeView *declarativeView();
+
+ QRectF adjustToScreenBoundaries(const QRectF &boundingRectInSceneSpace);
+
+ bool showAppOnTop() const;
+
+ void sendDesignModeBehavior(bool inDesignMode);
+ void sendCurrentObjects(QList<QObject*> items);
+ void sendAnimationSpeed(qreal slowDownFactor);
+ void sendAnimationPaused(bool paused);
+ void sendCurrentTool(Constants::DesignTool toolId);
+ void sendReloaded();
+ void sendShowAppOnTop(bool showAppOnTop);
+
+ QString idStringForObject(QObject *obj) const;
+
+public Q_SLOTS:
+ void sendColorChanged(const QColor &color);
+ void sendContextPathUpdated(const QStringList &contextPath);
+
+ void setDesignModeBehavior(bool value);
+ bool designModeBehavior();
+
+ void setShowAppOnTop(bool appOnTop);
+
+ void setAnimationSpeed(qreal factor);
+ void setAnimationPaused(bool paused);
+
+ void setObserverContext(int contextIndex);
+
+Q_SIGNALS:
+ void designModeBehaviorChanged(bool inDesignMode);
+ void showAppOnTopChanged(bool showAppOnTop);
+ void reloadRequested();
+ void marqueeSelectToolActivated();
+ void selectToolActivated();
+ void zoomToolActivated();
+ void colorPickerActivated();
+ void selectedColorChanged(const QColor &color);
+
+ void animationSpeedChanged(qreal factor);
+ void animationPausedChanged(bool paused);
+
+ void inspectorContextCleared();
+ void inspectorContextPushed(const QString &contextTitle);
+ void inspectorContextPopped();
+
+protected:
+ bool eventFilter(QObject *obj, QEvent *event);
+
+ bool leaveEvent(QEvent *);
+ bool mousePressEvent(QMouseEvent *event);
+ bool mouseMoveEvent(QMouseEvent *event);
+ bool mouseReleaseEvent(QMouseEvent *event);
+ bool keyPressEvent(QKeyEvent *event);
+ bool keyReleaseEvent(QKeyEvent *keyEvent);
+ bool mouseDoubleClickEvent(QMouseEvent *event);
+ bool wheelEvent(QWheelEvent *event);
+
+ void setSelectedItemsForTools(QList<QGraphicsItem *> items);
+
+private slots:
+ void handleMessage(const QByteArray &message);
+
+ void animationSpeedChangeRequested(qreal factor);
+ void animationPausedChangeRequested(bool paused);
+
+private:
+ Q_DISABLE_COPY(QDeclarativeViewObserver)
+
+ inline QDeclarativeViewObserverPrivate *d_func() { return data.data(); }
+ QScopedPointer<QDeclarativeViewObserverPrivate> data;
+ friend class QDeclarativeViewObserverPrivate;
+ friend class AbstractLiveEditTool;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEVIEWOBSERVER_P_H
diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p_p.h b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p_p.h
new file mode 100644
index 0000000..6022555
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p_p.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEVIEWOBSERVER_P_P_H
+#define QDECLARATIVEVIEWOBSERVER_P_P_H
+
+#include "qdeclarativeviewobserver_p.h"
+
+#include <QtCore/QWeakPointer>
+#include <QtCore/QPointF>
+
+#include "QtDeclarative/private/qdeclarativeobserverservice_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeViewObserver;
+class LiveSelectionTool;
+class ZoomTool;
+class ColorPickerTool;
+class LiveLayerItem;
+class BoundingRectHighlighter;
+class SubcomponentEditorTool;
+class ToolBox;
+class AbstractLiveEditTool;
+
+class QDeclarativeViewObserverPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ enum ContextFlags {
+ IgnoreContext,
+ ContextSensitive
+ };
+
+ QDeclarativeViewObserverPrivate(QDeclarativeViewObserver *);
+ ~QDeclarativeViewObserverPrivate();
+
+ QDeclarativeView *view;
+ QDeclarativeViewObserver *q;
+ QDeclarativeObserverService *debugService;
+ QWeakPointer<QWidget> viewport;
+ QHash<int, QString> stringIdForObjectId;
+
+ QPointF cursorPos;
+ QList<QWeakPointer<QGraphicsObject> > currentSelection;
+
+ Constants::DesignTool currentToolMode;
+ AbstractLiveEditTool *currentTool;
+
+ LiveSelectionTool *selectionTool;
+ ZoomTool *zoomTool;
+ ColorPickerTool *colorPickerTool;
+ SubcomponentEditorTool *subcomponentEditorTool;
+ LiveLayerItem *manipulatorLayer;
+
+ BoundingRectHighlighter *boundingRectHighlighter;
+
+ bool designModeBehavior;
+ bool showAppOnTop;
+
+ bool animationPaused;
+ qreal slowDownFactor;
+
+ ToolBox *toolBox;
+
+ void setViewport(QWidget *widget);
+
+ void clearEditorItems();
+ void createToolBox();
+ void changeToSelectTool();
+ QList<QGraphicsItem*> filterForCurrentContext(QList<QGraphicsItem*> &itemlist) const;
+ QList<QGraphicsItem*> filterForSelection(QList<QGraphicsItem*> &itemlist) const;
+
+ QList<QGraphicsItem*> selectableItems(const QPoint &pos) const;
+ QList<QGraphicsItem*> selectableItems(const QPointF &scenePos) const;
+ QList<QGraphicsItem*> selectableItems(const QRectF &sceneRect, Qt::ItemSelectionMode selectionMode) const;
+
+ void setSelectedItemsForTools(QList<QGraphicsItem *> items);
+ void setSelectedItems(QList<QGraphicsItem *> items);
+ QList<QGraphicsItem *> selectedItems() const;
+
+ void changeTool(Constants::DesignTool tool,
+ Constants::ToolFlags flags = Constants::NoToolFlags);
+
+ void clearHighlight();
+ void highlight(QList<QGraphicsObject *> item, ContextFlags flags = ContextSensitive);
+ void highlight(QGraphicsObject *item, ContextFlags flags = ContextSensitive);
+
+ bool mouseInsideContextItem() const;
+ bool isEditorItem(QGraphicsItem *item) const;
+
+ QGraphicsItem *currentRootItem() const;
+
+ void enterContext(QGraphicsItem *itemToEnter);
+
+public slots:
+ void _q_setToolBoxVisible(bool visible);
+
+ void _q_reloadView();
+ void _q_onStatusChanged(QDeclarativeView::Status status);
+ void _q_onCurrentObjectsChanged(QList<QObject*> objects);
+ void _q_applyChangesFromClient();
+ void _q_createQmlObject(const QString &qml, QObject *parent,
+ const QStringList &imports, const QString &filename = QString());
+ void _q_reparentQmlObject(QObject *, QObject *);
+
+ void _q_changeToSingleSelectTool();
+ void _q_changeToMarqueeSelectTool();
+ void _q_changeToZoomTool();
+ void _q_changeToColorPickerTool();
+ void _q_changeContextPathIndex(int index);
+ void _q_clearComponentCache();
+ void _q_removeFromSelection(QObject *);
+
+public:
+ static QDeclarativeViewObserverPrivate *get(QDeclarativeViewObserver *v) { return v->d_func(); }
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEVIEWOBSERVER_P_P_H
diff --git a/src/plugins/qmltooling/declarativeobserver/qmlobserverconstants_p.h b/src/plugins/qmltooling/declarativeobserver/qmlobserverconstants_p.h
new file mode 100644
index 0000000..353e235
--- /dev/null
+++ b/src/plugins/qmltooling/declarativeobserver/qmlobserverconstants_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLOBSERVERCONSTANTS_H
+#define QMLOBSERVERCONSTANTS_H
+
+#include <QtDeclarative/private/qdeclarativeglobal_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+namespace Constants {
+
+enum DesignTool {
+ NoTool = 0,
+ SelectionToolMode = 1,
+ MarqueeSelectionToolMode = 2,
+ MoveToolMode = 3,
+ ResizeToolMode = 4,
+ ColorPickerMode = 5,
+ ZoomMode = 6
+};
+
+enum ToolFlags {
+ NoToolFlags = 0,
+ UseCursorPos = 1
+};
+
+static const int DragStartTime = 50;
+
+static const int DragStartDistance = 20;
+
+static const double ZoomSnapDelta = 0.04;
+
+static const int EditorItemDataKey = 1000;
+
+enum GraphicsItemTypes {
+ EditorItemType = 0xEAAA,
+ ResizeHandleItemType = 0xEAEA
+};
+
+
+} // namespace Constants
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLOBSERVERCONSTANTS_H
diff --git a/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp b/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp
index 1c91c34..ac32081 100644
--- a/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp
+++ b/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp
@@ -109,6 +109,12 @@ void QmlOstPlugin::disconnect()
d->protocol = 0;
}
+bool QmlOstPlugin::waitForMessage()
+{
+ Q_D(QmlOstPlugin);
+ return d->protocol->waitForReadyRead(-1);
+}
+
void QmlOstPlugin::setPort(int port, bool block)
{
Q_UNUSED(port);
diff --git a/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.h b/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.h
index eee6ee1..b4ff377 100644
--- a/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.h
+++ b/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.h
@@ -68,6 +68,7 @@ public:
bool isConnected() const;
void send(const QByteArray &message);
void disconnect();
+ bool waitForMessage();
private Q_SLOTS:
void readyRead();
diff --git a/src/plugins/qmltooling/qmldbg_ost/qostdevice.cpp b/src/plugins/qmltooling/qmldbg_ost/qostdevice.cpp
index 21b0169..d3b2661 100644
--- a/src/plugins/qmltooling/qmldbg_ost/qostdevice.cpp
+++ b/src/plugins/qmltooling/qmldbg_ost/qostdevice.cpp
@@ -57,6 +57,8 @@ public:
Cancel();
}
+ TInt& AoFlags() { return ((TInt*)&iStatus)[1]; }
+
private:
void RunL();
void DoCancel();
@@ -65,6 +67,7 @@ private:
RUsbOstComm ost;
TBuf8<4096> readBuf;
QByteArray dataBuf;
+ TBool inReadyRead;
};
QOstDevice::QOstDevice(QObject *parent) :
@@ -116,7 +119,11 @@ void QOstDevicePrivate::RunL()
ost.ReadMessage(iStatus, readBuf);
SetActive();
- emit q->readyRead();
+ if (!inReadyRead) {
+ inReadyRead = true;
+ emit q->readyRead();
+ inReadyRead = false;
+ }
} else {
q->setErrorString(QString("Error %1 from RUsbOstComm::ReadMessage()").arg(iStatus.Int()));
}
@@ -178,3 +185,36 @@ qint64 QOstDevice::bytesAvailable() const
Q_D(const QOstDevice);
return d->dataBuf.length();
}
+
+bool QOstDevice::waitForReadyRead(int msecs)
+{
+ Q_D(QOstDevice);
+ if (msecs >= 0) {
+ RTimer timer;
+ TInt err = timer.CreateLocal();
+ if (err) return false;
+ TRequestStatus timeoutStat;
+ timer.After(timeoutStat, msecs*1000);
+ User::WaitForRequest(timeoutStat, d->iStatus);
+ if (timeoutStat != KRequestPending) {
+ // Timed out
+ timer.Close();
+ return false;
+ } else {
+ // We got data, so cancel timer
+ timer.Cancel();
+ User::WaitForRequest(timeoutStat);
+ timer.Close();
+ // And drop through
+ }
+ } else {
+ // Just wait forever for data
+ User::WaitForRequest(d->iStatus);
+ }
+
+ // If we get here we have data
+ TInt err = d->iStatus.Int();
+ d->AoFlags() &= ~3; // This is necessary to clean up the scheduler as you're not supposed to bypass it like this
+ TRAP_IGNORE(d->RunL());
+ return err == KErrNone;
+}
diff --git a/src/plugins/qmltooling/qmldbg_ost/qostdevice.h b/src/plugins/qmltooling/qmldbg_ost/qostdevice.h
index 2c26ff7..200e607 100644
--- a/src/plugins/qmltooling/qmldbg_ost/qostdevice.h
+++ b/src/plugins/qmltooling/qmldbg_ost/qostdevice.h
@@ -61,10 +61,12 @@ public:
bool open(int ostProtocolId);
void close();
+ bool waitForReadyRead(int msecs);
+ qint64 bytesAvailable() const;
+
protected:
qint64 readData(char *data, qint64 maxSize);
qint64 writeData(const char *data, qint64 maxSize);
- qint64 bytesAvailable() const;
private:
QOstDevicePrivate* d_ptr;
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
index 85c43e3..7cd3d73 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
+++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
@@ -41,6 +41,7 @@
#include "qtcpserverconnection.h"
+#include <QtCore/qplugin.h>
#include <QtNetwork/qtcpserver.h>
#include <QtNetwork/qtcpsocket.h>
@@ -54,6 +55,7 @@ public:
QTcpServerConnectionPrivate();
int port;
+ bool block;
QTcpSocket *socket;
QPacketProtocol *protocol;
QTcpServer *tcpServer;
@@ -63,6 +65,7 @@ public:
QTcpServerConnectionPrivate::QTcpServerConnectionPrivate() :
port(0),
+ block(false),
socket(0),
protocol(0),
tcpServer(0),
@@ -119,10 +122,17 @@ void QTcpServerConnection::disconnect()
d->socket = 0;
}
+bool QTcpServerConnection::waitForMessage()
+{
+ Q_D(QTcpServerConnection);
+ return d->protocol->waitForReadyRead(-1);
+}
+
void QTcpServerConnection::setPort(int port, bool block)
{
Q_D(QTcpServerConnection);
d->port = port;
+ d->block = block;
listen();
if (block)
@@ -169,8 +179,11 @@ void QTcpServerConnection::newConnection()
d->socket->setParent(this);
d->protocol = new QPacketProtocol(d->socket, this);
QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
-}
+ if (d->block) {
+ d->protocol->waitForReadyRead(-1);
+ }
+}
Q_EXPORT_PLUGIN2(tcpserver, QTcpServerConnection)
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h
index 66a10e1..dd5a5ec 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h
+++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h
@@ -42,7 +42,6 @@
#ifndef QTCPSERVERCONNECTION_H
#define QTCPSERVERCONNECTION_H
-#include <QtGui/QStylePlugin>
#include <QtDeclarative/private/qdeclarativedebugserverconnection_p.h>
QT_BEGIN_NAMESPACE
@@ -67,6 +66,7 @@ public:
bool isConnected() const;
void send(const QByteArray &message);
void disconnect();
+ bool waitForMessage();
void listen();
void waitForConnection();
diff --git a/src/plugins/qmltooling/qmltooling.pro b/src/plugins/qmltooling/qmltooling.pro
index 9b3346f..0d60eb1 100644
--- a/src/plugins/qmltooling/qmltooling.pro
+++ b/src/plugins/qmltooling/qmltooling.pro
@@ -1,4 +1,4 @@
TEMPLATE = subdirs
-SUBDIRS = qmldbg_tcp
+SUBDIRS = qmldbg_tcp declarativeobserver
symbian:SUBDIRS += qmldbg_ost