diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
index 3b959f83af0..61e1bd0e560 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
@@ -96,18 +96,28 @@ void QmlProjectRunConfiguration::ctor()
setDisplayName(tr("QML Viewer", "QMLRunConfiguration display name."));
- // prepend creator/bin dir to search path (only useful for special creator-qml package)
- const QString searchPath = QCoreApplication::applicationDirPath()
- + Utils::SynchronousProcess::pathSeparator()
- + QString(qgetenv("PATH"));
-
#ifdef Q_OS_MAC
const QString qmlViewerName = QLatin1String("QMLViewer");
#else
const QString qmlViewerName = QLatin1String("qmlviewer");
#endif
- m_qmlViewerDefaultPath = Utils::SynchronousProcess::locateBinary(searchPath, qmlViewerName);
+ if (m_qmlViewerDefaultPath.isEmpty()) {
+ QDir qmlviewerExecutable(QCoreApplication::applicationDirPath());
+#ifndef Q_OS_WIN
+ m_qmlViewerDefaultPath = qmlviewerExecutable.absoluteFilePath(qmlViewerName);
+#else
+ m_qmlViewerDefaultPath = qmlviewerExecutable.absoluteFilePath(QString("%1.exe").arg(qmlViewerName));
+#endif
+ QFileInfo qmlviewerFileInfo(m_qmlViewerDefaultPath);
+ if (!qmlviewerFileInfo.exists()) {
+ qWarning() << "QmlProjectRunConfiguration::ctor(): qmlviewer executable does not exist at" << m_qmlViewerDefaultPath;
+ m_qmlViewerDefaultPath.clear();
+ } else if (!qmlviewerFileInfo.isFile()) {
+ qWarning() << "QmlProjectRunConfiguration::ctor(): " << m_qmlViewerDefaultPath << " is not a file";
+ m_qmlViewerDefaultPath.clear();
+ }
+ }
}
QmlProjectRunConfiguration::~QmlProjectRunConfiguration()
diff --git a/src/tools/qml/qml.pro b/src/tools/qml/qml.pro
index fb6d736077a..42a03b117c3 100644
--- a/src/tools/qml/qml.pro
+++ b/src/tools/qml/qml.pro
@@ -4,7 +4,7 @@ contains(QT_CONFIG, declarative) {
include(../../private_headers.pri)
exists($${QT_PRIVATE_HEADERS}/QtDeclarative/private/qdeclarativemetatype_p.h) {
- SUBDIRS += qmldump
+ SUBDIRS += qmldump qmlviewer
} else {
warning()
warning("QmlDump utility has been disabled")
@@ -12,6 +12,11 @@ contains(QT_CONFIG, declarative) {
warning("This means the Qml editor will lack correct completion and type checking.")
warning("To enable it, pass 'QT_PRIVATE_HEADERS=$QTDIR/include' to qmake, where $QTDIR is the source directory of qt.")
warning()
+ warning("QmlViewer has been disabled")
+ warning("This application depends on private headers from QtDeclarative module.")
+ warning("This means the QML debugging facilities will be limited.")
+ warning("To enable it, pass 'QT_PRIVATE_HEADERS=$QTDIR/include' to qmake, where $QTDIR is the source directory of qt.")
+ warning()
}
}
diff --git a/src/tools/qml/qmlviewer/Info_mac.plist b/src/tools/qml/qmlviewer/Info_mac.plist
new file mode 100644
index 00000000000..80ca6a35269
--- /dev/null
+++ b/src/tools/qml/qmlviewer/Info_mac.plist
@@ -0,0 +1,18 @@
+
+
+
+
+ CFBundleIconFile
+ @ICON@
+ CFBundleIdentifier
+ com.nokia.qt.qml
+ CFBundlePackageType
+ APPL
+ CFBundleGetInfoString
+ Created by Qt/QMake
+ CFBundleSignature
+ @TYPEINFO@
+ CFBundleExecutable
+ @EXECUTABLE@
+
+
diff --git a/src/tools/qml/qmlviewer/content/Browser.qml b/src/tools/qml/qmlviewer/content/Browser.qml
new file mode 100644
index 00000000000..ff2bb476473
--- /dev/null
+++ b/src/tools/qml/qmlviewer/content/Browser.qml
@@ -0,0 +1,284 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 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$
+**
+****************************************************************************/
+
+import Qt 4.7
+import Qt.labs.folderlistmodel 1.0
+
+Rectangle {
+ id: root
+ property bool keyPressed: false
+ property variant folders: folders1
+ property variant view: view1
+ width: 320
+ height: 480
+ color: palette.window
+
+ FolderListModel {
+ id: folders1
+ nameFilters: [ "*.qml" ]
+ folder: qmlViewerFolder
+ }
+ FolderListModel {
+ id: folders2
+ nameFilters: [ "*.qml" ]
+ folder: qmlViewerFolder
+ }
+
+ SystemPalette { id: palette }
+
+ function down(path) {
+ if (folders == folders1) {
+ view = view2
+ folders = folders2;
+ view1.state = "exitLeft";
+ } else {
+ view = view1
+ folders = folders1;
+ view2.state = "exitLeft";
+ }
+ view.x = root.width;
+ view.state = "current";
+ view.focus = true;
+ folders.folder = path;
+ }
+ function up() {
+ var path = folders.parentFolder;
+ if (folders == folders1) {
+ view = view2
+ folders = folders2;
+ view1.state = "exitRight";
+ } else {
+ view = view1
+ folders = folders1;
+ view2.state = "exitRight";
+ }
+ view.x = -root.width;
+ view.state = "current";
+ view.focus = true;
+ folders.folder = path;
+ }
+
+ Component {
+ id: folderDelegate
+ Rectangle {
+ id: wrapper
+ function launch() {
+ if (folders.isFolder(index)) {
+ down(filePath);
+ } else {
+ qmlViewer.launch(filePath);
+ }
+ }
+ width: root.width
+ height: 52
+ color: "transparent"
+ Rectangle {
+ id: highlight; visible: false
+ anchors.fill: parent
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ }
+ Item {
+ width: 48; height: 48
+ Image { source: "images/folder.png"; anchors.centerIn: parent; visible: folders.isFolder(index)}
+ }
+ Text {
+ id: nameText
+ anchors.fill: parent; verticalAlignment: Text.AlignVCenter
+ text: fileName
+ anchors.leftMargin: 54
+ font.pixelSize: 32
+ color: (wrapper.ListView.isCurrentItem && root.keyPressed) ? palette.highlightedText : palette.windowText
+ elide: Text.ElideRight
+ }
+ MouseArea {
+ id: mouseRegion
+ anchors.fill: parent
+ onClicked: { if (folders == wrapper.ListView.view.model) launch() }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: mouseRegion.pressed
+ PropertyChanges { target: highlight; visible: true }
+ PropertyChanges { target: nameText; color: palette.highlightedText }
+ }
+ ]
+ }
+ }
+
+ ListView {
+ id: view1
+ anchors.top: titleBar.bottom
+ anchors.bottom: parent.bottom
+ x: 0
+ width: parent.width
+ model: folders1
+ delegate: folderDelegate
+ highlight: Rectangle { color: palette.highlight; visible: root.keyPressed && view1.count != 0 }
+ highlightMoveSpeed: 1000
+ pressDelay: 100
+ focus: true
+ state: "current"
+ states: [
+ State {
+ name: "current"
+ PropertyChanges { target: view1; x: 0 }
+ },
+ State {
+ name: "exitLeft"
+ PropertyChanges { target: view1; x: -root.width }
+ },
+ State {
+ name: "exitRight"
+ PropertyChanges { target: view1; x: root.width }
+ }
+ ]
+ transitions: [
+ Transition {
+ to: "current"
+ SequentialAnimation {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ },
+ Transition {
+ NumberAnimation { properties: "x"; duration: 250 }
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ ]
+ Keys.onPressed: { root.keyPressed = true; }
+ }
+
+ ListView {
+ id: view2
+ anchors.top: titleBar.bottom
+ anchors.bottom: parent.bottom
+ x: parent.width
+ width: parent.width
+ model: folders2
+ delegate: folderDelegate
+ highlight: Rectangle { color: palette.highlight; visible: root.keyPressed && view2.count != 0 }
+ highlightMoveSpeed: 1000
+ pressDelay: 100
+ states: [
+ State {
+ name: "current"
+ PropertyChanges { target: view2; x: 0 }
+ },
+ State {
+ name: "exitLeft"
+ PropertyChanges { target: view2; x: -root.width }
+ },
+ State {
+ name: "exitRight"
+ PropertyChanges { target: view2; x: root.width }
+ }
+ ]
+ transitions: [
+ Transition {
+ to: "current"
+ SequentialAnimation {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ },
+ Transition {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ ]
+ Keys.onPressed: { root.keyPressed = true; }
+ }
+
+ Keys.onPressed: {
+ root.keyPressed = true;
+ if (event.key == Qt.Key_Return || event.key == Qt.Key_Select || event.key == Qt.Key_Right) {
+ view.currentItem.launch();
+ event.accepted = true;
+ } else if (event.key == Qt.Key_Left) {
+ up();
+ }
+ }
+
+ BorderImage {
+ source: "images/titlebar.sci";
+ width: parent.width;
+ height: 52
+ y: -7
+ id: titleBar
+
+ Rectangle {
+ id: upButton
+ width: 48
+ height: titleBar.height - 7
+ color: "transparent"
+
+ Image { anchors.centerIn: parent; source: "images/up.png" }
+ MouseArea { id: upRegion; anchors.centerIn: parent
+ width: 56
+ height: 56
+ onClicked: if (folders.parentFolder != "") up()
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: upRegion.pressed
+ PropertyChanges { target: upButton; color: palette.highlight }
+ }
+ ]
+ }
+ Rectangle {
+ color: "gray"
+ x: 48
+ width: 1
+ height: 44
+ }
+
+ Text {
+ anchors.left: upButton.right; anchors.right: parent.right; height: parent.height
+ anchors.leftMargin: 4; anchors.rightMargin: 4
+ text: folders.folder
+ color: "white"
+ elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
+ font.pixelSize: 32
+ }
+ }
+}
diff --git a/src/tools/qml/qmlviewer/content/images/folder.png b/src/tools/qml/qmlviewer/content/images/folder.png
new file mode 100644
index 00000000000..e53e2ad464e
Binary files /dev/null and b/src/tools/qml/qmlviewer/content/images/folder.png differ
diff --git a/src/tools/qml/qmlviewer/content/images/titlebar.png b/src/tools/qml/qmlviewer/content/images/titlebar.png
new file mode 100644
index 00000000000..51c90082d05
Binary files /dev/null and b/src/tools/qml/qmlviewer/content/images/titlebar.png differ
diff --git a/src/tools/qml/qmlviewer/content/images/titlebar.sci b/src/tools/qml/qmlviewer/content/images/titlebar.sci
new file mode 100644
index 00000000000..0418d94cd60
--- /dev/null
+++ b/src/tools/qml/qmlviewer/content/images/titlebar.sci
@@ -0,0 +1,5 @@
+border.left: 10
+border.top: 12
+border.bottom: 12
+border.right: 10
+source: titlebar.png
diff --git a/src/tools/qml/qmlviewer/content/images/up.png b/src/tools/qml/qmlviewer/content/images/up.png
new file mode 100644
index 00000000000..b05f8025d01
Binary files /dev/null and b/src/tools/qml/qmlviewer/content/images/up.png differ
diff --git a/src/tools/qml/qmlviewer/deviceorientation.cpp b/src/tools/qml/qmlviewer/deviceorientation.cpp
new file mode 100644
index 00000000000..e7c70d5fde7
--- /dev/null
+++ b/src/tools/qml/qmlviewer/deviceorientation.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceorientation.h"
+
+QT_USE_NAMESPACE
+
+class DefaultDeviceOrientation : public DeviceOrientation
+{
+ Q_OBJECT
+public:
+ DefaultDeviceOrientation() : DeviceOrientation(), m_orientation(DeviceOrientation::Portrait) {}
+
+ Orientation orientation() const {
+ return m_orientation;
+ }
+
+ void setOrientation(Orientation o) {
+ if (o != m_orientation) {
+ m_orientation = o;
+ emit orientationChanged();
+ }
+ }
+
+ Orientation m_orientation;
+};
+
+DeviceOrientation* DeviceOrientation::instance()
+{
+ static DefaultDeviceOrientation *o = 0;
+ if (!o)
+ o = new DefaultDeviceOrientation;
+ return o;
+}
+
+#include "deviceorientation.moc"
+
diff --git a/src/tools/qml/qmlviewer/deviceorientation.h b/src/tools/qml/qmlviewer/deviceorientation.h
new file mode 100644
index 00000000000..817bfc8528c
--- /dev/null
+++ b/src/tools/qml/qmlviewer/deviceorientation.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ORIENTATION_H
+#define ORIENTATION_H
+
+#include
+
+QT_BEGIN_NAMESPACE
+
+class DeviceOrientationPrivate;
+class DeviceOrientation : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(Orientation)
+public:
+ enum Orientation {
+ UnknownOrientation,
+ Portrait,
+ Landscape,
+ PortraitInverted,
+ LandscapeInverted
+ };
+
+ virtual Orientation orientation() const = 0;
+ virtual void setOrientation(Orientation) = 0;
+
+ static DeviceOrientation *instance();
+
+signals:
+ void orientationChanged();
+
+protected:
+ DeviceOrientation() {}
+
+private:
+ DeviceOrientationPrivate *d_ptr;
+ friend class DeviceOrientationPrivate;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/tools/qml/qmlviewer/deviceorientation_maemo5.cpp b/src/tools/qml/qmlviewer/deviceorientation_maemo5.cpp
new file mode 100644
index 00000000000..e942579b70d
--- /dev/null
+++ b/src/tools/qml/qmlviewer/deviceorientation_maemo5.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceorientation.h"
+#include
+
+#include
+#include
+
+class MaemoOrientation : public DeviceOrientation
+{
+ Q_OBJECT
+public:
+ MaemoOrientation()
+ : o(UnknownOrientation)
+ {
+ // enable the orientation sensor
+ QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH,
+ MCE_REQUEST_IF, MCE_ACCELEROMETER_ENABLE_REQ));
+
+ // query the initial orientation
+ QDBusMessage reply = QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH,
+ MCE_REQUEST_IF, MCE_DEVICE_ORIENTATION_GET));
+ if (reply.type() == QDBusMessage::ErrorMessage) {
+ qWarning("Unable to retrieve device orientation: %s", qPrintable(reply.errorMessage()));
+ } else {
+ o = toOrientation(reply.arguments().value(0).toString());
+ }
+
+ // connect to the orientation change signal
+ QDBusConnection::systemBus().connect(QString(), MCE_SIGNAL_PATH, MCE_SIGNAL_IF,
+ MCE_DEVICE_ORIENTATION_SIG,
+ this,
+ SLOT(deviceOrientationChanged(QString)));
+ }
+
+ ~MaemoOrientation()
+ {
+ // disable the orientation sensor
+ QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH,
+ MCE_REQUEST_IF, MCE_ACCELEROMETER_DISABLE_REQ));
+ }
+
+ inline Orientation orientation() const
+ {
+ return o;
+ }
+
+ void setOrientation(Orientation o)
+ {
+ }
+
+private Q_SLOTS:
+ void deviceOrientationChanged(const QString &newOrientation)
+ {
+ o = toOrientation(newOrientation);
+
+ emit orientationChanged();
+// printf("%d\n", o);
+ }
+
+private:
+ static Orientation toOrientation(const QString &nativeOrientation)
+ {
+ if (nativeOrientation == MCE_ORIENTATION_LANDSCAPE)
+ return Landscape;
+ else if (nativeOrientation == MCE_ORIENTATION_LANDSCAPE_INVERTED)
+ return LandscapeInverted;
+ else if (nativeOrientation == MCE_ORIENTATION_PORTRAIT)
+ return Portrait;
+ else if (nativeOrientation == MCE_ORIENTATION_PORTRAIT_INVERTED)
+ return PortraitInverted;
+ return UnknownOrientation;
+ }
+
+private:
+ Orientation o;
+};
+
+DeviceOrientation* DeviceOrientation::instance()
+{
+ static MaemoOrientation *o = new MaemoOrientation;
+ return o;
+}
+
+#include "deviceorientation_maemo5.moc"
diff --git a/src/tools/qml/qmlviewer/editor/abstractformeditortool.cpp b/src/tools/qml/qmlviewer/editor/abstractformeditortool.cpp
new file mode 100644
index 00000000000..721a3464459
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/abstractformeditortool.cpp
@@ -0,0 +1,193 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "abstractformeditortool.h"
+#include "qdeclarativedesignview.h"
+
+#include
+#include
+
+#include
+#include
+#include
+
+namespace QmlViewer {
+
+AbstractFormEditorTool::AbstractFormEditorTool(QDeclarativeDesignView *editorView)
+ : QObject(editorView), m_view(editorView)
+{
+}
+
+
+AbstractFormEditorTool::~AbstractFormEditorTool()
+{
+
+}
+
+QDeclarativeDesignView* AbstractFormEditorTool::view() const
+{
+ return m_view;
+}
+
+QGraphicsScene* AbstractFormEditorTool::scene() const
+{
+ return view()->scene();
+}
+
+void AbstractFormEditorTool::setItems(const QList &itemList)
+{
+ m_itemList = itemList;
+ selectedItemsChanged(m_itemList);
+}
+
+QList AbstractFormEditorTool::items() const
+{
+ return m_itemList;
+}
+
+bool AbstractFormEditorTool::topItemIsMovable(const QList & itemList)
+{
+ QGraphicsItem *firstSelectableItem = topMovableGraphicsItem(itemList);
+ if (firstSelectableItem == 0)
+ return false;
+
+ QDeclarativeItem *declarativeItem = dynamic_cast(firstSelectableItem->toGraphicsObject());
+
+ if (declarativeItem != 0)
+ return true;
+
+ return false;
+
+}
+
+bool AbstractFormEditorTool::topSelectedItemIsMovable(const QList &itemList)
+{
+ QList selectedItems = view()->selectedItems();
+
+ foreach (QGraphicsItem *item, itemList) {
+ QDeclarativeItem *declarativeItem = toQDeclarativeItem(item);
+ if (declarativeItem
+ && selectedItems.contains(declarativeItem)
+ /*&& (declarativeItem->qmlItemNode().hasShowContent() || selectNonContentItems)*/)
+ return true;
+ }
+
+ return false;
+
+}
+
+bool AbstractFormEditorTool::topItemIsResizeHandle(const QList &/*itemList*/)
+{
+ return false;
+}
+
+QDeclarativeItem *AbstractFormEditorTool::toQDeclarativeItem(QGraphicsItem *item)
+{
+ return dynamic_cast(item->toGraphicsObject());
+}
+
+QGraphicsItem *AbstractFormEditorTool::topMovableGraphicsItem(const QList &itemList)
+{
+ foreach (QGraphicsItem *item, itemList) {
+ if (item->flags().testFlag(QGraphicsItem::ItemIsMovable))
+ return item;
+ }
+ return 0;
+}
+
+QDeclarativeItem *AbstractFormEditorTool::topMovableDeclarativeItem(const QList &itemList)
+{
+ foreach (QGraphicsItem *item, itemList) {
+ QDeclarativeItem *declarativeItem = toQDeclarativeItem(item);
+ if (declarativeItem /*&& (declarativeItem->qmlItemNode().hasShowContent())*/)
+ return declarativeItem;
+ }
+
+ return 0;
+}
+
+QList AbstractFormEditorTool::toGraphicsObjectList(const QList &itemList)
+{
+ QList gfxObjects;
+ foreach(QGraphicsItem *item, itemList) {
+ QGraphicsObject *obj = item->toGraphicsObject();
+ if (obj)
+ gfxObjects << obj;
+ }
+
+ return gfxObjects;
+}
+
+QList AbstractFormEditorTool::toObjectList(const QList &itemList)
+{
+ QList objects;
+ foreach(QGraphicsItem *item, itemList) {
+ QObject *obj = item->toGraphicsObject();
+ if (obj)
+ objects << obj;
+ }
+
+ return objects;
+}
+
+QString AbstractFormEditorTool::titleForItem(const QGraphicsItem *item)
+{
+ QString className("QGraphicsItem");
+ QString objectStringId;
+
+ const QGraphicsObject *gfxObject = item->toGraphicsObject();
+ if (gfxObject) {
+ className = gfxObject->metaObject()->className();
+ className.replace(QRegExp("_QMLTYPE_\\d+"), "");
+
+ const QDeclarativeItem *declarativeItem = qobject_cast(gfxObject);
+ if (declarativeItem) {
+ //QDeclarativeData *ddata = QDeclarativeData::get(declarativeItem);
+ //ddata->context->findObjectId(declarativeItem);
+
+ QDeclarativeContext *context = QDeclarativeEngine::contextForObject(declarativeItem);
+ if (context) {
+ QDeclarativeContextData *cdata = QDeclarativeContextData::get(context);
+ if (cdata)
+ objectStringId = cdata->findObjectId(declarativeItem);
+ }
+ }
+
+ if (objectStringId.isEmpty())
+ objectStringId = gfxObject->objectName();
+
+ if (!objectStringId.isEmpty())
+ return tr("%1 (%2)").arg(objectStringId, className);
+ }
+
+ return tr("(%1, type %2)").arg(className, QString::number(item->type()));
+}
+
+
+}
diff --git a/src/tools/qml/qmlviewer/editor/abstractformeditortool.h b/src/tools/qml/qmlviewer/editor/abstractformeditortool.h
new file mode 100644
index 00000000000..ae27805ab02
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/abstractformeditortool.h
@@ -0,0 +1,104 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef ABSTRACTFORMEDITORTOOL_H
+#define ABSTRACTFORMEDITORTOOL_H
+
+#include
+#include
+#include
+
+QT_BEGIN_NAMESPACE
+class QMouseEvent;
+class QGraphicsItem;
+class QDeclarativeItem;
+class QKeyEvent;
+class QGraphicsScene;
+class QGraphicsObject;
+class QWheelEvent;
+QT_END_NAMESPACE
+
+namespace QmlViewer {
+
+class QDeclarativeDesignView;
+
+
+class FormEditorView;
+
+class AbstractFormEditorTool : public QObject
+{
+ Q_OBJECT
+public:
+ AbstractFormEditorTool(QDeclarativeDesignView* view);
+
+ virtual ~AbstractFormEditorTool();
+
+ 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 &itemList) = 0;
+
+ virtual void clear() = 0;
+ virtual void graphicsObjectsChanged(const QList &itemList) = 0;
+
+ void setItems(const QList &itemList);
+ QList items() const;
+
+ bool topItemIsMovable(const QList &itemList);
+ bool topItemIsResizeHandle(const QList &itemList);
+ bool topSelectedItemIsMovable(const QList &itemList);
+
+ static QString titleForItem(const QGraphicsItem *item);
+ static QList toObjectList(const QList &itemList);
+ static QList toGraphicsObjectList(const QList &itemList);
+ static QGraphicsItem* topMovableGraphicsItem(const QList &itemList);
+ static QDeclarativeItem* topMovableDeclarativeItem(const QList &itemList);
+ static QDeclarativeItem *toQDeclarativeItem(QGraphicsItem *item);
+
+protected:
+ virtual void selectedItemsChanged(const QList &itemList) = 0;
+
+ QDeclarativeDesignView *view() const;
+ QGraphicsScene* scene() const;
+
+private:
+ QDeclarativeDesignView *m_view;
+ QList m_itemList;
+};
+
+}
+
+#endif // ABSTRACTFORMEDITORTOOL_H
diff --git a/src/tools/qml/qmlviewer/editor/boundingrecthighlighter.cpp b/src/tools/qml/qmlviewer/editor/boundingrecthighlighter.cpp
new file mode 100644
index 00000000000..83be4e4c091
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/boundingrecthighlighter.cpp
@@ -0,0 +1,129 @@
+#include "boundingrecthighlighter.h"
+#include "qdeclarativedesignview.h"
+#include "qmlviewerconstants.h"
+
+#include
+#include
+
+#include
+
+namespace QmlViewer {
+
+const qreal AnimDelta = 0.025f;
+const int AnimInterval = 30;
+const int AnimFrames = 10;
+
+BoundingBoxPolygonItem::BoundingBoxPolygonItem(QGraphicsItem *item) : QGraphicsPolygonItem(item)
+{
+ QPen pen;
+ pen.setColor(QColor(108, 141, 221));
+ setPen(pen);
+}
+
+int BoundingBoxPolygonItem::type() const
+{
+ return Constants::EditorItemType;
+}
+
+BoundingRectHighlighter::BoundingRectHighlighter(QDeclarativeDesignView *view) :
+ LayerItem(view->scene()),
+ m_view(view),
+ m_highlightPolygon(0),
+ m_highlightPolygonEdge(0),
+ m_animFrame(0)
+{
+ m_animTimer = new QTimer(this);
+ m_animTimer->setInterval(AnimInterval);
+ connect(m_animTimer, SIGNAL(timeout()), SLOT(animTimeout()));
+}
+
+void BoundingRectHighlighter::animTimeout()
+{
+ ++m_animFrame;
+ if (m_animFrame == AnimFrames) {
+ m_animTimer->stop();
+ }
+
+ m_highlightPolygon->setPen(QPen(QColor(0, 22, 159)));
+ m_highlightPolygonEdge->setPen(QPen(QColor(158, 199, 255)));
+ qreal alpha = m_animFrame / float(AnimFrames);
+ m_highlightPolygonEdge->setOpacity(alpha);
+}
+
+void BoundingRectHighlighter::clear()
+{
+ if (m_highlightPolygon) {
+ m_view->scene()->removeItem(m_highlightPolygon);
+ delete m_highlightPolygon;
+ m_highlightPolygon = 0;
+ delete m_highlightPolygonEdge;
+ m_highlightPolygonEdge = 0;
+ m_animTimer->stop();
+
+ disconnect(m_highlightedObject.data(), SIGNAL(xChanged()), this, SLOT(refresh()));
+ disconnect(m_highlightedObject.data(), SIGNAL(yChanged()), this, SLOT(refresh()));
+ disconnect(m_highlightedObject.data(), SIGNAL(widthChanged()), this, SLOT(refresh()));
+ disconnect(m_highlightedObject.data(), SIGNAL(heightChanged()), this, SLOT(refresh()));
+ disconnect(m_highlightedObject.data(), SIGNAL(rotationChanged()), this, SLOT(refresh()));
+
+ m_highlightedObject.clear();
+ }
+}
+
+void BoundingRectHighlighter::highlight(QGraphicsObject* item)
+{
+ if (!item)
+ return;
+
+ bool animate = false;
+ QGraphicsPolygonItem *polygonItem = 0;
+ QGraphicsPolygonItem *polygonItemEdge = 0;
+ if (item != m_highlightedObject.data() || !m_highlightPolygon) {
+ animate = true;
+ polygonItem = new BoundingBoxPolygonItem(this);
+ polygonItemEdge = new BoundingBoxPolygonItem(this);
+ } else {
+ polygonItem = m_highlightPolygon;
+ polygonItemEdge = m_highlightPolygonEdge;
+ }
+
+ QPolygonF boundingRectInSceneSpace(item->mapToScene(item->boundingRect()));
+ QPolygonF boundingRectInLayerItemSpace = mapFromScene(boundingRectInSceneSpace);
+ polygonItem->setPolygon(boundingRectInLayerItemSpace);
+ polygonItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
+
+ QRectF edgeRect = boundingRectInLayerItemSpace.boundingRect();
+ edgeRect.adjust(-1, -1, 1, 1);
+ polygonItemEdge->setPolygon(QPolygonF(edgeRect));
+ polygonItemEdge->setFlag(QGraphicsItem::ItemIsSelectable, false);
+
+ if (item != m_highlightedObject.data())
+ clear();
+
+ m_highlightPolygon = polygonItem;
+ m_highlightPolygonEdge = polygonItemEdge;
+ m_highlightedObject = item;
+
+ if (item != m_highlightedObject.data()) {
+ connect(m_highlightedObject.data(), SIGNAL(xChanged()), this, SLOT(refresh()));
+ connect(m_highlightedObject.data(), SIGNAL(yChanged()), this, SLOT(refresh()));
+ connect(m_highlightedObject.data(), SIGNAL(widthChanged()), this, SLOT(refresh()));
+ connect(m_highlightedObject.data(), SIGNAL(heightChanged()), this, SLOT(refresh()));
+ connect(m_highlightedObject.data(), SIGNAL(rotationChanged()), this, SLOT(refresh()));
+ }
+
+ if (animate) {
+ m_highlightPolygonEdge->setOpacity(0);
+ m_animFrame = 0;
+ m_animTimer->start();
+ }
+}
+
+void BoundingRectHighlighter::refresh()
+{
+ if (!m_highlightedObject.isNull())
+ highlight(m_highlightedObject.data());
+}
+
+
+} // namespace QmlViewer
diff --git a/src/tools/qml/qmlviewer/editor/boundingrecthighlighter.h b/src/tools/qml/qmlviewer/editor/boundingrecthighlighter.h
new file mode 100644
index 00000000000..81dc84579f2
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/boundingrecthighlighter.h
@@ -0,0 +1,54 @@
+#ifndef BOUNDINGRECTHIGHLIGHTER_H
+#define BOUNDINGRECTHIGHLIGHTER_H
+
+#include
+#include
+
+#include "layeritem.h"
+
+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);
+
+namespace QmlViewer {
+
+class QDeclarativeDesignView;
+
+class BoundingBoxPolygonItem : public QGraphicsPolygonItem
+{
+public:
+ explicit BoundingBoxPolygonItem(QGraphicsItem *item);
+ int type() const;
+};
+
+class BoundingRectHighlighter : public LayerItem
+{
+ Q_OBJECT
+public:
+ explicit BoundingRectHighlighter(QDeclarativeDesignView *view);
+ void clear();
+ void highlight(QGraphicsObject* item);
+
+private slots:
+ void refresh();
+ void animTimeout();
+
+private:
+ Q_DISABLE_COPY(BoundingRectHighlighter);
+
+ QDeclarativeDesignView *m_view;
+ QWeakPointer m_highlightedObject;
+ QGraphicsPolygonItem *m_highlightPolygon;
+ QGraphicsPolygonItem *m_highlightPolygonEdge;
+
+ QTimer *m_animTimer;
+ qreal m_animScale;
+ int m_animFrame;
+
+};
+
+} // namespace QmlViewer
+
+#endif // BOUNDINGRECTHIGHLIGHTER_H
diff --git a/src/tools/qml/qmlviewer/editor/colorpickertool.cpp b/src/tools/qml/qmlviewer/editor/colorpickertool.cpp
new file mode 100644
index 00000000000..62d5f3b49c0
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/colorpickertool.cpp
@@ -0,0 +1,99 @@
+#include "colorpickertool.h"
+#include "qdeclarativedesignview.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace QmlViewer {
+
+ColorPickerTool::ColorPickerTool(QDeclarativeDesignView *view) :
+ AbstractFormEditorTool(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 &/*itemList*/)
+{
+
+}
+
+void ColorPickerTool::clear()
+{
+ view()->setCursor(Qt::CrossCursor);
+}
+
+void ColorPickerTool::graphicsObjectsChanged(const QList &/*itemList*/)
+{
+
+}
+
+void ColorPickerTool::selectedItemsChanged(const QList &/*itemList*/)
+{
+
+}
+
+void ColorPickerTool::pickColor(const QPoint &pos)
+{
+ QRectF target(0,0, 1, 1);
+ QRect source(pos.x(), pos.y(), 1, 1);
+ QImage img(1, 1, QImage::Format_ARGB32);
+ QPainter painter(&img);
+ view()->render(&painter, target, source);
+ m_selectedColor = QColor::fromRgb(img.pixel(0, 0));
+
+ emit selectedColorChanged(m_selectedColor);
+}
+
+} // namespace QmlViewer
diff --git a/src/tools/qml/qmlviewer/editor/colorpickertool.h b/src/tools/qml/qmlviewer/editor/colorpickertool.h
new file mode 100644
index 00000000000..24221dce756
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/colorpickertool.h
@@ -0,0 +1,54 @@
+#ifndef COLORPICKERTOOL_H
+#define COLORPICKERTOOL_H
+
+#include "abstractformeditortool.h"
+
+#include
+
+QT_FORWARD_DECLARE_CLASS(QPoint);
+
+namespace QmlViewer {
+
+class ColorPickerTool : public AbstractFormEditorTool
+{
+ Q_OBJECT
+public:
+ explicit ColorPickerTool(QDeclarativeDesignView *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 &itemList);
+
+ void clear();
+ void graphicsObjectsChanged(const QList &itemList);
+
+signals:
+ void selectedColorChanged(const QColor &color);
+
+protected:
+
+ void selectedItemsChanged(const QList &itemList);
+
+private:
+ void pickColor(const QPoint &pos);
+
+private:
+ QColor m_selectedColor;
+
+};
+
+} // namespace QmlViewer
+
+#endif // COLORPICKERTOOL_H
diff --git a/src/tools/qml/qmlviewer/editor/editor.pri b/src/tools/qml/qmlviewer/editor/editor.pri
new file mode 100644
index 00000000000..f525315b1ca
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/editor.pri
@@ -0,0 +1,38 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/abstractformeditortool.h \
+ $$PWD/selectiontool.h \
+ $$PWD/layeritem.h \
+ $$PWD/singleselectionmanipulator.h \
+ $$PWD/rubberbandselectionmanipulator.h \
+ $$PWD/selectionrectangle.h \
+ $$PWD/selectionindicator.h \
+ $$PWD/qmlviewerconstants.h \
+ $$PWD/boundingrecthighlighter.h \
+ $$PWD/subcomponenteditortool.h \
+ $$PWD/subcomponentmasklayeritem.h \
+ $$PWD/zoomtool.h \
+ $$PWD/colorpickertool.h \
+ $$PWD/qmltoolbar.h \
+ $$PWD/toolbarcolorbox.h
+
+SOURCES += \
+ $$PWD/abstractformeditortool.cpp \
+ $$PWD/selectiontool.cpp \
+ $$PWD/layeritem.cpp \
+ $$PWD/singleselectionmanipulator.cpp \
+ $$PWD/rubberbandselectionmanipulator.cpp \
+ $$PWD/selectionrectangle.cpp \
+ $$PWD/selectionindicator.cpp \
+ $$PWD/boundingrecthighlighter.cpp \
+ $$PWD/subcomponenteditortool.cpp \
+ $$PWD/subcomponentmasklayeritem.cpp \
+ $$PWD/zoomtool.cpp \
+ $$PWD/colorpickertool.cpp \
+ $$PWD/qmltoolbar.cpp \
+ $$PWD/toolbarcolorbox.cpp
+
+RESOURCES += $$PWD/editor.qrc
+
+DEFINES += QWEAKPOINTER_ENABLE_ARROW
diff --git a/src/tools/qml/qmlviewer/editor/editor.qrc b/src/tools/qml/qmlviewer/editor/editor.qrc
new file mode 100644
index 00000000000..6657b325e38
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/editor.qrc
@@ -0,0 +1,13 @@
+
+
+ images/resize_handle.png
+ images/select.png
+ images/select-marquee.png
+ images/color-picker.png
+ images/play.png
+ images/pause.png
+ images/from-qml.png
+ images/zoom.png
+ images/to-qml.png
+
+
diff --git a/src/tools/qml/qmlviewer/editor/images/color-picker.png b/src/tools/qml/qmlviewer/editor/images/color-picker.png
new file mode 100644
index 00000000000..73d9ae3dfc4
Binary files /dev/null and b/src/tools/qml/qmlviewer/editor/images/color-picker.png differ
diff --git a/src/tools/qml/qmlviewer/editor/images/from-qml.png b/src/tools/qml/qmlviewer/editor/images/from-qml.png
new file mode 100644
index 00000000000..e3a6e24c199
Binary files /dev/null and b/src/tools/qml/qmlviewer/editor/images/from-qml.png differ
diff --git a/src/tools/qml/qmlviewer/editor/images/pause.png b/src/tools/qml/qmlviewer/editor/images/pause.png
new file mode 100644
index 00000000000..c5d33a2d04b
Binary files /dev/null and b/src/tools/qml/qmlviewer/editor/images/pause.png differ
diff --git a/src/tools/qml/qmlviewer/editor/images/play.png b/src/tools/qml/qmlviewer/editor/images/play.png
new file mode 100644
index 00000000000..af75fcdb628
Binary files /dev/null and b/src/tools/qml/qmlviewer/editor/images/play.png differ
diff --git a/src/tools/qml/qmlviewer/editor/images/resize_handle.png b/src/tools/qml/qmlviewer/editor/images/resize_handle.png
new file mode 100644
index 00000000000..2934f25b743
Binary files /dev/null and b/src/tools/qml/qmlviewer/editor/images/resize_handle.png differ
diff --git a/src/tools/qml/qmlviewer/editor/images/select-marquee.png b/src/tools/qml/qmlviewer/editor/images/select-marquee.png
new file mode 100644
index 00000000000..a28381f1176
Binary files /dev/null and b/src/tools/qml/qmlviewer/editor/images/select-marquee.png differ
diff --git a/src/tools/qml/qmlviewer/editor/images/select.png b/src/tools/qml/qmlviewer/editor/images/select.png
new file mode 100644
index 00000000000..5b0376f6f7e
Binary files /dev/null and b/src/tools/qml/qmlviewer/editor/images/select.png differ
diff --git a/src/tools/qml/qmlviewer/editor/images/to-qml.png b/src/tools/qml/qmlviewer/editor/images/to-qml.png
new file mode 100644
index 00000000000..84ff48fa951
Binary files /dev/null and b/src/tools/qml/qmlviewer/editor/images/to-qml.png differ
diff --git a/src/tools/qml/qmlviewer/editor/images/zoom.png b/src/tools/qml/qmlviewer/editor/images/zoom.png
new file mode 100644
index 00000000000..4abf3144400
Binary files /dev/null and b/src/tools/qml/qmlviewer/editor/images/zoom.png differ
diff --git a/src/tools/qml/qmlviewer/editor/layeritem.cpp b/src/tools/qml/qmlviewer/editor/layeritem.cpp
new file mode 100644
index 00000000000..65261f45953
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/layeritem.cpp
@@ -0,0 +1,78 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "layeritem.h"
+#include "qmlviewerconstants.h"
+
+#include
+
+namespace QmlViewer {
+
+LayerItem::LayerItem(QGraphicsScene* scene)
+ : QGraphicsObject()
+{
+ scene->addItem(this);
+ setZValue(1);
+ setFlag(QGraphicsItem::ItemIsMovable, false);
+}
+
+LayerItem::~LayerItem()
+{
+}
+
+void LayerItem::paint(QPainter * /*painter*/, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
+{
+}
+
+int LayerItem::type() const
+{
+ return Constants::EditorItemType;
+}
+
+QRectF LayerItem::boundingRect() const
+{
+ return childrenBoundingRect();
+}
+
+QList LayerItem::findAllChildItems() const
+{
+ return findAllChildItems(this);
+}
+
+QList LayerItem::findAllChildItems(const QGraphicsItem *item) const
+{
+ QList itemList(item->childItems());
+
+ foreach (QGraphicsItem *childItem, item->childItems())
+ itemList += findAllChildItems(childItem);
+
+ return itemList;
+}
+
+} // namespace QmlViewer
diff --git a/src/tools/qml/qmlviewer/editor/layeritem.h b/src/tools/qml/qmlviewer/editor/layeritem.h
new file mode 100644
index 00000000000..5ce3c82e56f
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/layeritem.h
@@ -0,0 +1,57 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef LAYERITEM_H
+#define LAYERITEM_H
+
+#include
+#include
+
+namespace QmlViewer {
+
+class FormEditorScene;
+
+class LayerItem : public QGraphicsObject
+{
+public:
+ LayerItem(QGraphicsScene* scene);
+ ~LayerItem();
+ void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 );
+ QRectF boundingRect() const;
+ int type() const;
+
+ QList findAllChildItems() const;
+
+protected:
+ QList findAllChildItems(const QGraphicsItem *item) const;
+};
+
+}
+
+#endif // LAYERITEM_H
diff --git a/src/tools/qml/qmlviewer/editor/movemanipulator.cpp b/src/tools/qml/qmlviewer/editor/movemanipulator.cpp
new file mode 100644
index 00000000000..a9182fad185
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/movemanipulator.cpp
@@ -0,0 +1,360 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "movemanipulator.h"
+#include "qdeclarativedesignview.h"
+//#include "layeritem.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace QmlViewer {
+
+MoveManipulator::MoveManipulator(/*LayerItem *layerItem, */QDeclarativeDesignView *view)
+ : //m_layerItem(layerItem),
+ m_view(view),
+ m_isActive(false)
+{
+}
+
+MoveManipulator::~MoveManipulator()
+{
+ deleteSnapLines();
+}
+
+QPointF MoveManipulator::beginPoint() const
+{
+ return m_beginPoint;
+}
+
+QList MoveManipulator::itemList() const
+{
+ return m_itemList;
+}
+
+void MoveManipulator::setItem(QGraphicsItem* item)
+{
+ QList itemList;
+ itemList.append(item);
+
+ setItems(itemList);
+}
+
+void MoveManipulator::setItems(const QList &itemList)
+{
+ m_itemList = itemList;
+
+ foreach (QGraphicsItem* item, m_itemList) {
+ //QPointF positionInParentSpace = m_snapper.containerQGraphicsItem()->mapFromScene(m_beginPositionInSceneSpaceHash.value(item));
+ //m_beginItemRectHash[item].translate(positionInParentSpace - m_beginPositionHash.value(item));
+ qDebug() << item << item->pos();
+ m_beginPositionHash.insert(item, item->pos());
+ }
+
+// if (!m_itemList.isEmpty()) {
+// if (m_itemList.first()->parentItem())
+// m_snapper.setContainerQGraphicsItem(m_itemList.first()->parentItem());
+// else
+// m_snapper.setContainerQGraphicsItem(m_itemList.first());
+// m_snapper.setTransformtionSpaceQGraphicsItem(m_snapper.containerQGraphicsItem());
+// }
+}
+
+void MoveManipulator::updateHashes()
+{
+// foreach (QGraphicsItem* item, m_itemList)
+// m_beginItemRectHash[item] = item->mapRectToParent(item->qmlItemNode().instanceBoundingRect());
+
+// foreach (QGraphicsItem* item, m_itemList) {
+// QPointF positionInParentSpace = m_snapper.containerQGraphicsItem()->mapFromScene(m_beginPositionInSceneSpaceHash.value(item));
+// m_beginItemRectHash[item].translate(positionInParentSpace - m_beginPositionHash.value(item));
+// m_beginPositionHash.insert(item, positionInParentSpace);
+// }
+}
+
+bool MoveManipulator::itemsCanReparented() const
+{
+ return true;
+}
+
+void MoveManipulator::begin(const QPointF &beginPoint)
+{
+ m_isActive = true;
+
+ //m_snapper.updateSnappingLines(m_itemList);
+
+
+// foreach (QGraphicsItem* item, m_itemList)
+// m_beginItemRectHash.insert(item, m_snapper.containerQGraphicsItem()->mapRectFromItem(item, item->qmlItemNode().instanceBoundingRect()));
+
+// foreach (QGraphicsItem* item, m_itemList) {
+// QPointF positionInParentSpace(item->qmlItemNode().instancePosition());
+// QPointF positionInScenesSpace = m_snapper.containerQGraphicsItem()->mapToScene(positionInParentSpace);
+// m_beginPositionInSceneSpaceHash.insert(item, positionInScenesSpace);
+// }
+
+// foreach (QGraphicsItem* item, m_itemList) {
+// QPointF positionInParentSpace = m_snapper.containerQGraphicsItem()->mapFromScene(m_beginPositionInSceneSpaceHash.value(item));
+// m_beginPositionHash.insert(item, positionInParentSpace);
+
+// QmlAnchors anchors(item->qmlItemNode().anchors());
+// m_beginTopMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Top));
+// m_beginLeftMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Left));
+// m_beginRightMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Right));
+// m_beginBottomMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Bottom));
+// m_beginHorizontalCenterHash.insert(item, anchors.instanceMargin(AnchorLine::HorizontalCenter));
+// m_beginVerticalCenterHash.insert(item, anchors.instanceMargin(AnchorLine::VerticalCenter));
+// }
+
+ m_beginPoint = beginPoint;
+
+}
+
+//QPointF MoveManipulator::findSnappingOffset(const QList &boundingRectList)
+//{
+// QPointF offset;
+
+// QMap verticalOffsetMap;
+// foreach (const QRectF &boundingRect, boundingRectList) {
+// double verticalOffset = m_snapper.snappedVerticalOffset(boundingRect);
+// if (verticalOffset < std::numeric_limits::max())
+// verticalOffsetMap.insert(qAbs(verticalOffset), verticalOffset);
+// }
+
+
+// if (!verticalOffsetMap.isEmpty())
+// offset.rx() = verticalOffsetMap.begin().value();
+
+
+
+// QMap horizontalOffsetMap;
+// foreach (const QRectF &boundingRect, boundingRectList) {
+// double horizontalOffset = m_snapper.snappedHorizontalOffset(boundingRect);
+// if (horizontalOffset < std::numeric_limits::max())
+// horizontalOffsetMap.insert(qAbs(horizontalOffset), horizontalOffset);
+// }
+
+
+// if (!horizontalOffsetMap.isEmpty())
+// offset.ry() = horizontalOffsetMap.begin().value();
+
+// return offset;
+//}
+
+//void MoveManipulator::generateSnappingLines(const QList &boundingRectList)
+//{
+// m_graphicsLineList = m_snapper.generateSnappingLines(boundingRectList,
+// m_layerItem.data(),
+// m_snapper.transformtionSpaceQGraphicsItem()->sceneTransform());
+//}
+
+QList MoveManipulator::translatedBoundingRects(const QList &boundingRectList, const QPointF& offsetVector)
+{
+ QList translatedBoundingRectList;
+ foreach (const QRectF &boundingRect, boundingRectList)
+ translatedBoundingRectList.append(boundingRect.translated(offsetVector));
+
+ return translatedBoundingRectList;
+}
+
+
+
+/*
+ /brief updates the position of the items.
+*/
+void MoveManipulator::update(const QPointF& updatePoint, Snapping /*useSnapping*/, State /*stateToBeManipulated*/)
+{
+ //deleteSnapLines(); //Since they position is changed and the item is moved the snapping lines are
+ //are obsolete. The new updated snapping lines (color and visibility) will be
+ //calculated in snapPoint() called in moveNode() later
+
+ if (m_itemList.isEmpty()) {
+ return;
+ } else {
+ //QPointF updatePointInContainerSpace(m_snapper.containerQGraphicsItem()->mapFromScene(updatePoint));
+ //QPointF beginPointInContainerSpace(m_snapper.containerQGraphicsItem()->mapFromScene(m_beginPoint));
+
+ QPointF offsetVector(updatePoint - m_beginPoint);
+
+// if (useSnapping == UseSnapping || useSnapping == UseSnappingAndAnchoring) {
+// offsetVector -= findSnappingOffset(translatedBoundingRects(m_beginItemRectHash.values(), offsetVector));
+// //generateSnappingLines(translatedBoundingRects(m_beginItemRectHash.values(), offsetVector));
+// }
+
+ foreach (QGraphicsItem* item, m_itemList) {
+ //qDebug() << "offset:" << m_beginPositionHash.value(item) << offsetVector;
+ QPointF positionInContainerSpace(m_beginPositionHash.value(item) + offsetVector);
+
+ // don't support anchors for base state because it is not needed by the droptool
+// if (stateToBeManipulated == UseActualState) {
+// QmlAnchors anchors(item->qmlItemNode().anchors());
+
+// if (anchors.instanceHasAnchor(AnchorLine::Top)) {
+// anchors.setMargin(AnchorLine::Top, m_beginTopMarginHash.value(item) + offsetVector.y());
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::Left)) {
+// anchors.setMargin(AnchorLine::Left, m_beginLeftMarginHash.value(item) + offsetVector.x());
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::Bottom)) {
+// anchors.setMargin(AnchorLine::Bottom, m_beginBottomMarginHash.value(item) - offsetVector.y());
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::Right)) {
+// anchors.setMargin(AnchorLine::Right, m_beginRightMarginHash.value(item) - offsetVector.x());
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
+// anchors.setMargin(AnchorLine::HorizontalCenter, m_beginHorizontalCenterHash.value(item) + offsetVector.x());
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
+// anchors.setMargin(AnchorLine::VerticalCenter, m_beginVerticalCenterHash.value(item) + offsetVector.y());
+// }
+
+// item->setPos(positionInContainerSpace);
+// } else {
+// item->qmlItemNode().modelNode().variantProperty("x").setValue(qRound(positionInContainerSpace.x()));
+// item->qmlItemNode().modelNode().variantProperty("y").setValue(qRound(positionInContainerSpace.y()));
+// }
+ item->setPos(positionInContainerSpace);
+ }
+ }
+}
+
+void MoveManipulator::clear()
+{
+ deleteSnapLines();
+ m_beginItemRectHash.clear();
+ m_beginPositionHash.clear();
+ m_beginPositionInSceneSpaceHash.clear();
+ m_itemList.clear();
+
+ m_beginTopMarginHash.clear();
+ m_beginLeftMarginHash.clear();
+ m_beginRightMarginHash.clear();
+ m_beginBottomMarginHash.clear();
+ m_beginHorizontalCenterHash.clear();
+ m_beginVerticalCenterHash.clear();
+}
+
+void MoveManipulator::reparentTo(QGraphicsItem *newParent)
+{
+ deleteSnapLines();
+
+ if (!newParent)
+ return;
+
+ if (!itemsCanReparented())
+ return;
+
+// foreach (QGraphicsItem* item, m_itemList) {
+// QmlItemNode parent(newParent->qmlItemNode());
+// if (parent.isValid()) {
+// item->qmlItemNode().setParentProperty(parent.nodeAbstractProperty("data"));
+// }
+// }
+
+// m_snapper.setContainerQGraphicsItem(newParent);
+// m_snapper.setTransformtionSpaceQGraphicsItem(m_snapper.containerQGraphicsItem());
+// m_snapper.updateSnappingLines(m_itemList);
+
+ updateHashes();
+}
+
+
+void MoveManipulator::end(const QPointF &/*endPoint*/)
+{
+ m_isActive = false;
+ deleteSnapLines();
+
+ clear();
+}
+
+void MoveManipulator::moveBy(double deltaX, double deltaY)
+{
+ foreach (QGraphicsItem* item, m_itemList) {
+// QmlAnchors anchors(item->qmlItemNode().anchors());
+
+// if (anchors.instanceHasAnchor(AnchorLine::Top)) {
+// anchors.setMargin(AnchorLine::Top, anchors.instanceMargin(AnchorLine::Top) + deltaY);
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::Left)) {
+// anchors.setMargin(AnchorLine::Left, anchors.instanceMargin(AnchorLine::Left) + deltaX);
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::Bottom)) {
+// anchors.setMargin(AnchorLine::Bottom, anchors.instanceMargin(AnchorLine::Bottom) - deltaY);
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::Right)) {
+// anchors.setMargin(AnchorLine::Right, anchors.instanceMargin(AnchorLine::Right) - deltaX);
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
+// anchors.setMargin(AnchorLine::HorizontalCenter, anchors.instanceMargin(AnchorLine::HorizontalCenter) + deltaX);
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
+// anchors.setMargin(AnchorLine::VerticalCenter, anchors.instanceMargin(AnchorLine::VerticalCenter) + deltaY);
+// }
+
+ item->moveBy(deltaX, deltaY);
+ }
+}
+
+void MoveManipulator::setOpacityForAllElements(qreal opacity)
+{
+ foreach (QGraphicsItem* item, m_itemList)
+ item->setOpacity(opacity);
+}
+
+void MoveManipulator::deleteSnapLines()
+{
+// if (m_layerItem) {
+// foreach (QGraphicsItem *item, m_graphicsLineList)
+// m_layerItem->scene()->removeItem(item);
+// }
+// m_graphicsLineList.clear();
+// m_view->scene()->update();
+}
+
+bool MoveManipulator::isActive() const
+{
+ return m_isActive;
+}
+
+}
diff --git a/src/tools/qml/qmlviewer/editor/movemanipulator.h b/src/tools/qml/qmlviewer/editor/movemanipulator.h
new file mode 100644
index 00000000000..f09a7436249
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/movemanipulator.h
@@ -0,0 +1,116 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MOVEMANIPULATOR_H
+#define MOVEMANIPULATOR_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+//#include "snapper.h"
+//#include "formeditorview.h"
+
+namespace QmlViewer {
+
+class QDeclarativeDesignView;
+
+class MoveManipulator
+{
+public:
+ enum Snapping {
+ UseSnapping,
+ UseSnappingAndAnchoring,
+ NoSnapping
+ };
+
+ enum State {
+ UseActualState,
+ UseBaseState
+ };
+
+ MoveManipulator(/*LayerItem *layerItem, */QDeclarativeDesignView *view);
+ ~MoveManipulator();
+ QList itemList() const;
+ void setItems(const QList &itemList);
+ void setItem(QGraphicsItem* item);
+
+ void begin(const QPointF& beginPoint);
+ void update(const QPointF& updatePoint, Snapping useSnapping, State stateToBeManipulated = UseActualState);
+ void reparentTo(QGraphicsItem *newParent);
+ void end(const QPointF& endPoint);
+
+ void moveBy(double deltaX, double deltaY);
+
+ QPointF beginPoint() const;
+
+ void clear();
+
+ bool isActive() const;
+
+protected:
+ void setOpacityForAllElements(qreal opacity);
+
+ //QPointF findSnappingOffset(const QList &boundingRectList);
+ void deleteSnapLines();
+
+ QList translatedBoundingRects(const QList &boundingRectList, const QPointF& offset);
+ QPointF calculateBoundingRectMovementOffset(const QPointF& updatePoint);
+ QRectF boundingRect(QGraphicsItem* item, const QPointF& updatePoint);
+
+ //void generateSnappingLines(const QList &boundingRectList);
+ void updateHashes();
+
+ bool itemsCanReparented() const;
+
+private:
+ //Snapper m_snapper;
+ //QWeakPointer m_layerItem;
+ QWeakPointer m_view;
+ QList m_itemList;
+ QHash m_beginItemRectHash;
+ QHash m_beginPositionHash;
+ QHash m_beginPositionInSceneSpaceHash;
+ QPointF m_beginPoint;
+ QHash m_beginTopMarginHash;
+ QHash m_beginLeftMarginHash;
+ QHash m_beginRightMarginHash;
+ QHash m_beginBottomMarginHash;
+ QHash m_beginHorizontalCenterHash;
+ QHash m_beginVerticalCenterHash;
+ QList m_graphicsLineList;
+ bool m_isActive;
+};
+
+}
+
+#endif // MOVEMANIPULATOR_H
diff --git a/src/tools/qml/qmlviewer/editor/movetool.cpp b/src/tools/qml/qmlviewer/editor/movetool.cpp
new file mode 100644
index 00000000000..20377c10ddb
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/movetool.cpp
@@ -0,0 +1,377 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "movetool.h"
+
+#include "resizehandleitem.h"
+#include "qdeclarativedesignview.h"
+
+#include
+#include
+#include
+#include
+#include
+
+namespace QmlViewer {
+
+MoveTool::MoveTool(QDeclarativeDesignView *editorView)
+ : AbstractFormEditorTool(editorView),
+ m_moving(false),
+ m_moveManipulator(editorView),
+ m_selectionIndicator(editorView->manipulatorLayer()),
+ m_resizeIndicator(editorView->manipulatorLayer())
+{
+
+}
+
+
+MoveTool::~MoveTool()
+{
+
+}
+
+void MoveTool::clear()
+{
+ view()->clearHighlightBoundingRect();
+ view()->setCursor(Qt::SizeAllCursor);
+ m_moveManipulator.clear();
+ m_movingItems.clear();
+ m_resizeIndicator.clear();
+ m_selectionIndicator.clear();
+}
+
+void MoveTool::mousePressEvent(QMouseEvent *event)
+{
+ QList itemList = view()->selectableItems(event->pos());
+
+ if (event->buttons() & Qt::LeftButton) {
+ m_moving = true;
+
+ if (itemList.isEmpty()) {
+ view()->changeTool(Constants::SelectionToolMode);
+ return;
+ }
+
+ m_movingItems = movingItems(items());
+ if (m_movingItems.isEmpty())
+ return;
+
+ m_moveManipulator.setItems(m_movingItems);
+
+ m_moveManipulator.begin(event->pos());
+ } else if (event->buttons() & Qt::RightButton) {
+ view()->changeTool(Constants::SelectionToolMode);
+ }
+
+}
+
+void MoveTool::mouseMoveEvent(QMouseEvent *event)
+{
+ if (m_movingItems.isEmpty())
+ return;
+
+ if (event->buttons() & Qt::LeftButton) {
+
+ m_selectionIndicator.hide();
+ m_resizeIndicator.hide();
+
+// QGraphicsItem *containerItem = containerQGraphicsItem(itemList, m_movingItems);
+// if (containerItem
+// && view()->currentState().isBaseState()) {
+// if (containerItem != m_movingItems.first()->parentItem()
+// && event->modifiers().testFlag(Qt::ShiftModifier)) {
+// m_moveManipulator.reparentTo(containerItem);
+// }
+// }
+// bool shouldSnapping = view()->widget()->snappingAction()->isChecked();
+// bool shouldSnappingAndAnchoring = view()->widget()->snappingAndAnchoringAction()->isChecked();
+// MoveManipulator::Snapping useSnapping = MoveManipulator::NoSnapping;
+// if (event->modifiers().testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) {
+// if (shouldSnappingAndAnchoring)
+// useSnapping = MoveManipulator::UseSnappingAndAnchoring;
+// else
+// useSnapping = MoveManipulator::UseSnapping;
+// }
+
+ m_moveManipulator.update(event->pos(), MoveManipulator::NoSnapping);
+ }
+}
+
+void MoveTool::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (m_movingItems.isEmpty())
+ return;
+
+ if (m_moving) {
+ QLineF moveVector(event->pos(), m_moveManipulator.beginPoint());
+ if (moveVector.length() < QApplication::startDragDistance())
+ {
+ QPointF beginPoint(m_moveManipulator.beginPoint());
+
+ m_moveManipulator.end(beginPoint);
+
+ m_selectionIndicator.show();
+ m_resizeIndicator.show();
+ m_movingItems.clear();
+ view()->changeTool(Constants::SelectionToolMode,
+ Constants::UseCursorPos);
+ } else {
+ m_moveManipulator.end(event->pos());
+
+ m_selectionIndicator.show();
+ m_resizeIndicator.show();
+ m_movingItems.clear();
+ }
+ qDebug() << "releasing";
+ view()->changeTool(Constants::ResizeToolMode);
+ }
+
+ m_moving = false;
+
+ qDebug() << "released";
+}
+
+
+void MoveTool::hoverMoveEvent(QMouseEvent *event)
+{
+ QList itemList = view()->items(event->pos());
+
+ if (itemList.isEmpty()) {
+ view()->changeTool(Constants::SelectionToolMode);
+ return;
+ }
+
+ ResizeHandleItem* resizeHandle = ResizeHandleItem::fromGraphicsItem(itemList.first());
+ if (resizeHandle) {
+ view()->changeTool(Constants::ResizeToolMode);
+ return;
+ }
+
+ QList selectableItemList = view()->selectableItems(event->pos());
+ if (!topSelectedItemIsMovable(selectableItemList)) {
+ view()->changeTool(Constants::SelectionToolMode);
+ return;
+ }
+}
+
+void MoveTool::keyPressEvent(QKeyEvent *event)
+{
+ switch(event->key()) {
+ case Qt::Key_Shift:
+ case Qt::Key_Alt:
+ case Qt::Key_Control:
+ case Qt::Key_AltGr:
+ event->setAccepted(false);
+ return;
+ }
+
+ double moveStep = 1.0;
+
+ if (event->modifiers().testFlag(Qt::ShiftModifier))
+ moveStep = 10.0;
+
+ if (!event->isAutoRepeat()) {
+ QList movableItems(movingItems(items()));
+ if (movableItems.isEmpty())
+ return;
+
+ m_moveManipulator.setItems(movableItems);
+ m_selectionIndicator.hide();
+ m_resizeIndicator.hide();
+ }
+
+ switch(event->key()) {
+ case Qt::Key_Left: m_moveManipulator.moveBy(-moveStep, 0.0); break;
+ case Qt::Key_Right: m_moveManipulator.moveBy(moveStep, 0.0); break;
+ case Qt::Key_Up: m_moveManipulator.moveBy(0.0, -moveStep); break;
+ case Qt::Key_Down: m_moveManipulator.moveBy(0.0, moveStep); break;
+ }
+
+
+}
+
+void MoveTool::keyReleaseEvent(QKeyEvent *keyEvent)
+{
+ switch(keyEvent->key()) {
+ case Qt::Key_Shift:
+ case Qt::Key_Alt:
+ case Qt::Key_Control:
+ case Qt::Key_AltGr:
+ keyEvent->setAccepted(false);
+ return;
+ }
+
+ if (!keyEvent->isAutoRepeat()) {
+ m_moveManipulator.clear();
+ m_selectionIndicator.show();
+ m_resizeIndicator.show();
+ }
+}
+
+void MoveTool::wheelEvent(QWheelEvent */*event*/)
+{
+
+}
+
+void MoveTool::mouseDoubleClickEvent(QMouseEvent * /*event*/)
+{
+
+}
+
+void MoveTool::itemsAboutToRemoved(const QList &removedItemList)
+{
+ foreach (QGraphicsItem* removedItem, removedItemList)
+ m_movingItems.removeOne(removedItem);
+}
+
+void MoveTool::selectedItemsChanged(const QList &itemList)
+{
+ m_selectionIndicator.setItems(toGraphicsObjectList(itemList));
+ m_resizeIndicator.setItems(toGraphicsObjectList(itemList));
+ updateMoveManipulator();
+}
+
+bool MoveTool::haveSameParent(const QList &itemList)
+{
+ if (itemList.isEmpty())
+ return false;
+
+ QGraphicsItem *firstParent = itemList.first()->parentItem();
+ foreach (QGraphicsItem* item, itemList)
+ {
+ if (firstParent != item->parentItem())
+ return false;
+ }
+
+ return true;
+}
+
+bool MoveTool::isAncestorOfAllItems(QGraphicsItem* maybeAncestorItem,
+ const QList &itemList)
+{
+ foreach (QGraphicsItem* item, itemList)
+ {
+ if (!maybeAncestorItem->isAncestorOf(item) && item != maybeAncestorItem)
+ return false;
+ }
+
+ return true;
+}
+
+
+QGraphicsItem* MoveTool::ancestorIfOtherItemsAreChild(const QList &itemList)
+{
+ if (itemList.isEmpty())
+ return 0;
+
+
+ foreach (QGraphicsItem* item, itemList)
+ {
+ if (isAncestorOfAllItems(item, itemList))
+ return item;
+ }
+
+ return 0;
+}
+
+void MoveTool::updateMoveManipulator()
+{
+ if (m_moveManipulator.isActive())
+ return;
+}
+
+void MoveTool::beginWithPoint(const QPointF &beginPoint)
+{
+ m_movingItems = movingItems(items());
+ if (m_movingItems.isEmpty())
+ return;
+
+ m_moving = true;
+ m_moveManipulator.setItems(m_movingItems);
+ m_moveManipulator.begin(beginPoint);
+}
+
+//static bool isNotAncestorOfItemInList(QGraphicsItem *graphicsItem, const QList &itemList)
+//{
+// foreach (QGraphicsItem *item, itemList) {
+// if (item->qmlItemNode().isAncestorOf(graphicsItem->qmlItemNode()))
+// return false;
+// }
+
+// return true;
+//}
+
+//QGraphicsItem* MoveTool::containerQGraphicsItem(const QList &itemUnderMouseList,
+// const QList &selectedItemList)
+//{
+// Q_ASSERT(!selectedItemList.isEmpty());
+
+// foreach (QGraphicsItem* item, itemUnderMouseList) {
+// QGraphicsItem *QGraphicsItem = QGraphicsItem::fromQGraphicsItem(item);
+// if (QGraphicsItem
+// && !selectedItemList.contains(QGraphicsItem)
+// && isNotAncestorOfItemInList(QGraphicsItem, selectedItemList))
+// return QGraphicsItem;
+
+// }
+
+// return 0;
+//}
+
+
+QList MoveTool::movingItems(const QList &selectedItemList)
+{
+ QGraphicsItem* ancestorItem = ancestorIfOtherItemsAreChild(selectedItemList);
+
+// if (ancestorItem != 0 && ancestorItem->qmlItemNode().isRootNode()) {
+// view()->changeTool(QDeclarativeDesignView::SelectionToolMode);
+// return QList();
+// }
+
+ if (ancestorItem != 0 && ancestorItem->parentItem() != 0) {
+ QList ancestorItemList;
+ ancestorItemList.append(ancestorItem);
+ return ancestorItemList;
+ }
+
+ if (!haveSameParent(selectedItemList)) {
+ view()->changeTool(Constants::SelectionToolMode);
+ return QList();
+ }
+
+ return selectedItemList;
+}
+
+void MoveTool::graphicsObjectsChanged(const QList &itemList)
+{
+ m_selectionIndicator.updateItems(itemList);
+ m_resizeIndicator.updateItems(itemList);
+}
+
+}
diff --git a/src/tools/qml/qmlviewer/editor/movetool.h b/src/tools/qml/qmlviewer/editor/movetool.h
new file mode 100644
index 00000000000..7514cf68664
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/movetool.h
@@ -0,0 +1,91 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MOVETOOL_H
+#define MOVETOOL_H
+
+#include "abstractformeditortool.h"
+#include "movemanipulator.h"
+#include "resizeindicator.h"
+#include "selectionindicator.h"
+#include
+
+namespace QmlViewer {
+
+class MoveTool : public AbstractFormEditorTool
+{
+public:
+ MoveTool(QDeclarativeDesignView* editorView);
+ ~MoveTool();
+
+ 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 &itemList);
+
+ void selectedItemsChanged(const QList &itemList);
+
+ void updateMoveManipulator();
+
+ void beginWithPoint(const QPointF &beginPoint);
+
+ void clear();
+
+ void graphicsObjectsChanged(const QList &itemList);
+
+protected:
+ static bool haveSameParent(const QList &itemList);
+
+ QList movingItems(const QList &selectedItemList);
+
+ static QGraphicsItem* containerFormEditorItem(const QList &itemUnderMouseList,
+ const QList &selectedItemList);
+
+ static bool isAncestorOfAllItems(QGraphicsItem* maybeAncestorItem,
+ const QList &itemList);
+ static QGraphicsItem* ancestorIfOtherItemsAreChild(const QList &itemList);
+
+private:
+ bool m_moving;
+ MoveManipulator m_moveManipulator;
+ SelectionIndicator m_selectionIndicator;
+ ResizeIndicator m_resizeIndicator;
+ QList m_movingItems;
+};
+
+}
+
+#endif // MOVETOOL_H
diff --git a/src/tools/qml/qmlviewer/editor/qmltoolbar.cpp b/src/tools/qml/qmlviewer/editor/qmltoolbar.cpp
new file mode 100644
index 00000000000..9bb1357f84b
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/qmltoolbar.cpp
@@ -0,0 +1,210 @@
+#include
+#include
+#include
+
+#include "qmltoolbar.h"
+#include "toolbarcolorbox.h"
+
+#include
+
+namespace QmlViewer {
+
+QmlToolbar::QmlToolbar(QWidget *parent) :
+ QToolBar(parent),
+ m_emitSignals(true),
+ ui(new Ui)
+{
+ ui->play = new QAction(QIcon(":/qml/images/play.png"), tr("Play"), this);
+ ui->pause = new QAction(QIcon(":/qml/images/pause.png"), tr("Pause"), this);
+ ui->select = new QAction(QIcon(":/qml/images/select.png"), tr("Select"), this);
+ ui->selectMarquee = new QAction(QIcon(":/qml/images/select-marquee.png"), tr("Select (Marquee)"), this);
+ ui->zoom = new QAction(QIcon(":/qml/images/zoom.png"), tr("Zoom"), this);
+ ui->colorPicker = new QAction(QIcon(":/qml/images/color-picker.png"), tr("Color Picker"), this);
+ ui->toQml = new QAction(QIcon(":/qml/images/to-qml.png"), tr("Apply Changes to QML Viewer"), this);
+ ui->fromQml = new QAction(QIcon(":/qml/images/from-qml.png"), tr("Apply Changes to Document"), this);
+ ui->play->setCheckable(true);
+ ui->play->setChecked(true);
+ ui->pause->setCheckable(true);
+ ui->select->setCheckable(true);
+ ui->selectMarquee->setCheckable(true);
+ ui->zoom->setCheckable(true);
+ ui->colorPicker->setCheckable(true);
+
+ setWindowTitle(tr("Tools"));
+
+ addAction(ui->play);
+ addAction(ui->pause);
+ addSeparator();
+
+ addAction(ui->select);
+ 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);
+
+ connect(ui->colorPicker, SIGNAL(triggered()), SLOT(activateColorPickerOnClick()));
+
+ connect(ui->play, SIGNAL(triggered()), SLOT(activatePlayOnClick()));
+ connect(ui->pause, SIGNAL(triggered()), SLOT(activatePauseOnClick()));
+
+ 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::startExecution()
+{
+ m_emitSignals = false;
+ activatePlayOnClick();
+ m_emitSignals = true;
+}
+
+void QmlToolbar::pauseExecution()
+{
+ m_emitSignals = false;
+ activatePauseOnClick();
+ m_emitSignals = true;
+}
+
+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::setColorBoxColor(const QColor &color)
+{
+ ui->colorBox->setColor(color);
+}
+
+void QmlToolbar::activatePlayOnClick()
+{
+ ui->pause->setChecked(false);
+ if (!m_isRunning) {
+ ui->play->setChecked(true);
+ m_isRunning = true;
+ if (m_emitSignals)
+ emit executionStarted();
+ }
+}
+
+void QmlToolbar::activatePauseOnClick()
+{
+ ui->play->setChecked(false);
+ if (m_isRunning) {
+ m_isRunning = false;
+ ui->pause->setChecked(true);
+ if (m_emitSignals)
+ emit executionPaused();
+ }
+}
+
+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();
+}
+
+}
diff --git a/src/tools/qml/qmlviewer/editor/qmltoolbar.h b/src/tools/qml/qmlviewer/editor/qmltoolbar.h
new file mode 100644
index 00000000000..e6a5ec418e0
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/qmltoolbar.h
@@ -0,0 +1,73 @@
+#ifndef QMLTOOLBAR_H
+#define QMLTOOLBAR_H
+
+#include
+#include "qmlviewerconstants.h"
+
+namespace QmlViewer {
+
+class ToolBarColorBox;
+
+class QmlToolbar : public QToolBar
+{
+ Q_OBJECT
+
+public:
+ explicit QmlToolbar(QWidget *parent = 0);
+ ~QmlToolbar();
+
+public slots:
+ void setColorBoxColor(const QColor &color);
+ void startExecution();
+ void pauseExecution();
+ void activateColorPicker();
+ void activateSelectTool();
+ void activateMarqueeSelectTool();
+ void activateZoom();
+
+signals:
+ void executionStarted();
+ void executionPaused();
+
+ void colorPickerSelected();
+ void selectToolSelected();
+ void marqueeSelectToolSelected();
+ void zoomToolSelected();
+
+ void applyChangesToQmlFileSelected();
+ void applyChangesFromQmlFileSelected();
+
+private slots:
+ void activatePlayOnClick();
+ void activatePauseOnClick();
+ void activateColorPickerOnClick();
+ void activateSelectToolOnClick();
+ void activateMarqueeSelectToolOnClick();
+ void activateZoomOnClick();
+
+ void activateFromQml();
+ void activateToQml();
+
+private:
+ class Ui {
+ public:
+ QAction *play;
+ QAction *pause;
+ QAction *select;
+ QAction *selectMarquee;
+ QAction *zoom;
+ QAction *colorPicker;
+ QAction *toQml;
+ QAction *fromQml;
+ ToolBarColorBox *colorBox;
+ };
+
+ bool m_emitSignals;
+ bool m_isRunning;
+ Constants::DesignTool m_activeTool;
+ Ui *ui;
+};
+
+}
+
+#endif // QMLTOOLBAR_H
diff --git a/src/tools/qml/qmlviewer/editor/qmlviewerconstants.h b/src/tools/qml/qmlviewer/editor/qmlviewerconstants.h
new file mode 100644
index 00000000000..aa9c1666da8
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/qmlviewerconstants.h
@@ -0,0 +1,37 @@
+#ifndef QMLVIEWERCONSTANTS_H
+#define QMLVIEWERCONSTANTS_H
+
+namespace QmlViewer {
+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;
+
+enum GraphicsItemTypes {
+ EditorItemType = 0xEAAA,
+ ResizeHandleItemType = 0xEAEA
+};
+
+
+} // namespace Constants
+} // namespace QmlViewer
+
+#endif // QMLVIEWERCONSTANTS_H
diff --git a/src/tools/qml/qmlviewer/editor/resize_handle.png b/src/tools/qml/qmlviewer/editor/resize_handle.png
new file mode 100644
index 00000000000..2934f25b743
Binary files /dev/null and b/src/tools/qml/qmlviewer/editor/resize_handle.png differ
diff --git a/src/tools/qml/qmlviewer/editor/resizecontroller.cpp b/src/tools/qml/qmlviewer/editor/resizecontroller.cpp
new file mode 100644
index 00000000000..27e5daf9176
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/resizecontroller.cpp
@@ -0,0 +1,293 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "resizecontroller.h"
+#include "layeritem.h"
+
+#include
+#include
+#include
+#include
+
+#include
+
+namespace QmlViewer {
+
+ResizeControllerData::ResizeControllerData(LayerItem *layerItem, QGraphicsObject *formEditorItem)
+ :
+ layerItem(layerItem),
+ formEditorItem(formEditorItem),
+ topLeftItem(0),
+ topRightItem(0),
+ bottomLeftItem(0),
+ bottomRightItem(0),
+ topItem(0),
+ leftItem(0),
+ rightItem(0),
+ bottomItem(0)
+{
+
+}
+
+ResizeControllerData::~ResizeControllerData()
+{
+ clear();
+}
+
+void ResizeControllerData::clear()
+{
+ if (!formEditorItem.isNull() && topLeftItem) {
+ formEditorItem.data()->scene()->removeItem(topLeftItem);
+ formEditorItem.data()->scene()->removeItem(topRightItem);
+ formEditorItem.data()->scene()->removeItem(bottomLeftItem);
+ formEditorItem.data()->scene()->removeItem(bottomRightItem);
+ formEditorItem.data()->scene()->removeItem(topItem);
+ formEditorItem.data()->scene()->removeItem(leftItem);
+ formEditorItem.data()->scene()->removeItem(rightItem);
+ formEditorItem.data()->scene()->removeItem(bottomItem);
+ formEditorItem.clear();
+ layerItem.clear();
+ topLeftItem = 0;
+ topRightItem = 0;
+ bottomLeftItem = 0;
+ bottomRightItem = 0;
+ topItem = 0;
+ leftItem = 0;
+ rightItem = 0;
+ bottomItem = 0;
+ }
+}
+
+ResizeController::ResizeController()
+ : m_data(new ResizeControllerData(0, 0))
+{
+
+}
+
+ResizeController::~ResizeController()
+{
+ delete m_data;
+ m_data = 0;
+}
+
+void ResizeController::setItem(LayerItem *layerItem, QGraphicsObject *item)
+{
+ createFor(layerItem, item);
+}
+
+ResizeController::ResizeController(LayerItem *layerItem, QGraphicsObject *formEditorItem) :
+ m_data(new ResizeControllerData(layerItem, formEditorItem))
+{
+ createFor(layerItem, formEditorItem);
+}
+
+void ResizeController::createFor(LayerItem *layerItem, QGraphicsObject *formEditorItem)
+{
+ if (m_data)
+ m_data->clear();
+ else
+ m_data = new ResizeControllerData(layerItem, formEditorItem);
+
+ m_data->formEditorItem = formEditorItem;
+ m_data->layerItem = layerItem;
+
+ m_data->topLeftItem = new ResizeHandleItem(layerItem, this);
+ m_data->topLeftItem->setZValue(3020);
+ m_data->topLeftItem->setCustomCursor(Qt::SizeFDiagCursor);
+
+ m_data->topRightItem = new ResizeHandleItem(layerItem, this);
+ m_data->topRightItem->setZValue(3010);
+ m_data->topRightItem->setCustomCursor(Qt::SizeBDiagCursor);
+
+ m_data->bottomLeftItem = new ResizeHandleItem(layerItem, this);
+ m_data->bottomLeftItem->setZValue(3010);
+ m_data->bottomLeftItem->setCustomCursor(Qt::SizeBDiagCursor);
+
+ m_data->bottomRightItem = new ResizeHandleItem(layerItem, this);
+ m_data->bottomRightItem->setZValue(3050);
+ m_data->bottomRightItem->setCustomCursor(Qt::SizeFDiagCursor);
+
+ m_data->topItem = new ResizeHandleItem(layerItem, this);
+ m_data->topItem->setZValue(3000);
+ m_data->topItem->setCustomCursor(Qt::SizeVerCursor);
+
+ m_data->leftItem = new ResizeHandleItem(layerItem, this);
+ m_data->leftItem->setZValue(3000);
+ m_data->leftItem->setCustomCursor(Qt::SizeHorCursor);
+
+ m_data->rightItem = new ResizeHandleItem(layerItem, this);
+ m_data->rightItem->setZValue(3000);
+ m_data->rightItem->setCustomCursor(Qt::SizeHorCursor);
+
+ m_data->bottomItem = new ResizeHandleItem(layerItem, this);
+ m_data->bottomItem->setZValue(3000);
+ m_data->bottomItem->setCustomCursor(Qt::SizeVerCursor);
+
+ updatePosition();
+}
+
+bool ResizeController::isValid() const
+{
+ return !m_data->formEditorItem.isNull();
+}
+
+void ResizeController::show()
+{
+ updatePosition();
+
+ m_data->topLeftItem->show();
+ m_data->topRightItem->show();
+ m_data->bottomLeftItem->show();
+ m_data->bottomRightItem->show();
+ m_data->topItem->show();
+ m_data->leftItem->show();
+ m_data->rightItem->show();
+ m_data->bottomItem->show();
+}
+void ResizeController::hide()
+{
+ m_data->topLeftItem->hide();
+ m_data->topRightItem->hide();
+ m_data->bottomLeftItem->hide();
+ m_data->bottomRightItem->hide();
+ m_data->topItem->hide();
+ m_data->leftItem->hide();
+ m_data->rightItem->hide();
+ m_data->bottomItem->hide();
+}
+
+
+static QPointF topCenter(const QRectF &rect)
+{
+ return QPointF(rect.center().x(), rect.top());
+}
+
+static QPointF leftCenter(const QRectF &rect)
+{
+ return QPointF(rect.left(), rect.center().y());
+}
+
+static QPointF rightCenter(const QRectF &rect)
+{
+ return QPointF(rect.right(), rect.center().y());
+}
+
+static QPointF bottomCenter(const QRectF &rect)
+{
+ return QPointF(rect.center().x(), rect.bottom());
+}
+
+
+void ResizeController::updatePosition()
+{
+ QGraphicsItem *formEditorItem = m_data->formEditorItem.data();
+ QRectF boundingRect =formEditorItem->boundingRect();
+ QPointF topLeftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
+ boundingRect.topLeft()));
+ QPointF topRightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
+ boundingRect.topRight()));
+ QPointF bottomLeftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
+ boundingRect.bottomLeft()));
+ QPointF bottomRightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
+ boundingRect.bottomRight()));
+
+ QPointF topPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
+ topCenter(boundingRect)));
+ QPointF leftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
+ leftCenter(boundingRect)));
+
+ QPointF rightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
+ rightCenter(boundingRect)));
+ QPointF bottomPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
+ bottomCenter(boundingRect)));
+
+
+ m_data->topRightItem->setHandlePosition(topRightPointInLayerSpace, boundingRect.topRight());
+ m_data->topLeftItem->setHandlePosition(topLeftPointInLayerSpace, boundingRect.topLeft());
+ m_data->bottomLeftItem->setHandlePosition(bottomLeftPointInLayerSpace, boundingRect.bottomLeft());
+ m_data->bottomRightItem->setHandlePosition(bottomRightPointInLayerSpace, boundingRect.bottomRight());
+ m_data->topItem->setHandlePosition(topPointInLayerSpace, topCenter(boundingRect));
+ m_data->leftItem->setHandlePosition(leftPointInLayerSpace, leftCenter(boundingRect));
+ m_data->rightItem->setHandlePosition(rightPointInLayerSpace, rightCenter(boundingRect));
+ m_data->bottomItem->setHandlePosition(bottomPointInLayerSpace, bottomCenter(boundingRect));
+
+}
+
+
+QGraphicsObject* ResizeController::formEditorItem() const
+{
+ return m_data->formEditorItem.data();
+}
+
+ResizeControllerData *ResizeController::data() const
+{
+ return m_data;
+}
+
+bool ResizeController::isTopLeftHandle(const ResizeHandleItem *handle) const
+{
+ return handle == m_data->topLeftItem;
+}
+
+bool ResizeController::isTopRightHandle(const ResizeHandleItem *handle) const
+{
+ return handle == m_data->topRightItem;
+}
+
+bool ResizeController::isBottomLeftHandle(const ResizeHandleItem *handle) const
+{
+ return handle == m_data->bottomLeftItem;
+}
+
+bool ResizeController::isBottomRightHandle(const ResizeHandleItem *handle) const
+{
+ return handle == m_data->bottomRightItem;
+}
+
+bool ResizeController::isTopHandle(const ResizeHandleItem *handle) const
+{
+ return handle == m_data->topItem;
+}
+
+bool ResizeController::isLeftHandle(const ResizeHandleItem *handle) const
+{
+ return handle == m_data->leftItem;
+}
+
+bool ResizeController::isRightHandle(const ResizeHandleItem *handle) const
+{
+ return handle == m_data->rightItem;
+}
+
+bool ResizeController::isBottomHandle(const ResizeHandleItem *handle) const
+{
+ return handle == m_data->bottomItem;
+}
+
+}
diff --git a/src/tools/qml/qmlviewer/editor/resizecontroller.h b/src/tools/qml/qmlviewer/editor/resizecontroller.h
new file mode 100644
index 00000000000..6b214195709
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/resizecontroller.h
@@ -0,0 +1,106 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef RESIZECONTROLLER_H
+#define RESIZECONTROLLER_H
+
+#include
+#include
+#include
+#include
+
+namespace QmlViewer {
+
+class LayerItem;
+class ResizeHandleItem;
+
+class ResizeControllerData
+{
+public:
+ ResizeControllerData(LayerItem *layerItem,
+ QGraphicsObject *formEditorItem);
+ //ResizeControllerData(const ResizeControllerData &other);
+ ~ResizeControllerData();
+ void clear();
+
+ QWeakPointer layerItem;
+ QWeakPointer formEditorItem;
+ ResizeHandleItem *topLeftItem;
+ ResizeHandleItem *topRightItem;
+ ResizeHandleItem *bottomLeftItem;
+ ResizeHandleItem *bottomRightItem;
+ ResizeHandleItem *topItem;
+ ResizeHandleItem *leftItem;
+ ResizeHandleItem *rightItem;
+ ResizeHandleItem *bottomItem;
+};
+
+
+
+
+class ResizeController
+{
+public:
+ friend class ResizeHandleItem;
+
+ ResizeController();
+ ~ResizeController();
+ ResizeController(LayerItem *layerItem, QGraphicsObject *formEditorItem);
+
+ void show();
+ void hide();
+ void setItem(LayerItem *layerItem, QGraphicsObject *item);
+
+ void updatePosition();
+
+ bool isValid() const;
+
+ QGraphicsObject *formEditorItem() const;
+
+ bool isTopLeftHandle(const ResizeHandleItem *handle) const;
+ bool isTopRightHandle(const ResizeHandleItem *handle) const;
+ bool isBottomLeftHandle(const ResizeHandleItem *handle) const;
+ bool isBottomRightHandle(const ResizeHandleItem *handle) const;
+
+ bool isTopHandle(const ResizeHandleItem *handle) const;
+ bool isLeftHandle(const ResizeHandleItem *handle) const;
+ bool isRightHandle(const ResizeHandleItem *handle) const;
+ bool isBottomHandle(const ResizeHandleItem *handle) const;
+
+private: // functions
+ void createFor(LayerItem *layerItem, QGraphicsObject *formEditorItem);
+ ResizeControllerData *data() const;
+
+private: // variables
+ ResizeControllerData *m_data;
+};
+
+}
+
+#endif // RESIZECONTROLLER_H
diff --git a/src/tools/qml/qmlviewer/editor/resizehandleitem.cpp b/src/tools/qml/qmlviewer/editor/resizehandleitem.cpp
new file mode 100644
index 00000000000..88d50b4650c
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/resizehandleitem.cpp
@@ -0,0 +1,126 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "resizehandleitem.h"
+
+#include
+
+namespace QmlViewer {
+
+ResizeHandleItem::ResizeHandleItem(QGraphicsItem *parent, ResizeController *resizeController)
+ : QGraphicsPixmapItem(QPixmap(":/editor/handle/resize_handle.png"), parent),
+ m_resizeController(resizeController)
+{
+ setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
+ setOffset(-pixmap().rect().center());
+ setFlag(QGraphicsItem::ItemIsMovable, true);
+ setFlag(QGraphicsItem::ItemIgnoresTransformations, true);
+}
+
+void ResizeHandleItem::setHandlePosition(const QPointF & globalPosition, const QPointF & itemSpacePosition)
+{
+ m_itemSpacePosition = itemSpacePosition;
+ setPos(globalPosition);
+}
+
+QRectF ResizeHandleItem::boundingRect() const
+{
+ return QGraphicsPixmapItem::boundingRect().adjusted(-1, -1, 1, 1);
+}
+
+QPainterPath ResizeHandleItem::shape() const
+{
+ return QGraphicsItem::shape();
+}
+
+ResizeController * ResizeHandleItem::resizeController() const
+{
+ return m_resizeController;
+}
+
+ResizeHandleItem* ResizeHandleItem::fromGraphicsItem(QGraphicsItem *item)
+{
+ return qgraphicsitem_cast(item);
+}
+
+bool ResizeHandleItem::isTopLeftHandle() const
+{
+ return resizeController()->isTopLeftHandle(this);
+}
+
+bool ResizeHandleItem::isTopRightHandle() const
+{
+ return resizeController()->isTopRightHandle(this);
+}
+
+bool ResizeHandleItem::isBottomLeftHandle() const
+{
+ return resizeController()->isBottomLeftHandle(this);
+}
+
+bool ResizeHandleItem::isBottomRightHandle() const
+{
+ return resizeController()->isBottomRightHandle(this);
+}
+
+bool ResizeHandleItem::isTopHandle() const
+{
+ return resizeController()->isTopHandle(this);
+}
+
+bool ResizeHandleItem::isLeftHandle() const
+{
+ return resizeController()->isLeftHandle(this);
+}
+
+bool ResizeHandleItem::isRightHandle() const
+{
+ return resizeController()->isRightHandle(this);
+}
+
+bool ResizeHandleItem::isBottomHandle() const
+{
+ return resizeController()->isBottomHandle(this);
+}
+
+QPointF ResizeHandleItem::itemSpacePosition() const
+{
+ return m_itemSpacePosition;
+}
+
+QCursor ResizeHandleItem::customCursor() const
+{
+ return m_customCursor;
+}
+void ResizeHandleItem::setCustomCursor(const QCursor &cursor)
+{
+ m_customCursor = cursor;
+}
+
+}
diff --git a/src/tools/qml/qmlviewer/editor/resizehandleitem.h b/src/tools/qml/qmlviewer/editor/resizehandleitem.h
new file mode 100644
index 00000000000..a758dc059fd
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/resizehandleitem.h
@@ -0,0 +1,89 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef RESIZEHANDLEITEM_H
+#define RESIZEHANDLEITEM_H
+
+#include
+#include
+
+#include "resizecontroller.h"
+
+namespace QmlViewer {
+
+class ResizeHandleItem : public QGraphicsPixmapItem
+{
+public:
+ enum
+ {
+ Type = 0xEAEA
+ };
+
+
+ ResizeHandleItem(QGraphicsItem *parent, ResizeController *resizeController);
+
+ void setHandlePosition(const QPointF & globalPosition, const QPointF & itemSpacePosition);
+
+ int type() const;
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+
+ ResizeController * resizeController() const;
+
+ static ResizeHandleItem* fromGraphicsItem(QGraphicsItem *item);
+
+ bool isTopLeftHandle() const;
+ bool isTopRightHandle() const;
+ bool isBottomLeftHandle() const;
+ bool isBottomRightHandle() const;
+
+ bool isTopHandle() const;
+ bool isLeftHandle() const;
+ bool isRightHandle() const;
+ bool isBottomHandle() const;
+
+ QPointF itemSpacePosition() const;
+ QCursor customCursor() const;
+ void setCustomCursor(const QCursor &cursor);
+
+private:
+ ResizeController *m_resizeController;
+ QPointF m_itemSpacePosition;
+ QCursor m_customCursor;
+
+};
+
+inline int ResizeHandleItem::type() const
+{
+ return Type;
+}
+
+}
+
+#endif // RESIZEHANDLEITEM_H
diff --git a/src/tools/qml/qmlviewer/editor/resizeindicator.cpp b/src/tools/qml/qmlviewer/editor/resizeindicator.cpp
new file mode 100644
index 00000000000..62a7eb29cff
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/resizeindicator.cpp
@@ -0,0 +1,95 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "resizeindicator.h"
+#include "layeritem.h"
+
+#include
+
+namespace QmlViewer {
+
+ResizeIndicator::ResizeIndicator(LayerItem *layerItem)
+ : m_layerItem(layerItem)
+{
+
+}
+
+ResizeIndicator::~ResizeIndicator()
+{
+ m_itemControllerHash.clear();
+}
+
+void ResizeIndicator::show()
+{
+ QHashIterator itemControllerIterator(m_itemControllerHash);
+ while (itemControllerIterator.hasNext()) {
+ ResizeController *controller = itemControllerIterator.next().value();
+ controller->show();
+ }
+}
+void ResizeIndicator::hide()
+{
+ QHashIterator itemControllerIterator(m_itemControllerHash);
+ while (itemControllerIterator.hasNext()) {
+ ResizeController *controller = itemControllerIterator.next().value();
+ controller->hide();
+ }
+}
+
+void ResizeIndicator::clear()
+{
+ QHashIterator itemControllerIterator(m_itemControllerHash);
+ while(itemControllerIterator.hasNext()) {
+ itemControllerIterator.next();
+ delete itemControllerIterator.value();
+ }
+ m_itemControllerHash.clear();
+}
+
+void ResizeIndicator::setItems(const QList &itemList)
+{
+ clear();
+
+ foreach (QGraphicsObject* item, itemList) {
+ ResizeController *controller = new ResizeController(m_layerItem.data(), item);
+ m_itemControllerHash.insert(item, controller);
+ }
+}
+
+void ResizeIndicator::updateItems(const QList &/*itemList*/)
+{
+// foreach (QDeclarativeItem* item, itemList) {
+// if (m_itemControllerHash.contains(item)) {
+// ResizeController *controller = new ResizeController(m_itemControllerHash.value(item));
+// controller.updatePosition();
+// }
+// }
+}
+
+}
diff --git a/src/tools/qml/qmlviewer/editor/resizeindicator.h b/src/tools/qml/qmlviewer/editor/resizeindicator.h
new file mode 100644
index 00000000000..360dba72b7b
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/resizeindicator.h
@@ -0,0 +1,82 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef RESIZEINDICATOR_H
+#define RESIZEINDICATOR_H
+
+#include
+#include
+#include
+#include
+#include
+
+#include "resizecontroller.h"
+
+QT_FORWARD_DECLARE_CLASS(QGraphicsRectItem);
+
+namespace QmlViewer {
+
+class LayerItem;
+
+class ResizeIndicator
+{
+public:
+ enum Orientation {
+ Top = 1,
+ Right = 2,
+ Bottom = 4,
+ Left = 8
+ };
+
+ ResizeIndicator(LayerItem *layerItem);
+ ~ResizeIndicator();
+
+ void show();
+ void hide();
+
+ void clear();
+
+ void setItems(const QList &itemList);
+ void updateItems(const QList &itemList);
+
+//
+// QPair pick(QGraphicsRectItem* pickedItem) const;
+//
+// void show();
+// void hide();
+
+private:
+ QWeakPointer m_layerItem;
+ QHash m_itemControllerHash;
+
+};
+
+}
+
+#endif // SCALEINDICATOR_H
diff --git a/src/tools/qml/qmlviewer/editor/resizemanipulator.cpp b/src/tools/qml/qmlviewer/editor/resizemanipulator.cpp
new file mode 100644
index 00000000000..329404244d6
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/resizemanipulator.cpp
@@ -0,0 +1,529 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "resizemanipulator.h"
+#include "resizehandleitem.h"
+
+#include "mathutils.h"
+
+#include
+#include
+#include
+#include
+
+namespace QmlViewer {
+
+ResizeManipulator::ResizeManipulator(LayerItem *layer, QDeclarativeView *view)
+ : m_view(view),
+ m_resizeController(0),
+ m_beginTopMargin(0.0),
+ m_beginLeftMargin(0.0),
+ m_beginRightMargin(0.0),
+ m_beginBottomMargin(0.0),
+ m_resizeHandle(0),
+ m_layerItem(layer)
+{
+}
+
+ResizeManipulator::~ResizeManipulator()
+{
+ deleteSnapLines();
+}
+
+void ResizeManipulator::setHandle(ResizeHandleItem *resizeHandle)
+{
+ Q_ASSERT(resizeHandle);
+ m_view->setCursor(resizeHandle->customCursor());
+ m_resizeHandle = resizeHandle;
+ m_resizeController = resizeHandle->resizeController();
+ //m_snapper.setContainerFormEditorItem(m_resizeController.formEditorItem()->parentItem());
+ //m_snapper.setTransformtionSpaceFormEditorItem(m_resizeController.formEditorItem());
+ Q_ASSERT(m_resizeController->isValid());
+}
+
+void ResizeManipulator::removeHandle()
+{
+ m_resizeController = 0;
+ m_resizeHandle = 0;
+}
+
+void ResizeManipulator::begin(const QPointF &/*beginPoint*/)
+{
+
+ if (m_resizeController->isValid()) {
+ m_beginBoundingRect = m_resizeController->formEditorItem()->boundingRect();
+ m_beginToSceneTransform = m_resizeController->formEditorItem()->sceneTransform();
+ m_beginFromSceneTransform = m_beginToSceneTransform.inverted();
+
+ if (m_resizeController->formEditorItem()->parentItem()) {
+ m_beginToParentTransform = m_resizeController->formEditorItem()->itemTransform(m_resizeController->formEditorItem()->parentItem());
+ } else {
+ m_beginToParentTransform = QTransform();
+ }
+
+ //m_snapper.updateSnappingLines(m_resizeController.formEditorItem());
+ m_beginBottomRightPoint = m_beginToParentTransform.map(m_resizeController->formEditorItem()->boundingRect().bottomRight());
+
+ //QmlAnchors anchors(m_resizeController.formEditorItem()->qmlItemNode().anchors());
+ m_beginTopMargin = 0;//anchors.instanceMargin(AnchorLine::Top);
+ m_beginLeftMargin = 0;//anchors.instanceMargin(AnchorLine::Left);
+ m_beginRightMargin = 0;//anchors.instanceMargin(AnchorLine::Right);
+ m_beginBottomMargin = 0;//anchors.instanceMargin(AnchorLine::Bottom);
+ }
+}
+
+//static QSizeF mapSizeToParent(const QSizeF &size, QGraphicsItem *item)
+//{
+// QPointF sizeAsPoint(size.width(), size.height());
+// sizeAsPoint = item->mapToParent(sizeAsPoint);
+// return QSizeF(sizeAsPoint.x(), sizeAsPoint.y());
+//}
+
+void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping)
+{
+ if (!m_resizeHandle || !m_resizeController)
+ return;
+
+ const double minimumWidth = 15.0;
+ const double minimumHeight = 15.0;
+
+ deleteSnapLines();
+
+ bool snap = useSnapping == UseSnapping || useSnapping == UseSnappingAndAnchoring;
+
+ if (m_resizeController->isValid()) {
+
+ QDeclarativeItem *formEditorItem = qobject_cast(m_resizeController->formEditorItem());
+
+ if (!formEditorItem)
+ return;
+
+ //FormEditorItem *containerItem = m_snapper.containerFormEditorItem();
+
+// if (!containerItem)
+// return;
+// QPointF updatePointInLocalSpace = QPointF(0,0);
+// if (formEditorItem->parentItem()) {
+// updatePointInLocalSpace = formEditorItem->parentItem()->mapFromScene(updatePoint);
+// } else {
+// updatePointInLocalSpace = updatePoint; //= m_beginFromSceneTransform.map(updatePoint);
+// }
+
+ QPointF updatePointInLocalSpace = m_beginFromSceneTransform.map(updatePoint);
+ //QmlAnchors anchors(formEditorItem->qmlItemNode().anchors());
+
+ QRectF boundingRect(m_beginBoundingRect);
+ if (m_resizeHandle->isBottomRightHandle()) {
+ boundingRect.setBottomRight(updatePointInLocalSpace);
+
+ if (snap) {
+// double rightOffset = m_snapper.snapRightOffset(boundingRect);
+// if (rightOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.rx() -= rightOffset;
+
+// double bottomOffset = m_snapper.snapBottomOffset(boundingRect);
+// if (bottomOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.ry() -= bottomOffset;
+ }
+ boundingRect.setBottomRight(updatePointInLocalSpace);
+
+// if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
+// boundingRect.setLeft(boundingRect.left() - (updatePointInLocalSpace.x() - m_beginBoundingRect.right()));
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
+// boundingRect.setTop(boundingRect.top() - (updatePointInLocalSpace.y() - m_beginBoundingRect.bottom()));
+// }
+
+
+ if (boundingRect.width() < minimumWidth)
+ boundingRect.setWidth(minimumWidth);
+ if (boundingRect.height() < minimumHeight)
+ boundingRect.setHeight(minimumHeight);
+
+ formEditorItem->setSize(boundingRect.size());
+
+// if (anchors.instanceHasAnchor(AnchorLine::Bottom)) {
+// anchors.setMargin(AnchorLine::Bottom,
+// m_beginBottomMargin - (m_beginToParentTransform.map(boundingRect.bottomRight()) - m_beginBottomRightPoint).y());
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::Right)) {
+// anchors.setMargin(AnchorLine::Right,
+// m_beginRightMargin - (m_beginToParentTransform.map(boundingRect.bottomRight()) - m_beginBottomRightPoint).x());
+// }
+ } else if (m_resizeHandle->isTopLeftHandle()) {
+ boundingRect.setTopLeft(updatePointInLocalSpace);
+
+ if (snap) {
+// double leftOffset = m_snapper.snapLeftOffset(boundingRect);
+// if (leftOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.rx() -= leftOffset;
+
+// double topOffset = m_snapper.snapTopOffset(boundingRect);
+// if (topOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.ry() -= topOffset;
+ }
+ //boundingRect.setTopLeft(updatePointInLocalSpace);
+
+// if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
+// boundingRect.setRight(boundingRect.right() - (updatePointInLocalSpace.x() - m_beginBoundingRect.left()));
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
+// boundingRect.setBottom(boundingRect.bottom() - (updatePointInLocalSpace.y() - m_beginBoundingRect.top()));
+// }
+
+
+ if (boundingRect.width() < minimumWidth)
+ boundingRect.setLeft(boundingRect.left() - minimumWidth + boundingRect.width());
+ if (boundingRect.height() < minimumHeight)
+ boundingRect.setTop(boundingRect.top() - minimumHeight + boundingRect.height());
+
+ formEditorItem->setSize(boundingRect.size());
+ formEditorItem->setPos(m_beginToParentTransform.map(boundingRect.topLeft()));
+
+
+// if (anchors.instanceHasAnchor(AnchorLine::Top)) {
+// anchors.setMargin(AnchorLine::Top,
+// m_beginTopMargin + (-m_beginToParentTransform.map(m_beginBoundingRect.topLeft()).y() + m_beginToParentTransform.map(boundingRect.topLeft()).y()));
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::Left)) {
+// anchors.setMargin(AnchorLine::Left,
+// m_beginLeftMargin + (-m_beginToParentTransform.map(m_beginBoundingRect.topLeft()).x() + m_beginToParentTransform.map(boundingRect.topLeft()).x()));
+// }
+
+ } else if (m_resizeHandle->isTopRightHandle()) {
+ boundingRect.setTopRight(updatePointInLocalSpace);
+
+ if (snap) {
+// double rightOffset = m_snapper.snapRightOffset(boundingRect);
+// if (rightOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.rx() -= rightOffset;
+
+// double topOffset = m_snapper.snapTopOffset(boundingRect);
+// if (topOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.ry() -= topOffset;
+ }
+ boundingRect.setTopRight(updatePointInLocalSpace);
+
+// if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
+// boundingRect.setLeft(boundingRect.left() - (updatePointInLocalSpace.x() - m_beginBoundingRect.right()));
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
+// boundingRect.setBottom(boundingRect.bottom() - (updatePointInLocalSpace.y() - m_beginBoundingRect.top()));
+// }
+
+ if (boundingRect.height() < minimumHeight)
+ boundingRect.setTop(boundingRect.top() - minimumHeight + boundingRect.height());
+ if (boundingRect.width() < minimumWidth)
+ boundingRect.setWidth(minimumWidth);
+
+ formEditorItem->setSize(boundingRect.size());
+
+ // was: setPositionWithBorder
+ formEditorItem->setPos(m_beginToParentTransform.map(boundingRect.topLeft()));
+
+// if (anchors.instanceHasAnchor(AnchorLine::Top)) {
+// anchors.setMargin(AnchorLine::Top,
+// m_beginTopMargin + (-m_beginToParentTransform.map(m_beginBoundingRect.topLeft()).y() + m_beginToParentTransform.map(boundingRect.topLeft()).y()));
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::Right)) {
+// anchors.setMargin(AnchorLine::Right,
+// m_beginRightMargin - (m_beginToParentTransform.map(boundingRect.bottomRight()) - m_beginBottomRightPoint).x());
+// }
+ } else if (m_resizeHandle->isBottomLeftHandle()) {
+ boundingRect.setBottomLeft(updatePointInLocalSpace);
+
+ if (snap) {
+// double leftOffset = m_snapper.snapLeftOffset(boundingRect);
+// if (leftOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.rx() -= leftOffset;
+
+// double bottomOffset = m_snapper.snapBottomOffset(boundingRect);
+// if (bottomOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.ry() -= bottomOffset;
+ }
+
+ boundingRect.setBottomLeft(updatePointInLocalSpace);
+
+// if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
+// boundingRect.setRight(boundingRect.right() - (updatePointInLocalSpace.x() - m_beginBoundingRect.left()));
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
+// boundingRect.setTop(boundingRect.top() - (updatePointInLocalSpace.y() - m_beginBoundingRect.bottom()));
+// }
+
+ if (boundingRect.height() < minimumHeight)
+ boundingRect.setHeight(minimumHeight);
+ if (boundingRect.width() < minimumWidth)
+ boundingRect.setLeft(boundingRect.left() - minimumWidth + boundingRect.width());
+
+ formEditorItem->setSize(boundingRect.size());
+ formEditorItem->setPos(m_beginToParentTransform.map(boundingRect.topLeft()));
+
+// if (anchors.instanceHasAnchor(AnchorLine::Left)) {
+// anchors.setMargin(AnchorLine::Left,
+// m_beginLeftMargin + (-m_beginToParentTransform.map(m_beginBoundingRect.topLeft()).x() + m_beginToParentTransform.map(boundingRect.topLeft()).x()));
+// }
+
+// if (anchors.instanceHasAnchor(AnchorLine::Bottom)) {
+// anchors.setMargin(AnchorLine::Bottom,
+// m_beginBottomMargin - (m_beginToParentTransform.map(boundingRect.bottomRight()) - m_beginBottomRightPoint).y());
+// }
+ } else if (m_resizeHandle->isBottomHandle()) {
+ boundingRect.setBottom(updatePointInLocalSpace.y());
+
+ if (snap) {
+// double bottomOffset = m_snapper.snapBottomOffset(boundingRect);
+// if (bottomOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.ry() -= bottomOffset;
+ }
+
+ boundingRect.setBottom(updatePointInLocalSpace.y());
+
+// if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
+// boundingRect.setTop(boundingRect.top() - (updatePointInLocalSpace.y() - m_beginBoundingRect.bottom()));
+// }
+
+ if (boundingRect.height() < minimumHeight)
+ boundingRect.setHeight(minimumHeight);
+
+ formEditorItem->setSize(boundingRect.size());
+
+// if (anchors.instanceHasAnchor(AnchorLine::Bottom)) {
+// anchors.setMargin(AnchorLine::Bottom,
+// m_beginBottomMargin - (m_beginToParentTransform.map(boundingRect.bottomRight()) - m_beginBottomRightPoint).y());
+// }
+ } else if (m_resizeHandle->isTopHandle()) {
+ boundingRect.setTop(updatePointInLocalSpace.y());
+
+ if (snap) {
+// double topOffset = m_snapper.snapTopOffset(boundingRect);
+// if (topOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.ry() -= topOffset;
+ }
+
+ boundingRect.setTop(updatePointInLocalSpace.y());
+
+// if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
+// boundingRect.setBottom(boundingRect.bottom() - (updatePointInLocalSpace.y() - m_beginBoundingRect.top()));
+// }
+
+ if (boundingRect.height() < minimumHeight)
+ boundingRect.setTop(boundingRect.top() - minimumHeight + boundingRect.height());
+
+ formEditorItem->setSize(boundingRect.size());
+ formEditorItem->setPos(m_beginToParentTransform.map(boundingRect.topLeft()));
+
+// if (anchors.instanceHasAnchor(AnchorLine::Top)) {
+// anchors.setMargin(AnchorLine::Top,
+// m_beginTopMargin + (-m_beginToParentTransform.map(m_beginBoundingRect.topLeft()).y() + m_beginToParentTransform.map(boundingRect.topLeft()).y()));
+// }
+ } else if (m_resizeHandle->isRightHandle()) {
+ boundingRect.setRight(updatePointInLocalSpace.x());
+
+ if (snap) {
+// double rightOffset = m_snapper.snapRightOffset(boundingRect);
+// if (rightOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.rx() -= rightOffset;
+ }
+
+ boundingRect.setRight(updatePointInLocalSpace.x());
+
+// if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
+// boundingRect.setLeft(boundingRect.left() - (updatePointInLocalSpace.x() - m_beginBoundingRect.right()));
+// }
+
+ if (boundingRect.width() < minimumWidth)
+ boundingRect.setWidth(minimumWidth);
+
+ formEditorItem->setSize(boundingRect.size());
+
+
+// if (anchors.instanceHasAnchor(AnchorLine::Right)) {
+// anchors.setMargin(AnchorLine::Right,
+// m_beginRightMargin - (m_beginToParentTransform.map(boundingRect.bottomRight()) - m_beginBottomRightPoint).x());
+// }
+ } else if (m_resizeHandle->isLeftHandle()) {
+ boundingRect.setLeft(updatePointInLocalSpace.x());
+
+ if (snap) {
+// double leftOffset = m_snapper.snapLeftOffset(boundingRect);
+// if (leftOffset < std::numeric_limits::max())
+// updatePointInLocalSpace.rx() -= leftOffset;
+ }
+
+ boundingRect.setLeft(updatePointInLocalSpace.x());
+
+// if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
+// boundingRect.setRight(boundingRect.right() - (updatePointInLocalSpace.x() - m_beginBoundingRect.left()));
+// }
+
+ if (boundingRect.width() < minimumWidth)
+ boundingRect.setLeft(boundingRect.left() - minimumWidth + boundingRect.width());
+
+ formEditorItem->setSize(boundingRect.size());
+ formEditorItem->setPos(m_beginToParentTransform.map(boundingRect.topLeft()));
+
+// if (anchors.instanceHasAnchor(AnchorLine::Left)) {
+// anchors.setMargin(AnchorLine::Left,
+// m_beginLeftMargin + (-m_beginToParentTransform.map(m_beginBoundingRect.topLeft()).x() + m_beginToParentTransform.map(boundingRect.topLeft()).x()));
+// }
+ }
+
+// if (snap)
+// m_graphicsLineList = m_snapper.generateSnappingLines(boundingRect,
+// m_layerItem.data(),
+// m_beginToSceneTransform);
+ }
+ m_resizeController->updatePosition();
+}
+
+void ResizeManipulator::end()
+{
+ //m_rewriterTransaction.commit();
+ clear();
+ removeHandle();
+}
+
+//void ResizeManipulator::moveBy(double deltaX, double deltaY)
+//{
+// if (resizeHandle()) {
+// //QmlItemNode qmlItemNode(m_resizeController.formEditorItem()->qmlItemNode());
+// //QmlAnchors anchors(qmlItemNode.anchors());
+
+// if (m_resizeController.isLeftHandle(resizeHandle())
+// || m_resizeController.isTopLeftHandle(resizeHandle())
+// || m_resizeController.isBottomLeftHandle(resizeHandle())) {
+// qmlItemNode.setVariantProperty("x", round((qmlItemNode.instanceValue("x").toDouble() + deltaX), 4));
+// qmlItemNode.setVariantProperty("width", round(qmlItemNode.instanceValue("width").toDouble() - deltaX, 4));
+
+
+//// if (anchors.instanceHasAnchor(AnchorLine::Left)) {
+//// anchors.setMargin(AnchorLine::Left, anchors.instanceMargin(AnchorLine::Left) + deltaX);
+//// }
+
+//// if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
+//// qmlItemNode.setVariantProperty("width", round(qmlItemNode.instanceValue("width").toDouble() - (deltaX * 2), 4));
+//// }
+// }
+
+// if (m_resizeController.isRightHandle(resizeHandle())
+// || m_resizeController.isTopRightHandle(resizeHandle())
+// || m_resizeController.isBottomRightHandle(resizeHandle())) {
+// qmlItemNode.setVariantProperty("width", round(qmlItemNode.instanceValue("width").toDouble() + deltaX, 4));
+
+//// if (anchors.instanceHasAnchor(AnchorLine::Right)) {
+//// anchors.setMargin(AnchorLine::Right, round(anchors.instanceMargin(AnchorLine::Right) - deltaX, 4));
+//// }
+
+//// if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
+//// qmlItemNode.setVariantProperty("width", round(qmlItemNode.instanceValue("width").toDouble() + (deltaX * 2), 4));
+//// }
+// }
+
+
+// if (m_resizeController.isTopHandle(resizeHandle())
+// || m_resizeController.isTopLeftHandle(resizeHandle())
+// || m_resizeController.isTopRightHandle(resizeHandle())) {
+// qmlItemNode.setVariantProperty("y", round(qmlItemNode.instanceValue("y").toDouble() + deltaY, 4));
+// qmlItemNode.setVariantProperty("height", round(qmlItemNode.instanceValue("height").toDouble() - deltaY, 4));
+
+//// if (anchors.instanceHasAnchor(AnchorLine::Top)) {
+//// anchors.setMargin(AnchorLine::Top, anchors.instanceMargin(AnchorLine::Top) + deltaY);
+//// }
+
+//// if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
+//// qmlItemNode.setVariantProperty("height", round(qmlItemNode.instanceValue("height").toDouble() - (deltaY * 2), 4));
+//// }
+// }
+
+// if (m_resizeController.isBottomHandle(resizeHandle())
+// || m_resizeController.isBottomLeftHandle(resizeHandle())
+// || m_resizeController.isBottomRightHandle(resizeHandle())) {
+// qmlItemNode.setVariantProperty("height", round(qmlItemNode.instanceValue("height").toDouble() + deltaY, 4));
+
+//// if (anchors.instanceHasAnchor(AnchorLine::Bottom)) {
+//// anchors.setMargin(AnchorLine::Bottom, anchors.instanceMargin(AnchorLine::Bottom) - deltaY);
+//// }
+
+//// if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
+//// qmlItemNode.setVariantProperty("height", round(qmlItemNode.instanceValue("height").toDouble() + (deltaY * 2), 4));
+//// }
+// }
+
+// }
+//}
+
+bool ResizeManipulator::isInvalidSize(const QSizeF & size)
+{
+ if (size.width() < 15 || size.height() < 15)
+ return true;
+
+ return false;
+}
+
+void ResizeManipulator::deleteSnapLines()
+{
+// if (m_layerItem) {
+// foreach (QGraphicsItem *item, m_graphicsLineList)
+// m_layerItem->scene()->removeItem(item);
+// }
+
+ m_graphicsLineList.clear();
+ m_view->scene()->update();
+}
+
+ResizeHandleItem *ResizeManipulator::resizeHandle()
+{
+ return m_resizeHandle;
+}
+
+void ResizeManipulator::clear()
+{
+ //m_rewriterTransaction.commit();
+
+ deleteSnapLines();
+ m_beginBoundingRect = QRectF();
+ m_beginFromSceneTransform = QTransform();
+ m_beginToSceneTransform = QTransform();
+ m_beginToParentTransform = QTransform();
+ m_beginTopMargin = 0.0;
+ m_beginLeftMargin = 0.0;
+ m_beginRightMargin = 0.0;
+ m_beginBottomMargin = 0.0;
+ removeHandle();
+}
+
+}
diff --git a/src/tools/qml/qmlviewer/editor/resizemanipulator.h b/src/tools/qml/qmlviewer/editor/resizemanipulator.h
new file mode 100644
index 00000000000..87bd943be31
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/resizemanipulator.h
@@ -0,0 +1,93 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef RESIZEMANIPULATOR_H
+#define RESIZEMANIPULATOR_H
+
+#include
+#include "layeritem.h"
+#include "resizehandleitem.h"
+
+#include
+#include
+
+namespace QmlViewer {
+
+class ResizeHandleItem;
+class Model;
+
+class ResizeManipulator
+{
+public:
+ enum Snapping {
+ UseSnapping,
+ UseSnappingAndAnchoring,
+ NoSnapping
+ };
+
+ ResizeManipulator(LayerItem *layer, QDeclarativeView *view);
+ ~ResizeManipulator();
+
+ void setHandle(ResizeHandleItem *resizeHandle);
+ void removeHandle();
+
+ void begin(const QPointF& beginPoint);
+ void update(const QPointF& updatePoint, Snapping useSnapping);
+ void end();
+
+ void moveBy(double deltaX, double deltaY);
+
+ void clear();
+
+protected:
+ bool isInvalidSize(const QSizeF & size);
+ void deleteSnapLines();
+ ResizeHandleItem *resizeHandle();
+
+private:
+// Snapper m_snapper;
+ QWeakPointer m_view;
+ QList m_graphicsLineList;
+ ResizeController *m_resizeController;
+ QTransform m_beginFromSceneTransform;
+ QTransform m_beginToSceneTransform;
+ QTransform m_beginToParentTransform;
+ QRectF m_beginBoundingRect;
+ QPointF m_beginBottomRightPoint;
+ double m_beginTopMargin;
+ double m_beginLeftMargin;
+ double m_beginRightMargin;
+ double m_beginBottomMargin;
+ ResizeHandleItem *m_resizeHandle;
+ QWeakPointer m_layerItem;
+};
+
+}
+
+#endif // RESIZEMANIPULATOR_H
diff --git a/src/tools/qml/qmlviewer/editor/resizetool.cpp b/src/tools/qml/qmlviewer/editor/resizetool.cpp
new file mode 100644
index 00000000000..d5845be6672
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/resizetool.cpp
@@ -0,0 +1,204 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "resizetool.h"
+#include "resizehandleitem.h"
+#include "qdeclarativedesignview.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace QmlViewer {
+
+ResizeTool::ResizeTool(QDeclarativeDesignView *view)
+ : AbstractFormEditorTool(view),
+ m_selectionIndicator(view->manipulatorLayer()),
+ m_resizeManipulator(new ResizeManipulator(view->manipulatorLayer(), view)),
+ m_resizeIndicator(view->manipulatorLayer())
+{
+}
+
+
+ResizeTool::~ResizeTool()
+{
+ delete m_resizeManipulator;
+}
+
+void ResizeTool::mousePressEvent(QMouseEvent *event)
+{
+ QList itemList = view()->items(event->pos());
+
+ if (itemList.isEmpty())
+ return;
+
+ ResizeHandleItem *resizeHandle = ResizeHandleItem::fromGraphicsItem(itemList.first());
+
+ if (resizeHandle)
+ qDebug() << resizeHandle->resizeController();
+
+ if (resizeHandle
+ && resizeHandle->resizeController()
+ && resizeHandle->resizeController()->isValid())
+ {
+ m_resizeManipulator->setHandle(resizeHandle);
+ m_resizeManipulator->begin(view()->mapToScene(event->pos()));
+ m_resizeIndicator.hide();
+ } else {
+ view()->setCursor(Qt::ArrowCursor);
+ }
+}
+
+void ResizeTool::mouseMoveEvent(QMouseEvent *event)
+{
+
+ bool shouldSnapping = false; //view()->widget()->snappingAction()->isChecked();
+ bool shouldSnappingAndAnchoring = false; //view()->widget()->snappingAndAnchoringAction()->isChecked();
+
+ ResizeManipulator::Snapping useSnapping = ResizeManipulator::NoSnapping;
+ if (event->modifiers().testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) {
+ if (shouldSnappingAndAnchoring)
+ useSnapping = ResizeManipulator::UseSnappingAndAnchoring;
+ else
+ useSnapping = ResizeManipulator::UseSnapping;
+ }
+ m_resizeManipulator->update(view()->mapToScene(event->pos()), useSnapping);
+}
+
+void ResizeTool::hoverMoveEvent(QMouseEvent *event)
+{
+ QList itemList = view()->items(event->pos());
+
+ if (itemList.isEmpty())
+ return;
+
+ ResizeHandleItem* resizeHandle = ResizeHandleItem::fromGraphicsItem(itemList.first());
+ if (resizeHandle && resizeHandle->resizeController()->isValid()) {
+ m_resizeManipulator->setHandle(resizeHandle);
+ } else {
+ qDebug() << "resize -> selection tool";
+ view()->changeTool(Constants::SelectionToolMode);
+ return;
+ }
+}
+
+void ResizeTool::mouseReleaseEvent(QMouseEvent *event)
+{
+ QList itemList = view()->selectableItems(event->pos());
+ if (itemList.isEmpty())
+ return;
+
+ view()->setCursor(Qt::ArrowCursor);
+ m_selectionIndicator.show();
+ m_resizeIndicator.show();
+ m_resizeManipulator->end();
+}
+
+void ResizeTool::mouseDoubleClickEvent(QMouseEvent * /*event*/)
+{
+}
+
+void ResizeTool::keyPressEvent(QKeyEvent * event)
+{
+ switch(event->key()) {
+ case Qt::Key_Shift:
+ case Qt::Key_Alt:
+ case Qt::Key_Control:
+ case Qt::Key_AltGr:
+ event->setAccepted(false);
+ return;
+ }
+
+ double moveStep = 1.0;
+
+ if (event->modifiers().testFlag(Qt::ShiftModifier))
+ moveStep = 10.0;
+
+// switch(event->key()) {
+// case Qt::Key_Left: m_resizeManipulator->moveBy(-moveStep, 0.0); break;
+// case Qt::Key_Right: m_resizeManipulator->moveBy(moveStep, 0.0); break;
+// case Qt::Key_Up: m_resizeManipulator->moveBy(0.0, -moveStep); break;
+// case Qt::Key_Down: m_resizeManipulator->moveBy(0.0, moveStep); break;
+// }
+
+}
+
+void ResizeTool::keyReleaseEvent(QKeyEvent * keyEvent)
+{
+ switch(keyEvent->key()) {
+ case Qt::Key_Shift:
+ case Qt::Key_Alt:
+ case Qt::Key_Control:
+ case Qt::Key_AltGr:
+ keyEvent->setAccepted(false);
+ return;
+ }
+
+ if (!keyEvent->isAutoRepeat())
+ m_resizeManipulator->clear();
+}
+
+void ResizeTool::wheelEvent(QWheelEvent */*event*/)
+{
+
+}
+
+void ResizeTool::itemsAboutToRemoved(const QList & /*itemList*/)
+{
+
+}
+
+void ResizeTool::selectedItemsChanged(const QList & itemList)
+{
+ m_selectionIndicator.setItems(toGraphicsObjectList(itemList));
+
+ m_resizeIndicator.setItems(toGraphicsObjectList(itemList));
+}
+
+void ResizeTool::clear()
+{
+ view()->clearHighlightBoundingRect();
+ view()->setCursor(Qt::ArrowCursor);
+ m_selectionIndicator.clear();
+ m_resizeIndicator.clear();
+ m_resizeManipulator->clear();
+}
+
+void ResizeTool::graphicsObjectsChanged(const QList &itemList)
+{
+ m_selectionIndicator.updateItems(itemList);
+ m_resizeIndicator.updateItems(itemList);
+}
+
+}
diff --git a/src/tools/qml/qmlviewer/editor/resizetool.h b/src/tools/qml/qmlviewer/editor/resizetool.h
new file mode 100644
index 00000000000..250441a4e5c
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/resizetool.h
@@ -0,0 +1,82 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef RESIZETOOL_H
+#define RESIZETOOL_H
+
+#include
+#include
+#include
+
+#include "resizeindicator.h"
+
+#include "resizemanipulator.h"
+#include "abstractformeditortool.h"
+#include "selectionindicator.h"
+
+#include "resizeindicator.h"
+
+namespace QmlViewer {
+
+class QDeclarativeDesignView;
+
+class ResizeTool : public AbstractFormEditorTool
+{
+public:
+ ResizeTool(QDeclarativeDesignView *view);
+ ~ResizeTool();
+
+ bool isActive() const;
+
+ 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 &itemList);
+
+ void selectedItemsChanged(const QList &itemList);
+
+ void clear();
+ void graphicsObjectsChanged(const QList &itemList);
+
+private:
+ SelectionIndicator m_selectionIndicator;
+ ResizeManipulator *m_resizeManipulator;
+ ResizeIndicator m_resizeIndicator;
+};
+
+}
+
+#endif // RESIZETOOL_H
diff --git a/src/tools/qml/qmlviewer/editor/rubberbandselectionmanipulator.cpp b/src/tools/qml/qmlviewer/editor/rubberbandselectionmanipulator.cpp
new file mode 100644
index 00000000000..3783a09c404
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/rubberbandselectionmanipulator.cpp
@@ -0,0 +1,143 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "rubberbandselectionmanipulator.h"
+#include "qdeclarativedesignview.h"
+
+#include
+
+namespace QmlViewer {
+
+RubberBandSelectionManipulator::RubberBandSelectionManipulator(LayerItem *layerItem, QDeclarativeDesignView *editorView)
+ : m_selectionRectangleElement(layerItem),
+ m_editorView(editorView),
+ m_beginFormEditorItem(0),
+ m_isActive(false)
+{
+ m_selectionRectangleElement.hide();
+}
+
+void RubberBandSelectionManipulator::clear()
+{
+ m_selectionRectangleElement.clear();
+ m_isActive = false;
+ m_beginPoint = QPointF();
+ m_itemList.clear();
+ m_oldSelectionList.clear();
+}
+
+QGraphicsItem *RubberBandSelectionManipulator::topFormEditorItem(const QList &itemList)
+{
+ if (itemList.isEmpty())
+ return 0;
+
+ return itemList.first();
+}
+
+void RubberBandSelectionManipulator::begin(const QPointF& beginPoint)
+{
+ m_beginPoint = beginPoint;
+ m_selectionRectangleElement.setRect(m_beginPoint, m_beginPoint);
+ m_selectionRectangleElement.show();
+ m_isActive = true;
+ m_beginFormEditorItem = topFormEditorItem(m_editorView->selectableItems(beginPoint));
+ m_oldSelectionList = m_editorView->selectedItems();
+}
+
+void RubberBandSelectionManipulator::update(const QPointF& updatePoint)
+{
+ m_selectionRectangleElement.setRect(m_beginPoint, updatePoint);
+}
+
+void RubberBandSelectionManipulator::end()
+{
+ m_oldSelectionList.clear();
+ m_selectionRectangleElement.hide();
+ m_isActive = false;
+}
+
+void RubberBandSelectionManipulator::select(SelectionType selectionType)
+{
+ QList itemList = m_editorView->selectableItems(m_selectionRectangleElement.rect(),
+ Qt::IntersectsItemShape);
+ QList newSelectionList;
+
+ foreach (QGraphicsItem* item, itemList) {
+ if (item
+ && item->parentItem()
+ //&& m_beginFormEditorItem->childItems().contains(item) // TODO activate this test
+ )
+ {
+ newSelectionList.append(item);
+ }
+ }
+
+ if (newSelectionList.isEmpty() && m_beginFormEditorItem)
+ newSelectionList.append(m_beginFormEditorItem);
+
+ QList resultList;
+
+ switch(selectionType) {
+ case AddToSelection: {
+ resultList.append(m_oldSelectionList);
+ resultList.append(newSelectionList);
+ }
+ break;
+ case ReplaceSelection: {
+ resultList.append(newSelectionList);
+ }
+ break;
+ case RemoveFromSelection: {
+ QSet oldSelectionSet(m_oldSelectionList.toSet());
+ QSet newSelectionSet(newSelectionList.toSet());
+ resultList.append(oldSelectionSet.subtract(newSelectionSet).toList());
+ }
+ }
+
+ m_editorView->setSelectedItems(resultList);
+}
+
+
+void RubberBandSelectionManipulator::setItems(const QList &itemList)
+{
+ m_itemList = itemList;
+}
+
+QPointF RubberBandSelectionManipulator::beginPoint() const
+{
+ return m_beginPoint;
+}
+
+bool RubberBandSelectionManipulator::isActive() const
+{
+ return m_isActive;
+
+}
+
+}
diff --git a/src/tools/qml/qmlviewer/editor/rubberbandselectionmanipulator.h b/src/tools/qml/qmlviewer/editor/rubberbandselectionmanipulator.h
new file mode 100644
index 00000000000..c2a4486cf31
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/rubberbandselectionmanipulator.h
@@ -0,0 +1,82 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef RUBBERBANDSELECTIONMANIPULATOR_H
+#define RUBBERBANDSELECTIONMANIPULATOR_H
+
+
+#include "selectionrectangle.h"
+
+namespace QmlViewer {
+
+class QDeclarativeDesignView;
+
+class RubberBandSelectionManipulator
+{
+public:
+ enum SelectionType {
+ ReplaceSelection,
+ AddToSelection,
+ RemoveFromSelection
+ };
+
+
+ RubberBandSelectionManipulator(LayerItem *layerItem, QDeclarativeDesignView *editorView);
+
+ void setItems(const QList &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 &itemList);
+
+
+private:
+ QList m_itemList;
+ QList m_oldSelectionList;
+ SelectionRectangle m_selectionRectangleElement;
+ QPointF m_beginPoint;
+ QDeclarativeDesignView *m_editorView;
+ QGraphicsItem *m_beginFormEditorItem;
+ bool m_isActive;
+};
+
+}
+
+#endif // RUBBERBANDSELECTIONMANIPULATOR_H
diff --git a/src/tools/qml/qmlviewer/editor/selectionindicator.cpp b/src/tools/qml/qmlviewer/editor/selectionindicator.cpp
new file mode 100644
index 00000000000..e16a0a1e600
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/selectionindicator.cpp
@@ -0,0 +1,114 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "selectionindicator.h"
+
+#include
+#include
+#include
+
+namespace QmlViewer {
+
+SelectionIndicator::SelectionIndicator(LayerItem *layerItem)
+ : m_layerItem(layerItem)
+{
+}
+
+SelectionIndicator::~SelectionIndicator()
+{
+ clear();
+}
+
+void SelectionIndicator::show()
+{
+ foreach (QGraphicsPolygonItem *item, m_indicatorShapeHash.values())
+ item->show();
+}
+
+void SelectionIndicator::hide()
+{
+ foreach (QGraphicsPolygonItem *item, m_indicatorShapeHash.values())
+ item->hide();
+}
+
+void SelectionIndicator::clear()
+{
+ if (m_layerItem) {
+ foreach (QGraphicsItem *item, m_indicatorShapeHash.values())
+ m_layerItem->scene()->removeItem(item);
+ }
+ m_indicatorShapeHash.clear();
+}
+
+//static void alignVertices(QPolygonF &polygon, double factor)
+//{
+// QMutableVectorIterator iterator(polygon);
+// while (iterator.hasNext()) {
+// QPointF &vertex = iterator.next();
+// vertex.setX(std::floor(vertex.x()) + factor);
+// vertex.setY(std::floor(vertex.y()) + factor);
+// }
+//
+//}
+
+void SelectionIndicator::setItems(const QList &itemList)
+{
+ clear();
+
+ foreach (QGraphicsItem *item, itemList) {
+ QGraphicsPolygonItem *newSelectionIndicatorGraphicsItem = new QGraphicsPolygonItem(m_layerItem.data());
+ m_indicatorShapeHash.insert(item, newSelectionIndicatorGraphicsItem);
+ QPolygonF boundingRectInSceneSpace(item->mapToScene(item->boundingRect()));
+
+ QPolygonF boundingRectInLayerItemSpace = m_layerItem->mapFromScene(boundingRectInSceneSpace);
+ newSelectionIndicatorGraphicsItem->setPolygon(boundingRectInLayerItemSpace);
+ newSelectionIndicatorGraphicsItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
+
+ QPen pen;
+ pen.setColor(QColor(108, 141, 221));
+ newSelectionIndicatorGraphicsItem->setPen(pen);
+ }
+}
+
+
+
+void SelectionIndicator::updateItems(const QList &itemList)
+{
+ foreach (QGraphicsItem *item, itemList) {
+ if (m_indicatorShapeHash.contains(item)) {
+ QGraphicsPolygonItem *indicatorGraphicsItem = m_indicatorShapeHash.value(item);
+ QPolygonF boundingRectInSceneSpace(item->mapToScene(item->boundingRect()));
+ QPolygonF boundingRectInLayerItemSpace = m_layerItem->mapFromScene(boundingRectInSceneSpace);
+ indicatorGraphicsItem->setPolygon(boundingRectInLayerItemSpace);
+ }
+ }
+}
+
+} //namespace QmlViewer
+
diff --git a/src/tools/qml/qmlviewer/editor/selectionindicator.h b/src/tools/qml/qmlviewer/editor/selectionindicator.h
new file mode 100644
index 00000000000..5eac8ad83e7
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/selectionindicator.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef SELECTIONINDICATOR_H
+#define SELECTIONINDICATOR_H
+
+#include
+#include
+#include "layeritem.h"
+
+namespace QmlViewer {
+
+class SelectionIndicator
+{
+public:
+ SelectionIndicator(LayerItem *layerItem);
+ ~SelectionIndicator();
+
+ void show();
+ void hide();
+
+ void clear();
+
+ void setItems(const QList &itemList);
+ void updateItems(const QList &itemList);
+
+private:
+ QHash m_indicatorShapeHash;
+ QWeakPointer m_layerItem;
+
+};
+
+}
+
+#endif // SELECTIONINDICATOR_H
diff --git a/src/tools/qml/qmlviewer/editor/selectionrectangle.cpp b/src/tools/qml/qmlviewer/editor/selectionrectangle.cpp
new file mode 100644
index 00000000000..74a308e0c1c
--- /dev/null
+++ b/src/tools/qml/qmlviewer/editor/selectionrectangle.cpp
@@ -0,0 +1,87 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "selectionrectangle.h"
+
+#include
+#include
+#include