added custom qmlviewer to creator

This qmlviewer will be also the default one when opening qmlproject files
as the runconfiguration was changed too.
This commit is contained in:
Lasse Holmstedt
2010-07-08 14:00:33 +02:00
parent aa4f9725eb
commit bb08fb6528
90 changed files with 12147 additions and 7 deletions

View File

@@ -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()

View File

@@ -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()
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.1">
<dict>
<key>CFBundleIconFile</key>
<string>@ICON@</string>
<key>CFBundleIdentifier</key>
<string>com.nokia.qt.qml</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string>
<key>CFBundleSignature</key>
<string>@TYPEINFO@</string>
<key>CFBundleExecutable</key>
<string>@EXECUTABLE@</string>
</dict>
</plist>

View File

@@ -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
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,5 @@
border.left: 10
border.top: 12
border.bottom: 12
border.right: 10
source: titlebar.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

View File

@@ -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"

View File

@@ -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 <QObject>
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

View File

@@ -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 <QtDBus>
#include <mce/mode-names.h>
#include <mce/dbus-names.h>
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"

View File

@@ -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 <private/qdeclarativecontext_p.h>
#include <QDeclarativeEngine>
#include <QtDebug>
#include <QGraphicsItem>
#include <QDeclarativeItem>
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<QGraphicsItem*> &itemList)
{
m_itemList = itemList;
selectedItemsChanged(m_itemList);
}
QList<QGraphicsItem*> AbstractFormEditorTool::items() const
{
return m_itemList;
}
bool AbstractFormEditorTool::topItemIsMovable(const QList<QGraphicsItem*> & itemList)
{
QGraphicsItem *firstSelectableItem = topMovableGraphicsItem(itemList);
if (firstSelectableItem == 0)
return false;
QDeclarativeItem *declarativeItem = dynamic_cast<QDeclarativeItem*>(firstSelectableItem->toGraphicsObject());
if (declarativeItem != 0)
return true;
return false;
}
bool AbstractFormEditorTool::topSelectedItemIsMovable(const QList<QGraphicsItem*> &itemList)
{
QList<QGraphicsItem*> 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<QGraphicsItem*> &/*itemList*/)
{
return false;
}
QDeclarativeItem *AbstractFormEditorTool::toQDeclarativeItem(QGraphicsItem *item)
{
return dynamic_cast<QDeclarativeItem*>(item->toGraphicsObject());
}
QGraphicsItem *AbstractFormEditorTool::topMovableGraphicsItem(const QList<QGraphicsItem*> &itemList)
{
foreach (QGraphicsItem *item, itemList) {
if (item->flags().testFlag(QGraphicsItem::ItemIsMovable))
return item;
}
return 0;
}
QDeclarativeItem *AbstractFormEditorTool::topMovableDeclarativeItem(const QList<QGraphicsItem*> &itemList)
{
foreach (QGraphicsItem *item, itemList) {
QDeclarativeItem *declarativeItem = toQDeclarativeItem(item);
if (declarativeItem /*&& (declarativeItem->qmlItemNode().hasShowContent())*/)
return declarativeItem;
}
return 0;
}
QList<QGraphicsObject*> AbstractFormEditorTool::toGraphicsObjectList(const QList<QGraphicsItem*> &itemList)
{
QList<QGraphicsObject*> gfxObjects;
foreach(QGraphicsItem *item, itemList) {
QGraphicsObject *obj = item->toGraphicsObject();
if (obj)
gfxObjects << obj;
}
return gfxObjects;
}
QList<QObject*> AbstractFormEditorTool::toObjectList(const QList<QGraphicsItem*> &itemList)
{
QList<QObject*> 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<const QDeclarativeItem*>(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()));
}
}

View File

@@ -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 <qglobal.h>
#include <QList>
#include <QObject>
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<QGraphicsItem*> &itemList) = 0;
virtual void clear() = 0;
virtual void graphicsObjectsChanged(const QList<QGraphicsObject*> &itemList) = 0;
void setItems(const QList<QGraphicsItem*> &itemList);
QList<QGraphicsItem*> items() const;
bool topItemIsMovable(const QList<QGraphicsItem*> &itemList);
bool topItemIsResizeHandle(const QList<QGraphicsItem*> &itemList);
bool topSelectedItemIsMovable(const QList<QGraphicsItem*> &itemList);
static QString titleForItem(const QGraphicsItem *item);
static QList<QObject*> toObjectList(const QList<QGraphicsItem*> &itemList);
static QList<QGraphicsObject*> toGraphicsObjectList(const QList<QGraphicsItem*> &itemList);
static QGraphicsItem* topMovableGraphicsItem(const QList<QGraphicsItem*> &itemList);
static QDeclarativeItem* topMovableDeclarativeItem(const QList<QGraphicsItem*> &itemList);
static QDeclarativeItem *toQDeclarativeItem(QGraphicsItem *item);
protected:
virtual void selectedItemsChanged(const QList<QGraphicsItem*> &itemList) = 0;
QDeclarativeDesignView *view() const;
QGraphicsScene* scene() const;
private:
QDeclarativeDesignView *m_view;
QList<QGraphicsItem*> m_itemList;
};
}
#endif // ABSTRACTFORMEDITORTOOL_H

View File

@@ -0,0 +1,129 @@
#include "boundingrecthighlighter.h"
#include "qdeclarativedesignview.h"
#include "qmlviewerconstants.h"
#include <QGraphicsPolygonItem>
#include <QTimer>
#include <QDebug>
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

View File

@@ -0,0 +1,54 @@
#ifndef BOUNDINGRECTHIGHLIGHTER_H
#define BOUNDINGRECTHIGHLIGHTER_H
#include <QObject>
#include <QWeakPointer>
#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<QGraphicsObject> m_highlightedObject;
QGraphicsPolygonItem *m_highlightPolygon;
QGraphicsPolygonItem *m_highlightPolygonEdge;
QTimer *m_animTimer;
qreal m_animScale;
int m_animFrame;
};
} // namespace QmlViewer
#endif // BOUNDINGRECTHIGHLIGHTER_H

View File

@@ -0,0 +1,99 @@
#include "colorpickertool.h"
#include "qdeclarativedesignview.h"
#include <QMouseEvent>
#include <QKeyEvent>
#include <QRectF>
#include <QRgb>
#include <QImage>
#include <QApplication>
#include <QDebug>
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<QGraphicsItem*> &/*itemList*/)
{
}
void ColorPickerTool::clear()
{
view()->setCursor(Qt::CrossCursor);
}
void ColorPickerTool::graphicsObjectsChanged(const QList<QGraphicsObject*> &/*itemList*/)
{
}
void ColorPickerTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*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

View File

@@ -0,0 +1,54 @@
#ifndef COLORPICKERTOOL_H
#define COLORPICKERTOOL_H
#include "abstractformeditortool.h"
#include <QColor>
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<QGraphicsItem*> &itemList);
void clear();
void graphicsObjectsChanged(const QList<QGraphicsObject*> &itemList);
signals:
void selectedColorChanged(const QColor &color);
protected:
void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
private:
void pickColor(const QPoint &pos);
private:
QColor m_selectedColor;
};
} // namespace QmlViewer
#endif // COLORPICKERTOOL_H

View File

@@ -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

View File

@@ -0,0 +1,13 @@
<RCC>
<qresource prefix="/qml">
<file>images/resize_handle.png</file>
<file>images/select.png</file>
<file>images/select-marquee.png</file>
<file>images/color-picker.png</file>
<file>images/play.png</file>
<file>images/pause.png</file>
<file>images/from-qml.png</file>
<file>images/zoom.png</file>
<file>images/to-qml.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -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 <QGraphicsScene>
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<QGraphicsItem*> LayerItem::findAllChildItems() const
{
return findAllChildItems(this);
}
QList<QGraphicsItem*> LayerItem::findAllChildItems(const QGraphicsItem *item) const
{
QList<QGraphicsItem*> itemList(item->childItems());
foreach (QGraphicsItem *childItem, item->childItems())
itemList += findAllChildItems(childItem);
return itemList;
}
} // namespace QmlViewer

View File

@@ -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 <QGraphicsObject>
#include <QWeakPointer>
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<QGraphicsItem*> findAllChildItems() const;
protected:
QList<QGraphicsItem*> findAllChildItems(const QGraphicsItem *item) const;
};
}
#endif // LAYERITEM_H

View File

@@ -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 <QPointF>
#include <QtDebug>
#include <QColor>
#include <QPen>
#include <QApplication>
#include <limits>
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<QGraphicsItem*> MoveManipulator::itemList() const
{
return m_itemList;
}
void MoveManipulator::setItem(QGraphicsItem* item)
{
QList<QGraphicsItem*> itemList;
itemList.append(item);
setItems(itemList);
}
void MoveManipulator::setItems(const QList<QGraphicsItem*> &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<QRectF> &boundingRectList)
//{
// QPointF offset;
// QMap<double, double> verticalOffsetMap;
// foreach (const QRectF &boundingRect, boundingRectList) {
// double verticalOffset = m_snapper.snappedVerticalOffset(boundingRect);
// if (verticalOffset < std::numeric_limits<double>::max())
// verticalOffsetMap.insert(qAbs(verticalOffset), verticalOffset);
// }
// if (!verticalOffsetMap.isEmpty())
// offset.rx() = verticalOffsetMap.begin().value();
// QMap<double, double> horizontalOffsetMap;
// foreach (const QRectF &boundingRect, boundingRectList) {
// double horizontalOffset = m_snapper.snappedHorizontalOffset(boundingRect);
// if (horizontalOffset < std::numeric_limits<double>::max())
// horizontalOffsetMap.insert(qAbs(horizontalOffset), horizontalOffset);
// }
// if (!horizontalOffsetMap.isEmpty())
// offset.ry() = horizontalOffsetMap.begin().value();
// return offset;
//}
//void MoveManipulator::generateSnappingLines(const QList<QRectF> &boundingRectList)
//{
// m_graphicsLineList = m_snapper.generateSnappingLines(boundingRectList,
// m_layerItem.data(),
// m_snapper.transformtionSpaceQGraphicsItem()->sceneTransform());
//}
QList<QRectF> MoveManipulator::translatedBoundingRects(const QList<QRectF> &boundingRectList, const QPointF& offsetVector)
{
QList<QRectF> 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;
}
}

View File

@@ -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 <QWeakPointer>
#include <QGraphicsItem>
#include <QGraphicsLineItem>
#include <QHash>
#include <QPointF>
#include <QRectF>
//#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<QGraphicsItem*> itemList() const;
void setItems(const QList<QGraphicsItem*> &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<QRectF> &boundingRectList);
void deleteSnapLines();
QList<QRectF> translatedBoundingRects(const QList<QRectF> &boundingRectList, const QPointF& offset);
QPointF calculateBoundingRectMovementOffset(const QPointF& updatePoint);
QRectF boundingRect(QGraphicsItem* item, const QPointF& updatePoint);
//void generateSnappingLines(const QList<QRectF> &boundingRectList);
void updateHashes();
bool itemsCanReparented() const;
private:
//Snapper m_snapper;
//QWeakPointer<LayerItem> m_layerItem;
QWeakPointer<QDeclarativeDesignView> m_view;
QList<QGraphicsItem*> m_itemList;
QHash<QGraphicsItem*, QRectF> m_beginItemRectHash;
QHash<QGraphicsItem*, QPointF> m_beginPositionHash;
QHash<QGraphicsItem*, QPointF> m_beginPositionInSceneSpaceHash;
QPointF m_beginPoint;
QHash<QGraphicsItem*, double> m_beginTopMarginHash;
QHash<QGraphicsItem*, double> m_beginLeftMarginHash;
QHash<QGraphicsItem*, double> m_beginRightMarginHash;
QHash<QGraphicsItem*, double> m_beginBottomMarginHash;
QHash<QGraphicsItem*, double> m_beginHorizontalCenterHash;
QHash<QGraphicsItem*, double> m_beginVerticalCenterHash;
QList<QGraphicsItem*> m_graphicsLineList;
bool m_isActive;
};
}
#endif // MOVEMANIPULATOR_H

View File

@@ -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 <QApplication>
#include <QWheelEvent>
#include <QAction>
#include <QMouseEvent>
#include <QtDebug>
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<QGraphicsItem*> 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<QGraphicsItem*> 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<QGraphicsItem*> 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<QGraphicsItem*> 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<QGraphicsItem*> &removedItemList)
{
foreach (QGraphicsItem* removedItem, removedItemList)
m_movingItems.removeOne(removedItem);
}
void MoveTool::selectedItemsChanged(const QList<QGraphicsItem*> &itemList)
{
m_selectionIndicator.setItems(toGraphicsObjectList(itemList));
m_resizeIndicator.setItems(toGraphicsObjectList(itemList));
updateMoveManipulator();
}
bool MoveTool::haveSameParent(const QList<QGraphicsItem*> &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<QGraphicsItem*> &itemList)
{
foreach (QGraphicsItem* item, itemList)
{
if (!maybeAncestorItem->isAncestorOf(item) && item != maybeAncestorItem)
return false;
}
return true;
}
QGraphicsItem* MoveTool::ancestorIfOtherItemsAreChild(const QList<QGraphicsItem*> &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<QGraphicsItem*> &itemList)
//{
// foreach (QGraphicsItem *item, itemList) {
// if (item->qmlItemNode().isAncestorOf(graphicsItem->qmlItemNode()))
// return false;
// }
// return true;
//}
//QGraphicsItem* MoveTool::containerQGraphicsItem(const QList<QGraphicsItem*> &itemUnderMouseList,
// const QList<QGraphicsItem*> &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<QGraphicsItem*> MoveTool::movingItems(const QList<QGraphicsItem*> &selectedItemList)
{
QGraphicsItem* ancestorItem = ancestorIfOtherItemsAreChild(selectedItemList);
// if (ancestorItem != 0 && ancestorItem->qmlItemNode().isRootNode()) {
// view()->changeTool(QDeclarativeDesignView::SelectionToolMode);
// return QList<QGraphicsItem*>();
// }
if (ancestorItem != 0 && ancestorItem->parentItem() != 0) {
QList<QGraphicsItem*> ancestorItemList;
ancestorItemList.append(ancestorItem);
return ancestorItemList;
}
if (!haveSameParent(selectedItemList)) {
view()->changeTool(Constants::SelectionToolMode);
return QList<QGraphicsItem*>();
}
return selectedItemList;
}
void MoveTool::graphicsObjectsChanged(const QList<QGraphicsObject*> &itemList)
{
m_selectionIndicator.updateItems(itemList);
m_resizeIndicator.updateItems(itemList);
}
}

View File

@@ -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 <QHash>
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<QGraphicsItem*> &itemList);
void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
void updateMoveManipulator();
void beginWithPoint(const QPointF &beginPoint);
void clear();
void graphicsObjectsChanged(const QList<QGraphicsObject*> &itemList);
protected:
static bool haveSameParent(const QList<QGraphicsItem*> &itemList);
QList<QGraphicsItem*> movingItems(const QList<QGraphicsItem*> &selectedItemList);
static QGraphicsItem* containerFormEditorItem(const QList<QGraphicsItem*> &itemUnderMouseList,
const QList<QGraphicsItem*> &selectedItemList);
static bool isAncestorOfAllItems(QGraphicsItem* maybeAncestorItem,
const QList<QGraphicsItem*> &itemList);
static QGraphicsItem* ancestorIfOtherItemsAreChild(const QList<QGraphicsItem*> &itemList);
private:
bool m_moving;
MoveManipulator m_moveManipulator;
SelectionIndicator m_selectionIndicator;
ResizeIndicator m_resizeIndicator;
QList<QGraphicsItem*> m_movingItems;
};
}
#endif // MOVETOOL_H

View File

@@ -0,0 +1,210 @@
#include <QLabel>
#include <QIcon>
#include <QAction>
#include "qmltoolbar.h"
#include "toolbarcolorbox.h"
#include <QDebug>
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();
}
}

View File

@@ -0,0 +1,73 @@
#ifndef QMLTOOLBAR_H
#define QMLTOOLBAR_H
#include <QToolBar>
#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

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

View File

@@ -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 <resizehandleitem.h>
#include <QCursor>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QDebug>
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;
}
}

View File

@@ -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 <QWeakPointer>
#include <QSharedPointer>
#include <QGraphicsItem>
#include <QGraphicsObject>
namespace QmlViewer {
class LayerItem;
class ResizeHandleItem;
class ResizeControllerData
{
public:
ResizeControllerData(LayerItem *layerItem,
QGraphicsObject *formEditorItem);
//ResizeControllerData(const ResizeControllerData &other);
~ResizeControllerData();
void clear();
QWeakPointer<LayerItem> layerItem;
QWeakPointer<QGraphicsObject> 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

View File

@@ -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 <QCursor>
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<ResizeHandleItem*>(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;
}
}

View File

@@ -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 <QGraphicsPixmapItem>
#include <QCursor>
#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

View File

@@ -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 <QGraphicsObject>
namespace QmlViewer {
ResizeIndicator::ResizeIndicator(LayerItem *layerItem)
: m_layerItem(layerItem)
{
}
ResizeIndicator::~ResizeIndicator()
{
m_itemControllerHash.clear();
}
void ResizeIndicator::show()
{
QHashIterator<QGraphicsObject*, ResizeController*> itemControllerIterator(m_itemControllerHash);
while (itemControllerIterator.hasNext()) {
ResizeController *controller = itemControllerIterator.next().value();
controller->show();
}
}
void ResizeIndicator::hide()
{
QHashIterator<QGraphicsObject*, ResizeController*> itemControllerIterator(m_itemControllerHash);
while (itemControllerIterator.hasNext()) {
ResizeController *controller = itemControllerIterator.next().value();
controller->hide();
}
}
void ResizeIndicator::clear()
{
QHashIterator<QGraphicsObject*, ResizeController*> itemControllerIterator(m_itemControllerHash);
while(itemControllerIterator.hasNext()) {
itemControllerIterator.next();
delete itemControllerIterator.value();
}
m_itemControllerHash.clear();
}
void ResizeIndicator::setItems(const QList<QGraphicsObject*> &itemList)
{
clear();
foreach (QGraphicsObject* item, itemList) {
ResizeController *controller = new ResizeController(m_layerItem.data(), item);
m_itemControllerHash.insert(item, controller);
}
}
void ResizeIndicator::updateItems(const QList<QGraphicsObject*> &/*itemList*/)
{
// foreach (QDeclarativeItem* item, itemList) {
// if (m_itemControllerHash.contains(item)) {
// ResizeController *controller = new ResizeController(m_itemControllerHash.value(item));
// controller.updatePosition();
// }
// }
}
}

View File

@@ -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 <QHash>
#include <QPair>
#include <QGraphicsObject>
#include <QDeclarativeItem>
#include <QWeakPointer>
#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<QGraphicsObject*> &itemList);
void updateItems(const QList<QGraphicsObject*> &itemList);
//
// QPair<FormEditorItem*,Orientation> pick(QGraphicsRectItem* pickedItem) const;
//
// void show();
// void hide();
private:
QWeakPointer<LayerItem> m_layerItem;
QHash<QGraphicsObject*, ResizeController*> m_itemControllerHash;
};
}
#endif // SCALEINDICATOR_H

View File

@@ -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 <QtDebug>
#include <QDeclarativeItem>
#include <QApplication>
#include <limits>
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<QDeclarativeItem*>(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<double>::max())
// updatePointInLocalSpace.rx() -= rightOffset;
// double bottomOffset = m_snapper.snapBottomOffset(boundingRect);
// if (bottomOffset < std::numeric_limits<double>::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<double>::max())
// updatePointInLocalSpace.rx() -= leftOffset;
// double topOffset = m_snapper.snapTopOffset(boundingRect);
// if (topOffset < std::numeric_limits<double>::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<double>::max())
// updatePointInLocalSpace.rx() -= rightOffset;
// double topOffset = m_snapper.snapTopOffset(boundingRect);
// if (topOffset < std::numeric_limits<double>::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<double>::max())
// updatePointInLocalSpace.rx() -= leftOffset;
// double bottomOffset = m_snapper.snapBottomOffset(boundingRect);
// if (bottomOffset < std::numeric_limits<double>::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<double>::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<double>::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<double>::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<double>::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();
}
}

