1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qdeclarativeviewinspector.h"
43 #include "qdeclarativeviewinspector_p.h"
45 #include "liveselectiontool.h"
47 #include "colorpickertool.h"
48 #include "livelayeritem.h"
49 #include "boundingrecthighlighter.h"
51 #include <QtQuick1/QDeclarativeItem>
52 #include <QtGui/QMouseEvent>
54 namespace QmlJSDebugger {
57 QDeclarativeViewInspectorPrivate::QDeclarativeViewInspectorPrivate(QDeclarativeViewInspector *q) :
62 QDeclarativeViewInspectorPrivate::~QDeclarativeViewInspectorPrivate()
66 QDeclarativeViewInspector::QDeclarativeViewInspector(QDeclarativeView *view,
68 AbstractViewInspector(parent),
69 data(new QDeclarativeViewInspectorPrivate(this))
72 data->manipulatorLayer = new LiveLayerItem(view->scene());
73 data->selectionTool = new LiveSelectionTool(this);
74 data->zoomTool = new ZoomTool(this);
75 data->colorPickerTool = new ColorPickerTool(this);
76 data->boundingRectHighlighter = new BoundingRectHighlighter(this);
77 setCurrentTool(data->selectionTool);
79 // to capture ChildRemoved event when viewport changes
80 data->view->installEventFilter(this);
82 data->setViewport(data->view->viewport());
84 connect(data->view, SIGNAL(statusChanged(QDeclarativeView::Status)),
85 data.data(), SLOT(_q_onStatusChanged(QDeclarativeView::Status)));
87 connect(data->colorPickerTool, SIGNAL(selectedColorChanged(QColor)),
88 SIGNAL(selectedColorChanged(QColor)));
89 connect(data->colorPickerTool, SIGNAL(selectedColorChanged(QColor)),
90 this, SLOT(sendColorChanged(QColor)));
92 changeTool(InspectorProtocol::SelectTool);
95 QDeclarativeViewInspector::~QDeclarativeViewInspector()
99 void QDeclarativeViewInspector::changeCurrentObjects(const QList<QObject*> &objects)
101 QList<QGraphicsItem*> items;
102 QList<QGraphicsObject*> gfxObjects;
103 foreach (QObject *obj, objects) {
104 if (QDeclarativeItem *declarativeItem = qobject_cast<QDeclarativeItem*>(obj)) {
105 items << declarativeItem;
106 gfxObjects << declarativeItem;
109 if (designModeBehavior()) {
110 data->setSelectedItemsForTools(items);
111 data->clearHighlight();
112 data->highlight(gfxObjects);
116 void QDeclarativeViewInspector::reloadView()
118 data->clearHighlight();
119 emit reloadRequested();
122 void QDeclarativeViewInspector::changeTool(InspectorProtocol::Tool tool)
125 case InspectorProtocol::ColorPickerTool:
126 data->changeToColorPickerTool();
128 case InspectorProtocol::SelectMarqueeTool:
129 data->changeToMarqueeSelectTool();
131 case InspectorProtocol::SelectTool:
132 data->changeToSingleSelectTool();
134 case InspectorProtocol::ZoomTool:
135 data->changeToZoomTool();
140 Qt::WindowFlags QDeclarativeViewInspector::windowFlags() const
142 return declarativeView()->window()->windowFlags();
145 void QDeclarativeViewInspector::setWindowFlags(Qt::WindowFlags flags)
147 declarativeView()->window()->setWindowFlags(flags);
148 declarativeView()->window()->show();
151 AbstractLiveEditTool *QDeclarativeViewInspector::currentTool() const
153 return static_cast<AbstractLiveEditTool*>(AbstractViewInspector::currentTool());
156 QDeclarativeEngine *QDeclarativeViewInspector::declarativeEngine() const
158 return data->view->engine();
161 void QDeclarativeViewInspectorPrivate::setViewport(QWidget *widget)
163 if (viewport.data() == widget)
167 viewport.data()->removeEventFilter(q);
171 // make sure we get mouse move events
172 viewport.data()->setMouseTracking(true);
173 viewport.data()->installEventFilter(q);
177 void QDeclarativeViewInspectorPrivate::clearEditorItems()
180 setSelectedItems(QList<QGraphicsItem*>());
183 bool QDeclarativeViewInspector::eventFilter(QObject *obj, QEvent *event)
185 if (obj == data->view) {
187 if (event->type() == QEvent::ChildRemoved) {
188 // Might mean that viewport has changed
189 if (data->view->viewport() != data->viewport.data())
190 data->setViewport(data->view->viewport());
192 return QObject::eventFilter(obj, event);
195 return AbstractViewInspector::eventFilter(obj, event);
198 bool QDeclarativeViewInspector::leaveEvent(QEvent *event)
200 data->clearHighlight();
201 return AbstractViewInspector::leaveEvent(event);
204 bool QDeclarativeViewInspector::mouseMoveEvent(QMouseEvent *event)
206 QList<QGraphicsItem*> selItems = data->selectableItems(event->pos());
207 if (!selItems.isEmpty()) {
208 declarativeView()->setToolTip(currentTool()->titleForItem(selItems.first()));
210 declarativeView()->setToolTip(QString());
213 return AbstractViewInspector::mouseMoveEvent(event);
216 void QDeclarativeViewInspector::reparentQmlObject(QObject *object, QObject *newParent)
221 object->setParent(newParent);
222 QDeclarativeItem *newParentItem = qobject_cast<QDeclarativeItem*>(newParent);
223 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(object);
224 if (newParentItem && item)
225 item->setParentItem(newParentItem);
228 void QDeclarativeViewInspectorPrivate::_q_removeFromSelection(QObject *obj)
230 QList<QGraphicsItem*> items = selectedItems();
231 if (QGraphicsItem *item = qobject_cast<QGraphicsObject*>(obj))
232 items.removeOne(item);
233 setSelectedItems(items);
236 void QDeclarativeViewInspectorPrivate::setSelectedItemsForTools(const QList<QGraphicsItem *> &items)
238 foreach (const QWeakPointer<QGraphicsObject> &obj, currentSelection) {
239 if (QGraphicsItem *item = obj.data()) {
240 if (!items.contains(item)) {
241 QObject::disconnect(obj.data(), SIGNAL(destroyed(QObject*)),
242 this, SLOT(_q_removeFromSelection(QObject*)));
243 currentSelection.removeOne(obj);
248 foreach (QGraphicsItem *item, items) {
249 if (QGraphicsObject *obj = item->toGraphicsObject()) {
250 if (!currentSelection.contains(obj)) {
251 QObject::connect(obj, SIGNAL(destroyed(QObject*)),
252 this, SLOT(_q_removeFromSelection(QObject*)));
253 currentSelection.append(obj);
258 q->currentTool()->updateSelectedItems();
261 void QDeclarativeViewInspectorPrivate::setSelectedItems(const QList<QGraphicsItem *> &items)
263 QList<QWeakPointer<QGraphicsObject> > oldList = currentSelection;
264 setSelectedItemsForTools(items);
265 if (oldList != currentSelection) {
266 QList<QObject*> objectList;
267 foreach (const QWeakPointer<QGraphicsObject> &graphicsObject, currentSelection) {
269 objectList << graphicsObject.data();
272 q->sendCurrentObjects(objectList);
276 QList<QGraphicsItem *> QDeclarativeViewInspectorPrivate::selectedItems() const
278 QList<QGraphicsItem *> selection;
279 foreach (const QWeakPointer<QGraphicsObject> &selectedObject, currentSelection) {
280 if (selectedObject.data())
281 selection << selectedObject.data();
287 void QDeclarativeViewInspector::setSelectedItems(QList<QGraphicsItem *> items)
289 data->setSelectedItems(items);
292 QList<QGraphicsItem *> QDeclarativeViewInspector::selectedItems() const
294 return data->selectedItems();
297 QDeclarativeView *QDeclarativeViewInspector::declarativeView() const
302 void QDeclarativeViewInspectorPrivate::clearHighlight()
304 boundingRectHighlighter->clear();
307 void QDeclarativeViewInspectorPrivate::highlight(const QList<QGraphicsObject *> &items)
312 QList<QGraphicsObject*> objectList;
313 foreach (QGraphicsItem *item, items) {
314 QGraphicsItem *child = item;
317 QGraphicsObject *childObject = child->toGraphicsObject();
319 objectList << childObject;
323 boundingRectHighlighter->highlight(objectList);
326 QList<QGraphicsItem*> QDeclarativeViewInspectorPrivate::selectableItems(
327 const QPointF &scenePos) const
329 QList<QGraphicsItem*> itemlist = view->scene()->items(scenePos);
330 return filterForSelection(itemlist);
333 QList<QGraphicsItem*> QDeclarativeViewInspectorPrivate::selectableItems(const QPoint &pos) const
335 QList<QGraphicsItem*> itemlist = view->items(pos);
336 return filterForSelection(itemlist);
339 QList<QGraphicsItem*> QDeclarativeViewInspectorPrivate::selectableItems(
340 const QRectF &sceneRect, Qt::ItemSelectionMode selectionMode) const
342 QList<QGraphicsItem*> itemlist = view->scene()->items(sceneRect, selectionMode);
343 return filterForSelection(itemlist);
346 void QDeclarativeViewInspectorPrivate::changeToSingleSelectTool()
348 selectionTool->setRubberbandSelectionMode(false);
350 changeToSelectTool();
352 emit q->selectToolActivated();
353 q->sendCurrentTool(Constants::SelectionToolMode);
356 void QDeclarativeViewInspectorPrivate::changeToSelectTool()
358 if (q->currentTool() == selectionTool)
361 q->currentTool()->clear();
362 q->setCurrentTool(selectionTool);
363 q->currentTool()->clear();
364 q->currentTool()->updateSelectedItems();
367 void QDeclarativeViewInspectorPrivate::changeToMarqueeSelectTool()
369 changeToSelectTool();
370 selectionTool->setRubberbandSelectionMode(true);
372 emit q->marqueeSelectToolActivated();
373 q->sendCurrentTool(Constants::MarqueeSelectionToolMode);
376 void QDeclarativeViewInspectorPrivate::changeToZoomTool()
378 q->currentTool()->clear();
379 q->setCurrentTool(zoomTool);
380 q->currentTool()->clear();
382 emit q->zoomToolActivated();
383 q->sendCurrentTool(Constants::ZoomMode);
386 void QDeclarativeViewInspectorPrivate::changeToColorPickerTool()
388 if (q->currentTool() == colorPickerTool)
391 q->currentTool()->clear();
392 q->setCurrentTool(colorPickerTool);
393 q->currentTool()->clear();
395 emit q->colorPickerActivated();
396 q->sendCurrentTool(Constants::ColorPickerMode);
400 static bool isEditorItem(QGraphicsItem *item)
402 return (item->type() == Constants::EditorItemType
403 || item->type() == Constants::ResizeHandleItemType
404 || item->data(Constants::EditorItemDataKey).toBool());
407 QList<QGraphicsItem*> QDeclarativeViewInspectorPrivate::filterForSelection(
408 QList<QGraphicsItem*> &itemlist) const
410 foreach (QGraphicsItem *item, itemlist) {
411 if (isEditorItem(item))
412 itemlist.removeOne(item);
418 void QDeclarativeViewInspectorPrivate::_q_onStatusChanged(QDeclarativeView::Status status)
420 if (status == QDeclarativeView::Ready)
424 // adjusts bounding boxes on edges of screen to be visible
425 QRectF QDeclarativeViewInspector::adjustToScreenBoundaries(const QRectF &boundingRectInSceneSpace)
427 int marginFromEdge = 1;
428 QRectF boundingRect(boundingRectInSceneSpace);
429 if (qAbs(boundingRect.left()) - 1 < 2)
430 boundingRect.setLeft(marginFromEdge);
432 QRect rect = data->view->rect();
434 if (boundingRect.right() >= rect.right())
435 boundingRect.setRight(rect.right() - marginFromEdge);
437 if (qAbs(boundingRect.top()) - 1 < 2)
438 boundingRect.setTop(marginFromEdge);
440 if (boundingRect.bottom() >= rect.bottom())
441 boundingRect.setBottom(rect.bottom() - marginFromEdge);
446 } // namespace QtQuick1
447 } // namespace QmlJSDebugger