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 "abstractviewinspector.h"
44 #include "abstracttool.h"
45 #include "qdeclarativeinspectorprotocol.h"
47 #include <QtDeclarative/QDeclarativeEngine>
48 #include <QtDeclarative/QDeclarativeComponent>
49 #include <QtCore/private/qabstractanimation_p.h>
50 #include <QtDeclarative/private/qdeclarativeinspectorservice_p.h>
52 #include <QtGui/QMouseEvent>
54 namespace QmlJSDebugger {
57 AbstractViewInspector::AbstractViewInspector(QObject *parent) :
60 m_showAppOnTop(false),
61 m_designModeBehavior(false),
62 m_animationPaused(false),
63 m_slowDownFactor(1.0),
64 m_debugService(QDeclarativeInspectorService::instance())
68 void AbstractViewInspector::createQmlObject(const QString &qml, QObject *parent,
69 const QStringList &importList,
70 const QString &filename)
76 foreach (const QString &s, importList) {
78 imports += QLatin1Char('\n');
81 QDeclarativeContext *parentContext = declarativeEngine()->contextForObject(parent);
82 QDeclarativeComponent component(declarativeEngine());
83 QByteArray constructedQml = QString(imports + qml).toLatin1();
85 component.setData(constructedQml, QUrl::fromLocalFile(filename));
86 QObject *newObject = component.create(parentContext);
88 reparentQmlObject(newObject, parent);
91 void AbstractViewInspector::clearComponentCache()
93 declarativeEngine()->clearComponentCache();
96 void AbstractViewInspector::setDesignModeBehavior(bool value)
98 if (m_designModeBehavior == value)
101 m_designModeBehavior = value;
102 emit designModeBehaviorChanged(value);
103 sendDesignModeBehavior(value);
106 void AbstractViewInspector::setAnimationSpeed(qreal slowDownFactor)
108 Q_ASSERT(slowDownFactor > 0);
109 if (m_slowDownFactor == slowDownFactor)
112 animationSpeedChangeRequested(slowDownFactor);
113 sendAnimationSpeed(slowDownFactor);
116 void AbstractViewInspector::setAnimationPaused(bool paused)
118 if (m_animationPaused == paused)
121 animationPausedChangeRequested(paused);
122 sendAnimationPaused(paused);
125 void AbstractViewInspector::animationSpeedChangeRequested(qreal factor)
127 if (m_slowDownFactor != factor) {
128 m_slowDownFactor = factor;
129 emit animationSpeedChanged(factor);
132 const float effectiveFactor = m_animationPaused ? 0 : factor;
133 QUnifiedTimer::instance()->setSlowModeEnabled(effectiveFactor != 1.0);
134 QUnifiedTimer::instance()->setSlowdownFactor(effectiveFactor);
137 void AbstractViewInspector::animationPausedChangeRequested(bool paused)
139 if (m_animationPaused != paused) {
140 m_animationPaused = paused;
141 emit animationPausedChanged(paused);
144 const float effectiveFactor = paused ? 0 : m_slowDownFactor;
145 QUnifiedTimer::instance()->setSlowModeEnabled(effectiveFactor != 1.0);
146 QUnifiedTimer::instance()->setSlowdownFactor(effectiveFactor);
149 void AbstractViewInspector::setShowAppOnTop(bool appOnTop)
151 Qt::WindowFlags flags = windowFlags();
153 flags |= Qt::WindowStaysOnTopHint;
155 flags &= ~Qt::WindowStaysOnTopHint;
157 setWindowFlags(flags);
159 m_showAppOnTop = appOnTop;
160 sendShowAppOnTop(appOnTop);
162 emit showAppOnTopChanged(appOnTop);
165 void AbstractViewInspector::changeToColorPickerTool()
167 changeTool(InspectorProtocol::ColorPickerTool);
170 void AbstractViewInspector::changeToZoomTool()
172 changeTool(InspectorProtocol::ZoomTool);
175 void AbstractViewInspector::changeToSingleSelectTool()
177 changeTool(InspectorProtocol::SelectTool);
180 void AbstractViewInspector::changeToMarqueeSelectTool()
182 changeTool(InspectorProtocol::SelectMarqueeTool);
185 bool AbstractViewInspector::eventFilter(QObject *obj, QEvent *event)
187 if (!designModeBehavior())
188 return QObject::eventFilter(obj, event);
190 switch (event->type()) {
192 if (leaveEvent(event))
195 case QEvent::MouseButtonPress:
196 if (mousePressEvent(static_cast<QMouseEvent*>(event)))
199 case QEvent::MouseMove:
200 if (mouseMoveEvent(static_cast<QMouseEvent*>(event)))
203 case QEvent::MouseButtonRelease:
204 if (mouseReleaseEvent(static_cast<QMouseEvent*>(event)))
207 case QEvent::KeyPress:
208 if (keyPressEvent(static_cast<QKeyEvent*>(event)))
211 case QEvent::KeyRelease:
212 if (keyReleaseEvent(static_cast<QKeyEvent*>(event)))
215 case QEvent::MouseButtonDblClick:
216 if (mouseDoubleClickEvent(static_cast<QMouseEvent*>(event)))
220 if (wheelEvent(static_cast<QWheelEvent*>(event)))
227 return QObject::eventFilter(obj, event);
230 bool AbstractViewInspector::leaveEvent(QEvent *event)
232 m_currentTool->leaveEvent(event);
236 bool AbstractViewInspector::mousePressEvent(QMouseEvent *event)
238 m_currentTool->mousePressEvent(event);
242 bool AbstractViewInspector::mouseMoveEvent(QMouseEvent *event)
244 if (event->buttons()) {
245 m_currentTool->mouseMoveEvent(event);
247 m_currentTool->hoverMoveEvent(event);
252 bool AbstractViewInspector::mouseReleaseEvent(QMouseEvent *event)
254 m_currentTool->mouseReleaseEvent(event);
258 bool AbstractViewInspector::keyPressEvent(QKeyEvent *event)
260 m_currentTool->keyPressEvent(event);
264 bool AbstractViewInspector::keyReleaseEvent(QKeyEvent *event)
266 switch (event->key()) {
268 changeTool(InspectorProtocol::SelectTool);
270 // disabled because multiselection does not do anything useful without design mode
272 // changeTool(InspectorProtocol::SelectMarqueeTool);
275 changeTool(InspectorProtocol::ColorPickerTool);
278 changeTool(InspectorProtocol::ZoomTool);
281 setAnimationPaused(!animationPaused());
287 m_currentTool->keyReleaseEvent(event);
291 bool AbstractViewInspector::mouseDoubleClickEvent(QMouseEvent *event)
293 m_currentTool->mouseDoubleClickEvent(event);
297 bool AbstractViewInspector::wheelEvent(QWheelEvent *event)
299 m_currentTool->wheelEvent(event);
303 void AbstractViewInspector::handleMessage(const QByteArray &message)
305 QDataStream ds(message);
307 InspectorProtocol::Message type;
311 case InspectorProtocol::SetCurrentObjects: {
315 QList<QObject*> selectedObjects;
316 for (int i = 0; i < itemCount; ++i) {
319 if (QObject *obj = QDeclarativeDebugService::objectForId(debugId))
320 selectedObjects << obj;
323 changeCurrentObjects(selectedObjects);
326 case InspectorProtocol::Reload: {
330 case InspectorProtocol::SetAnimationSpeed: {
333 animationSpeedChangeRequested(speed);
336 case InspectorProtocol::SetAnimationPaused: {
339 animationPausedChangeRequested(paused);
342 case InspectorProtocol::ChangeTool: {
343 InspectorProtocol::Tool tool;
348 case InspectorProtocol::SetDesignMode: {
351 setDesignModeBehavior(inDesignMode);
354 case InspectorProtocol::ShowAppOnTop: {
357 setShowAppOnTop(showOnTop);
360 case InspectorProtocol::CreateObject: {
365 ds >> qml >> parentId >> imports >> filename;
366 createQmlObject(qml, QDeclarativeDebugService::objectForId(parentId),
370 case InspectorProtocol::DestroyObject: {
373 if (QObject *obj = QDeclarativeDebugService::objectForId(debugId))
377 case InspectorProtocol::MoveObject: {
378 int debugId, newParent;
379 ds >> debugId >> newParent;
380 reparentQmlObject(QDeclarativeDebugService::objectForId(debugId),
381 QDeclarativeDebugService::objectForId(newParent));
384 case InspectorProtocol::ObjectIdList: {
387 m_stringIdForObjectId.clear();
388 for (int i = 0; i < itemCount; ++i) {
390 QString itemIdString;
394 m_stringIdForObjectId.insert(itemDebugId, itemIdString);
398 case InspectorProtocol::ClearComponentCache: {
399 clearComponentCache();
403 qWarning() << "Warning: Not handling message:" << type;
407 void AbstractViewInspector::sendDesignModeBehavior(bool inDesignMode)
410 QDataStream ds(&message, QIODevice::WriteOnly);
412 ds << InspectorProtocol::SetDesignMode
415 m_debugService->sendMessage(message);
418 void AbstractViewInspector::sendCurrentObjects(const QList<QObject*> &objects)
421 QDataStream ds(&message, QIODevice::WriteOnly);
423 ds << InspectorProtocol::CurrentObjectsChanged
426 foreach (QObject *object, objects) {
427 int id = QDeclarativeDebugService::idForObject(object);
431 m_debugService->sendMessage(message);
434 void AbstractViewInspector::sendCurrentTool(Constants::DesignTool toolId)
437 QDataStream ds(&message, QIODevice::WriteOnly);
439 ds << InspectorProtocol::ToolChanged
442 m_debugService->sendMessage(message);
445 void AbstractViewInspector::sendAnimationSpeed(qreal slowDownFactor)
448 QDataStream ds(&message, QIODevice::WriteOnly);
450 ds << InspectorProtocol::AnimationSpeedChanged
453 m_debugService->sendMessage(message);
456 void AbstractViewInspector::sendAnimationPaused(bool paused)
459 QDataStream ds(&message, QIODevice::WriteOnly);
461 ds << InspectorProtocol::AnimationPausedChanged
464 m_debugService->sendMessage(message);
467 void AbstractViewInspector::sendReloaded()
470 QDataStream ds(&message, QIODevice::WriteOnly);
472 ds << InspectorProtocol::Reloaded;
474 m_debugService->sendMessage(message);
477 void AbstractViewInspector::sendShowAppOnTop(bool showAppOnTop)
480 QDataStream ds(&message, QIODevice::WriteOnly);
482 ds << InspectorProtocol::ShowAppOnTop << showAppOnTop;
484 m_debugService->sendMessage(message);
487 void AbstractViewInspector::sendColorChanged(const QColor &color)
490 QDataStream ds(&message, QIODevice::WriteOnly);
492 ds << InspectorProtocol::ColorChanged
495 m_debugService->sendMessage(message);
498 QString AbstractViewInspector::idStringForObject(QObject *obj) const
500 const int id = QDeclarativeDebugService::idForObject(obj);
501 return m_stringIdForObjectId.value(id);
504 } // namespace QmlJSDebugger