View File

@@ -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 <QWeakPointer>
#include "layeritem.h"
#include "resizehandleitem.h"
#include <QDeclarativeItem>
#include <QDeclarativeView>
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<QDeclarativeView> m_view;
QList<QGraphicsItem*> 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<LayerItem> m_layerItem;
};
}
#endif // RESIZEMANIPULATOR_H

View File

@@ -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 <QApplication>
#include <QGraphicsSceneMouseEvent>
#include <QAction>
#include <QKeyEvent>
#include <QGraphicsObject>
#include <QWheelEvent>
#include <QtDebug>
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<QGraphicsItem*> 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<QGraphicsItem*> 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<QGraphicsItem*> 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<QGraphicsItem*> & /*itemList*/)
{
}
void ResizeTool::selectedItemsChanged(const QList<QGraphicsItem*> & 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<QGraphicsObject*> &itemList)
{
m_selectionIndicator.updateItems(itemList);
m_resizeIndicator.updateItems(itemList);
}
}

View File

@@ -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 <QMouseEvent>
#include <QKeyEvent>
#include <QDeclarativeItem>
#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<QGraphicsItem*> &itemList);
void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
void clear();
void graphicsObjectsChanged(const QList<QGraphicsObject*> &itemList);
private:
SelectionIndicator m_selectionIndicator;
ResizeManipulator *m_resizeManipulator;
ResizeIndicator m_resizeIndicator;
};
}
#endif // RESIZETOOL_H

View File

@@ -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 <QDebug>
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<QGraphicsItem*> &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<QGraphicsItem*> itemList = m_editorView->selectableItems(m_selectionRectangleElement.rect(),
Qt::IntersectsItemShape);
QList<QGraphicsItem*> 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<QGraphicsItem*> resultList;
switch(selectionType) {
case AddToSelection: {
resultList.append(m_oldSelectionList);
resultList.append(newSelectionList);
}
break;
case ReplaceSelection: {
resultList.append(newSelectionList);
}
break;
case RemoveFromSelection: {
QSet<QGraphicsItem*> oldSelectionSet(m_oldSelectionList.toSet());
QSet<QGraphicsItem*> newSelectionSet(newSelectionList.toSet());
resultList.append(oldSelectionSet.subtract(newSelectionSet).toList());
}
}
m_editorView->setSelectedItems(resultList);
}
void RubberBandSelectionManipulator::setItems(const QList<QGraphicsItem*> &itemList)
{
m_itemList = itemList;
}
QPointF RubberBandSelectionManipulator::beginPoint() const
{
return m_beginPoint;
}
bool RubberBandSelectionManipulator::isActive() const
{
return m_isActive;
}
}

View File

@@ -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<QGraphicsItem*> &itemList);
void begin(const QPointF& beginPoint);
void update(const QPointF& updatePoint);
void end();
void clear();
void select(SelectionType selectionType);
QPointF beginPoint() const;
bool isActive() const;
protected:
QGraphicsItem *topFormEditorItem(const QList<QGraphicsItem*> &itemList);
private:
QList<QGraphicsItem*> m_itemList;
QList<QGraphicsItem*> m_oldSelectionList;
SelectionRectangle m_selectionRectangleElement;
QPointF m_beginPoint;
QDeclarativeDesignView *m_editorView;
QGraphicsItem *m_beginFormEditorItem;
bool m_isActive;
};
}
#endif // RUBBERBANDSELECTIONMANIPULATOR_H

View File

@@ -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 <QPen>
#include <cmath>
#include <QGraphicsScene>
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<QPointF> 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<QGraphicsObject*> &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<QGraphicsObject*> &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

View File

@@ -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 <QWeakPointer>
#include <QGraphicsPolygonItem>
#include "layeritem.h"
namespace QmlViewer {
class SelectionIndicator
{
public:
SelectionIndicator(LayerItem *layerItem);
~SelectionIndicator();
void show();
void hide();
void clear();
void setItems(const QList<QGraphicsObject*> &itemList);
void updateItems(const QList<QGraphicsObject*> &itemList);
private:
QHash<QGraphicsItem*, QGraphicsPolygonItem *> m_indicatorShapeHash;
QWeakPointer<LayerItem> m_layerItem;
};
}
#endif // SELECTIONINDICATOR_H

View File

@@ -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 <QPen>
#include <QGraphicsScene>
#include <QtDebug>
#include <cmath>
#include <QGraphicsScene>
namespace QmlViewer {
SelectionRectangle::SelectionRectangle(LayerItem *layerItem)
: m_controlShape(new QGraphicsRectItem(layerItem)),
m_layerItem(layerItem)
{
m_controlShape->setPen(QPen(Qt::black));
m_controlShape->setBrush(QColor(128, 128, 128, 50));
}
SelectionRectangle::~SelectionRectangle()
{
if (m_layerItem)
m_layerItem->scene()->removeItem(m_controlShape);
}
void SelectionRectangle::clear()
{
hide();
}
void SelectionRectangle::show()
{
m_controlShape->show();
}
void SelectionRectangle::hide()
{
m_controlShape->hide();
}
QRectF SelectionRectangle::rect() const
{
return m_controlShape->mapFromScene(m_controlShape->rect()).boundingRect();
}
void SelectionRectangle::setRect(const QPointF &firstPoint,
const QPointF &secondPoint)
{
double firstX = std::floor(firstPoint.x()) + 0.5;
double firstY = std::floor(firstPoint.y()) + 0.5;
double secondX = std::floor(secondPoint.x()) + 0.5;
double secondY = std::floor(secondPoint.y()) + 0.5;
QPointF topLeftPoint(firstX < secondX ? firstX : secondX, firstY < secondY ? firstY : secondY);
QPointF bottomRightPoint(firstX > secondX ? firstX : secondX, firstY > secondY ? firstY : secondY);
QRectF rect(topLeftPoint, bottomRightPoint);
m_controlShape->setRect(rect);
}
}

View File

@@ -0,0 +1,62 @@
/**************************************************************************
**
** 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 SELECTIONRECTANGLE_H
#define SELECTIONRECTANGLE_H
#include <QWeakPointer>
#include <QGraphicsRectItem>
#include "layeritem.h"
namespace QmlViewer {
class SelectionRectangle
{
public:
SelectionRectangle(LayerItem *layerItem);
~SelectionRectangle();
void show();
void hide();
void clear();
void setRect(const QPointF &firstPoint,
const QPointF &secondPoint);
QRectF rect() const;
private:
QGraphicsRectItem *m_controlShape;
QWeakPointer<LayerItem> m_layerItem;
};
}
#endif // SELECTIONRECTANGLE_H

View File

@@ -0,0 +1,434 @@
/**************************************************************************
**
** 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 "selectiontool.h"
//#include "resizehandleitem.h"
#include "qdeclarativedesignview.h"
#include <private/qdeclarativeitem_p.h>
#include <private/qdeclarativecontext_p.h>
#include <QDeclarativeEngine>
#include <QApplication>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QClipboard>
#include <QMenu>
#include <QAction>
#include <QDeclarativeItem>
#include <QGraphicsObject>
#include <QDebug>
namespace QmlViewer {
SelectionTool::SelectionTool(QDeclarativeDesignView *editorView)
: AbstractFormEditorTool(editorView),
m_rubberbandSelectionMode(false),
m_rubberbandSelectionManipulator(editorView->manipulatorLayer(), editorView),
m_singleSelectionManipulator(editorView),
m_selectionIndicator(editorView->manipulatorLayer()),
//m_resizeIndicator(editorView->manipulatorLayer()),
m_selectOnlyContentItems(true)
{
}
SelectionTool::~SelectionTool()
{
}
void SelectionTool::setRubberbandSelectionMode(bool value)
{
m_rubberbandSelectionMode = value;
}
SingleSelectionManipulator::SelectionType SelectionTool::getSelectionType(Qt::KeyboardModifiers modifiers)
{
SingleSelectionManipulator::SelectionType selectionType = SingleSelectionManipulator::ReplaceSelection;
if (modifiers.testFlag(Qt::ControlModifier)) {
selectionType = SingleSelectionManipulator::RemoveFromSelection;
} else if (modifiers.testFlag(Qt::ShiftModifier)) {
selectionType = SingleSelectionManipulator::AddToSelection;
}
return selectionType;
}
bool SelectionTool::alreadySelected(const QList<QGraphicsItem*> &itemList) const
{
const QList<QGraphicsItem*> selectedItems = view()->selectedItems();
if (selectedItems.isEmpty())
return false;
foreach(QGraphicsItem *item, itemList) {
if (selectedItems.contains(item)) {
return true;
}
}
return false;
}
void SelectionTool::mousePressEvent(QMouseEvent *event)
{
QList<QGraphicsItem*> itemList = view()->selectableItems(event->pos());
SingleSelectionManipulator::SelectionType selectionType = getSelectionType(event->modifiers());
if (event->buttons() & Qt::LeftButton) {
m_mousePressTimer.start();
if (m_rubberbandSelectionMode) {
m_rubberbandSelectionManipulator.begin(event->pos());
} else {
if (itemList.isEmpty()) {
view()->setSelectedItems(itemList);
return;
}
if ((selectionType == SingleSelectionManipulator::InvertSelection
|| selectionType == SingleSelectionManipulator::ReplaceSelection)
&& alreadySelected(itemList))
{
//view()->changeToMoveTool(event->pos());
return;
}
QGraphicsItem* item = itemList.first();
if (item->children().isEmpty()) {
m_singleSelectionManipulator.begin(event->pos());
m_singleSelectionManipulator.select(selectionType, m_selectOnlyContentItems);
} else {
m_mousePressTimer.start();
if (itemList.isEmpty()) {
view()->setSelectedItems(itemList);
return;
}
if (item->children().isEmpty()) {
m_singleSelectionManipulator.begin(event->pos());
m_singleSelectionManipulator.select(selectionType, m_selectOnlyContentItems);
} else {
m_singleSelectionManipulator.begin(event->pos());
m_singleSelectionManipulator.select(selectionType, m_selectOnlyContentItems);
m_singleSelectionManipulator.end(event->pos());
//view()->changeToMoveTool(event->pos());
}
m_singleSelectionManipulator.begin(event->pos());
m_singleSelectionManipulator.select(selectionType, m_selectOnlyContentItems);
m_singleSelectionManipulator.end(event->pos());
//view()->changeToMoveTool(event->pos());
}
}
} else if (event->buttons() & Qt::RightButton) {
createContextMenu(itemList, event->globalPos());
}
}
void SelectionTool::createContextMenu(QList<QGraphicsItem*> itemList, QPoint globalPos)
{
if (!view()->mouseInsideContextItem())
return;
QMenu contextMenu;
connect(&contextMenu, SIGNAL(hovered(QAction*)), this, SLOT(contextMenuElementHovered(QAction*)));
// QList<QGraphicsItem*> sortedList;
// for(int i = itemList.length(); i>= 0; i--) {
// }
m_contextMenuItemList = itemList;
contextMenu.addAction("Items");
contextMenu.addSeparator();
int shortcutKey = Qt::Key_1;
bool addKeySequence = true;
int i = 0;
foreach(QGraphicsItem * const item, itemList) {
QString itemTitle = titleForItem(item);
QAction *elementAction = contextMenu.addAction(itemTitle, this, SLOT(contextMenuElementSelected()));
if (view()->selectedItems().contains(item)) {
QFont boldFont = elementAction->font();
boldFont.setBold(true);
elementAction->setFont(boldFont);
}
elementAction->setData(i);
if (addKeySequence)
elementAction->setShortcut(QKeySequence(shortcutKey));
shortcutKey++;
if (shortcutKey > Qt::Key_9)
addKeySequence = false;
++i;
}
// add root item separately
QString itemTitle = QString(tr("%1 (root)")).arg(titleForItem(view()->currentRootItem()));
contextMenu.addAction(itemTitle, this, SLOT(contextMenuElementSelected()));
m_contextMenuItemList.append(view()->currentRootItem());
contextMenu.exec(globalPos);
m_contextMenuItemList.clear();
}
void SelectionTool::contextMenuElementSelected()
{
QAction *senderAction = static_cast<QAction*>(sender());
int itemListIndex = senderAction->data().toInt();
if (itemListIndex >= 0 && itemListIndex < m_contextMenuItemList.length()) {
QPointF updatePt(0, 0);
m_singleSelectionManipulator.begin(updatePt);
m_singleSelectionManipulator.select(SingleSelectionManipulator::InvertSelection,
QList<QGraphicsItem*>() << m_contextMenuItemList.at(itemListIndex),
false);
m_singleSelectionManipulator.end(updatePt);
}
}
void SelectionTool::contextMenuElementHovered(QAction *action)
{
int itemListIndex = action->data().toInt();
if (itemListIndex >= 0 && itemListIndex < m_contextMenuItemList.length()) {
view()->highlightBoundingRect(m_contextMenuItemList.at(itemListIndex));
}
}
void SelectionTool::mouseMoveEvent(QMouseEvent *event)
{
if (m_singleSelectionManipulator.isActive()) {
QPointF mouseMovementVector = m_singleSelectionManipulator.beginPoint() - event->pos();
if ((mouseMovementVector.toPoint().manhattanLength() > Constants::DragStartDistance)
&& (m_mousePressTimer.elapsed() > Constants::DragStartTime))
{
m_singleSelectionManipulator.end(event->pos());
//view()->changeToMoveTool(m_singleSelectionManipulator.beginPoint());
return;
}
} else if (m_rubberbandSelectionManipulator.isActive()) {
QPointF mouseMovementVector = m_rubberbandSelectionManipulator.beginPoint() - event->pos();
if ((mouseMovementVector.toPoint().manhattanLength() > Constants::DragStartDistance)
&& (m_mousePressTimer.elapsed() > Constants::DragStartTime)) {
m_rubberbandSelectionManipulator.update(event->pos());
if (event->modifiers().testFlag(Qt::ControlModifier))
m_rubberbandSelectionManipulator.select(RubberBandSelectionManipulator::RemoveFromSelection);
else if (event->modifiers().testFlag(Qt::ShiftModifier))
m_rubberbandSelectionManipulator.select(RubberBandSelectionManipulator::AddToSelection);
else
m_rubberbandSelectionManipulator.select(RubberBandSelectionManipulator::ReplaceSelection);
}
}
}
void SelectionTool::hoverMoveEvent(QMouseEvent * event)
{
QList<QGraphicsItem*> itemList = view()->items(event->pos());
if (!itemList.isEmpty() && !m_rubberbandSelectionMode) {
// foreach(QGraphicsItem *item, itemList) {
// if (item->type() == Constants::ResizeHandleItemType) {
// ResizeHandleItem* resizeHandle = ResizeHandleItem::fromGraphicsItem(item);
// if (resizeHandle)
// view()->changeTool(Constants::ResizeToolMode);
// return;
// }
// }
// if (topSelectedItemIsMovable(itemList))
// view()->changeTool(Constants::MoveToolMode);
}
QList<QGraphicsItem*> selectableItemList = view()->selectableItems(event->pos());
if (!selectableItemList.isEmpty()) {
QGraphicsItem *topSelectableItem = 0;
foreach(QGraphicsItem* item, selectableItemList)
{
if (item
&& item->type() != Constants::EditorItemType
/*&& !item->qmlItemNode().isRootNode()
&& (QGraphicsItem->qmlItemNode().hasShowContent() || !m_selectOnlyContentItems)*/)
{
topSelectableItem = item;
break;
}
}
view()->highlightBoundingRect(topSelectableItem);
}
}
void SelectionTool::mouseReleaseEvent(QMouseEvent *event)
{
if (m_singleSelectionManipulator.isActive()) {
m_singleSelectionManipulator.end(event->pos());
}
else if (m_rubberbandSelectionManipulator.isActive()) {
QPointF mouseMovementVector = m_rubberbandSelectionManipulator.beginPoint() - event->pos();
if (mouseMovementVector.toPoint().manhattanLength() < Constants::DragStartDistance) {
m_singleSelectionManipulator.begin(event->pos());
if (event->modifiers().testFlag(Qt::ControlModifier))
m_singleSelectionManipulator.select(SingleSelectionManipulator::RemoveFromSelection, m_selectOnlyContentItems);
else if (event->modifiers().testFlag(Qt::ShiftModifier))
m_singleSelectionManipulator.select(SingleSelectionManipulator::AddToSelection, m_selectOnlyContentItems);
else
m_singleSelectionManipulator.select(SingleSelectionManipulator::InvertSelection, m_selectOnlyContentItems);
m_singleSelectionManipulator.end(event->pos());
} else {
m_rubberbandSelectionManipulator.update(event->pos());
if (event->modifiers().testFlag(Qt::ControlModifier))
m_rubberbandSelectionManipulator.select(RubberBandSelectionManipulator::RemoveFromSelection);
else if (event->modifiers().testFlag(Qt::ShiftModifier))
m_rubberbandSelectionManipulator.select(RubberBandSelectionManipulator::AddToSelection);
else
m_rubberbandSelectionManipulator.select(RubberBandSelectionManipulator::ReplaceSelection);
m_rubberbandSelectionManipulator.end();
}
}
}
void SelectionTool::mouseDoubleClickEvent(QMouseEvent * /*event*/)
{
}
void SelectionTool::keyPressEvent(QKeyEvent *event)
{
switch(event->key()) {
case Qt::Key_Left:
case Qt::Key_Right:
case Qt::Key_Up:
case Qt::Key_Down:
view()->changeTool(Constants::MoveToolMode);
view()->currentTool()->keyPressEvent(event);
break;
}
}
void SelectionTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/)
{
}
void SelectionTool::wheelEvent(QWheelEvent *event)
{
if (event->orientation() == Qt::Horizontal || m_rubberbandSelectionMode)
return;
QList<QGraphicsItem*> itemList = view()->selectableItems(event->pos());
int selectedIdx = 0;
if (!view()->selectedItems().isEmpty()) {
selectedIdx = itemList.indexOf(view()->selectedItems().first());
if (selectedIdx >= 0) {
if (event->delta() > 0) {
selectedIdx++;
if (selectedIdx == itemList.length())
selectedIdx = 0;
} else if (event->delta() < 0) {
selectedIdx--;
if (selectedIdx == -1)
selectedIdx = itemList.length() - 1;
}
} else {
selectedIdx = 0;
}
}
QPointF updatePt(0, 0);
m_singleSelectionManipulator.begin(updatePt);
m_singleSelectionManipulator.select(SingleSelectionManipulator::ReplaceSelection,
QList<QGraphicsItem*>() << itemList.at(selectedIdx),
false);
m_singleSelectionManipulator.end(updatePt);
}
void SelectionTool::setSelectOnlyContentItems(bool selectOnlyContentItems)
{
m_selectOnlyContentItems = selectOnlyContentItems;
}
void SelectionTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
{
}
void SelectionTool::clear()
{
view()->setCursor(Qt::ArrowCursor);
m_rubberbandSelectionManipulator.clear(),
m_singleSelectionManipulator.clear();
m_selectionIndicator.clear();
//m_resizeIndicator.clear();
}
void SelectionTool::selectedItemsChanged(const QList<QGraphicsItem*> &itemList)
{
m_selectionIndicator.setItems(toGraphicsObjectList(itemList));
//m_resizeIndicator.setItems(toGraphicsObjectList(itemList));
}
void SelectionTool::graphicsObjectsChanged(const QList<QGraphicsObject*> &itemList)
{
m_selectionIndicator.updateItems(itemList);
//m_resizeIndicator.updateItems(itemList);
}
void SelectionTool::selectUnderPoint(QMouseEvent *event)
{
m_singleSelectionManipulator.begin(event->pos());
if (event->modifiers().testFlag(Qt::ControlModifier))
m_singleSelectionManipulator.select(SingleSelectionManipulator::RemoveFromSelection, m_selectOnlyContentItems);
else if (event->modifiers().testFlag(Qt::ShiftModifier))
m_singleSelectionManipulator.select(SingleSelectionManipulator::AddToSelection, m_selectOnlyContentItems);
else
m_singleSelectionManipulator.select(SingleSelectionManipulator::InvertSelection, m_selectOnlyContentItems);
m_singleSelectionManipulator.end(event->pos());
}
}

View File

@@ -0,0 +1,110 @@
/**************************************************************************
**
** 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 SELECTIONTOOL_H
#define SELECTIONTOOL_H
#include "abstractformeditortool.h"
#include "movemanipulator.h"
#include "rubberbandselectionmanipulator.h"
#include "singleselectionmanipulator.h"
#include "selectionindicator.h"
#include "resizeindicator.h"
#include <QHash>
#include <QList>
#include <QTime>
QT_FORWARD_DECLARE_CLASS(QGraphicsItem);
QT_FORWARD_DECLARE_CLASS(QMouseEvent);
QT_FORWARD_DECLARE_CLASS(QKeyEvent);
namespace QmlViewer {
class SelectionTool : public AbstractFormEditorTool
{
Q_OBJECT
public:
SelectionTool(QDeclarativeDesignView* editorView);
~SelectionTool();
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void hoverMoveEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *keyEvent);
void wheelEvent(QWheelEvent *event);
void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList);
// QVariant itemChange(const QList<QGraphicsItem*> &itemList,
// QGraphicsItem::GraphicsItemChange change,
// const QVariant &value );
// void update();
void clear();
void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
void graphicsObjectsChanged(const QList<QGraphicsObject*> &itemList);
void selectUnderPoint(QMouseEvent *event);
void setSelectOnlyContentItems(bool selectOnlyContentItems);
void setRubberbandSelectionMode(bool value);
private slots:
void contextMenuElementSelected();
void contextMenuElementHovered(QAction *action);
private:
void createContextMenu(QList<QGraphicsItem*> itemList, QPoint globalPos);
SingleSelectionManipulator::SelectionType getSelectionType(Qt::KeyboardModifiers modifiers);
bool alreadySelected(const QList<QGraphicsItem*> &itemList) const;
private:
bool m_rubberbandSelectionMode;
RubberBandSelectionManipulator m_rubberbandSelectionManipulator;
SingleSelectionManipulator m_singleSelectionManipulator;
SelectionIndicator m_selectionIndicator;
//ResizeIndicator m_resizeIndicator;
QTime m_mousePressTimer;
bool m_selectOnlyContentItems;
QList<QGraphicsItem*> m_contextMenuItemList;
};
}
#endif // SELECTIONTOOL_H

View File

@@ -0,0 +1,133 @@
/**************************************************************************
**
** 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 "singleselectionmanipulator.h"
#include "qdeclarativedesignview.h"
#include <QtDebug>
namespace QmlViewer {
SingleSelectionManipulator::SingleSelectionManipulator(QDeclarativeDesignView *editorView)
: m_editorView(editorView),
m_isActive(false)
{
}
void SingleSelectionManipulator::begin(const QPointF &beginPoint)
{
m_beginPoint = beginPoint;
m_isActive = true;
m_oldSelectionList = m_editorView->selectedItems();
}
void SingleSelectionManipulator::update(const QPointF &/*updatePoint*/)
{
m_oldSelectionList.clear();
}
void SingleSelectionManipulator::clear()
{
m_beginPoint = QPointF();
m_oldSelectionList.clear();
}
void SingleSelectionManipulator::end(const QPointF &/*updatePoint*/)
{
m_oldSelectionList.clear();
m_isActive = false;
}
void SingleSelectionManipulator::select(SelectionType selectionType, const QList<QGraphicsItem*> &items, bool /*selectOnlyContentItems*/)
{
QGraphicsItem *selectedItem = 0;
foreach(QGraphicsItem* item, items)
{
//FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
if (item
/*&& !formEditorItem->qmlItemNode().isRootNode()
&& (formEditorItem->qmlItemNode().hasShowContent() || !selectOnlyContentItems)*/)
{
selectedItem = item;
break;
}
}
QList<QGraphicsItem*> resultList;
switch(selectionType) {
case AddToSelection: {
resultList.append(m_oldSelectionList);
if (selectedItem && !m_oldSelectionList.contains(selectedItem))
resultList.append(selectedItem);
}
break;
case ReplaceSelection: {
if (selectedItem)
resultList.append(selectedItem);
}
break;
case RemoveFromSelection: {
resultList.append(m_oldSelectionList);
if (selectedItem)
resultList.removeAll(selectedItem);
}
break;
case InvertSelection: {
if (selectedItem
&& !m_oldSelectionList.contains(selectedItem))
{
resultList.append(selectedItem);
}
}
}
m_editorView->setSelectedItems(resultList);
}
void SingleSelectionManipulator::select(SelectionType selectionType, bool selectOnlyContentItems)
{
QList<QGraphicsItem*> itemList = m_editorView->selectableItems(m_beginPoint);
select(selectionType, itemList, selectOnlyContentItems);
}
bool SingleSelectionManipulator::isActive() const
{
return m_isActive;
}
QPointF SingleSelectionManipulator::beginPoint() const
{
return m_beginPoint;
}
}

View File

@@ -0,0 +1,77 @@
/**************************************************************************
**
** 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 SINGLESELECTIONMANIPULATOR_H
#define SINGLESELECTIONMANIPULATOR_H
#include "selectionrectangle.h"
#include <QPointF>
#include <QList>
QT_FORWARD_DECLARE_CLASS(QGraphicsItem);
namespace QmlViewer {
class QDeclarativeDesignView;
class SingleSelectionManipulator
{
public:
SingleSelectionManipulator(QDeclarativeDesignView *editorView);
enum SelectionType {
ReplaceSelection,
AddToSelection,
RemoveFromSelection,
InvertSelection
};
void begin(const QPointF& beginPoint);
void update(const QPointF& updatePoint);
void end(const QPointF& updatePoint);
void select(SelectionType selectionType, const QList<QGraphicsItem*> &items, bool selectOnlyContentItems);
void select(SelectionType selectionType, bool selectOnlyContentItems);
void clear();
QPointF beginPoint() const;
bool isActive() const;
private:
QList<QGraphicsItem*> m_oldSelectionList;
QPointF m_beginPoint;
QDeclarativeDesignView *m_editorView;
bool m_isActive;
};
}
#endif // SINGLESELECTIONMANIPULATOR_H

View File

@@ -0,0 +1,188 @@
/**************************************************************************
**
** 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 "snappinglinecreator.h"
#include <QGraphicsItem>
#include "formeditoritem.h"
namespace QmlDesigner {
SnappingLineCreator::SnappingLineCreator(FormEditorItem *formEditorItem)
: m_formEditorItem(formEditorItem),
m_topOffset(formEditorItem->formEditorView()->spacing()),
m_bottomOffset(formEditorItem->formEditorView()->spacing()),
m_leftOffset(formEditorItem->formEditorView()->spacing()),
m_rightOffset(formEditorItem->formEditorView()->spacing()),
m_topMargin(formEditorItem->formEditorView()->margins()),
m_bottomMargin(formEditorItem->formEditorView()->margins()),
m_leftMargin(formEditorItem->formEditorView()->margins()),
m_rightMargin(formEditorItem->formEditorView()->margins())
{
Q_ASSERT(m_formEditorItem);
}
void SnappingLineCreator::clearLines()
{
m_topLineMap.clear();
m_bottomLineMap.clear();
m_leftLineMap.clear();
m_rightLineMap.clear();
m_horizontalCenterLineMap.clear();
m_verticalCenterLineMap.clear();
m_topOffsetMap.clear();
m_bottomOffsetMap.clear();
m_leftOffsetMap.clear();
m_rightOffsetMap.clear();
}
void SnappingLineCreator::addLines(const QRectF &rectInSceneSpace, FormEditorItem *item)
{
m_topLineMap.insert(rectInSceneSpace.top(), qMakePair(rectInSceneSpace, item));
m_bottomLineMap.insert(rectInSceneSpace.bottom(), qMakePair(rectInSceneSpace, item));
m_leftLineMap.insert(rectInSceneSpace.left(), qMakePair(rectInSceneSpace, item));
m_rightLineMap.insert(rectInSceneSpace.right(), qMakePair(rectInSceneSpace, item));
QPointF centerPoint(rectInSceneSpace.center());
m_horizontalCenterLineMap.insert(centerPoint.y(), qMakePair(rectInSceneSpace, item));
m_verticalCenterLineMap.insert(centerPoint.x(), qMakePair(rectInSceneSpace, item));
}
void SnappingLineCreator::addOffsets(const QRectF &rectInSceneSpace, FormEditorItem *item)
{
m_topOffsetMap.insert(rectInSceneSpace.top() - m_topOffset, qMakePair(rectInSceneSpace, item));
m_bottomOffsetMap.insert(rectInSceneSpace.bottom() + m_bottomOffset, qMakePair(rectInSceneSpace, item));
m_leftOffsetMap.insert(rectInSceneSpace.left() - m_leftOffset, qMakePair(rectInSceneSpace, item));
m_rightOffsetMap.insert(rectInSceneSpace.right() + m_rightOffset, qMakePair(rectInSceneSpace, item));
}
void SnappingLineCreator::generateLines(const QList<FormEditorItem*> &exceptionList,
FormEditorItem *transformationSpaceItem)
{
Q_ASSERT(transformationSpaceItem);
{
QRectF containerBoundingRectInTransformationSpace = m_formEditorItem->mapRectToItem(transformationSpaceItem,
m_formEditorItem->qmlItemNode().instanceBoundingRect());
addLines(containerBoundingRectInTransformationSpace, m_formEditorItem);
containerBoundingRectInTransformationSpace.adjust(m_leftMargin, m_topMargin, -m_rightMargin, -m_rightMargin);
addLines(containerBoundingRectInTransformationSpace, m_formEditorItem);
}
foreach (FormEditorItem *item, m_formEditorItem->childFormEditorItems()) {
if (exceptionList.contains(item))
continue;
QRectF boundingRectInContainerSpace;
boundingRectInContainerSpace = item->mapRectToItem(transformationSpaceItem, item->qmlItemNode().instanceBoundingRect());
boundingRectInContainerSpace = boundingRectInContainerSpace.toRect(); // round to integer
addLines(boundingRectInContainerSpace, item);
addOffsets(boundingRectInContainerSpace, item);
}
}
void SnappingLineCreator::setMargins(double margin)
{
m_topMargin = margin;
m_bottomMargin = margin;
m_leftMargin = margin;
m_rightMargin = margin;
}
void SnappingLineCreator::setSpacing(double spacing)
{
m_topOffset = spacing;
m_bottomOffset = spacing;
m_leftOffset = spacing;
m_rightOffset = spacing;
}
void SnappingLineCreator::update(const QList<FormEditorItem*> &exceptionList,
FormEditorItem *transformationSpaceItem)
{
clearLines();
setMargins(m_formEditorItem->formEditorView()->margins());
setSpacing(m_formEditorItem->formEditorView()->spacing());
generateLines(exceptionList, transformationSpaceItem);
}
SnapLineMap SnappingLineCreator::topLines() const
{
return m_topLineMap;
}
SnapLineMap SnappingLineCreator::bottomLines() const
{
return m_bottomLineMap;
}
SnapLineMap SnappingLineCreator::leftLines() const
{
return m_leftLineMap;
}
SnapLineMap SnappingLineCreator::rightLines() const
{
return m_rightLineMap;
}
SnapLineMap SnappingLineCreator::horizontalCenterLines() const
{
return m_horizontalCenterLineMap;
}
SnapLineMap SnappingLineCreator::verticalCenterLines() const
{
return m_verticalCenterLineMap;
}
SnapLineMap SnappingLineCreator::topOffsets() const
{
return m_topOffsetMap;
}
SnapLineMap SnappingLineCreator::bottomOffsets() const
{
return m_bottomOffsetMap;
}
SnapLineMap SnappingLineCreator::leftOffsets() const
{
return m_leftOffsetMap;
}
SnapLineMap SnappingLineCreator::rightOffsets() const
{
return m_rightOffsetMap;
}
}

View File

@@ -0,0 +1,102 @@
/**************************************************************************
**
** 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 SNAPPINGLINECREATOR_H
#define SNAPPINGLINECREATOR_H
#include "layeritem.h"
#include <QPair>
namespace QmlDesigner {
class FormEditorItem;
typedef QMultiMap<double, QPair<QRectF, FormEditorItem*> > SnapLineMap;
typedef QMapIterator<double, QPair<QRectF, FormEditorItem*> > SnapLineMapIterator;
class FormEditorItem;
class SnappingLineCreator
{
public:
SnappingLineCreator(FormEditorItem *formEditorItem);
void update(const QList<FormEditorItem*> &exceptionList,
FormEditorItem *transformationSpaceItem);
SnapLineMap topLines() const;
SnapLineMap bottomLines() const;
SnapLineMap leftLines() const;
SnapLineMap rightLines() const;
SnapLineMap horizontalCenterLines() const;
SnapLineMap verticalCenterLines() const;
SnapLineMap topOffsets() const;
SnapLineMap bottomOffsets() const;
SnapLineMap leftOffsets() const;
SnapLineMap rightOffsets() const;
void setMargins(double margin);
void setSpacing(double spacing);
protected:
void addLines(const QRectF &rectInSceneSpace, FormEditorItem *item);
void addOffsets(const QRectF &rectInSceneSpace, FormEditorItem *item);
void clearLines();
void generateLines(const QList<FormEditorItem*> &exceptionList,
FormEditorItem *transformationSpaceItem);
private:
SnapLineMap m_topLineMap;
SnapLineMap m_bottomLineMap;
SnapLineMap m_leftLineMap;
SnapLineMap m_rightLineMap;
SnapLineMap m_horizontalCenterLineMap;
SnapLineMap m_verticalCenterLineMap;
SnapLineMap m_topOffsetMap;
SnapLineMap m_bottomOffsetMap;
SnapLineMap m_leftOffsetMap;
SnapLineMap m_rightOffsetMap;
FormEditorItem *m_formEditorItem;
double m_topOffset;
double m_bottomOffset;
double m_leftOffset;
double m_rightOffset;
double m_topMargin;
double m_bottomMargin;
double m_leftMargin;
double m_rightMargin;
};
}
#endif // SNAPPINGLINECREATOR_H

View File

@@ -0,0 +1,227 @@
#include "subcomponenteditortool.h"
#include "qdeclarativedesignview.h"
#include "subcomponentmasklayeritem.h"
#include "layeritem.h"
#include <QGraphicsItem>
#include <QGraphicsObject>
#include <QTimer>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QDebug>
namespace QmlViewer {
SubcomponentEditorTool::SubcomponentEditorTool(QDeclarativeDesignView *view)
: AbstractFormEditorTool(view),
m_animIncrement(0.05f),
m_animTimer(new QTimer(this))
{
m_mask = new SubcomponentMaskLayerItem(view, view->manipulatorLayer());
connect(m_animTimer, SIGNAL(timeout()), SLOT(animate()));
m_animTimer->setInterval(20);
}
SubcomponentEditorTool::~SubcomponentEditorTool()
{
}
void SubcomponentEditorTool::mousePressEvent(QMouseEvent */*event*/)
{
}
void SubcomponentEditorTool::mouseMoveEvent(QMouseEvent */*event*/)
{
}
bool SubcomponentEditorTool::containsCursor(const QPoint &mousePos) const
{
if (!m_currentContext.size())
return false;
qDebug() << __FUNCTION__ << m_currentContext.top();
QPointF scenePos = view()->mapToScene(mousePos);
QRectF itemRect = m_currentContext.top()->boundingRect() | m_currentContext.top()->childrenBoundingRect();
QRectF polyRect = m_currentContext.top()->mapToScene(itemRect).boundingRect();
return polyRect.contains(scenePos);
}
void SubcomponentEditorTool::mouseReleaseEvent(QMouseEvent */*event*/)
{
}
void SubcomponentEditorTool::mouseDoubleClickEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton
&& !containsCursor(event->pos())
&& m_currentContext.size() > 1)
{
aboutToPopContext();
}
}
void SubcomponentEditorTool::hoverMoveEvent(QMouseEvent *event)
{
if (!containsCursor(event->pos()) && m_currentContext.size() > 1) {
view()->clearHighlightBoundingRect();
}
}
void SubcomponentEditorTool::wheelEvent(QWheelEvent */*event*/)
{
}
void SubcomponentEditorTool::keyPressEvent(QKeyEvent */*event*/)
{
}
void SubcomponentEditorTool::keyReleaseEvent(QKeyEvent */*keyEvent*/)
{
}
void SubcomponentEditorTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
{
}
void SubcomponentEditorTool::animate()
{
if (m_animIncrement > 0) {
if (m_mask->opacity() + m_animIncrement < 0.5f) {
m_mask->setOpacity(m_mask->opacity() + m_animIncrement);
} else {
m_animTimer->stop();
m_mask->setOpacity(0.5f);
}
} else {
if (m_mask->opacity() + m_animIncrement > 0) {
m_mask->setOpacity(m_mask->opacity() + m_animIncrement);
} else {
m_animTimer->stop();
m_mask->setOpacity(0);
popContext();
}
}
}
void SubcomponentEditorTool::clear()
{
m_currentContext.clear();
m_mask->setCurrentItem(0);
m_animTimer->stop();
m_mask->hide();
}
void SubcomponentEditorTool::graphicsObjectsChanged(const QList<QGraphicsObject*> &/*itemList*/)
{
}
void SubcomponentEditorTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/)
{
}
void SubcomponentEditorTool::setCurrentItem(QGraphicsItem* contextItem)
{
if (!contextItem)
return;
QGraphicsObject *gfxObject = contextItem->toGraphicsObject();
if (!gfxObject)
return;
//QString parentClassName = gfxObject->metaObject()->className();
//if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+")))
bool containsSelectableItems = false;
foreach(QGraphicsItem *item, gfxObject->childItems()) {
if (item->type() == Constants::EditorItemType
|| item->type() == Constants::ResizeHandleItemType)
{
continue;
}
containsSelectableItems = true;
break;
}
if (containsSelectableItems) {
m_mask->setCurrentItem(gfxObject);
m_mask->setOpacity(0);
m_mask->show();
m_animIncrement = 0.05f;
m_animTimer->start();
view()->clearHighlightBoundingRect();
view()->setSelectedItems(QList<QGraphicsItem*>());
pushContext(gfxObject);
}
}
bool SubcomponentEditorTool::isDirectChildOfContext(QGraphicsItem *item) const
{
return (item->parentItem() == m_currentContext.top());
}
bool SubcomponentEditorTool::itemIsChildOfQmlSubComponent(QGraphicsItem *item) const
{
if (item->parentItem() && item->parentItem() != m_currentContext.top()) {
QGraphicsObject *parent = item->parentItem()->toGraphicsObject();
QString parentClassName = parent->metaObject()->className();
if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+"))) {
return true;
} else {
return itemIsChildOfQmlSubComponent(parent);
}
}
return false;
}
void SubcomponentEditorTool::pushContext(QGraphicsObject *contextItem)
{
m_currentContext.push(contextItem);
}
void SubcomponentEditorTool::aboutToPopContext()
{
if (m_currentContext.size() > 2) {
popContext();
} else {
m_animIncrement = -0.05f;
m_animTimer->start();
}
}
QGraphicsObject *SubcomponentEditorTool::popContext()
{
QGraphicsObject *popped = m_currentContext.pop();
if (m_currentContext.size() > 1) {
m_mask->setCurrentItem(m_currentContext.top());
m_mask->setOpacity(0.5f);
m_mask->setVisible(true);
}
return popped;
}
QGraphicsObject *SubcomponentEditorTool::currentRootItem() const
{
return m_currentContext.top();
}
} // namespace QmlViewer

View File

@@ -0,0 +1,71 @@
#ifndef SUBCOMPONENTEDITORTOOL_H
#define SUBCOMPONENTEDITORTOOL_H
#include "abstractformeditortool.h"
#include <QStack>
QT_FORWARD_DECLARE_CLASS(QGraphicsObject)
QT_FORWARD_DECLARE_CLASS(QPoint)
QT_FORWARD_DECLARE_CLASS(QTimer)
namespace QmlViewer {
class SubcomponentMaskLayerItem;
class SubcomponentEditorTool : public AbstractFormEditorTool
{
Q_OBJECT
public:
SubcomponentEditorTool(QDeclarativeDesignView *view);
~SubcomponentEditorTool();
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void hoverMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *keyEvent);
void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList);
void clear();
void graphicsObjectsChanged(const QList<QGraphicsObject*> &itemList);
bool containsCursor(const QPoint &mousePos) const;
bool itemIsChildOfQmlSubComponent(QGraphicsItem *item) const;
bool isDirectChildOfContext(QGraphicsItem *item) const;
void setCurrentItem(QGraphicsItem *contextObject);
void pushContext(QGraphicsObject *contextItem);
QGraphicsObject *popContext();
QGraphicsObject *currentRootItem() const;
signals:
void exitContextRequested();
protected:
void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
private slots:
void animate();
private:
void aboutToPopContext();
private:
QStack<QGraphicsObject *> m_currentContext;
qreal m_animIncrement;
SubcomponentMaskLayerItem *m_mask;
QTimer *m_animTimer;
};
} // namespace QmlViewer
#endif // SUBCOMPONENTEDITORTOOL_H

View File

@@ -0,0 +1,53 @@
#include "subcomponentmasklayeritem.h"
#include "qmlviewerconstants.h"
#include "qdeclarativedesignview.h"
#include <QPolygonF>
namespace QmlViewer {
SubcomponentMaskLayerItem::SubcomponentMaskLayerItem(QDeclarativeDesignView *view, QGraphicsItem *parentItem) :
QGraphicsPolygonItem(parentItem),
m_view(view),
m_currentItem(0),
m_borderRect(new QGraphicsRectItem(this))
{
m_borderRect->setRect(0,0,0,0);
m_borderRect->setPen(QPen(QColor(60, 60, 60), 1));
setBrush(QBrush(Qt::black));
setPen(Qt::NoPen);
}
int SubcomponentMaskLayerItem::type() const
{
return Constants::EditorItemType;
}
void SubcomponentMaskLayerItem::setCurrentItem(QGraphicsItem *item)
{
m_currentItem = item;
if (!m_currentItem)
return;
QPolygonF viewPoly(QRectF(m_view->rect()));
viewPoly = m_view->mapToScene(viewPoly.toPolygon());
QRectF itemRect = item->boundingRect() | item->childrenBoundingRect();
QPolygonF itemPoly(itemRect);
itemPoly = item->mapToScene(itemPoly);
QRectF borderRect = itemPoly.boundingRect();
borderRect.adjust(-1, -1, 1, 1);
m_borderRect->setRect(borderRect);
itemPoly = viewPoly.subtracted(QPolygonF(itemPoly.boundingRect()));
setPolygon(itemPoly);
}
QGraphicsItem *SubcomponentMaskLayerItem::currentItem() const
{
return m_currentItem;
}
} // namespace QmlViewer

View File

@@ -0,0 +1,26 @@
#ifndef SUBCOMPONENTMASKLAYERITEM_H
#define SUBCOMPONENTMASKLAYERITEM_H
#include <QGraphicsPolygonItem>
namespace QmlViewer {
class QDeclarativeDesignView;
class SubcomponentMaskLayerItem : public QGraphicsPolygonItem
{
public:
explicit SubcomponentMaskLayerItem(QDeclarativeDesignView *view, QGraphicsItem *parentItem = 0);
int type() const;
void setCurrentItem(QGraphicsItem *item);
QGraphicsItem *currentItem() const;
private:
QDeclarativeDesignView *m_view;
QGraphicsItem *m_currentItem;
QGraphicsRectItem *m_borderRect;
};
} // namespace QmlViewer
#endif // SUBCOMPONENTMASKLAYERITEM_H

View File

@@ -0,0 +1,96 @@
#include "toolbarcolorbox.h"
#include "qmlviewerconstants.h"
#include <QPixmap>
#include <QPainter>
#include <QMenu>
#include <QAction>
#include <QContextMenuEvent>
#include <QClipboard>
#include <QApplication>
#include <QColorDialog>
#include <QDrag>
#include <QMimeData>
#include <QDebug>
namespace QmlViewer {
ToolBarColorBox::ToolBarColorBox(QWidget *parent) :
QLabel(parent)
{
m_copyHexColor = new QAction(tr("Copy"), this);
connect(m_copyHexColor, SIGNAL(triggered()), SLOT(copyColorToClipboard()));
setScaledContents(false);
}
void ToolBarColorBox::setColor(const QColor &color)
{
m_color = color;
QPixmap pix = createDragPixmap(width());
setPixmap(pix);
update();
}
void ToolBarColorBox::mousePressEvent(QMouseEvent *event)
{
m_dragBeginPoint = event->pos();
m_dragStarted = false;
}
void ToolBarColorBox::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton
&& QPoint(event->pos() - m_dragBeginPoint).manhattanLength() > Constants::DragStartDistance
&& !m_dragStarted)
{
m_dragStarted = true;
QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;
mimeData->setText(m_color.name());
drag->setMimeData(mimeData);
drag->setPixmap(createDragPixmap());
drag->exec();
}
}
QPixmap ToolBarColorBox::createDragPixmap(int size) const
{
QPixmap pix(size, size);
QPainter p(&pix);
QColor borderColor1 = QColor(143, 143 ,143);
QColor borderColor2 = Qt::white;
p.setBrush(QBrush(m_color));
p.setPen(QPen(QBrush(borderColor2),1));
p.fillRect(0, 0, size, size, borderColor1);
p.drawRect(1,1, size - 3, size - 3);
return pix;
}
void ToolBarColorBox::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu contextMenu;
contextMenu.addAction(m_copyHexColor);
contextMenu.exec(ev->globalPos());
}
void ToolBarColorBox::mouseDoubleClickEvent(QMouseEvent *)
{
QColorDialog dialog(m_color);
dialog.show();
}
void ToolBarColorBox::copyColorToClipboard()
{
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(m_color.name());
}
} // namespace QmlViewer

View File

@@ -0,0 +1,41 @@
#ifndef ToolBarColorBox_H
#define ToolBarColorBox_H
#include <QLabel>
#include <QColor>
#include <QPoint>
QT_FORWARD_DECLARE_CLASS(QContextMenuEvent);
QT_FORWARD_DECLARE_CLASS(QAction);
namespace QmlViewer {
class ToolBarColorBox : public QLabel
{
Q_OBJECT
public:
explicit ToolBarColorBox(QWidget *parent = 0);
void setColor(const QColor &color);
protected:
void contextMenuEvent(QContextMenuEvent *ev);
void mouseDoubleClickEvent(QMouseEvent *);
void mousePressEvent(QMouseEvent *ev);
void mouseMoveEvent(QMouseEvent *ev);
private slots:
void copyColorToClipboard();
private:
QPixmap createDragPixmap(int size = 24) const;
private:
bool m_dragStarted;
QPoint m_dragBeginPoint;
QAction *m_copyHexColor;
QColor m_color;
};
} // namespace QmlViewer
#endif // ToolBarColorBox_H

View File

@@ -0,0 +1,291 @@
#include "zoomtool.h"
#include "qdeclarativedesignview.h"
#include <QMouseEvent>
#include <QWheelEvent>
#include <QKeyEvent>
#include <QRectF>
#include <QMenu>
#include <QAction>
#include <QDebug>
namespace QmlViewer {
ZoomTool::ZoomTool(QDeclarativeDesignView *view) :
AbstractFormEditorTool(view),
m_rubberbandManipulator(view->manipulatorLayer(), view),
m_smoothZoomMultiplier(0.05f),
m_currentScale(1.0f)
{
m_zoomTo100Action = new QAction(tr("Zoom to &100%"), this);
m_zoomInAction = new QAction(tr("Zoom In"), this);
m_zoomOutAction = new QAction(tr("Zoom Out"), this);
m_zoomInAction->setShortcut(QKeySequence(Qt::Key_Plus));
m_zoomOutAction->setShortcut(QKeySequence(Qt::Key_Minus));
connect(m_zoomTo100Action, SIGNAL(triggered()), SLOT(zoomTo100()));
connect(m_zoomInAction, SIGNAL(triggered()), SLOT(zoomIn()));
connect(m_zoomOutAction, SIGNAL(triggered()), SLOT(zoomOut()));
}
ZoomTool::~ZoomTool()
{
}
void ZoomTool::mousePressEvent(QMouseEvent *event)
{
m_mousePos = event->pos();
QPointF scenePos = view()->mapToScene(event->pos());
if (event->buttons() & Qt::RightButton) {
QMenu contextMenu;
contextMenu.addAction(m_zoomTo100Action);
contextMenu.addSeparator();
contextMenu.addAction(m_zoomInAction);
contextMenu.addAction(m_zoomOutAction);
contextMenu.exec(event->globalPos());
} else if (event->buttons() & Qt::LeftButton) {
m_dragBeginPos = scenePos;
m_dragStarted = false;
}
}
void ZoomTool::mouseMoveEvent(QMouseEvent *event)
{
m_mousePos = event->pos();
QPointF scenePos = view()->mapToScene(event->pos());
if (event->buttons() & Qt::LeftButton
&& QPointF(scenePos - m_dragBeginPos).manhattanLength() > Constants::DragStartDistance / 3
&& !m_dragStarted)
{
m_dragStarted = true;
m_rubberbandManipulator.begin(m_dragBeginPos);
return;
}
if (m_dragStarted)
m_rubberbandManipulator.update(scenePos);
}
void ZoomTool::mouseReleaseEvent(QMouseEvent *event)
{
m_mousePos = event->pos();
QPointF scenePos = view()->mapToScene(event->pos());
if (m_dragStarted) {
m_rubberbandManipulator.end();
int x1 = qMin(scenePos.x(), m_rubberbandManipulator.beginPoint().x());
int x2 = qMax(scenePos.x(), m_rubberbandManipulator.beginPoint().x());
int y1 = qMin(scenePos.y(), m_rubberbandManipulator.beginPoint().y());
int y2 = qMax(scenePos.y(), m_rubberbandManipulator.beginPoint().y());
QPointF scenePosTopLeft = QPoint(x1, y1);
QPointF scenePosBottomRight = QPoint(x2, y2);
QRectF sceneArea(scenePosTopLeft, scenePosBottomRight);
m_currentScale = qMin(view()->rect().width() / sceneArea.width(),
view()->rect().height() / sceneArea.height());
QTransform transform;
transform.scale(m_currentScale, m_currentScale);
view()->setTransform(transform);
view()->setSceneRect(sceneArea);
} else {
Qt::KeyboardModifier modifierKey = Qt::ControlModifier;
#ifdef Q_WS_MAC
modifierKey = Qt::AltModifier;
#endif
if (event->modifiers() & modifierKey) {
zoomOut();
} else {
zoomIn();
}
}
}
void ZoomTool::zoomIn()
{
m_currentScale = nextZoomScale(ZoomIn);
scaleView(view()->mapToScene(m_mousePos));
}
void ZoomTool::zoomOut()
{
m_currentScale = nextZoomScale(ZoomOut);
scaleView(view()->mapToScene(m_mousePos));
}
void ZoomTool::mouseDoubleClickEvent(QMouseEvent *event)
{
m_mousePos = event->pos();
}
void ZoomTool::hoverMoveEvent(QMouseEvent *event)
{
m_mousePos = event->pos();
}
void ZoomTool::keyPressEvent(QKeyEvent */*event*/)
{
}
void ZoomTool::wheelEvent(QWheelEvent *event)
{
if (event->orientation() != Qt::Vertical)
return;
Qt::KeyboardModifier smoothZoomModifier = Qt::ControlModifier;
if (event->modifiers() & smoothZoomModifier) {
int numDegrees = event->delta() / 8;
m_currentScale += m_smoothZoomMultiplier * (numDegrees / 15.0f);
scaleView(view()->mapToScene(m_mousePos));
} else if (!event->modifiers()) {
if (event->delta() > 0) {
m_currentScale = nextZoomScale(ZoomIn);
} else if (event->delta() < 0) {
m_currentScale = nextZoomScale(ZoomOut);
}
scaleView(view()->mapToScene(m_mousePos));
}
}
void ZoomTool::keyReleaseEvent(QKeyEvent *event)
{
switch(event->key()) {
case Qt::Key_Plus:
zoomIn();
break;
case Qt::Key_Minus:
zoomOut();
break;
case Qt::Key_1:
case Qt::Key_2:
case Qt::Key_3:
case Qt::Key_4:
case Qt::Key_5:
case Qt::Key_6:
case Qt::Key_7:
case Qt::Key_8:
case Qt::Key_9:
{
m_currentScale = ((event->key() - Qt::Key_0) * 1.0f);
scaleView(view()->mapToScene(m_mousePos)); // view()->mapToScene(view()->rect().center())
break;
}
default:
break;
}
}
void ZoomTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
{
}
void ZoomTool::clear()
{
view()->setCursor(Qt::ArrowCursor);
}
void ZoomTool::graphicsObjectsChanged(const QList<QGraphicsObject*> &/*itemList*/)
{
}
void ZoomTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/)
{
}
void ZoomTool::scaleView(const QPointF &centerPos)
{
QTransform transform;
transform.scale(m_currentScale, m_currentScale);
view()->setTransform(transform);
QPointF adjustedCenterPos = centerPos;
QSize rectSize(view()->rect().width() / m_currentScale,
view()->rect().height() / m_currentScale);
QRectF sceneRect;
if (qAbs(m_currentScale - 1.0f) < Constants::ZoomSnapDelta) {
adjustedCenterPos.rx() = rectSize.width() / 2;
adjustedCenterPos.ry() = rectSize.height() / 2;
}
if (m_currentScale < 1.0f) {
adjustedCenterPos.rx() = rectSize.width() / 2;
adjustedCenterPos.ry() = rectSize.height() / 2;
sceneRect.setRect(view()->rect().width() / 2 -rectSize.width() / 2,
view()->rect().height() / 2 -rectSize.height() / 2,
rectSize.width(),
rectSize.height());
} else {
sceneRect.setRect(adjustedCenterPos.x() - rectSize.width() / 2,
adjustedCenterPos.y() - rectSize.height() / 2,
rectSize.width(),
rectSize.height());
}
view()->setSceneRect(sceneRect);
}
void ZoomTool::zoomTo100()
{
m_currentScale = 1.0f;
scaleView(view()->mapToScene(view()->rect().center()));
}
qreal ZoomTool::nextZoomScale(ZoomDirection direction) const
{
static QList<qreal> zoomScales =
QList<qreal>()
<< 0.125f
<< 1.0f / 6.0f
<< 0.25f
<< 1.0f / 3.0f
<< 0.5f
<< 2.0f / 3.0f
<< 1.0f
<< 2.0f
<< 3.0f
<< 4.0f
<< 5.0f
<< 6.0f
<< 7.0f
<< 8.0f
<< 12.0f
<< 16.0f
<< 32.0f
<< 48.0f;
if (direction == ZoomIn) {
for(int i = 0; i < zoomScales.length(); ++i) {
if (zoomScales[i] > m_currentScale || i == zoomScales.length() - 1)
return zoomScales[i];
}
} else {
for(int i = zoomScales.length() - 1; i >= 0; --i) {
if (zoomScales[i] < m_currentScale || i == 0)
return zoomScales[i];
}
}
return 1.0f;
}
} // namespace QmlViewer

View File

@@ -0,0 +1,67 @@
#ifndef ZOOMTOOL_H
#define ZOOMTOOL_H
#include "abstractformeditortool.h"
#include "rubberbandselectionmanipulator.h"
QT_FORWARD_DECLARE_CLASS(QAction);
namespace QmlViewer {
class ZoomTool : public AbstractFormEditorTool
{
Q_OBJECT
public:
enum ZoomDirection {
ZoomIn,
ZoomOut
};
explicit ZoomTool(QDeclarativeDesignView *view);
virtual ~ZoomTool();
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void hoverMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *keyEvent);
void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList);
void clear();
void graphicsObjectsChanged(const QList<QGraphicsObject*> &itemList);
protected:
void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
private slots:
void zoomTo100();
void zoomIn();
void zoomOut();
private:
qreal nextZoomScale(ZoomDirection direction) const;
void scaleView(const QPointF &centerPos);
private:
bool m_dragStarted;
QPoint m_mousePos; // in view coords
QPointF m_dragBeginPos;
QAction *m_zoomTo100Action;
QAction *m_zoomInAction;
QAction *m_zoomOutAction;
RubberBandSelectionManipulator m_rubberbandManipulator;
qreal m_smoothZoomMultiplier;
qreal m_currentScale;
};
} // namespace QmlViewer
#endif // ZOOMTOOL_H

View File

@@ -0,0 +1,201 @@
/****************************************************************************
**
** 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 <qglobal.h>
#include <QDebug>
#include <QSettings>
#include <QActionGroup>
#include <QMenu>
#include <QPlainTextEdit>
#ifdef Q_WS_MAEMO_5
# include <QScrollArea>
# include <QVBoxLayout>
# include "texteditautoresizer_maemo5.h"
#endif
#include "loggerwidget.h"
QT_BEGIN_NAMESPACE
LoggerWidget::LoggerWidget(QWidget *parent) :
QMainWindow(parent),
m_visibilityOrigin(SettingsOrigin)
{
setAttribute(Qt::WA_QuitOnClose, false);
setWindowTitle(tr("Warnings"));
m_plainTextEdit = new QPlainTextEdit();
#ifdef Q_WS_MAEMO_5
new TextEditAutoResizer(m_plainTextEdit);
setAttribute(Qt::WA_Maemo5StackedWindow);
QScrollArea *area = new QScrollArea();
area->setWidget(m_plainTextEdit);
area->setWidgetResizable(true);
setCentralWidget(area);
#else
setCentralWidget(m_plainTextEdit);
#endif
readSettings();
setupPreferencesMenu();
}
void LoggerWidget::append(const QString &msg)
{
m_plainTextEdit->appendPlainText(msg);
if (!isVisible() && (defaultVisibility() == AutoShowWarnings))
setVisible(true);
}
LoggerWidget::Visibility LoggerWidget::defaultVisibility() const
{
return m_visibility;
}
void LoggerWidget::setDefaultVisibility(LoggerWidget::Visibility visibility)
{
if (m_visibility == visibility)
return;
m_visibility = visibility;
m_visibilityOrigin = CommandLineOrigin;
m_preferencesMenu->setEnabled(m_visibilityOrigin == SettingsOrigin);
}
QMenu *LoggerWidget::preferencesMenu()
{
return m_preferencesMenu;
}
QAction *LoggerWidget::showAction()
{
return m_showWidgetAction;
}
void LoggerWidget::readSettings()
{
QSettings settings;
QString warningsPreferences = settings.value("warnings", "hide").toString();
if (warningsPreferences == "show") {
m_visibility = ShowWarnings;
} else if (warningsPreferences == "hide") {
m_visibility = HideWarnings;
} else {
m_visibility = AutoShowWarnings;
}
}
void LoggerWidget::saveSettings()
{
if (m_visibilityOrigin != SettingsOrigin)
return;
QString value = "autoShow";
if (defaultVisibility() == ShowWarnings) {
value = "show";
} else if (defaultVisibility() == HideWarnings) {
value = "hide";
}
QSettings settings;
settings.setValue("warnings", value);
}
void LoggerWidget::warningsPreferenceChanged(QAction *action)
{
Visibility newSetting = static_cast<Visibility>(action->data().toInt());
m_visibility = newSetting;
saveSettings();
}
void LoggerWidget::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);
emit opened();
}
void LoggerWidget::closeEvent(QCloseEvent *event)
{
QWidget::closeEvent(event);
emit closed();
}
void LoggerWidget::setupPreferencesMenu()
{
m_preferencesMenu = new QMenu(tr("Warnings"));
QActionGroup *warnings = new QActionGroup(m_preferencesMenu);
warnings->setExclusive(true);
connect(warnings, SIGNAL(triggered(QAction*)), this, SLOT(warningsPreferenceChanged(QAction*)));
QAction *showWarningsPreference = new QAction(tr("Show by default"), m_preferencesMenu);
showWarningsPreference->setCheckable(true);
showWarningsPreference->setData(LoggerWidget::ShowWarnings);
warnings->addAction(showWarningsPreference);
m_preferencesMenu->addAction(showWarningsPreference);
QAction *hideWarningsPreference = new QAction(tr("Hide by default"), m_preferencesMenu);
hideWarningsPreference->setCheckable(true);
hideWarningsPreference->setData(LoggerWidget::HideWarnings);
warnings->addAction(hideWarningsPreference);
m_preferencesMenu->addAction(hideWarningsPreference);
QAction *autoWarningsPreference = new QAction(tr("Show for first warning"), m_preferencesMenu);
autoWarningsPreference->setCheckable(true);
autoWarningsPreference->setData(LoggerWidget::AutoShowWarnings);
warnings->addAction(autoWarningsPreference);
m_preferencesMenu->addAction(autoWarningsPreference);
switch (defaultVisibility()) {
case LoggerWidget::ShowWarnings:
showWarningsPreference->setChecked(true);
break;
case LoggerWidget::HideWarnings:
hideWarningsPreference->setChecked(true);
break;
default:
autoWarningsPreference->setChecked(true);
}
}
QT_END_NAMESPACE

View File

@@ -0,0 +1,99 @@
/****************************************************************************
**
** 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 LOGGERWIDGET_H
#define LOGGERWIDGET_H
#include <QMainWindow>
#include <QMetaType>
QT_BEGIN_NAMESPACE
class QPlainTextEdit;
class QMenu;
class QAction;
class LoggerWidget : public QMainWindow {
Q_OBJECT
public:
LoggerWidget(QWidget *parent=0);
enum Visibility { ShowWarnings, HideWarnings, AutoShowWarnings };
Visibility defaultVisibility() const;
void setDefaultVisibility(Visibility visibility);
QMenu *preferencesMenu();
QAction *showAction();
public slots:
void append(const QString &msg);
private slots:
void warningsPreferenceChanged(QAction *action);
void readSettings();
void saveSettings();
protected:
void showEvent(QShowEvent *event);
void closeEvent(QCloseEvent *event);
signals:
void opened();
void closed();
private:
void setupPreferencesMenu();
QMenu *m_preferencesMenu;
QAction *m_showWidgetAction;
QPlainTextEdit *m_plainTextEdit;
enum ConfigOrigin { CommandLineOrigin, SettingsOrigin };
ConfigOrigin m_visibilityOrigin;
Visibility m_visibility;
};
QT_END_NAMESPACE
Q_DECLARE_METATYPE(LoggerWidget::Visibility)
#endif // LOGGERWIDGET_H

View File

@@ -0,0 +1,461 @@
/****************************************************************************
**
** 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 "qdeclarative.h"
#include "qmlruntime.h"
#include "qdeclarativeengine.h"
#include "loggerwidget.h"
#include <QWidget>
#include <QDir>
#include <QApplication>
#include <QTranslator>
#include <QDebug>
#include <QMessageBox>
#include "qdeclarativetester.h"
QT_USE_NAMESPACE
QtMsgHandler systemMsgOutput = 0;
#if defined (Q_OS_SYMBIAN)
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void myMessageOutput(QtMsgType type, const char *msg)
{
static int fd = -1;
if (fd == -1)
fd = ::open("E:\\qml.log", O_WRONLY | O_CREAT);
::write(fd, msg, strlen(msg));
::write(fd, "\n", 1);
::fsync(fd);
switch (type) {
case QtFatalMsg:
abort();
}
}
#else // !defined (Q_OS_SYMBIAN)
QWeakPointer<LoggerWidget> logger;
QString warnings;
void showWarnings()
{
if (!warnings.isEmpty()) {
QMessageBox::warning(0, QApplication::tr("Qt QML Viewer"), warnings);
}
}
void myMessageOutput(QtMsgType type, const char *msg)
{
if (!logger.isNull()) {
QString strMsg = QString::fromAscii(msg);
QMetaObject::invokeMethod(logger.data(), "append", Q_ARG(QString, strMsg));
} else {
warnings += msg;
warnings += QLatin1Char('\n');
}
if (systemMsgOutput) { // Windows
systemMsgOutput(type, msg);
} else { // Unix
fprintf(stderr, "%s\n",msg);
fflush(stderr);
}
}
#endif
void usage()
{
qWarning("Usage: qmlviewer [options] <filename>");
qWarning(" ");
qWarning(" options:");
qWarning(" -v, -version ............................. display version");
qWarning(" -frameless ............................... run with no window frame");
qWarning(" -maximized................................ run maximized");
qWarning(" -fullscreen............................... run fullscreen");
qWarning(" -stayontop................................ keep viewer window on top");
qWarning(" -sizeviewtorootobject .................... the view resizes to the changes in the content");
qWarning(" -sizerootobjecttoview .................... the content resizes to the changes in the view (default)");
qWarning(" -qmlbrowser .............................. use a QML-based file browser");
qWarning(" -warnings [show|hide]..................... show warnings in a separate log window");
qWarning(" -recordfile <output> ..................... set video recording file");
qWarning(" - ImageMagick 'convert' for GIF)");
qWarning(" - png file for raw frames");
qWarning(" - 'ffmpeg' for other formats");
qWarning(" -recorddither ordered|threshold|floyd .... set GIF dither recording mode");
qWarning(" -recordrate <fps> ........................ set recording frame rate");
qWarning(" -record arg .............................. add a recording process argument");
qWarning(" -autorecord [from-]<tomilliseconds> ...... set recording to start and stop");
qWarning(" -devicekeys .............................. use numeric keys (see F1)");
qWarning(" -dragthreshold <size> .................... set mouse drag threshold size");
qWarning(" -netcache <size> ......................... set disk cache to size bytes");
qWarning(" -translation <translationfile> ........... set the language to run in");
qWarning(" -I <directory> ........................... prepend to the module import search path,");
qWarning(" display path if <directory> is empty");
qWarning(" -P <directory> ........................... prepend to the plugin search path");
qWarning(" -opengl .................................. use a QGLWidget for the viewport");
qWarning(" -script <path> ........................... set the script to use");
qWarning(" -scriptopts <options>|help ............... set the script options to use");
qWarning(" ");
qWarning(" Press F1 for interactive help");
exit(1);
}
void scriptOptsUsage()
{
qWarning("Usage: qmlviewer -scriptopts <option>[,<option>...] ...");
qWarning(" options:");
qWarning(" record ................................... record a new script");
qWarning(" play ..................................... playback an existing script");
qWarning(" testimages ............................... record images or compare images on playback");
qWarning(" testerror ................................ test 'error' property of root item on playback");
qWarning(" snapshot ................................. file being recorded is static,");
qWarning(" only one frame will be recorded or tested");
qWarning(" exitoncomplete ........................... cleanly exit the viewer on script completion");
qWarning(" exitonfailure ............................ immediately exit the viewer on script failure");
qWarning(" saveonexit ............................... save recording on viewer exit");
qWarning(" ");
qWarning(" One of record, play or both must be specified.");
exit(1);
}
enum WarningsConfig { ShowWarnings, HideWarnings, DefaultWarnings };
int main(int argc, char ** argv)
{
#if defined (Q_OS_SYMBIAN)
qInstallMsgHandler(myMessageOutput);
#else
systemMsgOutput = qInstallMsgHandler(myMessageOutput);
#endif
#if defined (Q_OS_WIN)
// Debugging output is not visible by default on Windows -
// therefore show modal dialog with errors instad.
atexit(showWarnings);
#endif
#if defined (Q_WS_X11) || defined (Q_WS_MAC)
//### default to using raster graphics backend for now
bool gsSpecified = false;
for (int i = 0; i < argc; ++i) {
QString arg = argv[i];
if (arg == "-graphicssystem") {
gsSpecified = true;
break;
}
}
if (!gsSpecified)
QApplication::setGraphicsSystem("raster");
#endif
QApplication app(argc, argv);
app.setApplicationName("QtQmlViewer");
app.setOrganizationName("Nokia");
app.setOrganizationDomain("nokia.com");
QDeclarativeViewer::registerTypes();
QDeclarativeTester::registerTypes();
bool frameless = false;
QString fileName;
double fps = 0;
int autorecord_from = 0;
int autorecord_to = 0;
QString dither = "none";
QString recordfile;
QStringList recordargs;
QStringList imports;
QStringList plugins;
QString script;
QString scriptopts;
bool runScript = false;
bool devkeys = false;
int cache = 0;
QString translationFile;
bool useGL = false;
bool fullScreen = false;
bool stayOnTop = false;
bool maximized = false;
bool useNativeFileBrowser = true;
bool experimentalGestures = false;
bool designModeBehavior = false;
WarningsConfig warningsConfig = DefaultWarnings;
bool sizeToView = true;
#if defined(Q_OS_SYMBIAN)
maximized = true;
useNativeFileBrowser = false;
#endif
#if defined(Q_WS_MAC)
useGL = true;
#endif
for (int i = 1; i < argc; ++i) {
bool lastArg = (i == argc - 1);
QString arg = argv[i];
if (arg == "-frameless") {
frameless = true;
} else if (arg == "-maximized") {
maximized = true;
} else if (arg == "-fullscreen") {
fullScreen = true;
} else if (arg == "-stayontop") {
stayOnTop = true;
} else if (arg == "-netcache") {
if (lastArg) usage();
cache = QString(argv[++i]).toInt();
} else if (arg == "-recordrate") {
if (lastArg) usage();
fps = QString(argv[++i]).toDouble();
} else if (arg == "-recordfile") {
if (lastArg) usage();
recordfile = QString(argv[++i]);
} else if (arg == "-record") {
if (lastArg) usage();
recordargs << QString(argv[++i]);
} else if (arg == "-recorddither") {
if (lastArg) usage();
dither = QString(argv[++i]);
} else if (arg == "-autorecord") {
if (lastArg) usage();
QString range = QString(argv[++i]);
int dash = range.indexOf('-');
if (dash > 0)
autorecord_from = range.left(dash).toInt();
autorecord_to = range.mid(dash+1).toInt();
} else if (arg == "-devicekeys") {
devkeys = true;
} else if (arg == "-dragthreshold") {
if (lastArg) usage();
app.setStartDragDistance(QString(argv[++i]).toInt());
} else if (arg == QLatin1String("-v") || arg == QLatin1String("-version")) {
qWarning("Qt QML Viewer version %s", QT_VERSION_STR);
exit(0);
} else if (arg == "-translation") {
if (lastArg) usage();
translationFile = argv[++i];
} else if (arg == "-opengl") {
useGL = true;
} else if (arg == "-qmlbrowser") {
useNativeFileBrowser = false;
} else if (arg == "-warnings") {
if (lastArg) usage();
QString warningsStr = QString(argv[++i]);
if (warningsStr == QLatin1String("show")) {
warningsConfig = ShowWarnings;
} else if (warningsStr == QLatin1String("hide")) {
warningsConfig = HideWarnings;
} else {
usage();
}
} else if (arg == "-I" || arg == "-L") {
if (arg == "-L")
qWarning("-L option provided for compatibility only, use -I instead");
if (lastArg) {
QDeclarativeEngine tmpEngine;
QString paths = tmpEngine.importPathList().join(QLatin1String(":"));
qWarning("Current search path: %s", paths.toLocal8Bit().constData());
exit(0);
}
imports << QString(argv[++i]);
} else if (arg == "-P") {
if (lastArg) usage();
plugins << QString(argv[++i]);
} else if (arg == "-script") {
if (lastArg) usage();
script = QString(argv[++i]);
} else if (arg == "-scriptopts") {
if (lastArg) usage();
scriptopts = QString(argv[++i]);
} else if (arg == "-savescript") {
if (lastArg) usage();
script = QString(argv[++i]);
runScript = false;
} else if (arg == "-playscript") {
if (lastArg) usage();
script = QString(argv[++i]);
runScript = true;
} else if (arg == "-sizeviewtorootobject") {
sizeToView = false;
} else if (arg == "-sizerootobjecttoview") {
sizeToView = true;
} else if (arg == "-experimentalgestures") {
experimentalGestures = true;
} else if (arg == "-designmode") {
designModeBehavior = true;
} else if (arg[0] != '-') {
fileName = arg;
} else if (1 || arg == "-help") {
usage();
}
}
QTranslator qmlTranslator;
if (!translationFile.isEmpty()) {
qmlTranslator.load(translationFile);
app.installTranslator(&qmlTranslator);
}
Qt::WFlags wflags = (frameless ? Qt::FramelessWindowHint : Qt::Widget);
if (stayOnTop)
wflags |= Qt::WindowStaysOnTopHint;
QDeclarativeViewer *viewer = new QDeclarativeViewer(0, wflags);
viewer->setAttribute(Qt::WA_DeleteOnClose, true);
if (!scriptopts.isEmpty()) {
QStringList options =
scriptopts.split(QLatin1Char(','), QString::SkipEmptyParts);
QDeclarativeViewer::ScriptOptions scriptOptions = 0;
for (int i = 0; i < options.count(); ++i) {
const QString &option = options.at(i);
if (option == QLatin1String("help")) {
scriptOptsUsage();
} else if (option == QLatin1String("play")) {
scriptOptions |= QDeclarativeViewer::Play;
} else if (option == QLatin1String("record")) {
scriptOptions |= QDeclarativeViewer::Record;
} else if (option == QLatin1String("testimages")) {
scriptOptions |= QDeclarativeViewer::TestImages;
} else if (option == QLatin1String("testerror")) {
scriptOptions |= QDeclarativeViewer::TestErrorProperty;
} else if (option == QLatin1String("exitoncomplete")) {
scriptOptions |= QDeclarativeViewer::ExitOnComplete;
} else if (option == QLatin1String("exitonfailure")) {
scriptOptions |= QDeclarativeViewer::ExitOnFailure;
} else if (option == QLatin1String("saveonexit")) {
scriptOptions |= QDeclarativeViewer::SaveOnExit;
} else if (option == QLatin1String("snapshot")) {
scriptOptions |= QDeclarativeViewer::Snapshot;
} else {
scriptOptsUsage();
}
}
if (script.isEmpty())
usage();
if (!(scriptOptions & QDeclarativeViewer::Record) && !(scriptOptions & QDeclarativeViewer::Play))
scriptOptsUsage();
viewer->setScriptOptions(scriptOptions);
viewer->setScript(script);
} else if (!script.isEmpty()) {
usage();
}
#if !defined(Q_OS_SYMBIAN)
logger = viewer->warningsWidget();
if (warningsConfig == ShowWarnings) {
logger.data()->setDefaultVisibility(LoggerWidget::ShowWarnings);
logger.data()->show();
} else if (warningsConfig == HideWarnings){
logger.data()->setDefaultVisibility(LoggerWidget::HideWarnings);
}
#endif
if (experimentalGestures)
viewer->enableExperimentalGestures();
viewer->setDesignModeBehavior(designModeBehavior);
foreach (QString lib, imports)
viewer->addLibraryPath(lib);
foreach (QString plugin, plugins)
viewer->addPluginPath(plugin);
viewer->setNetworkCacheSize(cache);
viewer->setRecordFile(recordfile);
viewer->setSizeToView(sizeToView);
if (fps>0)
viewer->setRecordRate(fps);
if (autorecord_to)
viewer->setAutoRecord(autorecord_from,autorecord_to);
if (devkeys)
viewer->setDeviceKeys(true);
viewer->setRecordDither(dither);
if (recordargs.count())
viewer->setRecordArgs(recordargs);
viewer->setUseNativeFileBrowser(useNativeFileBrowser);
if (fullScreen && maximized)
qWarning() << "Both -fullscreen and -maximized specified. Using -fullscreen.";
if (fileName.isEmpty()) {
QFile qmlapp(QLatin1String("qmlapp"));
if (qmlapp.exists() && qmlapp.open(QFile::ReadOnly)) {
QString content = QString::fromUtf8(qmlapp.readAll());
qmlapp.close();
int newline = content.indexOf(QLatin1Char('\n'));
if (newline >= 0)
fileName = content.left(newline);
else
fileName = content;
}
}
if (!fileName.isEmpty()) {
viewer->open(fileName);
fullScreen ? viewer->showFullScreen() : maximized ? viewer->showMaximized() : viewer->show();
} else {
if (!useNativeFileBrowser)
viewer->openFile();
fullScreen ? viewer->showFullScreen() : maximized ? viewer->showMaximized() : viewer->show();
if (useNativeFileBrowser)
viewer->openFile();
}
viewer->setUseGL(useGL);
viewer->raise();
return app.exec();
}

View File

@@ -0,0 +1,113 @@
/****************************************************************************
**
** 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 <QIntValidator>
#include <QSettings>
#include "proxysettings.h"
QT_BEGIN_NAMESPACE
ProxySettings::ProxySettings (QWidget * parent)
: QDialog (parent), Ui::ProxySettings()
{
setupUi (this);
#if !defined Q_WS_MAEMO_5
// the onscreen keyboard can't cope with masks
proxyServerEdit->setInputMask ("000.000.000.000;_");
#endif
QIntValidator *validator = new QIntValidator (0, 9999, this);
proxyPortEdit->setValidator (validator);
QSettings settings;
proxyCheckBox->setChecked (settings.value ("http_proxy/use", 0).toBool ());
proxyServerEdit->insert (settings.value ("http_proxy/hostname", "").toString ());
proxyPortEdit->insert (settings.value ("http_proxy/port", "80").toString ());
usernameEdit->insert (settings.value ("http_proxy/username", "").toString ());
passwordEdit->insert (settings.value ("http_proxy/password", "").toString ());
}
ProxySettings::~ProxySettings()
{
}
void ProxySettings::accept ()
{
QSettings settings;
settings.setValue ("http_proxy/use", proxyCheckBox->isChecked ());
settings.setValue ("http_proxy/hostname", proxyServerEdit->text ());
settings.setValue ("http_proxy/port", proxyPortEdit->text ());
settings.setValue ("http_proxy/username", usernameEdit->text ());
settings.setValue ("http_proxy/password", passwordEdit->text ());
QDialog::accept ();
}
QNetworkProxy ProxySettings::httpProxy ()
{
QSettings settings;
QNetworkProxy proxy;
bool proxyInUse = settings.value ("http_proxy/use", 0).toBool ();
if (proxyInUse) {
proxy.setType (QNetworkProxy::HttpProxy);
proxy.setHostName (settings.value ("http_proxy/hostname", "").toString ());// "192.168.220.5"
proxy.setPort (settings.value ("http_proxy/port", 80).toInt ()); // 8080
proxy.setUser (settings.value ("http_proxy/username", "").toString ());
proxy.setPassword (settings.value ("http_proxy/password", "").toString ());
//QNetworkProxy::setApplicationProxy (proxy);
}
else {
proxy.setType (QNetworkProxy::NoProxy);
}
return proxy;
}
bool ProxySettings::httpProxyInUse()
{
QSettings settings;
return settings.value ("http_proxy/use", 0).toBool ();
}
QT_END_NAMESPACE

View File

@@ -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$
**
****************************************************************************/
#ifndef PROXYSETTINGS_H
#define PROXYSETTINGS_H
#include <QDialog>
#include <QNetworkProxy>
#ifdef Q_WS_MAEMO_5
#include "ui_proxysettings_maemo5.h"
#else
#include "ui_proxysettings.h"
#endif
QT_BEGIN_NAMESPACE
/**
*/
class ProxySettings : public QDialog, public Ui::ProxySettings
{
Q_OBJECT
public:
ProxySettings(QWidget * parent = 0);
~ProxySettings();
static QNetworkProxy httpProxy ();
static bool httpProxyInUse ();
public slots:
virtual void accept ();
};
QT_END_NAMESPACE
#endif // PROXYSETTINGS_H

View File

@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProxySettings</class>
<widget class="QDialog" name="ProxySettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>318</width>
<height>199</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="proxyCheckBox">
<property name="text">
<string>Use http proxy</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="serverAddressLabel">
<property name="text">
<string>Server Address:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="proxyServerEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Port:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="proxyPortEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="usernameLabel">
<property name="text">
<string>Username:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="usernameEdit"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="passwordLabel">
<property name="text">
<string>Password:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="passwordEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ProxySettings</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ProxySettings</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,177 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProxySettings</class>
<widget class="QDialog" name="ProxySettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>449</width>
<height>164</height>
</rect>
</property>
<property name="windowTitle">
<string>HTTP Proxy</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>16</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>16</number>
</property>
<property name="bottomMargin">
<number>8</number>
</property>
<property name="horizontalSpacing">
<number>16</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="proxyCheckBox">
<property name="text">
<string>Use HTTP Proxy</string>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" rowspan="2">
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout">
<property name="horizontalSpacing">
<number>16</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="serverAddressLabel">
<property name="text">
<string>Server</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="proxyServerEdit">
<property name="placeholderText">
<string>Name or IP</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="proxyPortEdit">
<property name="text">
<string>8080</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="usernameLabel">
<property name="text">
<string>Username</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="usernameEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="passwordLabel">
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="passwordEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>proxyCheckBox</tabstop>
<tabstop>proxyServerEdit</tabstop>
<tabstop>proxyPortEdit</tabstop>
<tabstop>usernameEdit</tabstop>
<tabstop>passwordEdit</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ProxySettings</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>318</x>
<y>100</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>116</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ProxySettings</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>318</x>
<y>100</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>116</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,92 @@
#include "qdeclarativedesigndebugserver.h"
#include <QDebug>
QDeclarativeDesignDebugServer::QDeclarativeDesignDebugServer(QObject *parent)
: QDeclarativeDebugService(QLatin1String("QDeclarativeDesignMode"), parent)
{
}
void QDeclarativeDesignDebugServer::messageReceived(const QByteArray &message)
{
QDataStream ds(message);
QByteArray type;
ds >> type;
if (type == "SET_CURRENT_OBJECTS") {
int itemCount = 0;
ds >> itemCount;
QList<QObject*> selectedObjects;
for(int i = 0; i < itemCount; ++i) {
int debugId = -1;
ds >> debugId;
QObject *obj = objectForId(debugId);
if (obj)
selectedObjects << obj;
}
emit currentObjectsChanged(selectedObjects);
} else if (type == "RELOAD") {
emit reloadRequested();
} else if (type == "SET_ANIMATION_SPEED") {
qreal speed;
ds >> speed;
emit animationSpeedChangeRequested(speed);
} else if (type == "CHANGE_TOOL") {
QByteArray toolName;
ds >> toolName;
if (toolName == "COLOR_PICKER") {
colorPickerToolRequested();
} else if (toolName == "SELECT") {
selectToolRequested();
} else if (toolName == "SELECT_MARQUEE") {
selectMarqueeToolRequested();
} else if (toolName == "ZOOM") {
zoomToolRequested();
}
}
}
void QDeclarativeDesignDebugServer::setCurrentObjects(QList<QObject*> objects)
{
QByteArray message;
QDataStream ds(&message, QIODevice::WriteOnly);
ds << QByteArray("CURRENT_OBJECTS_CHANGED")
<< objects.length();
foreach(QObject *object, objects) {
int id = idForObject(object);
ds << id;
}
sendMessage(message);
}
void QDeclarativeDesignDebugServer::setCurrentTool(QmlViewer::Constants::DesignTool toolId)
{
QByteArray message;
QDataStream ds(&message, QIODevice::WriteOnly);
ds << QByteArray("TOOL_CHANGED")
<< toolId;
sendMessage(message);
}
void QDeclarativeDesignDebugServer::setAnimationSpeed(qreal slowdownFactor)
{
QByteArray message;
QDataStream ds(&message, QIODevice::WriteOnly);
ds << QByteArray("ANIMATION_SPEED_CHANGED")
<< slowdownFactor;
sendMessage(message);
}

View File

@@ -0,0 +1,87 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef QDECLARATIVEDESIGNDEBUGSERVER_H
#define QDECLARATIVEDESIGNDEBUGSERVER_H
#include <private/qdeclarativedebugservice_p.h>
#include "qmlviewerconstants.h"
QT_BEGIN_NAMESPACE
class QDeclarativeEngine;
class QDeclarativeContext;
class QDeclarativeWatcher;
class QDataStream;
class QDeclarativeDesignDebugServer : public QDeclarativeDebugService
{
Q_OBJECT
public:
QDeclarativeDesignDebugServer(QObject *parent = 0);
void setCurrentObjects(QList<QObject*> items);
void setAnimationSpeed(qreal slowdownFactor);
void setCurrentTool(QmlViewer::Constants::DesignTool toolId);
Q_SIGNALS:
void currentObjectsChanged(const QList<QObject*> &objects);
void reloadRequested();
void selectToolRequested();
void selectMarqueeToolRequested();
void zoomToolRequested();
void colorPickerToolRequested();
// 1 = normal speed,
// 0 = paused,
// 1 < x < 16 = slowdown by some factor
void animationSpeedChangeRequested(qreal speedFactor);
protected:
virtual void messageReceived(const QByteArray &);
private:
};
QT_END_NAMESPACE
#endif // QDECLARATIVEDESIGNDEBUGSERVER_H

View File

@@ -0,0 +1,465 @@
#include "qdeclarativedesignview.h"
#include "qdeclarativedesigndebugserver.h"
#include "selectiontool.h"
#include "zoomtool.h"
#include "colorpickertool.h"
#include "layeritem.h"
#include "boundingrecthighlighter.h"
#include "subcomponenteditortool.h"
#include "qmltoolbar.h"
#include <QMouseEvent>
#include <QDeclarativeItem>
#include <QWidget>
#include <QGraphicsObject>
#include <QApplication>
#include <QAbstractAnimation>
#include <private/qabstractanimation_p.h>
namespace QmlViewer {
Q_GLOBAL_STATIC(QDeclarativeDesignDebugServer, qmlDesignDebugServer)
QDeclarativeDesignView::QDeclarativeDesignView(QWidget *parent) :
QDeclarativeView(parent),
m_designModeBehavior(false),
m_executionPaused(false),
m_slowdownFactor(1.0f),
m_toolbar(0)
{
m_manipulatorLayer = new LayerItem(scene());
m_selectionTool = new SelectionTool(this);
m_zoomTool = new ZoomTool(this);
m_colorPickerTool = new ColorPickerTool(this);
m_boundingRectHighlighter = new BoundingRectHighlighter(this);
m_subcomponentEditorTool = new SubcomponentEditorTool(this);
m_currentTool = m_selectionTool;
setMouseTracking(true);
connect(qmlDesignDebugServer(), SIGNAL(reloadRequested()), SLOT(reloadView()));
connect(qmlDesignDebugServer(),
SIGNAL(currentObjectsChanged(QList<QObject*>)),
SLOT(onCurrentObjectsChanged(QList<QObject*>)));
connect(qmlDesignDebugServer(), SIGNAL(animationSpeedChangeRequested(qreal)), SLOT(changeAnimationSpeed(qreal)));
connect(qmlDesignDebugServer(), SIGNAL(colorPickerToolRequested()), SLOT(changeToColorPickerTool()));
connect(qmlDesignDebugServer(), SIGNAL(selectMarqueeToolRequested()), SLOT(changeToMarqueeSelectTool()));
connect(qmlDesignDebugServer(), SIGNAL(selectToolRequested()), SLOT(changeToSingleSelectTool()));
connect(qmlDesignDebugServer(), SIGNAL(zoomToolRequested()), SLOT(changeToZoomTool()));
connect(this, SIGNAL(designModeBehaviorChanged(bool)), SLOT(setDesignModeBehavior(bool)));
connect(this, SIGNAL(statusChanged(QDeclarativeView::Status)), SLOT(onStatusChanged(QDeclarativeView::Status)));
connect(m_colorPickerTool, SIGNAL(selectedColorChanged(QColor)), SIGNAL(selectedColorChanged(QColor)));
createToolbar();
}
QDeclarativeDesignView::~QDeclarativeDesignView()
{
}
void QDeclarativeDesignView::reloadView()
{
m_subcomponentEditorTool->clear();
clearHighlightBoundingRect();
emit reloadRequested();
}
void QDeclarativeDesignView::mousePressEvent(QMouseEvent *event)
{
if (!designModeBehavior()) {
QDeclarativeView::mousePressEvent(event);
return;
}
m_cursorPos = event->pos();
m_currentTool->mousePressEvent(event);
}
void QDeclarativeDesignView::mouseMoveEvent(QMouseEvent *event)
{
if (!designModeBehavior()) {
QDeclarativeView::mouseMoveEvent(event);
return;
}
m_cursorPos = event->pos();
QList<QGraphicsItem*> selItems = selectableItems(event->pos());
if (!selItems.isEmpty()) {
setToolTip(AbstractFormEditorTool::titleForItem(selItems.first()));
} else {
setToolTip(QString());
}
if (event->buttons()) {
m_subcomponentEditorTool->mouseMoveEvent(event);
m_currentTool->mouseMoveEvent(event);
} else {
m_subcomponentEditorTool->hoverMoveEvent(event);
m_currentTool->hoverMoveEvent(event);
}
}
void QDeclarativeDesignView::mouseReleaseEvent(QMouseEvent *event)
{
if (!designModeBehavior()) {
QDeclarativeView::mouseReleaseEvent(event);
return;
}
m_subcomponentEditorTool->mouseReleaseEvent(event);
m_cursorPos = event->pos();
m_currentTool->mouseReleaseEvent(event);
if (event->buttons() & Qt::LeftButton) {
qDebug() << "setting current objects";
qmlDesignDebugServer()->setCurrentObjects(AbstractFormEditorTool::toObjectList(selectedItems()));
}
}
void QDeclarativeDesignView::keyPressEvent(QKeyEvent *event)
{
if (!designModeBehavior()) {
QDeclarativeView::keyPressEvent(event);
return;
}
m_currentTool->keyPressEvent(event);
}
void QDeclarativeDesignView::keyReleaseEvent(QKeyEvent *event)
{
if (!designModeBehavior()) {
QDeclarativeView::keyReleaseEvent(event);
return;
}
switch(event->key()) {
case Qt::Key_V:
changeToSingleSelectTool();
break;
case Qt::Key_M:
changeToMarqueeSelectTool();
break;
case Qt::Key_Enter:
case Qt::Key_Return:
if (!selectedItems().isEmpty())
m_subcomponentEditorTool->setCurrentItem(selectedItems().first());
break;
case Qt::Key_Space:
if (m_executionPaused) {
continueExecution(m_slowdownFactor);
} else {
pauseExecution();
}
break;
default:
break;
}
m_currentTool->keyReleaseEvent(event);
}
QGraphicsItem *QDeclarativeDesignView::currentRootItem() const
{
return m_subcomponentEditorTool->currentRootItem();
}
void QDeclarativeDesignView::mouseDoubleClickEvent(QMouseEvent *event)
{
if (!designModeBehavior()) {
QDeclarativeView::mouseDoubleClickEvent(event);
return;
}
QGraphicsItem *itemToEnter = 0;
QList<QGraphicsItem*> itemList = selectableItems(event->pos());
if (selectedItems().isEmpty() && !itemList.isEmpty()) {
itemToEnter = itemList.first();
} else if (!selectedItems().isEmpty() && !itemList.isEmpty()) {
itemToEnter = itemList.first();
}
m_subcomponentEditorTool->setCurrentItem(itemToEnter);
m_subcomponentEditorTool->mouseDoubleClickEvent(event);
if ((event->buttons() & Qt::LeftButton) && itemToEnter) {
QGraphicsObject *objectToEnter = itemToEnter->toGraphicsObject();
if (objectToEnter)
qmlDesignDebugServer()->setCurrentObjects(QList<QObject*>() << objectToEnter);
}
}
void QDeclarativeDesignView::wheelEvent(QWheelEvent *event)
{
if (!m_designModeBehavior) {
QDeclarativeView::wheelEvent(event);
return;
}
m_currentTool->wheelEvent(event);
}
void QDeclarativeDesignView::setDesignModeBehavior(bool value)
{
m_designModeBehavior = value;
if (m_subcomponentEditorTool) {
m_subcomponentEditorTool->clear();
clearHighlightBoundingRect();
if (rootObject())
m_subcomponentEditorTool->pushContext(rootObject());
}
}
bool QDeclarativeDesignView::designModeBehavior() const
{
return m_designModeBehavior;
}
void QDeclarativeDesignView::changeTool(Constants::DesignTool tool, Constants::ToolFlags /*flags*/)
{
switch(tool) {
case Constants::SelectionToolMode:
changeToSingleSelectTool();
break;
case Constants::NoTool:
default:
m_currentTool = 0;
break;
}
}
void QDeclarativeDesignView::setSelectedItems(QList<QGraphicsItem *> items)
{
m_currentSelection = items;
m_currentTool->setItems(items);
}
QList<QGraphicsItem *> QDeclarativeDesignView::selectedItems() const
{
return m_currentSelection;
}
AbstractFormEditorTool *QDeclarativeDesignView::currentTool() const
{
return m_currentTool;
}
void QDeclarativeDesignView::clearHighlightBoundingRect()
{
m_boundingRectHighlighter->clear();
}
void QDeclarativeDesignView::highlightBoundingRect(QGraphicsItem *item)
{
if (!item)
return;
m_boundingRectHighlighter->highlight(item->toGraphicsObject());
}
bool QDeclarativeDesignView::mouseInsideContextItem() const
{
return m_subcomponentEditorTool->containsCursor(m_cursorPos.toPoint());
}
QList<QGraphicsItem*> QDeclarativeDesignView::selectableItems(const QPointF &scenePos) const
{
QList<QGraphicsItem*> itemlist = scene()->items(scenePos);
return filteredItemList(itemlist);
}
QList<QGraphicsItem*> QDeclarativeDesignView::selectableItems(const QPoint &pos) const
{
QList<QGraphicsItem*> itemlist = items(pos);
return filteredItemList(itemlist);
}
QList<QGraphicsItem*> QDeclarativeDesignView::selectableItems(const QRectF &sceneRect, Qt::ItemSelectionMode selectionMode) const
{
QList<QGraphicsItem*> itemlist = scene()->items(sceneRect, selectionMode);
return filteredItemList(itemlist);
}
void QDeclarativeDesignView::changeToSingleSelectTool()
{
//qDebug() << "changing to selection tool";
m_currentToolMode = Constants::SelectionToolMode;
m_selectionTool->setRubberbandSelectionMode(false);
changeToSelectTool();
emit selectToolActivated();
qmlDesignDebugServer()->setCurrentTool(Constants::SelectionToolMode);
}
void QDeclarativeDesignView::changeToSelectTool()
{
if (m_currentTool == m_selectionTool)
return;
m_currentTool->clear();
m_currentTool = m_selectionTool;
m_currentTool->clear();
m_currentTool->setItems(m_currentSelection);
}
void QDeclarativeDesignView::changeToMarqueeSelectTool()
{
qDebug() << "changed to marquee select tool";
changeToSelectTool();
m_currentToolMode = Constants::MarqueeSelectionToolMode;
m_selectionTool->setRubberbandSelectionMode(true);
emit marqueeSelectToolActivated();
qmlDesignDebugServer()->setCurrentTool(Constants::MarqueeSelectionToolMode);
}
void QDeclarativeDesignView::changeToZoomTool()
{
m_currentToolMode = Constants::ZoomMode;
qDebug() << "changed to zoom tool";
m_currentTool->clear();
m_currentTool = m_zoomTool;
m_currentTool->clear();
emit zoomToolActivated();
qmlDesignDebugServer()->setCurrentTool(Constants::ZoomMode);
}
void QDeclarativeDesignView::changeToColorPickerTool()
{
if (m_currentTool == m_colorPickerTool)
return;
m_currentToolMode = Constants::ColorPickerMode;
m_currentTool->clear();
m_currentTool = m_colorPickerTool;
m_currentTool->clear();
emit colorPickerActivated();
qmlDesignDebugServer()->setCurrentTool(Constants::ColorPickerMode);
}
void QDeclarativeDesignView::changeAnimationSpeed(qreal slowdownFactor)
{
m_slowdownFactor = slowdownFactor;
if (m_slowdownFactor != 0) {
continueExecution(m_slowdownFactor);
} else {
pauseExecution();
}
}
void QDeclarativeDesignView::continueExecution(qreal slowdownFactor)
{
Q_ASSERT(slowdownFactor > 0);
m_slowdownFactor = slowdownFactor;
QUnifiedTimer *timer = QUnifiedTimer::instance();
timer->setSlowdownFactor(m_slowdownFactor);
timer->setSlowModeEnabled(false);
m_executionPaused = false;
emit executionStarted(m_slowdownFactor);
qmlDesignDebugServer()->setAnimationSpeed(m_slowdownFactor);
}
void QDeclarativeDesignView::pauseExecution()
{
QUnifiedTimer *timer = QUnifiedTimer::instance();
m_slowdownFactor = 0;
timer->setSlowdownFactor(m_slowdownFactor);
timer->setSlowModeEnabled(true);
m_executionPaused = true;
emit executionPaused();
qmlDesignDebugServer()->setAnimationSpeed(m_slowdownFactor);
}
void QDeclarativeDesignView::applyChangesFromClient()
{
}
LayerItem *QDeclarativeDesignView::manipulatorLayer() const
{
return m_manipulatorLayer;
}
QList<QGraphicsItem*> QDeclarativeDesignView::filteredItemList(QList<QGraphicsItem*> &itemlist) const
{
foreach(QGraphicsItem *item, itemlist) {
if (item->type() == Constants::EditorItemType
|| item->type() == Constants::ResizeHandleItemType
|| !m_subcomponentEditorTool->isDirectChildOfContext(item))
{
itemlist.removeOne(item);
}
}
return itemlist;
}
void QDeclarativeDesignView::onStatusChanged(QDeclarativeView::Status status)
{
if (status == QDeclarativeView::Ready) {
if (rootObject()) {
m_subcomponentEditorTool->pushContext(rootObject());
emit executionStarted(1.0f);
}
}
}
void QDeclarativeDesignView::onCurrentObjectsChanged(QList<QObject*> objects)
{
QList<QGraphicsItem*> items;
foreach(QObject *obj, objects) {
QDeclarativeItem* declarativeItem = qobject_cast<QDeclarativeItem*>(obj);
if (declarativeItem)
items << declarativeItem;
}
setSelectedItems(items);
clearHighlightBoundingRect();
if (!items.isEmpty())
highlightBoundingRect(items.first());
}
QToolBar *QDeclarativeDesignView::toolbar() const
{
return m_toolbar;
}
void QDeclarativeDesignView::createToolbar()
{
m_toolbar = new QmlToolbar(this);
connect(this, SIGNAL(selectedColorChanged(QColor)), m_toolbar, SLOT(setColorBoxColor(QColor)));
connect(m_toolbar, SIGNAL(executionStarted()), this, SLOT(continueExecution()));
connect(m_toolbar, SIGNAL(executionPaused()), this, SLOT(pauseExecution()));
connect(m_toolbar, SIGNAL(colorPickerSelected()), this, SLOT(changeToColorPickerTool()));
connect(m_toolbar, SIGNAL(zoomToolSelected()), this, SLOT(changeToZoomTool()));
connect(m_toolbar, SIGNAL(selectToolSelected()), this, SLOT(changeToSingleSelectTool()));
connect(m_toolbar, SIGNAL(marqueeSelectToolSelected()), this, SLOT(changeToMarqueeSelectTool()));
connect(m_toolbar, SIGNAL(applyChangesFromQmlFileSelected()), SLOT(applyChangesFromClient()));
connect(this, SIGNAL(executionStarted(qreal)), m_toolbar, SLOT(startExecution()));
connect(this, SIGNAL(executionPaused()), m_toolbar, SLOT(pauseExecution()));
connect(this, SIGNAL(selectToolActivated()), m_toolbar, SLOT(activateSelectTool()));
// disabled features
//connect(m_toolbar, SIGNAL(applyChangesToQmlFileSelected()), SLOT(applyChangesToClient()));
//connect(this, SIGNAL(resizeToolActivated()), m_toolbar, SLOT(activateSelectTool()));
//connect(this, SIGNAL(moveToolActivated()), m_toolbar, SLOT(activateSelectTool()));
connect(this, SIGNAL(colorPickerActivated()), m_toolbar, SLOT(activateColorPicker()));
connect(this, SIGNAL(zoomToolActivated()), m_toolbar, SLOT(activateZoom()));
connect(this, SIGNAL(marqueeSelectToolActivated()), m_toolbar, SLOT(activateMarqueeSelectTool()));
}
} //namespace QmlViewer

View File

@@ -0,0 +1,118 @@
#ifndef QDECLARATIVEDESIGNVIEW_H
#define QDECLARATIVEDESIGNVIEW_H
#include "qmlviewerconstants.h"
#include <qdeclarativeview.h>
QT_FORWARD_DECLARE_CLASS(QDeclarativeItem);
QT_FORWARD_DECLARE_CLASS(QMouseEvent);
QT_FORWARD_DECLARE_CLASS(QToolBar);
namespace QmlViewer {
class AbstractFormEditorTool;
class SelectionTool;
class ZoomTool;
class ColorPickerTool;
class LayerItem;
class BoundingRectHighlighter;
class SubcomponentEditorTool;
class QmlToolbar;
class QDeclarativeDesignView : public QDeclarativeView
{
Q_OBJECT
public:
explicit QDeclarativeDesignView(QWidget *parent = 0);
~QDeclarativeDesignView();
void setSelectedItems(QList<QGraphicsItem *> items);
QList<QGraphicsItem *> selectedItems() const;
AbstractFormEditorTool *currentTool() const;
LayerItem *manipulatorLayer() const;
void changeTool(Constants::DesignTool tool,
Constants::ToolFlags flags = Constants::NoToolFlags);
void clearHighlightBoundingRect();
void highlightBoundingRect(QGraphicsItem *item);
bool mouseInsideContextItem() const;
QList<QGraphicsItem*> selectableItems(const QPoint &pos) const;
QList<QGraphicsItem*> selectableItems(const QPointF &scenePos) const;
QList<QGraphicsItem*> selectableItems(const QRectF &sceneRect, Qt::ItemSelectionMode selectionMode) const;
QGraphicsItem *currentRootItem() const;
QToolBar *toolbar() const;
public Q_SLOTS:
void setDesignModeBehavior(bool value);
bool designModeBehavior() const;
void changeToSingleSelectTool();
void changeToMarqueeSelectTool();
void changeToZoomTool();
void changeToColorPickerTool();
void changeAnimationSpeed(qreal slowdownFactor);
void continueExecution(qreal slowdownFactor = 1.0f);
void pauseExecution();
Q_SIGNALS:
void designModeBehaviorChanged(bool inDesignMode);
void reloadRequested();
void marqueeSelectToolActivated();
void selectToolActivated();
void zoomToolActivated();
void colorPickerActivated();
void selectedColorChanged(const QColor &color);
void executionStarted(qreal slowdownFactor);
void executionPaused();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *keyEvent);
void mouseDoubleClickEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
private Q_SLOTS:
void reloadView();
void onStatusChanged(QDeclarativeView::Status status);
void onCurrentObjectsChanged(QList<QObject*> objects);
void applyChangesFromClient();
private:
void createToolbar();
void changeToSelectTool();
QList<QGraphicsItem*> filteredItemList(QList<QGraphicsItem*> &itemlist) const;
private:
QPointF m_cursorPos;
QList<QGraphicsItem *> m_currentSelection;
Constants::DesignTool m_currentToolMode;
AbstractFormEditorTool *m_currentTool;
SelectionTool *m_selectionTool;
ZoomTool *m_zoomTool;
ColorPickerTool *m_colorPickerTool;
SubcomponentEditorTool *m_subcomponentEditorTool;
LayerItem *m_manipulatorLayer;
BoundingRectHighlighter *m_boundingRectHighlighter;
bool m_designModeBehavior;
bool m_executionPaused;
qreal m_slowdownFactor;
QmlToolbar *m_toolbar;
};
} //namespace QmlViewer
#endif // QDECLARATIVEDESIGNVIEW_H

View File

@@ -0,0 +1,407 @@
/****************************************************************************
**
** 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 <qdeclarativetester.h>
#include <QDebug>
#include <QApplication>
#include <qdeclarativeview.h>
#include <QFile>
#include <QDeclarativeComponent>
#include <QDir>
#include <QCryptographicHash>
#include <private/qabstractanimation_p.h>
#include <private/qdeclarativeitem_p.h>
QT_BEGIN_NAMESPACE
QDeclarativeTester::QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions opts,
QDeclarativeView *parent)
: QAbstractAnimation(parent), m_script(script), m_view(parent), filterEvents(true), options(opts),
testscript(0), hasCompleted(false), hasFailed(false)
{
parent->viewport()->installEventFilter(this);
parent->installEventFilter(this);
QUnifiedTimer::instance()->setConsistentTiming(true);
if (options & QDeclarativeViewer::Play)
this->run();
start();
}
QDeclarativeTester::~QDeclarativeTester()
{
if (!hasFailed &&
options & QDeclarativeViewer::Record &&
options & QDeclarativeViewer::SaveOnExit)
save();
}
int QDeclarativeTester::duration() const
{
return -1;
}
void QDeclarativeTester::addMouseEvent(Destination dest, QMouseEvent *me)
{
MouseEvent e(me);
e.destination = dest;
m_mouseEvents << e;
}
void QDeclarativeTester::addKeyEvent(Destination dest, QKeyEvent *ke)
{
KeyEvent e(ke);
e.destination = dest;
m_keyEvents << e;
}
bool QDeclarativeTester::eventFilter(QObject *o, QEvent *e)
{
if (!filterEvents)
return false;
Destination destination;
if (o == m_view) {
destination = View;
} else if (o == m_view->viewport()) {
destination = ViewPort;
} else {
return false;
}
switch (e->type()) {
case QEvent::KeyPress:
case QEvent::KeyRelease:
addKeyEvent(destination, (QKeyEvent *)e);
return true;
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseMove:
case QEvent::MouseButtonDblClick:
addMouseEvent(destination, (QMouseEvent *)e);
return true;
default:
break;
}
return false;
}
void QDeclarativeTester::executefailure()
{
hasFailed = true;
if (options & QDeclarativeViewer::ExitOnFailure)
exit(-1);
}
void QDeclarativeTester::imagefailure()
{
hasFailed = true;
if (options & QDeclarativeViewer::ExitOnFailure)
exit(-1);
}
void QDeclarativeTester::complete()
{
if ((options & QDeclarativeViewer::TestErrorProperty) && !hasFailed) {
QString e = m_view->rootObject()->property("error").toString();
if (!e.isEmpty()) {
qWarning() << "Test failed:" << e;
hasFailed = true;
}
}
if (options & QDeclarativeViewer::ExitOnComplete)
QApplication::exit(hasFailed?-1:0);
if (hasCompleted)
return;
hasCompleted = true;
if (options & QDeclarativeViewer::Play)
qWarning("Script playback complete");
}
void QDeclarativeTester::run()
{
QDeclarativeComponent c(m_view->engine(), m_script + QLatin1String(".qml"));
testscript = qobject_cast<QDeclarativeVisualTest *>(c.create());
if (testscript) testscript->setParent(this);
else { executefailure(); exit(-1); }
testscriptidx = 0;
}
void QDeclarativeTester::save()
{
QString filename = m_script + QLatin1String(".qml");
QFileInfo filenameInfo(filename);
QDir saveDir = filenameInfo.absoluteDir();
saveDir.mkpath(".");
QFile file(filename);
file.open(QIODevice::WriteOnly);
QTextStream ts(&file);
ts << "import Qt.VisualTest 4.7\n\n";
ts << "VisualTest {\n";
int imgCount = 0;
QList<KeyEvent> keyevents = m_savedKeyEvents;
QList<MouseEvent> mouseevents = m_savedMouseEvents;
for (int ii = 0; ii < m_savedFrameEvents.count(); ++ii) {
const FrameEvent &fe = m_savedFrameEvents.at(ii);
ts << " Frame {\n";
ts << " msec: " << fe.msec << "\n";
if (!fe.hash.isEmpty()) {
ts << " hash: \"" << fe.hash.toHex() << "\"\n";
} else if (!fe.image.isNull()) {
QString filename = filenameInfo.baseName() + "." + QString::number(imgCount) + ".png";
fe.image.save(m_script + "." + QString::number(imgCount) + ".png");
imgCount++;
ts << " image: \"" << filename << "\"\n";
}
ts << " }\n";
while (!mouseevents.isEmpty() &&
mouseevents.first().msec == fe.msec) {
MouseEvent me = mouseevents.takeFirst();
ts << " Mouse {\n";
ts << " type: " << me.type << "\n";
ts << " button: " << me.button << "\n";
ts << " buttons: " << me.buttons << "\n";
ts << " x: " << me.pos.x() << "; y: " << me.pos.y() << "\n";
ts << " modifiers: " << me.modifiers << "\n";
if (me.destination == ViewPort)
ts << " sendToViewport: true\n";
ts << " }\n";
}
while (!keyevents.isEmpty() &&
keyevents.first().msec == fe.msec) {
KeyEvent ke = keyevents.takeFirst();
ts << " Key {\n";
ts << " type: " << ke.type << "\n";
ts << " key: " << ke.key << "\n";
ts << " modifiers: " << ke.modifiers << "\n";
ts << " text: \"" << ke.text.toUtf8().toHex() << "\"\n";
ts << " autorep: " << (ke.autorep?"true":"false") << "\n";
ts << " count: " << ke.count << "\n";
if (ke.destination == ViewPort)
ts << " sendToViewport: true\n";
ts << " }\n";
}
}
ts << "}\n";
file.close();
}
void QDeclarativeTester::updateCurrentTime(int msec)
{
QDeclarativeItemPrivate::setConsistentTime(msec);
if (!testscript && msec > 16 && options & QDeclarativeViewer::Snapshot)
return;
QImage img(m_view->width(), m_view->height(), QImage::Format_RGB32);
if (options & QDeclarativeViewer::TestImages) {
img.fill(qRgb(255,255,255));
QPainter p(&img);
m_view->render(&p);
}
bool snapshot = msec == 16 && (options & QDeclarativeViewer::Snapshot
|| (testscript && testscript->count() == 2));
FrameEvent fe;
fe.msec = msec;
if (msec == 0 || !(options & QDeclarativeViewer::TestImages)) {
// Skip first frame, skip if not doing images
} else if (0 == (m_savedFrameEvents.count() % 60) || snapshot) {
fe.image = img;
} else {
QCryptographicHash hash(QCryptographicHash::Md5);
hash.addData((const char *)img.bits(), img.bytesPerLine() * img.height());
fe.hash = hash.result();
}
m_savedFrameEvents.append(fe);
// Deliver mouse events
filterEvents = false;
if (!testscript) {
for (int ii = 0; ii < m_mouseEvents.count(); ++ii) {
MouseEvent &me = m_mouseEvents[ii];
me.msec = msec;
QMouseEvent event(me.type, me.pos, me.button, me.buttons, me.modifiers);
if (me.destination == View) {
QCoreApplication::sendEvent(m_view, &event);
} else {
QCoreApplication::sendEvent(m_view->viewport(), &event);
}
}
for (int ii = 0; ii < m_keyEvents.count(); ++ii) {
KeyEvent &ke = m_keyEvents[ii];
ke.msec = msec;
QKeyEvent event(ke.type, ke.key, ke.modifiers, ke.text, ke.autorep, ke.count);
if (ke.destination == View) {
QCoreApplication::sendEvent(m_view, &event);
} else {
QCoreApplication::sendEvent(m_view->viewport(), &event);
}
}
m_savedMouseEvents.append(m_mouseEvents);
m_savedKeyEvents.append(m_keyEvents);
}
m_mouseEvents.clear();
m_keyEvents.clear();
// Advance test script
while (testscript && testscript->count() > testscriptidx) {
QObject *event = testscript->event(testscriptidx);
if (QDeclarativeVisualTestFrame *frame = qobject_cast<QDeclarativeVisualTestFrame *>(event)) {
if (frame->msec() < msec) {
if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record)) {
qWarning() << "QDeclarativeTester: Extra frame. Seen:"
<< msec << "Expected:" << frame->msec();
imagefailure();
}
} else if (frame->msec() == msec) {
if (!frame->hash().isEmpty() && frame->hash().toUtf8() != fe.hash.toHex()) {
if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record)) {
qWarning() << "QDeclarativeTester: Mismatched frame hash at" << msec
<< ". Seen:" << fe.hash.toHex()
<< "Expected:" << frame->hash().toUtf8();
imagefailure();
}
}
} else if (frame->msec() > msec) {
break;
}
if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record) && !frame->image().isEmpty()) {
QImage goodImage(frame->image().toLocalFile());
if (goodImage != img) {
QString reject(frame->image().toLocalFile() + ".reject.png");
qWarning() << "QDeclarativeTester: Image mismatch. Reject saved to:"
<< reject;
img.save(reject);
bool doDiff = (goodImage.size() == img.size());
if (doDiff) {
QImage diffimg(m_view->width(), m_view->height(), QImage::Format_RGB32);
diffimg.fill(qRgb(255,255,255));
QPainter p(&diffimg);
int diffCount = 0;
for (int x = 0; x < img.width(); ++x) {
for (int y = 0; y < img.height(); ++y) {
if (goodImage.pixel(x,y) != img.pixel(x,y)) {
++diffCount;
p.drawPoint(x,y);
}
}
}
QString diff(frame->image().toLocalFile() + ".diff.png");
diffimg.save(diff);
qWarning().nospace() << " Diff (" << diffCount << " pixels differed) saved to: " << diff;
}
imagefailure();
}
}
} else if (QDeclarativeVisualTestMouse *mouse = qobject_cast<QDeclarativeVisualTestMouse *>(event)) {
QPoint pos(mouse->x(), mouse->y());
QPoint globalPos = m_view->mapToGlobal(QPoint(0, 0)) + pos;
QMouseEvent event((QEvent::Type)mouse->type(), pos, globalPos, (Qt::MouseButton)mouse->button(), (Qt::MouseButtons)mouse->buttons(), (Qt::KeyboardModifiers)mouse->modifiers());
MouseEvent me(&event);
me.msec = msec;
if (!mouse->sendToViewport()) {
QCoreApplication::sendEvent(m_view, &event);
me.destination = View;
} else {
QCoreApplication::sendEvent(m_view->viewport(), &event);
me.destination = ViewPort;
}
m_savedMouseEvents.append(me);
} else if (QDeclarativeVisualTestKey *key = qobject_cast<QDeclarativeVisualTestKey *>(event)) {
QKeyEvent event((QEvent::Type)key->type(), key->key(), (Qt::KeyboardModifiers)key->modifiers(), QString::fromUtf8(QByteArray::fromHex(key->text().toUtf8())), key->autorep(), key->count());
KeyEvent ke(&event);
ke.msec = msec;
if (!key->sendToViewport()) {
QCoreApplication::sendEvent(m_view, &event);
ke.destination = View;
} else {
QCoreApplication::sendEvent(m_view->viewport(), &event);
ke.destination = ViewPort;
}
m_savedKeyEvents.append(ke);
}
testscriptidx++;
}
filterEvents = true;
if (testscript && testscript->count() <= testscriptidx) {
//if (msec == 16) //for a snapshot, leave it up long enough to see
// (void)::sleep(1);
complete();
}
}
void QDeclarativeTester::registerTypes()
{
qmlRegisterType<QDeclarativeVisualTest>("Qt.VisualTest", 4,7, "VisualTest");
qmlRegisterType<QDeclarativeVisualTestFrame>("Qt.VisualTest", 4,7, "Frame");
qmlRegisterType<QDeclarativeVisualTestMouse>("Qt.VisualTest", 4,7, "Mouse");
qmlRegisterType<QDeclarativeVisualTestKey>("Qt.VisualTest", 4,7, "Key");
}
QT_END_NAMESPACE

View File

@@ -0,0 +1,289 @@
/****************************************************************************
**
** 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 QDECLARATIVETESTER_H
#define QDECLARATIVETESTER_H
#include <QEvent>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QImage>
#include <QUrl>
#include <qmlruntime.h>
#include <qdeclarativelist.h>
#include <qdeclarative.h>
#include <QAbstractAnimation>
QT_BEGIN_NAMESPACE
class QDeclarativeVisualTest : public QObject
{
Q_OBJECT
Q_PROPERTY(QDeclarativeListProperty<QObject> events READ events CONSTANT)
Q_CLASSINFO("DefaultProperty", "events")
public:
QDeclarativeVisualTest() {}
QDeclarativeListProperty<QObject> events() { return QDeclarativeListProperty<QObject>(this, m_events); }
int count() const { return m_events.count(); }
QObject *event(int idx) { return m_events.at(idx); }
private:
QList<QObject *> m_events;
};
QT_END_NAMESPACE
QML_DECLARE_TYPE(QDeclarativeVisualTest)
QT_BEGIN_NAMESPACE
class QDeclarativeVisualTestFrame : public QObject
{
Q_OBJECT
Q_PROPERTY(int msec READ msec WRITE setMsec)
Q_PROPERTY(QString hash READ hash WRITE setHash)
Q_PROPERTY(QUrl image READ image WRITE setImage)
public:
QDeclarativeVisualTestFrame() : m_msec(-1) {}
int msec() const { return m_msec; }
void setMsec(int m) { m_msec = m; }
QString hash() const { return m_hash; }
void setHash(const QString &hash) { m_hash = hash; }
QUrl image() const { return m_image; }
void setImage(const QUrl &image) { m_image = image; }
private:
int m_msec;
QString m_hash;
QUrl m_image;
};
QT_END_NAMESPACE
QML_DECLARE_TYPE(QDeclarativeVisualTestFrame)
QT_BEGIN_NAMESPACE
class QDeclarativeVisualTestMouse : public QObject
{
Q_OBJECT
Q_PROPERTY(int type READ type WRITE setType)
Q_PROPERTY(int button READ button WRITE setButton)
Q_PROPERTY(int buttons READ buttons WRITE setButtons)
Q_PROPERTY(int x READ x WRITE setX)
Q_PROPERTY(int y READ y WRITE setY)
Q_PROPERTY(int modifiers READ modifiers WRITE setModifiers)
Q_PROPERTY(bool sendToViewport READ sendToViewport WRITE setSendToViewport)
public:
QDeclarativeVisualTestMouse() : m_type(0), m_button(0), m_buttons(0), m_x(0), m_y(0), m_modifiers(0), m_viewport(false) {}
int type() const { return m_type; }
void setType(int t) { m_type = t; }
int button() const { return m_button; }
void setButton(int b) { m_button = b; }
int buttons() const { return m_buttons; }
void setButtons(int b) { m_buttons = b; }
int x() const { return m_x; }
void setX(int x) { m_x = x; }
int y() const { return m_y; }
void setY(int y) { m_y = y; }
int modifiers() const { return m_modifiers; }
void setModifiers(int modifiers) { m_modifiers = modifiers; }
bool sendToViewport() const { return m_viewport; }
void setSendToViewport(bool v) { m_viewport = v; }
private:
int m_type;
int m_button;
int m_buttons;
int m_x;
int m_y;
int m_modifiers;
bool m_viewport;
};
QT_END_NAMESPACE
QML_DECLARE_TYPE(QDeclarativeVisualTestMouse)
QT_BEGIN_NAMESPACE
class QDeclarativeVisualTestKey : public QObject
{
Q_OBJECT
Q_PROPERTY(int type READ type WRITE setType)
Q_PROPERTY(int key READ key WRITE setKey)
Q_PROPERTY(int modifiers READ modifiers WRITE setModifiers)
Q_PROPERTY(QString text READ text WRITE setText)
Q_PROPERTY(bool autorep READ autorep WRITE setAutorep)
Q_PROPERTY(int count READ count WRITE setCount)
Q_PROPERTY(bool sendToViewport READ sendToViewport WRITE setSendToViewport)
public:
QDeclarativeVisualTestKey() : m_type(0), m_key(0), m_modifiers(0), m_autorep(false), m_count(0), m_viewport(false) {}
int type() const { return m_type; }
void setType(int t) { m_type = t; }
int key() const { return m_key; }
void setKey(int k) { m_key = k; }
int modifiers() const { return m_modifiers; }
void setModifiers(int m) { m_modifiers = m; }
QString text() const { return m_text; }
void setText(const QString &t) { m_text = t; }
bool autorep() const { return m_autorep; }
void setAutorep(bool a) { m_autorep = a; }
int count() const { return m_count; }
void setCount(int c) { m_count = c; }
bool sendToViewport() const { return m_viewport; }
void setSendToViewport(bool v) { m_viewport = v; }
private:
int m_type;
int m_key;
int m_modifiers;
QString m_text;
bool m_autorep;
int m_count;
bool m_viewport;
};
QT_END_NAMESPACE
QML_DECLARE_TYPE(QDeclarativeVisualTestKey)
QT_BEGIN_NAMESPACE
class QDeclarativeTester : public QAbstractAnimation
{
public:
QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions options, QDeclarativeView *parent);
~QDeclarativeTester();
static void registerTypes();
virtual int duration() const;
void run();
void save();
void executefailure();
protected:
virtual void updateCurrentTime(int msecs);
virtual bool eventFilter(QObject *, QEvent *);
private:
QString m_script;
void imagefailure();
void complete();
enum Destination { View, ViewPort };
void addKeyEvent(Destination, QKeyEvent *);
void addMouseEvent(Destination, QMouseEvent *);
QDeclarativeView *m_view;
struct MouseEvent {
MouseEvent(QMouseEvent *e)
: type(e->type()), button(e->button()), buttons(e->buttons()),
pos(e->pos()), modifiers(e->modifiers()), destination(View) {}
QEvent::Type type;
Qt::MouseButton button;
Qt::MouseButtons buttons;
QPoint pos;
Qt::KeyboardModifiers modifiers;
Destination destination;
int msec;
};
struct KeyEvent {
KeyEvent(QKeyEvent *e)
: type(e->type()), key(e->key()), modifiers(e->modifiers()), text(e->text()),
autorep(e->isAutoRepeat()), count(e->count()), destination(View) {}
QEvent::Type type;
int key;
Qt::KeyboardModifiers modifiers;
QString text;
bool autorep;
ushort count;
Destination destination;
int msec;
};
struct FrameEvent {
QImage image;
QByteArray hash;
int msec;
};
QList<MouseEvent> m_mouseEvents;
QList<KeyEvent> m_keyEvents;
QList<MouseEvent> m_savedMouseEvents;
QList<KeyEvent> m_savedKeyEvents;
QList<FrameEvent> m_savedFrameEvents;
bool filterEvents;
QDeclarativeViewer::ScriptOptions options;
int testscriptidx;
QDeclarativeVisualTest *testscript;
bool hasCompleted;
bool hasFailed;
};
QT_END_NAMESPACE
#endif // QDECLARATIVETESTER_H

Binary file not shown.

View File

@@ -0,0 +1,38 @@
QT += declarative script network sql
contains(QT_CONFIG, opengl) {
QT += opengl
DEFINES += GL_SUPPORTED
}
include($$PWD/editor/editor.pri)
INCLUDEPATH += $$PWD
HEADERS += $$PWD/qmlruntime.h \
$$PWD/proxysettings.h \
$$PWD/qdeclarativetester.h \
$$PWD/deviceorientation.h \
$$PWD/loggerwidget.h \
$$PWD/qdeclarativedesigndebugserver.h \
$$PWD/qdeclarativedesignview.h
SOURCES += $$PWD/qmlruntime.cpp \
$$PWD/proxysettings.cpp \
$$PWD/qdeclarativetester.cpp \
$$PWD/loggerwidget.cpp \
$$PWD/qdeclarativedesigndebugserver.cpp \
$$PWD/qdeclarativedesignview.cpp
RESOURCES += $$PWD/qmlruntime.qrc
maemo5 {
QT += dbus
HEADERS += $$PWD/texteditautoresizer_maemo5.h
SOURCES += $$PWD/deviceorientation_maemo5.cpp
FORMS += $$PWD/recopts_maemo5.ui \
$$PWD/proxysettings_maemo5.ui
} else {
SOURCES += $$PWD/deviceorientation.cpp
FORMS += $$PWD/recopts.ui \
$$PWD/proxysettings.ui
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,210 @@
/****************************************************************************
**
** 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 QDECLARATIVEVIEWER_H
#define QDECLARATIVEVIEWER_H
#include <QMainWindow>
#include <QTimer>
#include <QTime>
#include <QList>
#include "loggerwidget.h"
namespace QmlViewer {
class QDeclarativeDesignView;
}
QT_BEGIN_NAMESPACE
class QDeclarativeView;
class PreviewDeviceSkin;
class QDeclarativeTestEngine;
class QProcess;
class RecordingDialog;
class QDeclarativeTester;
class QNetworkReply;
class QNetworkCookieJar;
class NetworkAccessManagerFactory;
class QTranslator;
class QActionGroup;
class QMenuBar;
class QDeclarativeViewer
: public QMainWindow
{
Q_OBJECT
public:
QDeclarativeViewer(QWidget *parent = 0, Qt::WindowFlags flags = 0);
~QDeclarativeViewer();
static void registerTypes();
enum ScriptOption {
Play = 0x00000001,
Record = 0x00000002,
TestImages = 0x00000004,
TestErrorProperty = 0x00000008,
SaveOnExit = 0x00000010,
ExitOnComplete = 0x00000020,
ExitOnFailure = 0x00000040,
Snapshot = 0x00000080
};
Q_DECLARE_FLAGS(ScriptOptions, ScriptOption)
void setScript(const QString &s) { m_script = s; }
void setScriptOptions(ScriptOptions opt) { m_scriptOptions = opt; }
void setRecordDither(const QString& s) { record_dither = s; }
void setRecordRate(int fps);
void setRecordFile(const QString&);
void setRecordArgs(const QStringList&);
void setRecording(bool on);
bool isRecording() const { return recordTimer.isActive(); }
void setAutoRecord(int from, int to);
void setDeviceKeys(bool);
void setNetworkCacheSize(int size);
void addLibraryPath(const QString& lib);
void addPluginPath(const QString& plugin);
void setUseGL(bool use);
void setUseNativeFileBrowser(bool);
void setSizeToView(bool sizeToView);
QDeclarativeView *view() const;
LoggerWidget *warningsWidget() const;
void enableExperimentalGestures();
public slots:
void setDesignModeBehavior(bool value);
void sceneResized(QSize size);
bool open(const QString&);
void openFile();
void reload();
void takeSnapShot();
void toggleRecording();
void toggleRecordingWithSelection();
void ffmpegFinished(int code);
void showProxySettings ();
void proxySettingsChanged ();
void rotateOrientation();
void statusChanged();
void setSlowMode(bool);
void launch(const QString &);
protected:
virtual void keyPressEvent(QKeyEvent *);
virtual bool event(QEvent *);
void createMenu();
private slots:
void appAboutToQuit();
void autoStartRecording();
void autoStopRecording();
void recordFrame();
void chooseRecordingOptions();
void pickRecordingFile();
void toggleFullScreen();
void changeOrientation(QAction*);
void orientationChanged();
void showWarnings(bool show);
void warningsWidgetOpened();
void warningsWidgetClosed();
void updateSizeHints();
private:
QString getVideoFileName();
LoggerWidget *loggerWindow;
QmlViewer::QDeclarativeDesignView *canvas;
QSize initialSize;
QString currentFileOrUrl;
QTimer recordTimer;
QString frame_fmt;
QImage frame;
QList<QImage*> frames;
QProcess* frame_stream;
QTimer autoStartTimer;
QTimer autoStopTimer;
QString record_dither;
QString record_file;
QSize record_outsize;
QStringList record_args;
int record_rate;
int record_autotime;
bool devicemode;
QAction *recordAction;
QString currentSkin;
bool scaleSkin;
RecordingDialog *recdlg;
void senseImageMagick();
void senseFfmpeg();
QWidget *ffmpegHelpWindow;
bool ffmpegAvailable;
bool convertAvailable;
QActionGroup *orientation;
QAction *showWarningsWindow;
QAction *designModeBehaviorAction;
QString m_script;
ScriptOptions m_scriptOptions;
QDeclarativeTester *tester;
QNetworkReply *wgtreply;
QString wgtdir;
NetworkAccessManagerFactory *namFactory;
bool useQmlFileBrowser;
QTranslator *translator;
void loadTranslationFile(const QString& directory);
void loadDummyDataFiles(const QString& directory);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeViewer::ScriptOptions)
QT_END_NAMESPACE
#endif

View File

@@ -0,0 +1,9 @@
<RCC>
<qresource prefix="/" >
<file>content/Browser.qml</file>
<file>content/images/up.png</file>
<file>content/images/folder.png</file>
<file>content/images/titlebar.sci</file>
<file>content/images/titlebar.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,18 @@
TEMPLATE = app
QT += declarative
include(qml.pri)
SOURCES += main.cpp
include(../../../../qtcreator.pri)
include(../../../private_headers.pri)
DESTDIR = $$IDE_BIN_PATH
include(../../../rpath.pri)
mac {
QMAKE_INFO_PLIST=Info_mac.plist
ICON=qml.icns
}
TARGET=qmlviewer

View File

@@ -0,0 +1,513 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RecordingOptions</class>
<widget class="QDialog" name="RecordingOptions">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>316</width>
<height>436</height>
</rect>
</property>
<property name="windowTitle">
<string>Video options</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>File:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="file"/>
</item>
<item>
<widget class="QToolButton" name="pickfile">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Size</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QRadioButton" name="sizeOriginal">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="sizeVGA">
<property name="text">
<string>VGA</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="size720p">
<property name="text">
<string>720p</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="sizeQVGA">
<property name="text">
<string>QVGA</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="sizeCustom">
<property name="text">
<string>Width:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sizeWidth">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Height:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sizeHeight">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="rateOptions">
<property name="title">
<string>Rate</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QRadioButton" name="hz60">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>60Hz</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="hz50">
<property name="text">
<string>50Hz</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QRadioButton" name="hz25">
<property name="text">
<string>25Hz</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="4">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QRadioButton" name="hzCustom">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="hz">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Hz</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="2">
<widget class="QRadioButton" name="hz24">
<property name="text">
<string>24Hz</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="ffmpegOptions">
<property name="title">
<string>Profile</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" colspan="3">
<widget class="QComboBox" name="profile"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLineEdit" name="args"/>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="ffmpegHelp">
<property name="text">
<string>Help</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="warning">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>file</tabstop>
<tabstop>pickfile</tabstop>
<tabstop>sizeOriginal</tabstop>
<tabstop>sizeVGA</tabstop>
<tabstop>size720p</tabstop>
<tabstop>sizeQVGA</tabstop>
<tabstop>sizeCustom</tabstop>
<tabstop>sizeWidth</tabstop>
<tabstop>sizeHeight</tabstop>
<tabstop>hz60</tabstop>
<tabstop>hz25</tabstop>
<tabstop>hz50</tabstop>
<tabstop>hz24</tabstop>
<tabstop>hzCustom</tabstop>
<tabstop>hz</tabstop>
<tabstop>profile</tabstop>
<tabstop>args</tabstop>
<tabstop>ffmpegHelp</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>hzCustom</sender>
<signal>clicked()</signal>
<receiver>hz</receiver>
<slot>setFocus()</slot>
<hints>
<hint type="sourcelabel">
<x>43</x>
<y>257</y>
</hint>
<hint type="destinationlabel">
<x>129</x>
<y>262</y>
</hint>
</hints>
</connection>
<connection>
<sender>hz</sender>
<signal>textChanged(QString)</signal>
<receiver>hzCustom</receiver>
<slot>toggle()</slot>
<hints>
<hint type="sourcelabel">
<x>143</x>
<y>262</y>
</hint>
<hint type="destinationlabel">
<x>43</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>hz</sender>
<signal>selectionChanged()</signal>
<receiver>hzCustom</receiver>
<slot>toggle()</slot>
<hints>
<hint type="sourcelabel">
<x>143</x>
<y>262</y>
</hint>
<hint type="destinationlabel">
<x>43</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>RecordingOptions</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>258</x>
<y>424</y>
</hint>
<hint type="destinationlabel">
<x>60</x>
<y>219</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>RecordingOptions</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>258</x>
<y>424</y>
</hint>
<hint type="destinationlabel">
<x>92</x>
<y>219</y>
</hint>
</hints>
</connection>
<connection>
<sender>profile</sender>
<signal>activated(int)</signal>
<receiver>RecordingOptions</receiver>
<slot>pickProfile(int)</slot>
<hints>
<hint type="sourcelabel">
<x>92</x>
<y>329</y>
</hint>
<hint type="destinationlabel">
<x>48</x>
<y>194</y>
</hint>
</hints>
</connection>
<connection>
<sender>args</sender>
<signal>textEdited(QString)</signal>
<receiver>RecordingOptions</receiver>
<slot>storeCustomArgs(QString)</slot>
<hints>
<hint type="sourcelabel">
<x>128</x>
<y>357</y>
</hint>
<hint type="destinationlabel">
<x>102</x>
<y>189</y>
</hint>
</hints>
</connection>
<connection>
<sender>sizeWidth</sender>
<signal>valueChanged(int)</signal>
<receiver>sizeCustom</receiver>
<slot>toggle()</slot>
<hints>
<hint type="sourcelabel">
<x>108</x>
<y>133</y>
</hint>
<hint type="destinationlabel">
<x>48</x>
<y>133</y>
</hint>
</hints>
</connection>
<connection>
<sender>sizeHeight</sender>
<signal>valueChanged(int)</signal>
<receiver>sizeCustom</receiver>
<slot>toggle()</slot>
<hints>
<hint type="sourcelabel">
<x>212</x>
<y>133</y>
</hint>
<hint type="destinationlabel">
<x>64</x>
<y>129</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<signal>filePicked(QString)</signal>
<signal>argumentsPicked(QString)</signal>
<slot>pickFile()</slot>
<slot>pickProfile(int)</slot>
<slot>storeCustomArgs(QString)</slot>
</slots>
</ui>

View File

@@ -0,0 +1,254 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RecordingOptions</class>
<widget class="QDialog" name="RecordingOptions">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>469</width>
<height>142</height>
</rect>
</property>
<property name="windowTitle">
<string>Video options</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,2,0">
<property name="sizeConstraint">
<enum>QLayout::SetMinAndMaxSize</enum>
</property>
<property name="leftMargin">
<number>16</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>16</number>
</property>
<property name="bottomMargin">
<number>8</number>
</property>
<property name="horizontalSpacing">
<number>16</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="QLineEdit" name="file"/>
</item>
<item row="0" column="2" rowspan="3">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>72</width>
<height>56</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="sizeCombo">
<item>
<property name="text">
<string/>
</property>
</item>
<item>
<property name="text">
<string>VGA</string>
</property>
</item>
<item>
<property name="text">
<string>QVGA</string>
</property>
</item>
<item>
<property name="text">
<string>720p</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0" rowspan="2">
<widget class="QLabel" name="rateLabel">
<property name="text">
<string>Rate</string>
</property>
</widget>
</item>
<item row="2" column="1" rowspan="2">
<widget class="QComboBox" name="rateCombo">
<item>
<property name="text">
<string>60 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>50 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>25 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>24 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>20 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>15 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>10 Hz</string>
</property>
</item>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="args"/>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="profile"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="profileLabel">
<property name="text">
<string>Profile</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QLabel" name="warning">
<property name="text">
<string notr="true">warning</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="2" rowspan="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="pickfile">
<property name="text">
<string>File</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QPushButton" name="ffmpegHelp">
<property name="text">
<string>Options</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>RecordingOptions</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>258</x>
<y>424</y>
</hint>
<hint type="destinationlabel">
<x>60</x>
<y>219</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>RecordingOptions</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>258</x>
<y>424</y>
</hint>
<hint type="destinationlabel">
<x>92</x>
<y>219</y>
</hint>
</hints>
</connection>
<connection>
<sender>profile</sender>
<signal>activated(int)</signal>
<receiver>RecordingOptions</receiver>
<slot>pickProfile(int)</slot>
<hints>
<hint type="sourcelabel">
<x>92</x>
<y>329</y>
</hint>
<hint type="destinationlabel">
<x>48</x>
<y>194</y>
</hint>
</hints>
</connection>
<connection>
<sender>args</sender>
<signal>textEdited(QString)</signal>
<receiver>RecordingOptions</receiver>
<slot>storeCustomArgs(QString)</slot>
<hints>
<hint type="sourcelabel">
<x>128</x>
<y>357</y>
</hint>
<hint type="destinationlabel">
<x>102</x>
<y>189</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<signal>filePicked(QString)</signal>
<signal>argumentsPicked(QString)</signal>
<slot>pickFile()</slot>
<slot>pickProfile(int)</slot>
<slot>storeCustomArgs(QString)</slot>
</slots>
</ui>

View File

@@ -0,0 +1,113 @@
/****************************************************************************
**
** 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 examples 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 <QtGui/qplaintextedit.h>
#include <QtGui/qtextedit.h>
#include <QtGui/qabstractkineticscroller.h>
#include <QtGui/qscrollarea.h>
#include <QtDebug>
#ifndef TEXTEDITAUTORESIZER_H
#define TEXTEDITAUTORESIZER_H
class TextEditAutoResizer : public QObject
{
Q_OBJECT
public:
TextEditAutoResizer(QWidget *parent)
: QObject(parent), plainTextEdit(qobject_cast<QPlainTextEdit *>(parent)),
textEdit(qobject_cast<QTextEdit *>(parent)), edit(qobject_cast<QFrame *>(parent))
{
// parent must either inherit QPlainTextEdit or QTextEdit!
Q_ASSERT(plainTextEdit || textEdit);
connect(parent, SIGNAL(textChanged()), this, SLOT(textEditChanged()));
connect(parent, SIGNAL(cursorPositionChanged()), this, SLOT(textEditChanged()));
textEditChanged();
}
private Q_SLOTS:
inline void textEditChanged();
private:
QPlainTextEdit *plainTextEdit;
QTextEdit *textEdit;
QFrame *edit;
};
void TextEditAutoResizer::textEditChanged()
{
QTextDocument *doc = textEdit ? textEdit->document() : plainTextEdit->document();
QRect cursor = textEdit ? textEdit->cursorRect() : plainTextEdit->cursorRect();
QSize s = doc->size().toSize();
if (plainTextEdit)
s.setHeight((s.height() + 2) * edit->fontMetrics().lineSpacing());
const QRect fr = edit->frameRect();
const QRect cr = edit->contentsRect();
edit->setMinimumHeight(qMax(70, s.height() + (fr.height() - cr.height() - 1)));
// make sure the cursor is visible in case we have a QAbstractScrollArea parent
QPoint pos = edit->pos();
QWidget *pw = edit->parentWidget();
while (pw) {
if (qobject_cast<QScrollArea *>(pw))
break;
pw = pw->parentWidget();
}
if (pw) {
QScrollArea *area = static_cast<QScrollArea *>(pw);
QPoint scrollto = area->widget()->mapFrom(edit, cursor.center());
QPoint margin(10 + cursor.width(), 2 * cursor.height());
if (QAbstractKineticScroller *scroller = area->property("kineticScroller").value<QAbstractKineticScroller *>()) {
scroller->ensureVisible(scrollto, margin.x(), margin.y());
} else {
area->ensureVisible(scrollto.x(), scrollto.y(), margin.x(), margin.y());
}
}
}
#endif