From 96d991bbdc34b00b4ba1c3b4f5690f04edfb4cf0 Mon Sep 17 00:00:00 2001 From: Lasse Holmstedt Date: Mon, 27 Sep 2010 17:22:57 +0200 Subject: QML Observer: Build together on runtime with debugging tools Moved qmljsdebugger to a dir under qml/, made qmlobserver compile without creator dependencies and made it compile with debugging helpers. Reviewed-by: hjk --- .../editor/abstractformeditortool.cpp | 204 +++ .../qmljsdebugger/editor/abstractformeditortool.h | 106 ++ .../editor/boundingrecthighlighter.cpp | 241 +++ .../qmljsdebugger/editor/boundingrecthighlighter.h | 78 + .../qml/qmljsdebugger/editor/colorpickertool.cpp | 89 ++ .../qml/qmljsdebugger/editor/colorpickertool.h | 53 + .../qtcreator/qml/qmljsdebugger/editor/editor.pri | 37 + .../qtcreator/qml/qmljsdebugger/editor/editor.qrc | 24 + .../editor/images/color-picker-24.png | Bin 0 -> 3440 bytes .../editor/images/color-picker-hicontrast.png | Bin 0 -> 3192 bytes .../qmljsdebugger/editor/images/color-picker.png | Bin 0 -> 3173 bytes .../qmljsdebugger/editor/images/from-qml-24.png | Bin 0 -> 3395 bytes .../qml/qmljsdebugger/editor/images/from-qml.png | Bin 0 -> 3205 bytes .../editor/images/observermode-24.png | Bin 0 -> 1283 bytes .../qmljsdebugger/editor/images/observermode.png | Bin 0 -> 3539 bytes .../qml/qmljsdebugger/editor/images/pause-24.png | Bin 0 -> 3307 bytes .../qml/qmljsdebugger/editor/images/pause.png | Bin 0 -> 3097 bytes .../qml/qmljsdebugger/editor/images/play-24.png | Bin 0 -> 3655 bytes .../qml/qmljsdebugger/editor/images/play.png | Bin 0 -> 3363 bytes .../qml/qmljsdebugger/editor/images/reload.png | Bin 0 -> 3418 bytes .../qmljsdebugger/editor/images/resize_handle.png | Bin 0 -> 160 bytes .../qml/qmljsdebugger/editor/images/select-24.png | Bin 0 -> 3510 bytes .../editor/images/select-marquee-24.png | Bin 0 -> 2891 bytes .../qmljsdebugger/editor/images/select-marquee.png | Bin 0 -> 2871 bytes .../qml/qmljsdebugger/editor/images/select.png | Bin 0 -> 3308 bytes .../qml/qmljsdebugger/editor/images/to-qml-24.png | Bin 0 -> 3407 bytes .../qml/qmljsdebugger/editor/images/to-qml.png | Bin 0 -> 3227 bytes .../qml/qmljsdebugger/editor/images/zoom-24.png | Bin 0 -> 3566 bytes .../qml/qmljsdebugger/editor/images/zoom.png | Bin 0 -> 3347 bytes .../qml/qmljsdebugger/editor/layeritem.cpp | 78 + .../qtcreator/qml/qmljsdebugger/editor/layeritem.h | 57 + .../qml/qmljsdebugger/editor/qmltoolbar.cpp | 323 ++++ .../qml/qmljsdebugger/editor/qmltoolbar.h | 96 ++ .../editor/rubberbandselectionmanipulator.cpp | 144 ++ .../editor/rubberbandselectionmanipulator.h | 82 + .../qmljsdebugger/editor/selectionindicator.cpp | 127 ++ .../qml/qmljsdebugger/editor/selectionindicator.h | 66 + .../qmljsdebugger/editor/selectionrectangle.cpp | 95 ++ .../qml/qmljsdebugger/editor/selectionrectangle.h | 62 + .../qml/qmljsdebugger/editor/selectiontool.cpp | 447 ++++++ .../qml/qmljsdebugger/editor/selectiontool.h | 110 ++ .../editor/singleselectionmanipulator.cpp | 134 ++ .../editor/singleselectionmanipulator.h | 76 + .../editor/subcomponenteditortool.cpp | 320 ++++ .../qmljsdebugger/editor/subcomponenteditortool.h | 83 + .../editor/subcomponentmasklayeritem.cpp | 80 + .../editor/subcomponentmasklayeritem.h | 29 + .../qml/qmljsdebugger/editor/toolbarcolorbox.cpp | 96 ++ .../qml/qmljsdebugger/editor/toolbarcolorbox.h | 41 + .../qml/qmljsdebugger/editor/zoomtool.cpp | 287 ++++ .../qtcreator/qml/qmljsdebugger/editor/zoomtool.h | 65 + .../qml/qmljsdebugger/include/jsdebuggeragent.h | 144 ++ .../include/qdeclarativeobserverservice.h | 110 ++ .../include/qdeclarativeviewobserver.h | 129 ++ .../qmljsdebugger/include/qmljsdebugger_global.h | 43 + .../qmljsdebugger/include/qmlobserverconstants.h | 68 + .../qml/qmljsdebugger/jsdebuggeragent.cpp | 519 +++++++ .../qml/qmljsdebugger/private_headers.pri | 17 + .../qmljsdebugger/qdeclarativeobserverservice.cpp | 239 +++ .../qml/qmljsdebugger/qdeclarativeviewobserver.cpp | 804 ++++++++++ .../qml/qmljsdebugger/qdeclarativeviewobserver_p.h | 141 ++ .../qml/qmljsdebugger/qmljsdebugger-lib.pri | 35 + .../qtcreator/qml/qmljsdebugger/qmljsdebugger.pri | 5 + .../qtcreator/qml/qmljsdebugger/qmljsdebugger.pro | 10 + share/qtcreator/qml/qmlobserver/Info_mac.plist | 18 + share/qtcreator/qml/qmlobserver/LGPL_EXCEPTION.TXT | 3 + share/qtcreator/qml/qmlobserver/LICENSE.LGPL | 504 +++++++ .../qtcreator/qml/qmlobserver/content/Browser.qml | 284 ++++ .../qml/qmlobserver/content/images/folder.png | Bin 0 -> 1841 bytes .../qml/qmlobserver/content/images/titlebar.png | Bin 0 -> 1436 bytes .../qml/qmlobserver/content/images/titlebar.sci | 5 + .../qml/qmlobserver/content/images/up.png | Bin 0 -> 662 bytes .../qml/qmlobserver/deviceorientation.cpp | 75 + .../qtcreator/qml/qmlobserver/deviceorientation.h | 81 + .../qml/qmlobserver/deviceorientation_maemo5.cpp | 127 ++ share/qtcreator/qml/qmlobserver/loggerwidget.cpp | 201 +++ share/qtcreator/qml/qmlobserver/loggerwidget.h | 99 ++ share/qtcreator/qml/qmlobserver/main.cpp | 471 ++++++ share/qtcreator/qml/qmlobserver/proxysettings.cpp | 113 ++ share/qtcreator/qml/qmlobserver/proxysettings.h | 75 + share/qtcreator/qml/qmlobserver/proxysettings.ui | 115 ++ .../qml/qmlobserver/proxysettings_maemo5.ui | 177 +++ .../qml/qmlobserver/qdeclarativetester.cpp | 407 +++++ .../qtcreator/qml/qmlobserver/qdeclarativetester.h | 289 ++++ share/qtcreator/qml/qmlobserver/qml.icns | Bin 0 -> 196156 bytes share/qtcreator/qml/qmlobserver/qml.pri | 38 + share/qtcreator/qml/qmlobserver/qmlobserver.pro | 24 + share/qtcreator/qml/qmlobserver/qmlruntime.cpp | 1581 ++++++++++++++++++++ share/qtcreator/qml/qmlobserver/qmlruntime.h | 230 +++ share/qtcreator/qml/qmlobserver/qmlruntime.qrc | 9 + share/qtcreator/qml/qmlobserver/recopts.ui | 513 +++++++ share/qtcreator/qml/qmlobserver/recopts_maemo5.ui | 254 ++++ .../qml/qmlobserver/texteditautoresizer_maemo5.h | 113 ++ .../editor/abstractformeditortool.cpp | 204 --- .../qmljsdebugger/editor/abstractformeditortool.h | 106 -- .../editor/boundingrecthighlighter.cpp | 241 --- .../qmljsdebugger/editor/boundingrecthighlighter.h | 78 - .../qmljsdebugger/editor/colorpickertool.cpp | 89 -- .../qmljsdebugger/editor/colorpickertool.h | 53 - share/qtcreator/qmljsdebugger/editor/editor.pri | 37 - share/qtcreator/qmljsdebugger/editor/editor.qrc | 24 - .../editor/images/color-picker-24.png | Bin 3440 -> 0 bytes .../editor/images/color-picker-hicontrast.png | Bin 3192 -> 0 bytes .../qmljsdebugger/editor/images/color-picker.png | Bin 3173 -> 0 bytes .../qmljsdebugger/editor/images/from-qml-24.png | Bin 3395 -> 0 bytes .../qmljsdebugger/editor/images/from-qml.png | Bin 3205 -> 0 bytes .../editor/images/observermode-24.png | Bin 1283 -> 0 bytes .../qmljsdebugger/editor/images/observermode.png | Bin 3539 -> 0 bytes .../qmljsdebugger/editor/images/pause-24.png | Bin 3307 -> 0 bytes .../qmljsdebugger/editor/images/pause.png | Bin 3097 -> 0 bytes .../qmljsdebugger/editor/images/play-24.png | Bin 3655 -> 0 bytes .../qtcreator/qmljsdebugger/editor/images/play.png | Bin 3363 -> 0 bytes .../qmljsdebugger/editor/images/reload.png | Bin 3418 -> 0 bytes .../qmljsdebugger/editor/images/resize_handle.png | Bin 160 -> 0 bytes .../qmljsdebugger/editor/images/select-24.png | Bin 3510 -> 0 bytes .../editor/images/select-marquee-24.png | Bin 2891 -> 0 bytes .../qmljsdebugger/editor/images/select-marquee.png | Bin 2871 -> 0 bytes .../qmljsdebugger/editor/images/select.png | Bin 3308 -> 0 bytes .../qmljsdebugger/editor/images/to-qml-24.png | Bin 3407 -> 0 bytes .../qmljsdebugger/editor/images/to-qml.png | Bin 3227 -> 0 bytes .../qmljsdebugger/editor/images/zoom-24.png | Bin 3566 -> 0 bytes .../qtcreator/qmljsdebugger/editor/images/zoom.png | Bin 3347 -> 0 bytes share/qtcreator/qmljsdebugger/editor/layeritem.cpp | 78 - share/qtcreator/qmljsdebugger/editor/layeritem.h | 57 - .../qtcreator/qmljsdebugger/editor/qmltoolbar.cpp | 323 ---- share/qtcreator/qmljsdebugger/editor/qmltoolbar.h | 96 -- .../editor/rubberbandselectionmanipulator.cpp | 144 -- .../editor/rubberbandselectionmanipulator.h | 82 - .../qmljsdebugger/editor/selectionindicator.cpp | 127 -- .../qmljsdebugger/editor/selectionindicator.h | 66 - .../qmljsdebugger/editor/selectionrectangle.cpp | 95 -- .../qmljsdebugger/editor/selectionrectangle.h | 62 - .../qmljsdebugger/editor/selectiontool.cpp | 447 ------ .../qtcreator/qmljsdebugger/editor/selectiontool.h | 110 -- .../editor/singleselectionmanipulator.cpp | 134 -- .../editor/singleselectionmanipulator.h | 76 - .../editor/subcomponenteditortool.cpp | 320 ---- .../qmljsdebugger/editor/subcomponenteditortool.h | 83 - .../editor/subcomponentmasklayeritem.cpp | 80 - .../editor/subcomponentmasklayeritem.h | 29 - .../qmljsdebugger/editor/toolbarcolorbox.cpp | 96 -- .../qmljsdebugger/editor/toolbarcolorbox.h | 41 - share/qtcreator/qmljsdebugger/editor/zoomtool.cpp | 287 ---- share/qtcreator/qmljsdebugger/editor/zoomtool.h | 65 - .../qmljsdebugger/include/jsdebuggeragent.h | 144 -- .../include/qdeclarativeobserverservice.h | 110 -- .../include/qdeclarativeviewobserver.h | 129 -- .../qmljsdebugger/include/qmljsdebugger_global.h | 43 - .../qmljsdebugger/include/qmlobserverconstants.h | 68 - share/qtcreator/qmljsdebugger/jsdebuggeragent.cpp | 519 ------- share/qtcreator/qmljsdebugger/private_headers.pri | 17 - .../qmljsdebugger/qdeclarativeobserverservice.cpp | 239 --- .../qmljsdebugger/qdeclarativeviewobserver.cpp | 804 ---------- .../qmljsdebugger/qdeclarativeviewobserver_p.h | 141 -- .../qtcreator/qmljsdebugger/qmljsdebugger-lib.pri | 35 - share/qtcreator/qmljsdebugger/qmljsdebugger.pri | 5 - share/qtcreator/qmljsdebugger/qmljsdebugger.pro | 10 - src/libs/qmljs/qmljsmodelmanagerinterface.h | 1 + src/plugins/debugger/debuggerrunner.cpp | 8 +- src/plugins/projectexplorer/debugginghelper.cpp | 3 +- src/plugins/qmljseditor/qmljsmodelmanager.cpp | 27 +- .../qmlprojectrunconfiguration.cpp | 50 +- src/plugins/qt4projectmanager/qmldumptool.cpp | 14 +- src/plugins/qt4projectmanager/qmldumptool.h | 4 +- src/plugins/qt4projectmanager/qmlobservertool.cpp | 219 +++ src/plugins/qt4projectmanager/qmlobservertool.h | 69 + src/plugins/qt4projectmanager/qt4project.cpp | 32 + .../qt4projectmanager/qt4projectmanager.pro | 6 +- src/plugins/qt4projectmanager/qtoptionspage.cpp | 76 +- src/plugins/qt4projectmanager/qtoptionspage.h | 4 + src/plugins/qt4projectmanager/qtversionmanager.cpp | 62 +- src/plugins/qt4projectmanager/qtversionmanager.h | 7 +- src/tools/qml/qmlobserver/Info_mac.plist | 18 - src/tools/qml/qmlobserver/content/Browser.qml | 284 ---- .../qml/qmlobserver/content/images/folder.png | Bin 1841 -> 0 bytes .../qml/qmlobserver/content/images/titlebar.png | Bin 1436 -> 0 bytes .../qml/qmlobserver/content/images/titlebar.sci | 5 - src/tools/qml/qmlobserver/content/images/up.png | Bin 662 -> 0 bytes src/tools/qml/qmlobserver/deviceorientation.cpp | 75 - src/tools/qml/qmlobserver/deviceorientation.h | 81 - .../qml/qmlobserver/deviceorientation_maemo5.cpp | 127 -- src/tools/qml/qmlobserver/loggerwidget.cpp | 201 --- src/tools/qml/qmlobserver/loggerwidget.h | 99 -- src/tools/qml/qmlobserver/main.cpp | 471 ------ src/tools/qml/qmlobserver/proxysettings.cpp | 113 -- src/tools/qml/qmlobserver/proxysettings.h | 75 - src/tools/qml/qmlobserver/proxysettings.ui | 115 -- src/tools/qml/qmlobserver/proxysettings_maemo5.ui | 177 --- src/tools/qml/qmlobserver/qdeclarativetester.cpp | 407 ----- src/tools/qml/qmlobserver/qdeclarativetester.h | 289 ---- src/tools/qml/qmlobserver/qml.icns | Bin 196156 -> 0 bytes src/tools/qml/qmlobserver/qml.pri | 36 - src/tools/qml/qmlobserver/qmlobserver.pro | 30 - src/tools/qml/qmlobserver/qmlruntime.cpp | 1581 -------------------- src/tools/qml/qmlobserver/qmlruntime.h | 231 --- src/tools/qml/qmlobserver/qmlruntime.qrc | 9 - src/tools/qml/qmlobserver/recopts.ui | 513 ------- src/tools/qml/qmlobserver/recopts_maemo5.ui | 254 ---- .../qml/qmlobserver/texteditautoresizer_maemo5.h | 113 -- 199 files changed, 12281 insertions(+), 11399 deletions(-) create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/abstractformeditortool.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/abstractformeditortool.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/boundingrecthighlighter.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/boundingrecthighlighter.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/colorpickertool.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/colorpickertool.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/editor.pri create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/editor.qrc create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/color-picker-24.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/color-picker-hicontrast.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/color-picker.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/from-qml-24.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/from-qml.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/observermode-24.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/observermode.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/pause-24.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/pause.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/play-24.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/play.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/reload.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/resize_handle.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/select-24.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/select-marquee-24.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/select-marquee.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/select.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/to-qml-24.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/to-qml.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/zoom-24.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/images/zoom.png create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/layeritem.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/layeritem.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/qmltoolbar.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/qmltoolbar.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/rubberbandselectionmanipulator.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/rubberbandselectionmanipulator.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/selectionindicator.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/selectionindicator.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/selectionrectangle.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/selectionrectangle.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/selectiontool.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/selectiontool.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/singleselectionmanipulator.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/singleselectionmanipulator.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/subcomponenteditortool.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/subcomponenteditortool.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/subcomponentmasklayeritem.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/subcomponentmasklayeritem.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/toolbarcolorbox.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/toolbarcolorbox.h create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/zoomtool.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/editor/zoomtool.h create mode 100644 share/qtcreator/qml/qmljsdebugger/include/jsdebuggeragent.h create mode 100644 share/qtcreator/qml/qmljsdebugger/include/qdeclarativeobserverservice.h create mode 100644 share/qtcreator/qml/qmljsdebugger/include/qdeclarativeviewobserver.h create mode 100644 share/qtcreator/qml/qmljsdebugger/include/qmljsdebugger_global.h create mode 100644 share/qtcreator/qml/qmljsdebugger/include/qmlobserverconstants.h create mode 100644 share/qtcreator/qml/qmljsdebugger/jsdebuggeragent.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/private_headers.pri create mode 100644 share/qtcreator/qml/qmljsdebugger/qdeclarativeobserverservice.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/qdeclarativeviewobserver.cpp create mode 100644 share/qtcreator/qml/qmljsdebugger/qdeclarativeviewobserver_p.h create mode 100644 share/qtcreator/qml/qmljsdebugger/qmljsdebugger-lib.pri create mode 100644 share/qtcreator/qml/qmljsdebugger/qmljsdebugger.pri create mode 100644 share/qtcreator/qml/qmljsdebugger/qmljsdebugger.pro create mode 100644 share/qtcreator/qml/qmlobserver/Info_mac.plist create mode 100644 share/qtcreator/qml/qmlobserver/LGPL_EXCEPTION.TXT create mode 100644 share/qtcreator/qml/qmlobserver/LICENSE.LGPL create mode 100644 share/qtcreator/qml/qmlobserver/content/Browser.qml create mode 100644 share/qtcreator/qml/qmlobserver/content/images/folder.png create mode 100644 share/qtcreator/qml/qmlobserver/content/images/titlebar.png create mode 100644 share/qtcreator/qml/qmlobserver/content/images/titlebar.sci create mode 100644 share/qtcreator/qml/qmlobserver/content/images/up.png create mode 100644 share/qtcreator/qml/qmlobserver/deviceorientation.cpp create mode 100644 share/qtcreator/qml/qmlobserver/deviceorientation.h create mode 100644 share/qtcreator/qml/qmlobserver/deviceorientation_maemo5.cpp create mode 100644 share/qtcreator/qml/qmlobserver/loggerwidget.cpp create mode 100644 share/qtcreator/qml/qmlobserver/loggerwidget.h create mode 100644 share/qtcreator/qml/qmlobserver/main.cpp create mode 100644 share/qtcreator/qml/qmlobserver/proxysettings.cpp create mode 100644 share/qtcreator/qml/qmlobserver/proxysettings.h create mode 100644 share/qtcreator/qml/qmlobserver/proxysettings.ui create mode 100644 share/qtcreator/qml/qmlobserver/proxysettings_maemo5.ui create mode 100644 share/qtcreator/qml/qmlobserver/qdeclarativetester.cpp create mode 100644 share/qtcreator/qml/qmlobserver/qdeclarativetester.h create mode 100644 share/qtcreator/qml/qmlobserver/qml.icns create mode 100644 share/qtcreator/qml/qmlobserver/qml.pri create mode 100644 share/qtcreator/qml/qmlobserver/qmlobserver.pro create mode 100644 share/qtcreator/qml/qmlobserver/qmlruntime.cpp create mode 100644 share/qtcreator/qml/qmlobserver/qmlruntime.h create mode 100644 share/qtcreator/qml/qmlobserver/qmlruntime.qrc create mode 100644 share/qtcreator/qml/qmlobserver/recopts.ui create mode 100644 share/qtcreator/qml/qmlobserver/recopts_maemo5.ui create mode 100644 share/qtcreator/qml/qmlobserver/texteditautoresizer_maemo5.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/abstractformeditortool.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/abstractformeditortool.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/boundingrecthighlighter.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/boundingrecthighlighter.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/colorpickertool.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/colorpickertool.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/editor.pri delete mode 100644 share/qtcreator/qmljsdebugger/editor/editor.qrc delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/color-picker-24.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/color-picker-hicontrast.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/color-picker.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/from-qml-24.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/from-qml.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/observermode-24.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/observermode.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/pause-24.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/pause.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/play-24.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/play.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/reload.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/resize_handle.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/select-24.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/select-marquee-24.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/select-marquee.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/select.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/to-qml-24.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/to-qml.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/zoom-24.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/images/zoom.png delete mode 100644 share/qtcreator/qmljsdebugger/editor/layeritem.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/layeritem.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/qmltoolbar.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/qmltoolbar.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/rubberbandselectionmanipulator.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/rubberbandselectionmanipulator.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/selectionindicator.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/selectionindicator.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/selectionrectangle.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/selectionrectangle.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/selectiontool.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/selectiontool.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/singleselectionmanipulator.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/singleselectionmanipulator.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/subcomponenteditortool.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/subcomponenteditortool.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/subcomponentmasklayeritem.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/subcomponentmasklayeritem.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/toolbarcolorbox.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/toolbarcolorbox.h delete mode 100644 share/qtcreator/qmljsdebugger/editor/zoomtool.cpp delete mode 100644 share/qtcreator/qmljsdebugger/editor/zoomtool.h delete mode 100644 share/qtcreator/qmljsdebugger/include/jsdebuggeragent.h delete mode 100644 share/qtcreator/qmljsdebugger/include/qdeclarativeobserverservice.h delete mode 100644 share/qtcreator/qmljsdebugger/include/qdeclarativeviewobserver.h delete mode 100644 share/qtcreator/qmljsdebugger/include/qmljsdebugger_global.h delete mode 100644 share/qtcreator/qmljsdebugger/include/qmlobserverconstants.h delete mode 100644 share/qtcreator/qmljsdebugger/jsdebuggeragent.cpp delete mode 100644 share/qtcreator/qmljsdebugger/private_headers.pri delete mode 100644 share/qtcreator/qmljsdebugger/qdeclarativeobserverservice.cpp delete mode 100644 share/qtcreator/qmljsdebugger/qdeclarativeviewobserver.cpp delete mode 100644 share/qtcreator/qmljsdebugger/qdeclarativeviewobserver_p.h delete mode 100644 share/qtcreator/qmljsdebugger/qmljsdebugger-lib.pri delete mode 100644 share/qtcreator/qmljsdebugger/qmljsdebugger.pri delete mode 100644 share/qtcreator/qmljsdebugger/qmljsdebugger.pro create mode 100644 src/plugins/qt4projectmanager/qmlobservertool.cpp create mode 100644 src/plugins/qt4projectmanager/qmlobservertool.h delete mode 100644 src/tools/qml/qmlobserver/Info_mac.plist delete mode 100644 src/tools/qml/qmlobserver/content/Browser.qml delete mode 100644 src/tools/qml/qmlobserver/content/images/folder.png delete mode 100644 src/tools/qml/qmlobserver/content/images/titlebar.png delete mode 100644 src/tools/qml/qmlobserver/content/images/titlebar.sci delete mode 100644 src/tools/qml/qmlobserver/content/images/up.png delete mode 100644 src/tools/qml/qmlobserver/deviceorientation.cpp delete mode 100644 src/tools/qml/qmlobserver/deviceorientation.h delete mode 100644 src/tools/qml/qmlobserver/deviceorientation_maemo5.cpp delete mode 100644 src/tools/qml/qmlobserver/loggerwidget.cpp delete mode 100644 src/tools/qml/qmlobserver/loggerwidget.h delete mode 100644 src/tools/qml/qmlobserver/main.cpp delete mode 100644 src/tools/qml/qmlobserver/proxysettings.cpp delete mode 100644 src/tools/qml/qmlobserver/proxysettings.h delete mode 100644 src/tools/qml/qmlobserver/proxysettings.ui delete mode 100644 src/tools/qml/qmlobserver/proxysettings_maemo5.ui delete mode 100644 src/tools/qml/qmlobserver/qdeclarativetester.cpp delete mode 100644 src/tools/qml/qmlobserver/qdeclarativetester.h delete mode 100644 src/tools/qml/qmlobserver/qml.icns delete mode 100644 src/tools/qml/qmlobserver/qml.pri delete mode 100644 src/tools/qml/qmlobserver/qmlobserver.pro delete mode 100644 src/tools/qml/qmlobserver/qmlruntime.cpp delete mode 100644 src/tools/qml/qmlobserver/qmlruntime.h delete mode 100644 src/tools/qml/qmlobserver/qmlruntime.qrc delete mode 100644 src/tools/qml/qmlobserver/recopts.ui delete mode 100644 src/tools/qml/qmlobserver/recopts_maemo5.ui delete mode 100644 src/tools/qml/qmlobserver/texteditautoresizer_maemo5.h diff --git a/share/qtcreator/qml/qmljsdebugger/editor/abstractformeditortool.cpp b/share/qtcreator/qml/qmljsdebugger/editor/abstractformeditortool.cpp new file mode 100644 index 0000000000..557a301112 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/abstractformeditortool.cpp @@ -0,0 +1,204 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "abstractformeditortool.h" +#include "qdeclarativeviewobserver.h" +#include "qdeclarativeviewobserver_p.h" + +#include + +#include +#include +#include + +namespace QmlJSDebugger { + +AbstractFormEditorTool::AbstractFormEditorTool(QDeclarativeViewObserver *editorView) + : QObject(editorView), m_observer(editorView) +{ +} + + +AbstractFormEditorTool::~AbstractFormEditorTool() +{ + +} + +QDeclarativeViewObserver *AbstractFormEditorTool::observer() const +{ + return m_observer; +} + +QDeclarativeView *AbstractFormEditorTool::view() const +{ + return m_observer->declarativeView(); +} + +QGraphicsScene* AbstractFormEditorTool::scene() const +{ + return view()->scene(); +} + +void AbstractFormEditorTool::updateSelectedItems() +{ + selectedItemsChanged(items()); +} + +QList AbstractFormEditorTool::items() const +{ + return observer()->selectedItems(); +} + +void AbstractFormEditorTool::enterContext(QGraphicsItem *itemToEnter) +{ + observer()->data->enterContext(itemToEnter); +} + +bool AbstractFormEditorTool::topItemIsMovable(const QList & itemList) +{ + QGraphicsItem *firstSelectableItem = topMovableGraphicsItem(itemList); + if (firstSelectableItem == 0) + return false; + + QDeclarativeItem *declarativeItem = dynamic_cast(firstSelectableItem->toGraphicsObject()); + + if (declarativeItem != 0) + return true; + + return false; + +} + +bool AbstractFormEditorTool::topSelectedItemIsMovable(const QList &itemList) +{ + QList selectedItems = observer()->selectedItems(); + + foreach (QGraphicsItem *item, itemList) { + QDeclarativeItem *declarativeItem = toQDeclarativeItem(item); + if (declarativeItem + && selectedItems.contains(declarativeItem) + /*&& (declarativeItem->qmlItemNode().hasShowContent() || selectNonContentItems)*/) + return true; + } + + return false; + +} + +bool AbstractFormEditorTool::topItemIsResizeHandle(const QList &/*itemList*/) +{ + return false; +} + +QDeclarativeItem *AbstractFormEditorTool::toQDeclarativeItem(QGraphicsItem *item) +{ + return dynamic_cast(item->toGraphicsObject()); +} + +QGraphicsItem *AbstractFormEditorTool::topMovableGraphicsItem(const QList &itemList) +{ + foreach (QGraphicsItem *item, itemList) { + if (item->flags().testFlag(QGraphicsItem::ItemIsMovable)) + return item; + } + return 0; +} + +QDeclarativeItem *AbstractFormEditorTool::topMovableDeclarativeItem(const QList &itemList) +{ + foreach (QGraphicsItem *item, itemList) { + QDeclarativeItem *declarativeItem = toQDeclarativeItem(item); + if (declarativeItem /*&& (declarativeItem->qmlItemNode().hasShowContent())*/) + return declarativeItem; + } + + return 0; +} + +QList AbstractFormEditorTool::toGraphicsObjectList(const QList &itemList) +{ + QList gfxObjects; + foreach(QGraphicsItem *item, itemList) { + QGraphicsObject *obj = item->toGraphicsObject(); + if (obj) + gfxObjects << obj; + } + + return gfxObjects; +} + +QList AbstractFormEditorTool::toObjectList(const QList &itemList) +{ + QList objects; + foreach(QGraphicsItem *item, itemList) { + QObject *obj = item->toGraphicsObject(); + if (obj) + objects << obj; + } + + return objects; +} + +QString AbstractFormEditorTool::titleForItem(QGraphicsItem *item) +{ + QString className("QGraphicsItem"); + QString objectStringId; + + QString constructedName; + + QGraphicsObject *gfxObject = item->toGraphicsObject(); + if (gfxObject) { + className = gfxObject->metaObject()->className(); + + className.replace(QRegExp("_QMLTYPE_\\d+"), ""); + className.replace(QRegExp("_QML_\\d+"), ""); + if (className.startsWith(QLatin1String("QDeclarative"))) + className = className.replace(QLatin1String("QDeclarative"), ""); + + QDeclarativeItem *declarativeItem = qobject_cast(gfxObject); + if (declarativeItem) { + objectStringId = QDeclarativeViewObserver::idStringForObject(declarativeItem); + } + + if (!objectStringId.isEmpty()) { + constructedName = objectStringId + " (" + className + ")"; + } else { + if (!gfxObject->objectName().isEmpty()) { + constructedName = gfxObject->objectName() + " (" + className + ")"; + } else { + constructedName = className; + } + } + } + + return constructedName; +} + + +} diff --git a/share/qtcreator/qml/qmljsdebugger/editor/abstractformeditortool.h b/share/qtcreator/qml/qmljsdebugger/editor/abstractformeditortool.h new file mode 100644 index 0000000000..63f50c876f --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/abstractformeditortool.h @@ -0,0 +1,106 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef ABSTRACTFORMEDITORTOOL_H +#define ABSTRACTFORMEDITORTOOL_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QMouseEvent; +class QGraphicsItem; +class QDeclarativeItem; +class QKeyEvent; +class QGraphicsScene; +class QGraphicsObject; +class QWheelEvent; +class QDeclarativeView; +QT_END_NAMESPACE + +namespace QmlJSDebugger { + +class QDeclarativeViewObserver; + +class FormEditorView; + +class AbstractFormEditorTool : public QObject +{ + Q_OBJECT +public: + AbstractFormEditorTool(QDeclarativeViewObserver* observer); + + virtual ~AbstractFormEditorTool(); + + virtual void mousePressEvent(QMouseEvent *event) = 0; + virtual void mouseMoveEvent(QMouseEvent *event) = 0; + virtual void mouseReleaseEvent(QMouseEvent *event) = 0; + virtual void mouseDoubleClickEvent(QMouseEvent *event) = 0; + + virtual void hoverMoveEvent(QMouseEvent *event) = 0; + virtual void wheelEvent(QWheelEvent *event) = 0; + + virtual void keyPressEvent(QKeyEvent *event) = 0; + virtual void keyReleaseEvent(QKeyEvent *keyEvent) = 0; + virtual void itemsAboutToRemoved(const QList &itemList) = 0; + + virtual void clear() = 0; + + void updateSelectedItems(); + QList items() const; + + void enterContext(QGraphicsItem *itemToEnter); + + bool topItemIsMovable(const QList &itemList); + bool topItemIsResizeHandle(const QList &itemList); + bool topSelectedItemIsMovable(const QList &itemList); + + static QString titleForItem(QGraphicsItem *item); + static QList toObjectList(const QList &itemList); + static QList toGraphicsObjectList(const QList &itemList); + static QGraphicsItem* topMovableGraphicsItem(const QList &itemList); + static QDeclarativeItem* topMovableDeclarativeItem(const QList &itemList); + static QDeclarativeItem *toQDeclarativeItem(QGraphicsItem *item); + +protected: + virtual void selectedItemsChanged(const QList &objectList) = 0; + + QDeclarativeViewObserver *observer() const; + QDeclarativeView *view() const; + QGraphicsScene* scene() const; + +private: + QDeclarativeViewObserver *m_observer; + QList m_itemList; +}; + +} + +#endif // ABSTRACTFORMEDITORTOOL_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/boundingrecthighlighter.cpp b/share/qtcreator/qml/qmljsdebugger/editor/boundingrecthighlighter.cpp new file mode 100644 index 0000000000..c1daee8b19 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/boundingrecthighlighter.cpp @@ -0,0 +1,241 @@ +#include "boundingrecthighlighter.h" +#include "qdeclarativeviewobserver.h" +#include "qmlobserverconstants.h" + +#include +#include +#include + +#include + +namespace QmlJSDebugger { + +const qreal AnimDelta = 0.025f; +const int AnimInterval = 30; +const int AnimFrames = 10; + +BoundingBox::BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parentItem, QObject *parent) + : QObject(parent), + highlightedObject(itemToHighlight), + highlightPolygon(0), + highlightPolygonEdge(0) +{ + highlightPolygon = new BoundingBoxPolygonItem(parentItem); + highlightPolygonEdge = new BoundingBoxPolygonItem(parentItem); + + highlightPolygon->setPen(QPen(QColor(0, 22, 159))); + highlightPolygonEdge->setPen(QPen(QColor(158, 199, 255))); + + highlightPolygon->setFlag(QGraphicsItem::ItemIsSelectable, false); + highlightPolygonEdge->setFlag(QGraphicsItem::ItemIsSelectable, false); +} + +BoundingBox::~BoundingBox() +{ + highlightedObject.clear(); +} + +BoundingBoxPolygonItem::BoundingBoxPolygonItem(QGraphicsItem *item) : QGraphicsPolygonItem(item) +{ + QPen pen; + pen.setColor(QColor(108, 141, 221)); + pen.setWidth(1); + setPen(pen); +} + +int BoundingBoxPolygonItem::type() const +{ + return Constants::EditorItemType; +} + +BoundingRectHighlighter::BoundingRectHighlighter(QDeclarativeViewObserver *view) : + LayerItem(view->declarativeView()->scene()), + m_view(view), + m_animFrame(0) +{ + m_animTimer = new QTimer(this); + m_animTimer->setInterval(AnimInterval); + connect(m_animTimer, SIGNAL(timeout()), SLOT(animTimeout())); +} + +BoundingRectHighlighter::~BoundingRectHighlighter() +{ + +} + +void BoundingRectHighlighter::animTimeout() +{ + ++m_animFrame; + if (m_animFrame == AnimFrames) { + m_animTimer->stop(); + } + + qreal alpha = m_animFrame / float(AnimFrames); + + foreach(BoundingBox *box, m_boxes) { + box->highlightPolygonEdge->setOpacity(alpha); + } +} + +void BoundingRectHighlighter::clear() +{ + if (m_boxes.length()) { + m_animTimer->stop(); + + foreach(BoundingBox *box, m_boxes) { + freeBoundingBox(box); + } + } +} + +BoundingBox *BoundingRectHighlighter::boxFor(QGraphicsObject *item) const +{ + foreach(BoundingBox *box, m_boxes) { + if (box->highlightedObject.data() == item) { + return box; + } + } + return 0; +} + +void BoundingRectHighlighter::highlight(QList items) +{ + if (items.isEmpty()) + return; + + bool animate = false; + + QList newBoxes; + foreach(QGraphicsObject *itemToHighlight, items) { + BoundingBox *box = boxFor(itemToHighlight); + if (!box) { + box = createBoundingBox(itemToHighlight); + animate = true; + } + + newBoxes << box; + } + qSort(newBoxes); + + if (newBoxes != m_boxes) { + clear(); + m_boxes << newBoxes; + } + + highlightAll(animate); +} + +void BoundingRectHighlighter::highlight(QGraphicsObject* itemToHighlight) +{ + if (!itemToHighlight) + return; + + bool animate = false; + + BoundingBox *box = boxFor(itemToHighlight); + if (!box) { + box = createBoundingBox(itemToHighlight); + m_boxes << box; + animate = true; + qSort(m_boxes); + } + + highlightAll(animate); +} + +BoundingBox *BoundingRectHighlighter::createBoundingBox(QGraphicsObject *itemToHighlight) +{ + if (!m_freeBoxes.isEmpty()) { + BoundingBox *box = m_freeBoxes.last(); + if (box->highlightedObject.isNull()) { + box->highlightedObject = itemToHighlight; + box->highlightPolygon->show(); + box->highlightPolygonEdge->show(); + m_freeBoxes.removeLast(); + return box; + } + } + + BoundingBox *box = new BoundingBox(itemToHighlight, this, this); + + connect(itemToHighlight, SIGNAL(xChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(yChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(widthChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(heightChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(rotationChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(destroyed(QObject*)), this, SLOT(itemDestroyed(QObject*))); + + return box; +} + +void BoundingRectHighlighter::removeBoundingBox(BoundingBox *box) +{ + delete box; + box = 0; +} + +void BoundingRectHighlighter::freeBoundingBox(BoundingBox *box) +{ + if (!box->highlightedObject.isNull()) { + disconnect(box->highlightedObject.data(), SIGNAL(xChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(yChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(widthChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(heightChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(rotationChanged()), this, SLOT(refresh())); + } + + box->highlightedObject.clear(); + box->highlightPolygon->hide(); + box->highlightPolygonEdge->hide(); + m_boxes.removeOne(box); + m_freeBoxes << box; +} + +void BoundingRectHighlighter::itemDestroyed(QObject *obj) +{ + foreach(BoundingBox *box, m_boxes) { + if (box->highlightedObject.data() == obj) { + freeBoundingBox(box); + break; + } + } +} + +void BoundingRectHighlighter::highlightAll(bool animate) +{ + foreach(BoundingBox *box, m_boxes) { + if (box && box->highlightedObject.isNull()) { + // clear all highlights + clear(); + return; + } + QGraphicsObject *item = box->highlightedObject.data(); + QRectF itemAndChildRect = item->boundingRect() | item->childrenBoundingRect(); + + QPolygonF boundingRectInSceneSpace(item->mapToScene(itemAndChildRect)); + QPolygonF boundingRectInLayerItemSpace = mapFromScene(boundingRectInSceneSpace); + QRectF bboxRect = m_view->adjustToScreenBoundaries(boundingRectInLayerItemSpace.boundingRect()); + QRectF edgeRect = bboxRect; + edgeRect.adjust(-1, -1, 1, 1); + + box->highlightPolygon->setPolygon(QPolygonF(bboxRect)); + box->highlightPolygonEdge->setPolygon(QPolygonF(edgeRect)); + + if (animate) + box->highlightPolygonEdge->setOpacity(0); + } + + if (animate) { + m_animFrame = 0; + m_animTimer->start(); + } +} + +void BoundingRectHighlighter::refresh() +{ + if (!m_boxes.isEmpty()) + highlightAll(true); +} + + +} // namespace QmlJSDebugger diff --git a/share/qtcreator/qml/qmljsdebugger/editor/boundingrecthighlighter.h b/share/qtcreator/qml/qmljsdebugger/editor/boundingrecthighlighter.h new file mode 100644 index 0000000000..2463d78d2c --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/boundingrecthighlighter.h @@ -0,0 +1,78 @@ +#ifndef BOUNDINGRECTHIGHLIGHTER_H +#define BOUNDINGRECTHIGHLIGHTER_H + +#include +#include + +#include "layeritem.h" + +QT_FORWARD_DECLARE_CLASS(QGraphicsItem); +QT_FORWARD_DECLARE_CLASS(QPainter); +QT_FORWARD_DECLARE_CLASS(QWidget); +QT_FORWARD_DECLARE_CLASS(QStyleOptionGraphicsItem); +QT_FORWARD_DECLARE_CLASS(QTimer); + +namespace QmlJSDebugger { + +class QDeclarativeViewObserver; +class BoundingBox; + +class BoundingRectHighlighter : public LayerItem +{ + Q_OBJECT +public: + explicit BoundingRectHighlighter(QDeclarativeViewObserver *view); + ~BoundingRectHighlighter(); + void clear(); + void highlight(QList items); + void highlight(QGraphicsObject* item); + +private slots: + void refresh(); + void animTimeout(); + void itemDestroyed(QObject *); + +private: + BoundingBox *boxFor(QGraphicsObject *item) const; + void highlightAll(bool animate); + BoundingBox *createBoundingBox(QGraphicsObject *itemToHighlight); + void removeBoundingBox(BoundingBox *box); + void freeBoundingBox(BoundingBox *box); + +private: + Q_DISABLE_COPY(BoundingRectHighlighter); + + QDeclarativeViewObserver *m_view; + QList m_boxes; + QList m_freeBoxes; + QTimer *m_animTimer; + qreal m_animScale; + int m_animFrame; + +}; + +class BoundingBox : public QObject +{ + Q_OBJECT +public: + explicit BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parentItem, QObject *parent = 0); + ~BoundingBox(); + QWeakPointer highlightedObject; + QGraphicsPolygonItem *highlightPolygon; + QGraphicsPolygonItem *highlightPolygonEdge; + +private: + Q_DISABLE_COPY(BoundingBox); + +}; + +class BoundingBoxPolygonItem : public QGraphicsPolygonItem +{ +public: + explicit BoundingBoxPolygonItem(QGraphicsItem *item); + int type() const; +}; + +} // namespace QmlJSDebugger + +#endif // BOUNDINGRECTHIGHLIGHTER_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/colorpickertool.cpp b/share/qtcreator/qml/qmljsdebugger/editor/colorpickertool.cpp new file mode 100644 index 0000000000..bf52075fc7 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/colorpickertool.cpp @@ -0,0 +1,89 @@ +#include "colorpickertool.h" +#include "qdeclarativeviewobserver.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace QmlJSDebugger { + +ColorPickerTool::ColorPickerTool(QDeclarativeViewObserver *view) : + AbstractFormEditorTool(view) +{ + m_selectedColor.setRgb(0,0,0); +} + +ColorPickerTool::~ColorPickerTool() +{ + +} + +void ColorPickerTool::mousePressEvent(QMouseEvent * /*event*/) +{ +} + +void ColorPickerTool::mouseMoveEvent(QMouseEvent *event) +{ + pickColor(event->pos()); +} + +void ColorPickerTool::mouseReleaseEvent(QMouseEvent *event) +{ + pickColor(event->pos()); +} + +void ColorPickerTool::mouseDoubleClickEvent(QMouseEvent * /*event*/) +{ +} + + +void ColorPickerTool::hoverMoveEvent(QMouseEvent * /*event*/) +{ +} + +void ColorPickerTool::keyPressEvent(QKeyEvent * /*event*/) +{ +} + +void ColorPickerTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/) +{ +} +void ColorPickerTool::wheelEvent(QWheelEvent * /*event*/) +{ +} + +void ColorPickerTool::itemsAboutToRemoved(const QList &/*itemList*/) +{ +} + +void ColorPickerTool::clear() +{ + view()->setCursor(Qt::CrossCursor); +} + +void ColorPickerTool::selectedItemsChanged(const QList &/*itemList*/) +{ +} + +void ColorPickerTool::pickColor(const QPoint &pos) +{ + QRgb fillColor = view()->backgroundBrush().color().rgb(); + if (view()->backgroundBrush().style() == Qt::NoBrush) + fillColor = view()->palette().color(QPalette::Base).rgb(); + + QRectF target(0,0, 1, 1); + QRect source(pos.x(), pos.y(), 1, 1); + QImage img(1, 1, QImage::Format_ARGB32); + img.fill(fillColor); + QPainter painter(&img); + view()->render(&painter, target, source); + m_selectedColor = QColor::fromRgb(img.pixel(0, 0)); + + emit selectedColorChanged(m_selectedColor); +} + +} // namespace QmlJSDebugger diff --git a/share/qtcreator/qml/qmljsdebugger/editor/colorpickertool.h b/share/qtcreator/qml/qmljsdebugger/editor/colorpickertool.h new file mode 100644 index 0000000000..748ad581aa --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/colorpickertool.h @@ -0,0 +1,53 @@ +#ifndef COLORPICKERTOOL_H +#define COLORPICKERTOOL_H + +#include "abstractformeditortool.h" + +#include + +QT_FORWARD_DECLARE_CLASS(QPoint); + +namespace QmlJSDebugger { + +class ColorPickerTool : public AbstractFormEditorTool +{ + Q_OBJECT +public: + explicit ColorPickerTool(QDeclarativeViewObserver *view); + + virtual ~ColorPickerTool(); + + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + + void hoverMoveEvent(QMouseEvent *event); + + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *keyEvent); + + void wheelEvent(QWheelEvent *event); + + void itemsAboutToRemoved(const QList &itemList); + + void clear(); + +signals: + void selectedColorChanged(const QColor &color); + +protected: + + void selectedItemsChanged(const QList &itemList); + +private: + void pickColor(const QPoint &pos); + +private: + QColor m_selectedColor; + +}; + +} // namespace QmlJSDebugger + +#endif // COLORPICKERTOOL_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/editor.pri b/share/qtcreator/qml/qmljsdebugger/editor/editor.pri new file mode 100644 index 0000000000..150ca7dd08 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/editor.pri @@ -0,0 +1,37 @@ +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/boundingrecthighlighter.h \ + $$PWD/subcomponenteditortool.h \ + $$PWD/subcomponentmasklayeritem.h \ + $$PWD/zoomtool.h \ + $$PWD/colorpickertool.h \ + $$PWD/qmltoolbar.h \ + $$PWD/toolbarcolorbox.h + +SOURCES += \ + $$PWD/abstractformeditortool.cpp \ + $$PWD/selectiontool.cpp \ + $$PWD/layeritem.cpp \ + $$PWD/singleselectionmanipulator.cpp \ + $$PWD/rubberbandselectionmanipulator.cpp \ + $$PWD/selectionrectangle.cpp \ + $$PWD/selectionindicator.cpp \ + $$PWD/boundingrecthighlighter.cpp \ + $$PWD/subcomponenteditortool.cpp \ + $$PWD/subcomponentmasklayeritem.cpp \ + $$PWD/zoomtool.cpp \ + $$PWD/colorpickertool.cpp \ + $$PWD/qmltoolbar.cpp \ + $$PWD/toolbarcolorbox.cpp + +RESOURCES += $$PWD/editor.qrc + +DEFINES += QWEAKPOINTER_ENABLE_ARROW diff --git a/share/qtcreator/qml/qmljsdebugger/editor/editor.qrc b/share/qtcreator/qml/qmljsdebugger/editor/editor.qrc new file mode 100644 index 0000000000..77744d57bb --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/editor.qrc @@ -0,0 +1,24 @@ + + + images/resize_handle.png + images/select.png + images/select-marquee.png + images/color-picker.png + images/play.png + images/pause.png + images/from-qml.png + images/to-qml.png + images/color-picker-hicontrast.png + images/zoom.png + images/color-picker-24.png + images/from-qml-24.png + images/pause-24.png + images/play-24.png + images/to-qml-24.png + images/zoom-24.png + images/select-24.png + images/select-marquee-24.png + images/observermode.png + images/observermode-24.png + + diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/color-picker-24.png b/share/qtcreator/qml/qmljsdebugger/editor/images/color-picker-24.png new file mode 100644 index 0000000000..cff47212a4 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/color-picker-24.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/color-picker-hicontrast.png b/share/qtcreator/qml/qmljsdebugger/editor/images/color-picker-hicontrast.png new file mode 100644 index 0000000000..b953d08a68 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/color-picker-hicontrast.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/color-picker.png b/share/qtcreator/qml/qmljsdebugger/editor/images/color-picker.png new file mode 100644 index 0000000000..026c31b3e1 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/color-picker.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/from-qml-24.png b/share/qtcreator/qml/qmljsdebugger/editor/images/from-qml-24.png new file mode 100644 index 0000000000..0ad21f3dbb Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/from-qml-24.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/from-qml.png b/share/qtcreator/qml/qmljsdebugger/editor/images/from-qml.png new file mode 100644 index 0000000000..666382c06d Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/from-qml.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/observermode-24.png b/share/qtcreator/qml/qmljsdebugger/editor/images/observermode-24.png new file mode 100644 index 0000000000..5e74d867c0 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/observermode-24.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/observermode.png b/share/qtcreator/qml/qmljsdebugger/editor/images/observermode.png new file mode 100644 index 0000000000..daed21c944 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/observermode.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/pause-24.png b/share/qtcreator/qml/qmljsdebugger/editor/images/pause-24.png new file mode 100644 index 0000000000..d9a2f6f814 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/pause-24.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/pause.png b/share/qtcreator/qml/qmljsdebugger/editor/images/pause.png new file mode 100644 index 0000000000..114d89b12b Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/pause.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/play-24.png b/share/qtcreator/qml/qmljsdebugger/editor/images/play-24.png new file mode 100644 index 0000000000..e2b9fbcf51 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/play-24.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/play.png b/share/qtcreator/qml/qmljsdebugger/editor/images/play.png new file mode 100644 index 0000000000..011598a746 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/play.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/reload.png b/share/qtcreator/qml/qmljsdebugger/editor/images/reload.png new file mode 100644 index 0000000000..7042bec9ae Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/reload.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/resize_handle.png b/share/qtcreator/qml/qmljsdebugger/editor/images/resize_handle.png new file mode 100644 index 0000000000..2934f25b74 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/resize_handle.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/select-24.png b/share/qtcreator/qml/qmljsdebugger/editor/images/select-24.png new file mode 100644 index 0000000000..5388a9d16a Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/select-24.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/select-marquee-24.png b/share/qtcreator/qml/qmljsdebugger/editor/images/select-marquee-24.png new file mode 100644 index 0000000000..0111ddae45 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/select-marquee-24.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/select-marquee.png b/share/qtcreator/qml/qmljsdebugger/editor/images/select-marquee.png new file mode 100644 index 0000000000..92fe40d1ad Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/select-marquee.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/select.png b/share/qtcreator/qml/qmljsdebugger/editor/images/select.png new file mode 100644 index 0000000000..672285582b Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/select.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/to-qml-24.png b/share/qtcreator/qml/qmljsdebugger/editor/images/to-qml-24.png new file mode 100644 index 0000000000..b72450ddd4 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/to-qml-24.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/to-qml.png b/share/qtcreator/qml/qmljsdebugger/editor/images/to-qml.png new file mode 100644 index 0000000000..2ab951fd08 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/to-qml.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/zoom-24.png b/share/qtcreator/qml/qmljsdebugger/editor/images/zoom-24.png new file mode 100644 index 0000000000..03462001ec Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/zoom-24.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/images/zoom.png b/share/qtcreator/qml/qmljsdebugger/editor/images/zoom.png new file mode 100644 index 0000000000..17f0da6d64 Binary files /dev/null and b/share/qtcreator/qml/qmljsdebugger/editor/images/zoom.png differ diff --git a/share/qtcreator/qml/qmljsdebugger/editor/layeritem.cpp b/share/qtcreator/qml/qmljsdebugger/editor/layeritem.cpp new file mode 100644 index 0000000000..285b3e3074 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/layeritem.cpp @@ -0,0 +1,78 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "layeritem.h" +#include "qmlobserverconstants.h" + +#include + +namespace QmlJSDebugger { + +LayerItem::LayerItem(QGraphicsScene* scene) + : QGraphicsObject() +{ + scene->addItem(this); + setZValue(1); + setFlag(QGraphicsItem::ItemIsMovable, false); +} + +LayerItem::~LayerItem() +{ +} + +void LayerItem::paint(QPainter * /*painter*/, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) +{ +} + +int LayerItem::type() const +{ + return Constants::EditorItemType; +} + +QRectF LayerItem::boundingRect() const +{ + return childrenBoundingRect(); +} + +QList LayerItem::findAllChildItems() const +{ + return findAllChildItems(this); +} + +QList LayerItem::findAllChildItems(const QGraphicsItem *item) const +{ + QList itemList(item->childItems()); + + foreach (QGraphicsItem *childItem, item->childItems()) + itemList += findAllChildItems(childItem); + + return itemList; +} + +} // namespace QmlJSDebugger diff --git a/share/qtcreator/qml/qmljsdebugger/editor/layeritem.h b/share/qtcreator/qml/qmljsdebugger/editor/layeritem.h new file mode 100644 index 0000000000..c699cb8bc9 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/layeritem.h @@ -0,0 +1,57 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef LAYERITEM_H +#define LAYERITEM_H + +#include +#include + +namespace QmlJSDebugger { + +class FormEditorScene; + +class LayerItem : public QGraphicsObject +{ +public: + LayerItem(QGraphicsScene* scene); + ~LayerItem(); + void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + QRectF boundingRect() const; + int type() const; + + QList findAllChildItems() const; + +protected: + QList findAllChildItems(const QGraphicsItem *item) const; +}; + +} + +#endif // LAYERITEM_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/qmltoolbar.cpp b/share/qtcreator/qml/qmljsdebugger/editor/qmltoolbar.cpp new file mode 100644 index 0000000000..355a13b6c3 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/qmltoolbar.cpp @@ -0,0 +1,323 @@ +#include +#include +#include +#include + +#include "qmltoolbar.h" +#include "toolbarcolorbox.h" + +#include + +namespace QmlJSDebugger { + +QmlToolbar::QmlToolbar(QWidget *parent) + : QToolBar(parent) + , m_emitSignals(true) + , m_isRunning(false) + , m_animationSpeed(1.0f) + , m_previousAnimationSpeed(0.0f) + , ui(new Ui) +{ + ui->playIcon = QIcon(QLatin1String(":/qml/images/play-24.png")); + ui->pauseIcon = QIcon(QLatin1String(":/qml/images/pause-24.png")); + + ui->designmode = new QAction(QIcon(QLatin1String(":/qml/images/observermode-24.png")), tr("Observer Mode"), this); + ui->play = new QAction(ui->pauseIcon, tr("Play/Pause Animations"), this); + ui->select = new QAction(QIcon(QLatin1String(":/qml/images/select-24.png")), tr("Select"), this); + ui->selectMarquee = new QAction(QIcon(QLatin1String(":/qml/images/select-marquee-24.png")), tr("Select (Marquee)"), this); + ui->zoom = new QAction(QIcon(QLatin1String(":/qml/images/zoom-24.png")), tr("Zoom"), this); + ui->colorPicker = new QAction(QIcon(QLatin1String(":/qml/images/color-picker-24.png")), tr("Color Picker"), this); + ui->toQml = new QAction(QIcon(QLatin1String(":/qml/images/to-qml-24.png")), tr("Apply Changes to QML Viewer"), this); + ui->fromQml = new QAction(QIcon(QLatin1String(":/qml/images/from-qml-24.png")), tr("Apply Changes to Document"), this); + ui->designmode->setCheckable(true); + ui->designmode->setChecked(false); + + ui->play->setCheckable(false); + ui->select->setCheckable(true); + ui->selectMarquee->setCheckable(true); + ui->zoom->setCheckable(true); + ui->colorPicker->setCheckable(true); + + setWindowTitle(tr("Tools")); + + addAction(ui->designmode); + addAction(ui->play); + addSeparator(); + + addAction(ui->select); + // disabled because multi selection does not do anything useful without design mode + //addAction(ui->selectMarquee); + addSeparator(); + addAction(ui->zoom); + addAction(ui->colorPicker); + //addAction(ui->fromQml); + + ui->colorBox = new ToolBarColorBox(this); + ui->colorBox->setMinimumSize(24, 24); + ui->colorBox->setMaximumSize(28, 28); + ui->colorBox->setColor(Qt::black); + addWidget(ui->colorBox); + + setWindowFlags(Qt::Tool); + + QMenu *playSpeedMenu = new QMenu(this); + QActionGroup *playSpeedMenuActions = new QActionGroup(this); + playSpeedMenuActions->setExclusive(true); + playSpeedMenu->addAction(tr("Animation Speed")); + playSpeedMenu->addSeparator(); + ui->defaultAnimSpeedAction = playSpeedMenu->addAction(tr("1x"), this, SLOT(changeToDefaultAnimSpeed())); + ui->defaultAnimSpeedAction->setCheckable(true); + ui->defaultAnimSpeedAction->setChecked(true); + playSpeedMenuActions->addAction(ui->defaultAnimSpeedAction); + + ui->halfAnimSpeedAction = playSpeedMenu->addAction(tr("0.5x"), this, SLOT(changeToHalfAnimSpeed())); + ui->halfAnimSpeedAction->setCheckable(true); + playSpeedMenuActions->addAction(ui->halfAnimSpeedAction); + + ui->fourthAnimSpeedAction = playSpeedMenu->addAction(tr("0.25x"), this, SLOT(changeToFourthAnimSpeed())); + ui->fourthAnimSpeedAction->setCheckable(true); + playSpeedMenuActions->addAction(ui->fourthAnimSpeedAction); + + ui->eighthAnimSpeedAction = playSpeedMenu->addAction(tr("0.125x"), this, SLOT(changeToEighthAnimSpeed())); + ui->eighthAnimSpeedAction->setCheckable(true); + playSpeedMenuActions->addAction(ui->eighthAnimSpeedAction); + + ui->tenthAnimSpeedAction = playSpeedMenu->addAction(tr("0.1x"), this, SLOT(changeToTenthAnimSpeed())); + ui->tenthAnimSpeedAction->setCheckable(true); + playSpeedMenuActions->addAction(ui->tenthAnimSpeedAction); + + ui->menuPauseAction = playSpeedMenu->addAction(tr("Pause"), this, SLOT(updatePauseAction())); + ui->menuPauseAction->setCheckable(true); + ui->menuPauseAction->setIcon(ui->pauseIcon); + playSpeedMenuActions->addAction(ui->menuPauseAction); + ui->play->setMenu(playSpeedMenu); + + connect(ui->designmode, SIGNAL(toggled(bool)), SLOT(setDesignModeBehaviorOnClick(bool))); + + connect(ui->colorPicker, SIGNAL(triggered()), SLOT(activateColorPickerOnClick())); + + connect(ui->play, SIGNAL(triggered()), SLOT(activatePlayOnClick())); + + connect(ui->zoom, SIGNAL(triggered()), SLOT(activateZoomOnClick())); + connect(ui->colorPicker, SIGNAL(triggered()), SLOT(activateColorPickerOnClick())); + connect(ui->select, SIGNAL(triggered()), SLOT(activateSelectToolOnClick())); + connect(ui->selectMarquee, SIGNAL(triggered()), SLOT(activateMarqueeSelectToolOnClick())); + + connect(ui->toQml, SIGNAL(triggered()), SLOT(activateToQml())); + connect(ui->fromQml, SIGNAL(triggered()), SLOT(activateFromQml())); +} + +QmlToolbar::~QmlToolbar() +{ + delete ui; +} + +void QmlToolbar::activateColorPicker() +{ + m_emitSignals = false; + activateColorPickerOnClick(); + m_emitSignals = true; +} + +void QmlToolbar::activateSelectTool() +{ + m_emitSignals = false; + activateSelectToolOnClick(); + m_emitSignals = true; +} + +void QmlToolbar::activateMarqueeSelectTool() +{ + m_emitSignals = false; + activateMarqueeSelectToolOnClick(); + m_emitSignals = true; +} + +void QmlToolbar::activateZoom() +{ + m_emitSignals = false; + activateZoomOnClick(); + m_emitSignals = true; +} + +void QmlToolbar::setAnimationSpeed(qreal slowdownFactor) +{ + m_emitSignals = false; + if (slowdownFactor != 0) { + m_animationSpeed = slowdownFactor; + + if (slowdownFactor == 1.0f) { + ui->defaultAnimSpeedAction->setChecked(true); + } else if (slowdownFactor == 2.0f) { + ui->halfAnimSpeedAction->setChecked(true); + } else if (slowdownFactor == 4.0f) { + ui->fourthAnimSpeedAction->setChecked(true); + } else if (slowdownFactor == 8.0f) { + ui->eighthAnimSpeedAction->setChecked(true); + } else if (slowdownFactor == 10.0f) { + ui->tenthAnimSpeedAction->setChecked(true); + } + updatePlayAction(); + } else { + ui->menuPauseAction->setChecked(true); + updatePauseAction(); + } + + m_emitSignals = true; +} + +void QmlToolbar::changeToDefaultAnimSpeed() +{ + m_animationSpeed = 1.0f; + updatePlayAction(); +} + +void QmlToolbar::changeToHalfAnimSpeed() +{ + m_animationSpeed = 2.0f; + updatePlayAction(); +} + +void QmlToolbar::changeToFourthAnimSpeed() +{ + m_animationSpeed = 4.0f; + updatePlayAction(); +} + +void QmlToolbar::changeToEighthAnimSpeed() +{ + m_animationSpeed = 8.0f; + updatePlayAction(); +} + +void QmlToolbar::changeToTenthAnimSpeed() +{ + m_animationSpeed = 10.0f; + updatePlayAction(); +} + + +void QmlToolbar::setDesignModeBehavior(bool inDesignMode) +{ + m_emitSignals = false; + ui->designmode->setChecked(inDesignMode); + setDesignModeBehaviorOnClick(inDesignMode); + m_emitSignals = true; +} + +void QmlToolbar::setDesignModeBehaviorOnClick(bool checked) +{ + ui->play->setEnabled(checked); + ui->select->setEnabled(checked); + ui->selectMarquee->setEnabled(checked); + ui->zoom->setEnabled(checked); + ui->colorPicker->setEnabled(checked); + ui->toQml->setEnabled(checked); + ui->fromQml->setEnabled(checked); + + if (m_emitSignals) + emit designModeBehaviorChanged(checked); +} + +void QmlToolbar::setColorBoxColor(const QColor &color) +{ + ui->colorBox->setColor(color); +} + +void QmlToolbar::activatePlayOnClick() +{ + if (m_isRunning) { + updatePauseAction(); + } else { + updatePlayAction(); + } +} + +void QmlToolbar::updatePlayAction() +{ + m_isRunning = true; + ui->play->setIcon(ui->pauseIcon); + if (m_animationSpeed != m_previousAnimationSpeed) + m_previousAnimationSpeed = m_animationSpeed; + + if (m_emitSignals) + emit animationSpeedChanged(m_animationSpeed); +} + +void QmlToolbar::updatePauseAction() +{ + m_isRunning = false; + ui->play->setIcon(ui->playIcon); + if (m_emitSignals) + emit animationSpeedChanged(0.0f); +} + +void QmlToolbar::activateColorPickerOnClick() +{ + ui->zoom->setChecked(false); + ui->select->setChecked(false); + ui->selectMarquee->setChecked(false); + + ui->colorPicker->setChecked(true); + if (m_activeTool != Constants::ColorPickerMode) { + m_activeTool = Constants::ColorPickerMode; + if (m_emitSignals) + emit colorPickerSelected(); + } +} + +void QmlToolbar::activateSelectToolOnClick() +{ + ui->zoom->setChecked(false); + ui->selectMarquee->setChecked(false); + ui->colorPicker->setChecked(false); + + ui->select->setChecked(true); + if (m_activeTool != Constants::SelectionToolMode) { + m_activeTool = Constants::SelectionToolMode; + if (m_emitSignals) + emit selectToolSelected(); + } +} + +void QmlToolbar::activateMarqueeSelectToolOnClick() +{ + ui->zoom->setChecked(false); + ui->select->setChecked(false); + ui->colorPicker->setChecked(false); + + ui->selectMarquee->setChecked(true); + if (m_activeTool != Constants::MarqueeSelectionToolMode) { + m_activeTool = Constants::MarqueeSelectionToolMode; + if (m_emitSignals) + emit marqueeSelectToolSelected(); + } +} + +void QmlToolbar::activateZoomOnClick() +{ + ui->select->setChecked(false); + ui->selectMarquee->setChecked(false); + ui->colorPicker->setChecked(false); + + ui->zoom->setChecked(true); + if (m_activeTool != Constants::ZoomMode) { + m_activeTool = Constants::ZoomMode; + if (m_emitSignals) + emit zoomToolSelected(); + } +} + +void QmlToolbar::activateFromQml() +{ + if (m_emitSignals) + emit applyChangesFromQmlFileSelected(); +} + +void QmlToolbar::activateToQml() +{ + if (m_emitSignals) + emit applyChangesToQmlFileSelected(); +} + +} diff --git a/share/qtcreator/qml/qmljsdebugger/editor/qmltoolbar.h b/share/qtcreator/qml/qmljsdebugger/editor/qmltoolbar.h new file mode 100644 index 0000000000..77685b9b4f --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/qmltoolbar.h @@ -0,0 +1,96 @@ +#ifndef QMLTOOLBAR_H +#define QMLTOOLBAR_H + +#include +#include +#include "qmlobserverconstants.h" + +namespace QmlJSDebugger { + +class ToolBarColorBox; + +class QmlToolbar : public QToolBar +{ + Q_OBJECT + +public: + explicit QmlToolbar(QWidget *parent = 0); + ~QmlToolbar(); + +public slots: + void setDesignModeBehavior(bool inDesignMode); + void setColorBoxColor(const QColor &color); + void activateColorPicker(); + void activateSelectTool(); + void activateMarqueeSelectTool(); + void activateZoom(); + void setAnimationSpeed(qreal slowdownFactor = 0.0f); + +signals: + void animationSpeedChanged(qreal slowdownFactor = 1.0f); + + void designModeBehaviorChanged(bool inDesignMode); + void colorPickerSelected(); + void selectToolSelected(); + void marqueeSelectToolSelected(); + void zoomToolSelected(); + + void applyChangesToQmlFileSelected(); + void applyChangesFromQmlFileSelected(); + +private slots: + void setDesignModeBehaviorOnClick(bool inDesignMode); + void activatePlayOnClick(); + void activateColorPickerOnClick(); + void activateSelectToolOnClick(); + void activateMarqueeSelectToolOnClick(); + void activateZoomOnClick(); + + void activateFromQml(); + void activateToQml(); + + void changeToDefaultAnimSpeed(); + void changeToHalfAnimSpeed(); + void changeToFourthAnimSpeed(); + void changeToEighthAnimSpeed(); + void changeToTenthAnimSpeed(); + + void updatePlayAction(); + void updatePauseAction(); + +private: + class Ui { + public: + QAction *designmode; + QAction *play; + QAction *select; + QAction *selectMarquee; + QAction *zoom; + QAction *colorPicker; + QAction *toQml; + QAction *fromQml; + QIcon playIcon; + QIcon pauseIcon; + ToolBarColorBox *colorBox; + + QAction *defaultAnimSpeedAction; + QAction *halfAnimSpeedAction; + QAction *fourthAnimSpeedAction; + QAction *eighthAnimSpeedAction; + QAction *tenthAnimSpeedAction; + QAction *menuPauseAction; + }; + + bool m_emitSignals; + bool m_isRunning; + qreal m_animationSpeed; + qreal m_previousAnimationSpeed; + + Constants::DesignTool m_activeTool; + + Ui *ui; +}; + +} + +#endif // QMLTOOLBAR_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/rubberbandselectionmanipulator.cpp b/share/qtcreator/qml/qmljsdebugger/editor/rubberbandselectionmanipulator.cpp new file mode 100644 index 0000000000..379ba98c44 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/rubberbandselectionmanipulator.cpp @@ -0,0 +1,144 @@ +/************************************************************************** +** +** 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 "qdeclarativeviewobserver_p.h" + +#include + +namespace QmlJSDebugger { + +RubberBandSelectionManipulator::RubberBandSelectionManipulator(QGraphicsObject *layerItem, QDeclarativeViewObserver *editorView) + : m_selectionRectangleElement(layerItem), + m_editorView(editorView), + m_beginFormEditorItem(0), + m_isActive(false) +{ + m_selectionRectangleElement.hide(); +} + +void RubberBandSelectionManipulator::clear() +{ + m_selectionRectangleElement.clear(); + m_isActive = false; + m_beginPoint = QPointF(); + m_itemList.clear(); + m_oldSelectionList.clear(); +} + +QGraphicsItem *RubberBandSelectionManipulator::topFormEditorItem(const QList &itemList) +{ + if (itemList.isEmpty()) + return 0; + + return itemList.first(); +} + +void RubberBandSelectionManipulator::begin(const QPointF& beginPoint) +{ + m_beginPoint = beginPoint; + m_selectionRectangleElement.setRect(m_beginPoint, m_beginPoint); + m_selectionRectangleElement.show(); + m_isActive = true; + m_beginFormEditorItem = topFormEditorItem(QDeclarativeViewObserverPrivate::get(m_editorView)->selectableItems(beginPoint)); + m_oldSelectionList = m_editorView->selectedItems(); +} + +void RubberBandSelectionManipulator::update(const QPointF& updatePoint) +{ + m_selectionRectangleElement.setRect(m_beginPoint, updatePoint); +} + +void RubberBandSelectionManipulator::end() +{ + m_oldSelectionList.clear(); + m_selectionRectangleElement.hide(); + m_isActive = false; +} + +void RubberBandSelectionManipulator::select(SelectionType selectionType) +{ + QList itemList = QDeclarativeViewObserverPrivate::get(m_editorView)->selectableItems(m_selectionRectangleElement.rect(), + Qt::IntersectsItemShape); + QList newSelectionList; + + foreach (QGraphicsItem* item, itemList) { + if (item + && item->parentItem() + && !newSelectionList.contains(item) + //&& m_beginFormEditorItem->childItems().contains(item) // TODO activate this test + ) + { + newSelectionList.append(item); + } + } + + if (newSelectionList.isEmpty() && m_beginFormEditorItem) + newSelectionList.append(m_beginFormEditorItem); + + QList resultList; + + switch(selectionType) { + case AddToSelection: { + resultList.append(m_oldSelectionList); + resultList.append(newSelectionList); + } + break; + case ReplaceSelection: { + resultList.append(newSelectionList); + } + break; + case RemoveFromSelection: { + QSet oldSelectionSet(m_oldSelectionList.toSet()); + QSet newSelectionSet(newSelectionList.toSet()); + resultList.append(oldSelectionSet.subtract(newSelectionSet).toList()); + } + } + + m_editorView->setSelectedItems(resultList); +} + + +void RubberBandSelectionManipulator::setItems(const QList &itemList) +{ + m_itemList = itemList; +} + +QPointF RubberBandSelectionManipulator::beginPoint() const +{ + return m_beginPoint; +} + +bool RubberBandSelectionManipulator::isActive() const +{ + return m_isActive; + +} + +} diff --git a/share/qtcreator/qml/qmljsdebugger/editor/rubberbandselectionmanipulator.h b/share/qtcreator/qml/qmljsdebugger/editor/rubberbandselectionmanipulator.h new file mode 100644 index 0000000000..e681569577 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/rubberbandselectionmanipulator.h @@ -0,0 +1,82 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef RUBBERBANDSELECTIONMANIPULATOR_H +#define RUBBERBANDSELECTIONMANIPULATOR_H + + +#include "selectionrectangle.h" + +namespace QmlJSDebugger { + +class QDeclarativeViewObserver; + +class RubberBandSelectionManipulator +{ +public: + enum SelectionType { + ReplaceSelection, + AddToSelection, + RemoveFromSelection + }; + + + RubberBandSelectionManipulator(QGraphicsObject *layerItem, QDeclarativeViewObserver *editorView); + + void setItems(const QList &itemList); + + void begin(const QPointF& beginPoint); + void update(const QPointF& updatePoint); + void end(); + + void clear(); + + void select(SelectionType selectionType); + + QPointF beginPoint() const; + + bool isActive() const; + +protected: + QGraphicsItem *topFormEditorItem(const QList &itemList); + + +private: + QList m_itemList; + QList m_oldSelectionList; + SelectionRectangle m_selectionRectangleElement; + QPointF m_beginPoint; + QDeclarativeViewObserver *m_editorView; + QGraphicsItem *m_beginFormEditorItem; + bool m_isActive; +}; + +} + +#endif // RUBBERBANDSELECTIONMANIPULATOR_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/selectionindicator.cpp b/share/qtcreator/qml/qmljsdebugger/editor/selectionindicator.cpp new file mode 100644 index 0000000000..5782f2a5ee --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/selectionindicator.cpp @@ -0,0 +1,127 @@ +/************************************************************************** +** +** 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 "qdeclarativeviewobserver_p.h" +#include "qmlobserverconstants.h" + +#include +#include +#include +#include + +namespace QmlJSDebugger { + +SelectionIndicator::SelectionIndicator(QDeclarativeViewObserver *editorView, QGraphicsObject *layerItem) + : m_layerItem(layerItem), m_view(editorView) +{ +} + +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.isNull()) { + QHashIterator iter(m_indicatorShapeHash); + while(iter.hasNext()) { + iter.next(); + m_layerItem->scene()->removeItem(iter.value()); + delete iter.value(); + } + } + + m_indicatorShapeHash.clear(); + +} + +QPolygonF SelectionIndicator::addBoundingRectToPolygon(QGraphicsItem *item, QPolygonF &polygon) +{ + // ### remove this if statement when QTBUG-12172 gets fixed + if (item->boundingRect() != QRectF(0,0,0,0)) { + QPolygonF bounding = item->mapToScene(item->boundingRect()); + if (bounding.isClosed()) //avoid crashes if there is an infinite scale. + polygon = polygon.united(bounding); + } + + foreach(QGraphicsItem *child, item->childItems()) { + if (!QDeclarativeViewObserverPrivate::get(m_view)->isEditorItem(child)) + addBoundingRectToPolygon(child, polygon); + } + return polygon; +} + +void SelectionIndicator::setItems(const QList > &itemList) +{ + clear(); + + // set selections to also all children if they are not editor items + + foreach (QWeakPointer obj, itemList) { + if (obj.isNull()) + continue; + + QGraphicsItem *item = obj.data(); + + QGraphicsPolygonItem *newSelectionIndicatorGraphicsItem = new QGraphicsPolygonItem(m_layerItem.data()); + if (!m_indicatorShapeHash.contains(item)) { + m_indicatorShapeHash.insert(item, newSelectionIndicatorGraphicsItem); + + QPolygonF boundingShapeInSceneSpace; + addBoundingRectToPolygon(item, boundingShapeInSceneSpace); + + QRectF boundingRect = m_view->adjustToScreenBoundaries(boundingShapeInSceneSpace.boundingRect()); + QPolygonF boundingRectInLayerItemSpace = m_layerItem->mapFromScene(boundingRect); + + QPen pen; + pen.setColor(QColor(108, 141, 221)); + newSelectionIndicatorGraphicsItem->setData(Constants::EditorItemDataKey, QVariant(true)); + newSelectionIndicatorGraphicsItem->setFlag(QGraphicsItem::ItemIsSelectable, false); + newSelectionIndicatorGraphicsItem->setPolygon(boundingRectInLayerItemSpace); + newSelectionIndicatorGraphicsItem->setPen(pen); + } + } +} + +} //namespace QmlJSDebugger + diff --git a/share/qtcreator/qml/qmljsdebugger/editor/selectionindicator.h b/share/qtcreator/qml/qmljsdebugger/editor/selectionindicator.h new file mode 100644 index 0000000000..ecfeda86a0 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/selectionindicator.h @@ -0,0 +1,66 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef SELECTIONINDICATOR_H +#define SELECTIONINDICATOR_H + +#include +#include +#include + +namespace QmlJSDebugger { + +class QDeclarativeViewObserver; + +class SelectionIndicator +{ +public: + SelectionIndicator(QDeclarativeViewObserver* editorView, QGraphicsObject *layerItem); + ~SelectionIndicator(); + + void show(); + void hide(); + + void clear(); + + void setItems(const QList > &itemList); + +private: + QPolygonF addBoundingRectToPolygon(QGraphicsItem *item, QPolygonF &polygon); + +private: + QHash m_indicatorShapeHash; + QWeakPointer m_layerItem; + QDeclarativeViewObserver *m_view; + +}; + +} + +#endif // SELECTIONINDICATOR_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/selectionrectangle.cpp b/share/qtcreator/qml/qmljsdebugger/editor/selectionrectangle.cpp new file mode 100644 index 0000000000..dc8ee26cce --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/selectionrectangle.cpp @@ -0,0 +1,95 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "selectionrectangle.h" +#include "qmlobserverconstants.h" + +#include +#include +#include +#include +#include + +namespace QmlJSDebugger { + +class SelectionRectShape : public QGraphicsRectItem +{ +public: + SelectionRectShape(QGraphicsItem *parent = 0) : QGraphicsRectItem(parent) {} + int type() const { return Constants::EditorItemType; } +}; + +SelectionRectangle::SelectionRectangle(QGraphicsObject *layerItem) + : m_controlShape(new SelectionRectShape(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); +} + +} diff --git a/share/qtcreator/qml/qmljsdebugger/editor/selectionrectangle.h b/share/qtcreator/qml/qmljsdebugger/editor/selectionrectangle.h new file mode 100644 index 0000000000..03346d7bb9 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/selectionrectangle.h @@ -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 +#include +#include + +namespace QmlJSDebugger { + +class SelectionRectangle +{ +public: + SelectionRectangle(QGraphicsObject *layerItem); + ~SelectionRectangle(); + + void show(); + void hide(); + + void clear(); + + void setRect(const QPointF &firstPoint, + const QPointF &secondPoint); + + QRectF rect() const; + +private: + QGraphicsRectItem *m_controlShape; + QWeakPointer m_layerItem; +}; + +} + +#endif // SELECTIONRECTANGLE_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/selectiontool.cpp b/share/qtcreator/qml/qmljsdebugger/editor/selectiontool.cpp new file mode 100644 index 0000000000..b677a10577 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/selectiontool.cpp @@ -0,0 +1,447 @@ +/************************************************************************** +** +** 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 "layeritem.h" + +//#include "resizehandleitem.h" +#include "qdeclarativeviewobserver_p.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace QmlJSDebugger { + +SelectionTool::SelectionTool(QDeclarativeViewObserver *editorView) + : AbstractFormEditorTool(editorView), + m_rubberbandSelectionMode(false), + m_rubberbandSelectionManipulator(QDeclarativeViewObserverPrivate::get(editorView)->manipulatorLayer, editorView), + m_singleSelectionManipulator(editorView), + m_selectionIndicator(editorView, QDeclarativeViewObserverPrivate::get(editorView)->manipulatorLayer), + //m_resizeIndicator(editorView->manipulatorLayer()), + m_selectOnlyContentItems(true) +{ + +} + +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 &itemList) const +{ + const QList selectedItems = QDeclarativeViewObserverPrivate::get(observer())->selectedItems(); + + if (selectedItems.isEmpty()) + return false; + + foreach(QGraphicsItem *item, itemList) { + if (selectedItems.contains(item)) { + return true; + } + } + + return false; +} + +void SelectionTool::mousePressEvent(QMouseEvent *event) +{ + QList itemList = QDeclarativeViewObserverPrivate::get(observer())->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()) { + QDeclarativeViewObserverPrivate::get(observer())->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()) { + observer()->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 itemList, QPoint globalPos) +{ + if (!QDeclarativeViewObserverPrivate::get(observer())->mouseInsideContextItem()) + return; + + QMenu contextMenu; + connect(&contextMenu, SIGNAL(hovered(QAction*)), this, SLOT(contextMenuElementHovered(QAction*))); + + m_contextMenuItemList = itemList; + + contextMenu.addAction("Items"); + contextMenu.addSeparator(); + int shortcutKey = Qt::Key_1; + bool addKeySequence = true; + int i = 0; + + foreach(QGraphicsItem * const item, itemList) { + QString itemTitle = titleForItem(item); + QAction *elementAction = contextMenu.addAction(itemTitle, this, SLOT(contextMenuElementSelected())); + + if (observer()->selectedItems().contains(item)) { + QFont boldFont = elementAction->font(); + boldFont.setBold(true); + elementAction->setFont(boldFont); + } + + elementAction->setData(i); + if (addKeySequence) + elementAction->setShortcut(QKeySequence(shortcutKey)); + + shortcutKey++; + if (shortcutKey > Qt::Key_9) + addKeySequence = false; + + ++i; + } + // add root item separately +// QString itemTitle = QString(tr("%1")).arg(titleForItem(view()->currentRootItem())); +// contextMenu.addAction(itemTitle, this, SLOT(contextMenuElementSelected())); +// m_contextMenuItemList.append(view()->currentRootItem()); + + contextMenu.exec(globalPos); + m_contextMenuItemList.clear(); +} + +void SelectionTool::contextMenuElementSelected() +{ + QAction *senderAction = static_cast(sender()); + int itemListIndex = senderAction->data().toInt(); + if (itemListIndex >= 0 && itemListIndex < m_contextMenuItemList.length()) { + + QPointF updatePt(0, 0); + QGraphicsItem *item = m_contextMenuItemList.at(itemListIndex); + m_singleSelectionManipulator.begin(updatePt); + m_singleSelectionManipulator.select(SingleSelectionManipulator::InvertSelection, + QList() << item, + false); + m_singleSelectionManipulator.end(updatePt); + enterContext(item); + } +} + +void SelectionTool::contextMenuElementHovered(QAction *action) +{ + int itemListIndex = action->data().toInt(); + if (itemListIndex >= 0 && itemListIndex < m_contextMenuItemList.length()) { + QGraphicsObject *item = m_contextMenuItemList.at(itemListIndex)->toGraphicsObject(); + QDeclarativeViewObserverPrivate::get(observer())->highlight(item); + } +} + +void 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) +{ +// ### commented out until move tool is re-enabled +// QList 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 selectableItemList = QDeclarativeViewObserverPrivate::get(observer())->selectableItems(event->pos()); + if (!selectableItemList.isEmpty()) { + QGraphicsObject *item = selectableItemList.first()->toGraphicsObject(); + if (item) + QDeclarativeViewObserverPrivate::get(observer())->highlight(item); + + return; + } + + QDeclarativeViewObserverPrivate::get(observer())->clearHighlight(); +} + +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: + // disabled for now, cannot move stuff yet. + //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 itemList = QDeclarativeViewObserverPrivate::get(observer())->selectableItems(event->pos()); + + int selectedIdx = 0; + if (!observer()->selectedItems().isEmpty()) { + selectedIdx = itemList.indexOf(observer()->selectedItems().first()); + if (selectedIdx >= 0) { + if (event->delta() > 0) { + selectedIdx++; + if (selectedIdx == itemList.length()) + selectedIdx = 0; + } else if (event->delta() < 0) { + selectedIdx--; + if (selectedIdx == -1) + selectedIdx = itemList.length() - 1; + } + } else { + selectedIdx = 0; + } + } + + QPointF updatePt(0, 0); + m_singleSelectionManipulator.begin(updatePt); + m_singleSelectionManipulator.select(SingleSelectionManipulator::ReplaceSelection, + QList() << itemList.at(selectedIdx), + false); + m_singleSelectionManipulator.end(updatePt); + +} + +void SelectionTool::setSelectOnlyContentItems(bool selectOnlyContentItems) +{ + m_selectOnlyContentItems = selectOnlyContentItems; +} + +void SelectionTool::itemsAboutToRemoved(const QList &/*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 &itemList) +{ + foreach(QWeakPointer obj, m_selectedItemList) { + if (!obj.isNull()) { + disconnect(obj.data(), SIGNAL(xChanged()), this, SLOT(repaintBoundingRects())); + disconnect(obj.data(), SIGNAL(yChanged()), this, SLOT(repaintBoundingRects())); + disconnect(obj.data(), SIGNAL(widthChanged()), this, SLOT(repaintBoundingRects())); + disconnect(obj.data(), SIGNAL(heightChanged()), this, SLOT(repaintBoundingRects())); + disconnect(obj.data(), SIGNAL(rotationChanged()), this, SLOT(repaintBoundingRects())); + } + } + + QList objects = toGraphicsObjectList(itemList); + m_selectedItemList.clear(); + + foreach(QGraphicsObject *obj, objects) { + m_selectedItemList.append(obj); + connect(obj, SIGNAL(xChanged()), this, SLOT(repaintBoundingRects())); + connect(obj, SIGNAL(yChanged()), this, SLOT(repaintBoundingRects())); + connect(obj, SIGNAL(widthChanged()), this, SLOT(repaintBoundingRects())); + connect(obj, SIGNAL(heightChanged()), this, SLOT(repaintBoundingRects())); + connect(obj, SIGNAL(rotationChanged()), this, SLOT(repaintBoundingRects())); + } + + m_selectionIndicator.setItems(m_selectedItemList); + //m_resizeIndicator.setItems(toGraphicsObjectList(itemList)); +} + +void SelectionTool::repaintBoundingRects() +{ + m_selectionIndicator.setItems(m_selectedItemList); +} + +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()); +} + +} diff --git a/share/qtcreator/qml/qmljsdebugger/editor/selectiontool.h b/share/qtcreator/qml/qmljsdebugger/editor/selectiontool.h new file mode 100644 index 0000000000..63461da296 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/selectiontool.h @@ -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 "rubberbandselectionmanipulator.h" +#include "singleselectionmanipulator.h" +#include "selectionindicator.h" + +#include +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QGraphicsItem); +QT_FORWARD_DECLARE_CLASS(QMouseEvent); +QT_FORWARD_DECLARE_CLASS(QKeyEvent); + +namespace QmlJSDebugger { + +class SelectionTool : public AbstractFormEditorTool +{ + Q_OBJECT + +public: + SelectionTool(QDeclarativeViewObserver* 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 &itemList); + // QVariant itemChange(const QList &itemList, +// QGraphicsItem::GraphicsItemChange change, +// const QVariant &value ); + +// void update(); + + void clear(); + + void selectedItemsChanged(const QList &itemList); + + void selectUnderPoint(QMouseEvent *event); + + void setSelectOnlyContentItems(bool selectOnlyContentItems); + + void setRubberbandSelectionMode(bool value); + +private slots: + void contextMenuElementSelected(); + void contextMenuElementHovered(QAction *action); + void repaintBoundingRects(); + +private: + void createContextMenu(QList itemList, QPoint globalPos); + SingleSelectionManipulator::SelectionType getSelectionType(Qt::KeyboardModifiers modifiers); + bool alreadySelected(const QList &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 > m_selectedItemList; + + QList m_contextMenuItemList; +}; + +} + +#endif // SELECTIONTOOL_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/singleselectionmanipulator.cpp b/share/qtcreator/qml/qmljsdebugger/editor/singleselectionmanipulator.cpp new file mode 100644 index 0000000000..d006481549 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/singleselectionmanipulator.cpp @@ -0,0 +1,134 @@ +/************************************************************************** +** +** 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 "qdeclarativeviewobserver.h" +#include "qdeclarativeviewobserver_p.h" +#include + +namespace QmlJSDebugger { + +SingleSelectionManipulator::SingleSelectionManipulator(QDeclarativeViewObserver *editorView) + : m_editorView(editorView), + m_isActive(false) +{ +} + + +void SingleSelectionManipulator::begin(const QPointF &beginPoint) +{ + m_beginPoint = beginPoint; + m_isActive = true; + m_oldSelectionList = QDeclarativeViewObserverPrivate::get(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 &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 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 itemList = QDeclarativeViewObserverPrivate::get(m_editorView)->selectableItems(m_beginPoint); + select(selectionType, itemList, selectOnlyContentItems); +} + + +bool SingleSelectionManipulator::isActive() const +{ + return m_isActive; +} + +QPointF SingleSelectionManipulator::beginPoint() const +{ + return m_beginPoint; +} + +} diff --git a/share/qtcreator/qml/qmljsdebugger/editor/singleselectionmanipulator.h b/share/qtcreator/qml/qmljsdebugger/editor/singleselectionmanipulator.h new file mode 100644 index 0000000000..e4ff0f346a --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/singleselectionmanipulator.h @@ -0,0 +1,76 @@ +/************************************************************************** +** +** 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 +#include + +QT_FORWARD_DECLARE_CLASS(QGraphicsItem); + +namespace QmlJSDebugger { + +class QDeclarativeViewObserver; + +class SingleSelectionManipulator +{ +public: + SingleSelectionManipulator(QDeclarativeViewObserver *editorView); + + enum SelectionType { + ReplaceSelection, + AddToSelection, + RemoveFromSelection, + InvertSelection + }; + + void begin(const QPointF& beginPoint); + void update(const QPointF& updatePoint); + void end(const QPointF& updatePoint); + + void select(SelectionType selectionType, const QList &items, bool selectOnlyContentItems); + void select(SelectionType selectionType, bool selectOnlyContentItems); + + void clear(); + + QPointF beginPoint() const; + + bool isActive() const; + +private: + QList m_oldSelectionList; + QPointF m_beginPoint; + QDeclarativeViewObserver *m_editorView; + bool m_isActive; +}; + +} + +#endif // SINGLESELECTIONMANIPULATOR_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/subcomponenteditortool.cpp b/share/qtcreator/qml/qmljsdebugger/editor/subcomponenteditortool.cpp new file mode 100644 index 0000000000..5089944ddb --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/subcomponenteditortool.cpp @@ -0,0 +1,320 @@ +#include "subcomponenteditortool.h" +#include "qdeclarativeviewobserver_p.h" +#include "subcomponentmasklayeritem.h" +#include "layeritem.h" + +#include +#include +#include +#include +#include + +#include + + +namespace QmlJSDebugger { + +const qreal MaxOpacity = 0.5f; + +SubcomponentEditorTool::SubcomponentEditorTool(QDeclarativeViewObserver *view) + : AbstractFormEditorTool(view), + m_animIncrement(0.05f), + m_animTimer(new QTimer(this)) +{ + m_mask = new SubcomponentMaskLayerItem(view, QDeclarativeViewObserverPrivate::get(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; + + QPointF scenePos = view()->mapToScene(mousePos); + QRectF itemRect = m_currentContext.top()->boundingRect() | m_currentContext.top()->childrenBoundingRect(); + QRectF polyRect = m_currentContext.top()->mapToScene(itemRect).boundingRect(); + + return polyRect.contains(scenePos); +} + +void SubcomponentEditorTool::mouseReleaseEvent(QMouseEvent * /*event*/) +{ + +} + +void SubcomponentEditorTool::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (event->buttons() & Qt::LeftButton + && !containsCursor(event->pos()) + && m_currentContext.size() > 1) + { + aboutToPopContext(); + } +} + +void SubcomponentEditorTool::hoverMoveEvent(QMouseEvent *event) +{ + if (!containsCursor(event->pos()) && m_currentContext.size() > 1) { + QDeclarativeViewObserverPrivate::get(observer())->clearHighlight(); + } +} + +void SubcomponentEditorTool::wheelEvent(QWheelEvent * /*event*/) +{ + +} + +void SubcomponentEditorTool::keyPressEvent(QKeyEvent * /*event*/) +{ + +} + +void SubcomponentEditorTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/) +{ + +} + +void SubcomponentEditorTool::itemsAboutToRemoved(const QList &/*itemList*/) +{ + +} + +void SubcomponentEditorTool::animate() +{ + if (m_animIncrement > 0) { + if (m_mask->opacity() + m_animIncrement < MaxOpacity) { + m_mask->setOpacity(m_mask->opacity() + m_animIncrement); + } else { + m_animTimer->stop(); + m_mask->setOpacity(MaxOpacity); + } + } else { + if (m_mask->opacity() + m_animIncrement > 0) { + m_mask->setOpacity(m_mask->opacity() + m_animIncrement); + } else { + m_animTimer->stop(); + m_mask->setOpacity(0); + popContext(); + emit contextPathChanged(m_path); + } + } + +} + +void SubcomponentEditorTool::clear() +{ + m_currentContext.clear(); + m_mask->setCurrentItem(0); + m_animTimer->stop(); + m_mask->hide(); + m_path.clear(); + + emit contextPathChanged(m_path); + emit cleared(); +} + +void SubcomponentEditorTool::selectedItemsChanged(const QList &/*itemList*/) +{ + +} + +void SubcomponentEditorTool::setCurrentItem(QGraphicsItem* contextItem) +{ + if (!contextItem) + return; + + QGraphicsObject *gfxObject = contextItem->toGraphicsObject(); + if (!gfxObject) + return; + + //QString parentClassName = gfxObject->metaObject()->className(); + //if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+"))) + + bool containsSelectableItems = false; + foreach(QGraphicsItem *item, gfxObject->childItems()) { + if (item->type() == Constants::EditorItemType + || item->type() == Constants::ResizeHandleItemType) + { + continue; + } + containsSelectableItems = true; + break; + } + + if (containsSelectableItems) { + m_mask->setCurrentItem(gfxObject); + m_mask->setOpacity(0); + m_mask->show(); + m_animIncrement = 0.05f; + m_animTimer->start(); + + QDeclarativeViewObserverPrivate::get(observer())->clearHighlight(); + observer()->setSelectedItems(QList()); + + pushContext(gfxObject); + } +} + +QGraphicsItem *SubcomponentEditorTool::firstChildOfContext(QGraphicsItem *item) const +{ + if (!item) + return 0; + + if (isDirectChildOfContext(item)) + return item; + + QGraphicsItem *parent = item->parentItem(); + while (parent) { + if (isDirectChildOfContext(parent)) + return parent; + parent = parent->parentItem(); + } + + return 0; +} + +bool SubcomponentEditorTool::isChildOfContext(QGraphicsItem *item) const +{ + return (firstChildOfContext(item) != 0); +} + +bool SubcomponentEditorTool::isDirectChildOfContext(QGraphicsItem *item) const +{ + return (item->parentItem() == m_currentContext.top()); +} + +bool SubcomponentEditorTool::itemIsChildOfQmlSubComponent(QGraphicsItem *item) const +{ + if (item->parentItem() && item->parentItem() != m_currentContext.top()) { + QGraphicsObject *parent = item->parentItem()->toGraphicsObject(); + QString parentClassName = parent->metaObject()->className(); + + if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+"))) { + return true; + } else { + return itemIsChildOfQmlSubComponent(parent); + } + } + + return false; +} + +void SubcomponentEditorTool::pushContext(QGraphicsObject *contextItem) +{ + connect(contextItem, SIGNAL(destroyed(QObject*)), this, SLOT(contextDestroyed(QObject*))); + connect(contextItem, SIGNAL(xChanged()), this, SLOT(resizeMask())); + connect(contextItem, SIGNAL(yChanged()), this, SLOT(resizeMask())); + connect(contextItem, SIGNAL(widthChanged()), this, SLOT(resizeMask())); + connect(contextItem, SIGNAL(heightChanged()), this, SLOT(resizeMask())); + connect(contextItem, SIGNAL(rotationChanged()), this, SLOT(resizeMask())); + + m_currentContext.push(contextItem); + QString title = titleForItem(contextItem); + emit contextPushed(title); + + m_path << title; + emit contextPathChanged(m_path); +} + +void SubcomponentEditorTool::aboutToPopContext() +{ + if (m_currentContext.size() > 2) { + popContext(); + emit contextPathChanged(m_path); + } else { + m_animIncrement = -0.05f; + m_animTimer->start(); + } +} + +QGraphicsObject *SubcomponentEditorTool::popContext() +{ + QGraphicsObject *popped = m_currentContext.pop(); + m_path.removeLast(); + + emit contextPopped(); + + disconnect(popped, SIGNAL(xChanged()), this, SLOT(resizeMask())); + disconnect(popped, SIGNAL(yChanged()), this, SLOT(resizeMask())); + disconnect(popped, SIGNAL(scaleChanged()), this, SLOT(resizeMask())); + disconnect(popped, SIGNAL(widthChanged()), this, SLOT(resizeMask())); + disconnect(popped, SIGNAL(heightChanged()), this, SLOT(resizeMask())); + + if (m_currentContext.size() > 1) { + QGraphicsObject *item = m_currentContext.top(); + m_mask->setCurrentItem(item); + m_mask->setOpacity(MaxOpacity); + m_mask->setVisible(true); + } else { + m_mask->setVisible(false); + } + + return popped; +} + +void SubcomponentEditorTool::resizeMask() +{ + QGraphicsObject *item = m_currentContext.top(); + m_mask->setCurrentItem(item); +} + +QGraphicsObject *SubcomponentEditorTool::currentRootItem() const +{ + return m_currentContext.top(); +} + +void SubcomponentEditorTool::contextDestroyed(QObject *contextToDestroy) +{ + disconnect(contextToDestroy, SIGNAL(destroyed(QObject*)), this, SLOT(contextDestroyed(QObject*))); + + // pop out the whole context - it might not be safe anymore. + while (m_currentContext.size() > 1) { + m_currentContext.pop(); + m_path.removeLast(); + emit contextPopped(); + } + m_mask->setVisible(false); + + emit contextPathChanged(m_path); +} + +QGraphicsObject *SubcomponentEditorTool::setContext(int contextIndex) +{ + Q_ASSERT(contextIndex >= 0); + + // sometimes we have to delete the context while user was still clicking around, + // so just bail out. + if (contextIndex >= m_currentContext.size() -1) + return 0; + + while (m_currentContext.size() - 1 > contextIndex) { + popContext(); + } + emit contextPathChanged(m_path); + + return m_currentContext.top(); +} + +int SubcomponentEditorTool::contextIndex() const +{ + return m_currentContext.size() - 1; +} + + +} // namespace QmlJSDebugger diff --git a/share/qtcreator/qml/qmljsdebugger/editor/subcomponenteditortool.h b/share/qtcreator/qml/qmljsdebugger/editor/subcomponenteditortool.h new file mode 100644 index 0000000000..c1652ddb24 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/subcomponenteditortool.h @@ -0,0 +1,83 @@ +#ifndef SUBCOMPONENTEDITORTOOL_H +#define SUBCOMPONENTEDITORTOOL_H + +#include "abstractformeditortool.h" +#include +#include + +QT_FORWARD_DECLARE_CLASS(QGraphicsObject) +QT_FORWARD_DECLARE_CLASS(QPoint) +QT_FORWARD_DECLARE_CLASS(QTimer) + +namespace QmlJSDebugger { + +class SubcomponentMaskLayerItem; + +class SubcomponentEditorTool : public AbstractFormEditorTool +{ + Q_OBJECT + +public: + SubcomponentEditorTool(QDeclarativeViewObserver *view); + ~SubcomponentEditorTool(); + + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + + void hoverMoveEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); + + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *keyEvent); + void itemsAboutToRemoved(const QList &itemList); + + void clear(); + + bool containsCursor(const QPoint &mousePos) const; + bool itemIsChildOfQmlSubComponent(QGraphicsItem *item) const; + + bool isChildOfContext(QGraphicsItem *item) const; + bool isDirectChildOfContext(QGraphicsItem *item) const; + QGraphicsItem *firstChildOfContext(QGraphicsItem *item) const; + + void setCurrentItem(QGraphicsItem *contextObject); + + void pushContext(QGraphicsObject *contextItem); + + QGraphicsObject *currentRootItem() const; + QGraphicsObject *setContext(int contextIndex); + int contextIndex() const; + +signals: + void exitContextRequested(); + void cleared(); + void contextPushed(const QString &contextTitle); + void contextPopped(); + void contextPathChanged(const QStringList &path); + +protected: + void selectedItemsChanged(const QList &itemList); + +private slots: + void animate(); + void contextDestroyed(QObject *context); + void resizeMask(); + +private: + QGraphicsObject *popContext(); + void aboutToPopContext(); + +private: + QStack m_currentContext; + QStringList m_path; + + qreal m_animIncrement; + SubcomponentMaskLayerItem *m_mask; + QTimer *m_animTimer; +}; + +} // namespace QmlJSDebugger + +#endif // SUBCOMPONENTEDITORTOOL_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/subcomponentmasklayeritem.cpp b/share/qtcreator/qml/qmljsdebugger/editor/subcomponentmasklayeritem.cpp new file mode 100644 index 0000000000..1e8ff42466 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/subcomponentmasklayeritem.cpp @@ -0,0 +1,80 @@ +#include "subcomponentmasklayeritem.h" +#include "qmlobserverconstants.h" +#include "qdeclarativeviewobserver.h" +#include + +namespace QmlJSDebugger { + +SubcomponentMaskLayerItem::SubcomponentMaskLayerItem(QDeclarativeViewObserver *observer, QGraphicsItem *parentItem) : + QGraphicsPolygonItem(parentItem), + m_observer(observer), + m_currentItem(0), + m_borderRect(new QGraphicsRectItem(this)) +{ + m_borderRect->setRect(0,0,0,0); + m_borderRect->setPen(QPen(QColor(60, 60, 60), 1)); + m_borderRect->setData(Constants::EditorItemDataKey, QVariant(true)); + + setBrush(QBrush(QColor(160,160,160))); + setPen(Qt::NoPen); +} + +int SubcomponentMaskLayerItem::type() const +{ + return Constants::EditorItemType; +} + +static QRectF resizeRect(const QRectF &newRect, const QRectF &oldRect) +{ + QRectF result = newRect; + if (oldRect.left() < newRect.left()) + result.setLeft(oldRect.left()); + + if (oldRect.top() < newRect.top()) + result.setTop(oldRect.top()); + + if (oldRect.right() > newRect.right()) + result.setRight(oldRect.right()); + + if (oldRect.bottom() > newRect.bottom()) + result.setBottom(oldRect.bottom()); + + return result; +} + + +void SubcomponentMaskLayerItem::setCurrentItem(QGraphicsItem *item) +{ + QGraphicsItem *prevItem = m_currentItem; + m_currentItem = item; + + if (!m_currentItem) + return; + + QPolygonF viewPoly(QRectF(m_observer->declarativeView()->rect())); + viewPoly = m_observer->declarativeView()->mapToScene(viewPoly.toPolygon()); + + QRectF itemRect = item->boundingRect() | item->childrenBoundingRect(); + QPolygonF itemPoly(itemRect); + itemPoly = item->mapToScene(itemPoly); + + // if updating the same item as before, resize the rectangle only bigger, not smaller. + if (prevItem == item && prevItem != 0) { + m_itemPolyRect = resizeRect(itemPoly.boundingRect(), m_itemPolyRect); + } else { + m_itemPolyRect = itemPoly.boundingRect(); + } + QRectF borderRect = m_itemPolyRect; + borderRect.adjust(-1, -1, 1, 1); + m_borderRect->setRect(borderRect); + + itemPoly = viewPoly.subtracted(QPolygonF(m_itemPolyRect)); + setPolygon(itemPoly); +} + +QGraphicsItem *SubcomponentMaskLayerItem::currentItem() const +{ + return m_currentItem; +} + +} // namespace QmlJSDebugger diff --git a/share/qtcreator/qml/qmljsdebugger/editor/subcomponentmasklayeritem.h b/share/qtcreator/qml/qmljsdebugger/editor/subcomponentmasklayeritem.h new file mode 100644 index 0000000000..37759ebf71 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/subcomponentmasklayeritem.h @@ -0,0 +1,29 @@ +#ifndef SUBCOMPONENTMASKLAYERITEM_H +#define SUBCOMPONENTMASKLAYERITEM_H + +#include + +namespace QmlJSDebugger { + +class QDeclarativeViewObserver; + +class SubcomponentMaskLayerItem : public QGraphicsPolygonItem +{ +public: + explicit SubcomponentMaskLayerItem(QDeclarativeViewObserver *observer, QGraphicsItem *parentItem = 0); + int type() const; + void setCurrentItem(QGraphicsItem *item); + void setBoundingBox(const QRectF &boundingBox); + QGraphicsItem *currentItem() const; + QRectF itemRect() const; + +private: + QDeclarativeViewObserver *m_observer; + QGraphicsItem *m_currentItem; + QGraphicsRectItem *m_borderRect; + QRectF m_itemPolyRect; +}; + +} // namespace QmlJSDebugger + +#endif // SUBCOMPONENTMASKLAYERITEM_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/toolbarcolorbox.cpp b/share/qtcreator/qml/qmljsdebugger/editor/toolbarcolorbox.cpp new file mode 100644 index 0000000000..dd6eb7e4a7 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/toolbarcolorbox.cpp @@ -0,0 +1,96 @@ +#include "toolbarcolorbox.h" +#include "qmlobserverconstants.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace QmlJSDebugger { + +ToolBarColorBox::ToolBarColorBox(QWidget *parent) : + QLabel(parent) +{ + m_copyHexColor = new QAction(QIcon(QLatin1String(":/qml/images/color-picker-hicontrast.png")), 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 = QColor(43, 43, 43); + + p.setBrush(QBrush(m_color)); + p.setPen(QPen(QBrush(borderColor2),1)); + + p.fillRect(0, 0, size, size, borderColor1); + p.drawRect(1,1, size - 3, size - 3); + return pix; +} + +void ToolBarColorBox::contextMenuEvent(QContextMenuEvent *ev) +{ + QMenu contextMenu; + contextMenu.addAction(m_copyHexColor); + contextMenu.exec(ev->globalPos()); +} + +void ToolBarColorBox::mouseDoubleClickEvent(QMouseEvent *) +{ + QColorDialog dialog(m_color); + dialog.show(); +} + +void ToolBarColorBox::copyColorToClipboard() +{ + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(m_color.name()); +} + + +} // namespace QmlJSDebugger diff --git a/share/qtcreator/qml/qmljsdebugger/editor/toolbarcolorbox.h b/share/qtcreator/qml/qmljsdebugger/editor/toolbarcolorbox.h new file mode 100644 index 0000000000..d4be7921bb --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/toolbarcolorbox.h @@ -0,0 +1,41 @@ +#ifndef ToolBarColorBox_H +#define ToolBarColorBox_H + +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QContextMenuEvent); +QT_FORWARD_DECLARE_CLASS(QAction); + +namespace QmlJSDebugger { + +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 QmlJSDebugger + +#endif // ToolBarColorBox_H diff --git a/share/qtcreator/qml/qmljsdebugger/editor/zoomtool.cpp b/share/qtcreator/qml/qmljsdebugger/editor/zoomtool.cpp new file mode 100644 index 0000000000..2bb152e2d6 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/zoomtool.cpp @@ -0,0 +1,287 @@ +#include "zoomtool.h" +#include "qdeclarativeviewobserver_p.h" + +#include +#include +#include +#include +#include +#include + +#include + +namespace QmlJSDebugger { + +ZoomTool::ZoomTool(QDeclarativeViewObserver *view) : + AbstractFormEditorTool(view), + m_rubberbandManipulator(reinterpret_cast(QDeclarativeViewObserverPrivate::get(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 &/*itemList*/) +{ +} + +void ZoomTool::clear() +{ + view()->setCursor(Qt::ArrowCursor); +} + +void ZoomTool::selectedItemsChanged(const QList &/*itemList*/) +{ +} + +void ZoomTool::scaleView(const QPointF ¢erPos) +{ + + 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 zoomScales = + QList() + << 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 QmlJSDebugger diff --git a/share/qtcreator/qml/qmljsdebugger/editor/zoomtool.h b/share/qtcreator/qml/qmljsdebugger/editor/zoomtool.h new file mode 100644 index 0000000000..299efee3ea --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/editor/zoomtool.h @@ -0,0 +1,65 @@ +#ifndef ZOOMTOOL_H +#define ZOOMTOOL_H + +#include "abstractformeditortool.h" +#include "rubberbandselectionmanipulator.h" + +QT_FORWARD_DECLARE_CLASS(QAction); + +namespace QmlJSDebugger { + +class ZoomTool : public AbstractFormEditorTool +{ + Q_OBJECT +public: + enum ZoomDirection { + ZoomIn, + ZoomOut + }; + + explicit ZoomTool(QDeclarativeViewObserver *view); + + virtual ~ZoomTool(); + + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + + void hoverMoveEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); + + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *keyEvent); + void itemsAboutToRemoved(const QList &itemList); + + void clear(); +protected: + void selectedItemsChanged(const QList &itemList); + +private slots: + void zoomTo100(); + void zoomIn(); + void zoomOut(); + +private: + qreal nextZoomScale(ZoomDirection direction) const; + void scaleView(const QPointF ¢erPos); + +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 QmlJSDebugger + +#endif // ZOOMTOOL_H diff --git a/share/qtcreator/qml/qmljsdebugger/include/jsdebuggeragent.h b/share/qtcreator/qml/qmljsdebugger/include/jsdebuggeragent.h new file mode 100644 index 0000000000..39b559cabe --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/include/jsdebuggeragent.h @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** 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 QtSCriptTools 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 QSCRIPTDEBUGGERAGENT_P_H +#define QSCRIPTDEBUGGERAGENT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include + +#include "qmljsdebugger_global.h" + +QT_FORWARD_DECLARE_CLASS(QScriptContext); +QT_FORWARD_DECLARE_CLASS(QDeclarativeEngine); + +namespace QmlJSDebugger { + +class JSAgentWatchData; + +class QMLJSDEBUGGER_EXPORT JSDebuggerAgent : public QDeclarativeDebugService , public QScriptEngineAgent +{ + Q_OBJECT +public: + JSDebuggerAgent(QScriptEngine *engine); + JSDebuggerAgent(QDeclarativeEngine *engine); + ~JSDebuggerAgent(); + + // reimplemented + void scriptLoad(qint64 id, const QString &program, + const QString &fileName, int baseLineNumber); + void scriptUnload(qint64 id); + + void contextPush(); + void contextPop(); + + void functionEntry(qint64 scriptId); + void functionExit(qint64 scriptId, + const QScriptValue &returnValue); + + void positionChange(qint64 scriptId, + int lineNumber, int columnNumber); + + void exceptionThrow(qint64 scriptId, + const QScriptValue &exception, + bool hasHandler); + void exceptionCatch(qint64 scriptId, + const QScriptValue &exception); + + bool supportsExtension(Extension extension) const; + QVariant extension(Extension extension, + const QVariant &argument = QVariant()); + + void messageReceived(const QByteArray &); + void enabledChanged(bool); + +public slots: +// void pauses(); + +private: + class SetupExecEnv; + friend class SetupExecEnv; + + enum State { + NoState, + SteppingIntoState, + SteppingOverState, + SteppingOutState, + Stopped + }; + State state; + int stepDepth; + int stepCount; + + void continueExec(); + void stopped(bool becauseOfException = false, const QScriptValue &exception = QScriptValue()); + + + void recordKnownObjects(const QList &); + QList getLocals(QScriptContext *); + + QEventLoop loop; + QHash filenames; + QSet< QPair > breakpointList; + QStringList watchExpressions; + QSet knownObjectIds; + + Q_DISABLE_COPY(JSDebuggerAgent) +}; + +} // namespace QmlJSDebugger + +#endif diff --git a/share/qtcreator/qml/qmljsdebugger/include/qdeclarativeobserverservice.h b/share/qtcreator/qml/qmljsdebugger/include/qdeclarativeobserverservice.h new file mode 100644 index 0000000000..121a847684 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/include/qdeclarativeobserverservice.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** 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 +#include "qmlobserverconstants.h" +#include "qmljsdebugger_global.h" + +#include + +QT_FORWARD_DECLARE_CLASS(QColor) +QT_FORWARD_DECLARE_CLASS(QDeclarativeEngine) +QT_FORWARD_DECLARE_CLASS(QDeclarativeContext) +QT_FORWARD_DECLARE_CLASS(QDeclarativeWatcher) +QT_FORWARD_DECLARE_CLASS(QDataStream) + +namespace QmlJSDebugger { + +class QMLJSDEBUGGER_EXPORT QDeclarativeObserverService : public QDeclarativeDebugService +{ + Q_OBJECT +public: + QDeclarativeObserverService(); + static QDeclarativeObserverService *instance(); + + void setDesignModeBehavior(bool inDesignMode); + void setCurrentObjects(QList items); + void setAnimationSpeed(qreal slowdownFactor); + void setCurrentTool(QmlJSDebugger::Constants::DesignTool toolId); + void reloaded(); + QString idStringForObject(QObject *obj) const; + +public Q_SLOTS: + void selectedColorChanged(const QColor &color); + void contextPathUpdated(const QStringList &contextPath); + +Q_SIGNALS: + void debuggingClientChanged(bool hasDebuggingClient); + + void currentObjectsChanged(const QList &objects); + void designModeBehaviorChanged(bool inDesignMode); + void reloadRequested(); + void selectToolRequested(); + void selectMarqueeToolRequested(); + void zoomToolRequested(); + void colorPickerToolRequested(); + + void objectCreationRequested(const QString &qml, QObject *parent, + const QStringList &imports, const QString &filename = QString()); + void objectReparentRequested(QObject *object, QObject *newParent); + + // 1 = normal speed, + // 0 = paused, + // 1 < x < 16 = slowdown by some factor + void animationSpeedChangeRequested(qreal speedFactor); + + void contextPathIndexChanged(int contextPathIndex); + void clearComponentCacheRequested(); + +protected: + virtual void enabledChanged(bool enabled); + virtual void messageReceived(const QByteArray &); + +private: + QHash m_stringIdForObjectId; +}; + +} // namespace QmlJSDebugger + +#endif // QDECLARATIVEDESIGNDEBUGSERVER_H diff --git a/share/qtcreator/qml/qmljsdebugger/include/qdeclarativeviewobserver.h b/share/qtcreator/qml/qmljsdebugger/include/qdeclarativeviewobserver.h new file mode 100644 index 0000000000..02aee970a2 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/include/qdeclarativeviewobserver.h @@ -0,0 +1,129 @@ +/************************************************************************** +** +** 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 QDECLARATIVEVIEWOBSERVER_H +#define QDECLARATIVEVIEWOBSERVER_H + +#include "qmljsdebugger_global.h" +#include "qmlobserverconstants.h" +#include +#include + +QT_FORWARD_DECLARE_CLASS(QDeclarativeItem); +QT_FORWARD_DECLARE_CLASS(QMouseEvent); +QT_FORWARD_DECLARE_CLASS(QToolBar); + +namespace QmlJSDebugger { + +class CrumblePath; +class QDeclarativeViewObserverPrivate; + +class QMLJSDEBUGGER_EXPORT QDeclarativeViewObserver : public QObject +{ + Q_OBJECT +public: + + explicit QDeclarativeViewObserver(QDeclarativeView *view, QObject *parent = 0); + ~QDeclarativeViewObserver(); + + void setSelectedItems(QList items); + QList selectedItems(); + + QDeclarativeView *declarativeView(); + + QToolBar *toolbar() const; + static QString idStringForObject(QObject *obj); + QRectF adjustToScreenBoundaries(const QRectF &boundingRectInSceneSpace); + void setDebugMode(bool isDebugMode); + +public Q_SLOTS: + void setDesignModeBehavior(bool value); + bool designModeBehavior(); + + void changeAnimationSpeed(qreal slowdownFactor); + void continueExecution(qreal slowdownFactor = 1.0f); + void pauseExecution(); + + void setObserverContext(int contextIndex); + +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(); + + void inspectorContextCleared(); + void inspectorContextPushed(const QString &contextTitle); + void inspectorContextPopped(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + + bool leaveEvent(QEvent *); + bool mousePressEvent(QMouseEvent *event); + bool mouseMoveEvent(QMouseEvent *event); + bool mouseReleaseEvent(QMouseEvent *event); + bool keyPressEvent(QKeyEvent *event); + bool keyReleaseEvent(QKeyEvent *keyEvent); + bool mouseDoubleClickEvent(QMouseEvent *event); + bool wheelEvent(QWheelEvent *event); + + void setSelectedItemsForTools(QList items); + +private: + Q_DISABLE_COPY(QDeclarativeViewObserver) + Q_PRIVATE_SLOT(d_func(), void _q_reloadView()) + Q_PRIVATE_SLOT(d_func(), void _q_onStatusChanged(QDeclarativeView::Status)) + Q_PRIVATE_SLOT(d_func(), void _q_onCurrentObjectsChanged(QList)) + Q_PRIVATE_SLOT(d_func(), void _q_applyChangesFromClient()) + Q_PRIVATE_SLOT(d_func(), void _q_createQmlObject(const QString &, QObject *, const QStringList &, const QString &)) + Q_PRIVATE_SLOT(d_func(), void _q_reparentQmlObject(QObject *, QObject *)) + Q_PRIVATE_SLOT(d_func(), void _q_changeToSingleSelectTool()) + Q_PRIVATE_SLOT(d_func(), void _q_changeToMarqueeSelectTool()) + Q_PRIVATE_SLOT(d_func(), void _q_changeToZoomTool()) + Q_PRIVATE_SLOT(d_func(), void _q_changeToColorPickerTool()) + Q_PRIVATE_SLOT(d_func(), void _q_changeContextPathIndex(int index)) + Q_PRIVATE_SLOT(d_func(), void _q_clearComponentCache()); + + inline QDeclarativeViewObserverPrivate *d_func() { return data.data(); } + QScopedPointer data; + friend class QDeclarativeViewObserverPrivate; + friend class AbstractFormEditorTool; + +}; + +} //namespace QmlJSDebugger + +#endif // QDECLARATIVEVIEWOBSERVER_H diff --git a/share/qtcreator/qml/qmljsdebugger/include/qmljsdebugger_global.h b/share/qtcreator/qml/qmljsdebugger/include/qmljsdebugger_global.h new file mode 100644 index 0000000000..6aba5be426 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/include/qmljsdebugger_global.h @@ -0,0 +1,43 @@ +/************************************************************************** +** +** 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 QMLJSDEBUGGER_GLOBAL_H +#define QMLJSDEBUGGER_GLOBAL_H + +#include + +# if defined(BUILD_QMLJSDEBUGGER_LIB) +# define QMLJSDEBUGGER_EXPORT Q_DECL_EXPORT +# elif defined(BUILD_QMLJSDEBUGGER_STATIC_LIB) +# define QMLJSDEBUGGER_EXPORT +# else +# define QMLJSDEBUGGER_EXPORT Q_DECL_IMPORT +#endif + +#endif // QMLJSDEBUGGER_GLOBAL_H diff --git a/share/qtcreator/qml/qmljsdebugger/include/qmlobserverconstants.h b/share/qtcreator/qml/qmljsdebugger/include/qmlobserverconstants.h new file mode 100644 index 0000000000..8709cfef00 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/include/qmlobserverconstants.h @@ -0,0 +1,68 @@ +/************************************************************************** +** +** 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 QMLOBSERVERCONSTANTS_H +#define QMLOBSERVERCONSTANTS_H + +namespace QmlJSDebugger { +namespace Constants { + +enum DesignTool { + NoTool = 0, + SelectionToolMode = 1, + MarqueeSelectionToolMode = 2, + MoveToolMode = 3, + ResizeToolMode = 4, + ColorPickerMode = 5, + ZoomMode = 6 +}; + +enum ToolFlags { + NoToolFlags = 0, + UseCursorPos = 1 +}; + +static const int DragStartTime = 50; + +static const int DragStartDistance = 20; + +static const double ZoomSnapDelta = 0.04; + +static const int EditorItemDataKey = 1000; + +enum GraphicsItemTypes { + EditorItemType = 0xEAAA, + ResizeHandleItemType = 0xEAEA +}; + + +} // namespace Constants +} // namespace QmlJSDebugger + +#endif // QMLOBSERVERCONSTANTS_H diff --git a/share/qtcreator/qml/qmljsdebugger/jsdebuggeragent.cpp b/share/qtcreator/qml/qmljsdebugger/jsdebuggeragent.cpp new file mode 100644 index 0000000000..4258882e10 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/jsdebuggeragent.cpp @@ -0,0 +1,519 @@ +/**************************************************************************** +** +** 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 QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "jsdebuggeragent.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace QmlJSDebugger { + +class JSDebuggerAgent::SetupExecEnv { + JSDebuggerAgent* agent; + JSDebuggerAgent::State previousState; + bool hadException; +public: + SetupExecEnv(JSDebuggerAgent *a) + : agent(a), + previousState(a->state), + hadException(a->engine()->hasUncaughtException()) + { + agent->state = JSDebuggerAgent::Stopped; + } + + ~SetupExecEnv() { + if (!hadException && agent->engine()->hasUncaughtException()) + agent->engine()->clearExceptions(); + agent->state = previousState; + } +}; + +class JSAgentWatchData { +public: + QByteArray exp; + QString name; + QString value; + QString type; + bool hasChildren; + quint64 objectId; + + static JSAgentWatchData fromScriptValue(const QString &expression, const QScriptValue &value) + { + JSAgentWatchData data; + data.exp = expression.toUtf8(); + data.name = expression; + data.hasChildren = false; + data.value = value.toString(); + data.objectId = value.objectId(); + if (value.isArray()) { + data.type = QLatin1String("Array"); + data.value = QString::fromLatin1("[Array of length %1]").arg(value.property("length").toString()); + data.hasChildren = true; + } else if (value.isBool()) { + data.type = QLatin1String("Bool"); +// data.value = value.toBool() ? QLatin1String("true") : QLatin1String("false"); + } else if (value.isDate()) { + data.type = QLatin1String("Date"); + data.value = value.toDateTime().toString(); + } else if (value.isError()) { + data.type = QLatin1String("Error"); + } else if (value.isFunction()) { + data.type = QLatin1String("Function"); + } else if (value.isUndefined()) { + data.type = QLatin1String(""); + } else if (value.isNumber()) { + data.type = QLatin1String("Number"); + } else if (value.isRegExp()) { + data.type = QLatin1String("RegExp"); + } else if (value.isString()) { + data.type = QLatin1String("String"); + } else if (value.isVariant()) { + data.type = QLatin1String("Variant"); + } else if (value.isQObject()) { + const QObject *obj = value.toQObject(); + data.value = QString::fromLatin1("[%1]").arg(obj->metaObject()->className()); + data.type = QLatin1String("Object"); + data.hasChildren = true; + } else if (value.isObject()) { + data.type = QLatin1String("Object"); + data.hasChildren = true; + data.type = QLatin1String("Object"); + data.value = QLatin1String("[Object]"); + } else if (value.isNull()) { + data.type = QLatin1String(""); + } else { + data.type = QLatin1String(""); + } + return data; + } +}; + + +QDataStream& operator<<(QDataStream& s, const JSAgentWatchData& data) +{ + return s << data.exp << data.name << data.value << data.type << data.hasChildren << data.objectId; +} + +static QList expandObject(const QScriptValue &object) +{ + QList result; + QScriptValueIterator it(object); + QByteArray expPrefix = '@' + QByteArray::number(object.objectId(), 16) + "->"; + while (it.hasNext()) { + it.next(); + if (it.flags() & QScriptValue::SkipInEnumeration) + continue; + if (object.isQObject() && it.value().isFunction()) { + // cosmetics: skip all signals and slot, there is too many of them, + // and it is not usefull in the debugger. + continue; + } + JSAgentWatchData data = JSAgentWatchData::fromScriptValue(it.name(), it.value()); + data.exp.prepend(expPrefix); + result << data; + } + return result; +} + +void JSDebuggerAgent::recordKnownObjects(const QList& list) +{ + foreach (const JSAgentWatchData &data, list) + knownObjectIds << data.objectId; +} + +QList JSDebuggerAgent::getLocals(QScriptContext *ctx) +{ + QList locals; + if (ctx) { + QScriptValue activationObject = ctx->activationObject(); + QScriptValue thisObject = ctx->thisObject(); + locals = expandObject(activationObject); + if (thisObject.isObject() && thisObject.objectId() != engine()->globalObject().objectId()) + locals.prepend(JSAgentWatchData::fromScriptValue("this", thisObject)); + recordKnownObjects(locals); + knownObjectIds << activationObject.objectId(); + } + return locals; +} + +/*! + Constructs a new agent for the given \a engine. The agent will + report debugging-related events (e.g. step completion) to the given + \a backend. +*/ +JSDebuggerAgent::JSDebuggerAgent(QScriptEngine *engine) + : QDeclarativeDebugService("JSDebugger"), QScriptEngineAgent(engine) + , state(NoState) +{} + +JSDebuggerAgent::JSDebuggerAgent(QDeclarativeEngine *engine) + : QDeclarativeDebugService("JSDebugger") + , QScriptEngineAgent(QDeclarativeEnginePrivate::getScriptEngine(engine)) + , state(NoState) +{} + +/*! + Destroys this QScriptDebuggerAgent. +*/ +JSDebuggerAgent::~JSDebuggerAgent() +{} + +/*! + \reimp +*/ +void JSDebuggerAgent::scriptLoad(qint64 id, const QString & program, + const QString &fileName, int ) +{ + Q_UNUSED(program); + filenames.insert(id, QUrl(fileName).toLocalFile()); +} + +/*! + \reimp +*/ +void JSDebuggerAgent::scriptUnload(qint64 id) +{ + filenames.remove(id); +} + +/*! + \reimp +*/ +void JSDebuggerAgent::contextPush() +{ +} + +/*! + \reimp +*/ +void JSDebuggerAgent::contextPop() +{ +} + +/*! + \reimp +*/ +void JSDebuggerAgent::functionEntry(qint64 scriptId) +{ + Q_UNUSED(scriptId); + stepDepth++; +} + +/*! + \reimp +*/ +void JSDebuggerAgent::functionExit(qint64 scriptId, const QScriptValue &returnValue) +{ + Q_UNUSED(scriptId); + Q_UNUSED(returnValue); + stepDepth--; +} + +/*! + \reimp +*/ +void JSDebuggerAgent::positionChange(qint64 scriptId, + int lineNumber, int columnNumber) +{ + Q_UNUSED(columnNumber); + + if(state == Stopped) + return; //no re-entrency + + // check breakpoints + if (!breakpointList.isEmpty()) { + QHash::const_iterator it = filenames.constFind(scriptId); + if (it == filenames.constEnd()) { + // It is possible that the scripts are loaded before the agent is attached + QString filename = QUrl(QScriptContextInfo(engine()->currentContext()).fileName()).toLocalFile(); + QPair key = qMakePair(filename, lineNumber); + it = filenames.insert(scriptId, filename); + } + QPair key = qMakePair(*it, lineNumber); + if (breakpointList.contains(key)) { + stopped(); + return; + } + } + + switch (state) { + case NoState: + case Stopped: + // Do nothing + break; + case SteppingOutState: + if (stepDepth >= 0) + break; + //fallthough + case SteppingOverState: + if (stepDepth > 0) + break; + //fallthough + case SteppingIntoState: + stopped(); + break; + } + +} + +/*! + \reimp +*/ +void JSDebuggerAgent::exceptionThrow(qint64 scriptId, + const QScriptValue &exception, + bool hasHandler) +{ + Q_UNUSED(scriptId); + Q_UNUSED(exception); + Q_UNUSED(hasHandler); +// qDebug() << Q_FUNC_INFO << exception.toString() << hasHandler; +#if 0 //sometimes, we get exceptions that we should just ignore. + if (!hasHandler && state != Stopped) + stopped(true, exception); +#endif +} + +/*! + \reimp +*/ +void JSDebuggerAgent::exceptionCatch(qint64 scriptId, + const QScriptValue &exception) +{ + Q_UNUSED(scriptId); + Q_UNUSED(exception); +} + +bool JSDebuggerAgent::supportsExtension(QScriptEngineAgent::Extension extension) const +{ + return extension == QScriptEngineAgent::DebuggerInvocationRequest; +} + +QVariant JSDebuggerAgent::extension(QScriptEngineAgent::Extension extension, const QVariant& argument) +{ + if (extension == QScriptEngineAgent::DebuggerInvocationRequest) { + stopped(); + return QVariant(); + } + return QScriptEngineAgent::extension(extension, argument); +} + + + +void JSDebuggerAgent::messageReceived(const QByteArray& message) +{ + QDataStream ds(message); + QByteArray command; + ds >> command; + if (command == "BREAKPOINTS") { + ds >> breakpointList; + } else if (command == "WATCH_EXPRESSIONS") { + ds >> watchExpressions; + } else if (command == "STEPOVER") { + stepDepth = 0; + state = SteppingOverState; + continueExec(); + } else if (command == "STEPINTO" || command == "INTERRUPT") { + stepDepth = 0; + state = SteppingIntoState; + continueExec(); + } else if (command == "STEPOUT") { + stepDepth = 0; + state = SteppingOutState; + continueExec(); + } else if (command == "CONTINUE") { + state = NoState; + continueExec(); + } else if (command == "EXEC") { + SetupExecEnv execEnv(this); + + QByteArray id; + QString expr; + ds >> id >> expr; + + JSAgentWatchData data = JSAgentWatchData::fromScriptValue(expr, engine()->evaluate(expr)); + knownObjectIds << data.objectId; + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("RESULT") << id << data; + sendMessage(reply); + } else if (command == "EXPAND") { + SetupExecEnv execEnv(this); + + QByteArray requestId; + quint64 objectId; + ds >> requestId >> objectId; + QScriptValue v; + if (knownObjectIds.contains(objectId)) + v = engine()->objectById(objectId); + + QList result = expandObject(v); + recordKnownObjects(result); + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("EXPANDED") << requestId << result; + sendMessage(reply); + + } else if (command == "ACTIVATE_FRAME") { + SetupExecEnv execEnv(this); + + int frameId; + ds >> frameId; + + int deep = 0; + QScriptContext *ctx = engine()->currentContext(); + while (ctx && deep < frameId) { + ctx = ctx->parentContext(); + deep++; + } + + QList locals = getLocals(ctx); + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("LOCALS") << frameId << locals; + sendMessage(reply); + } else if (command == "SET_PROPERTY") { + SetupExecEnv execEnv(this); + + QByteArray id; + qint64 objectId; + QString property; + QString value; + ds >> id >> objectId >> property >> value; + + if (knownObjectIds.contains(objectId)) { + QScriptValue object; + object = engine()->objectById(objectId); + + if(object.isObject()) { + QScriptValue result = engine()->evaluate(value); + object.setProperty(property, result); + } + } + + //TODO: feedback + } else if (command == "PING") { + int ping; + ds >> ping; + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("PONG") << ping; + sendMessage(reply); + } else { + qDebug() << Q_FUNC_INFO << "Unknown command" << command; + } + + QDeclarativeDebugService::messageReceived(message); +} + +void JSDebuggerAgent::stopped(bool becauseOfException, const QScriptValue& exception) +{ + knownObjectIds.clear(); + state = Stopped; + QList > > backtrace; + + for (QScriptContext* ctx = engine()->currentContext(); ctx; ctx = ctx->parentContext()) { + QScriptContextInfo info(ctx); + + QString functionName = info.functionName(); + if (functionName.isEmpty()) { + if (ctx->parentContext()) { + switch (info.functionType()) { + case QScriptContextInfo::ScriptFunction: + functionName = QLatin1String(""); + break; + case QScriptContextInfo::NativeFunction: + functionName = QLatin1String(""); + break; + case QScriptContextInfo::QtFunction: + case QScriptContextInfo::QtPropertyFunction: + functionName = QLatin1String(""); + break; + } + } else { + functionName = QLatin1String(""); + } + } + int lineNumber = info.lineNumber(); + if (lineNumber == -1) // if the line number is unknown, fallback to the function line number + lineNumber = info.functionStartLineNumber(); + backtrace.append(qMakePair(functionName, qMakePair( QUrl(info.fileName()).toLocalFile(), lineNumber ) ) ); + } + QList watches; + foreach (const QString &expr, watchExpressions) + watches << JSAgentWatchData::fromScriptValue(expr, engine()->evaluate(expr)); + recordKnownObjects(watches); + + QList locals = getLocals(engine()->currentContext()); + + if (!becauseOfException) { + // Clear any exceptions occurred during locals evaluation. + engine()->clearExceptions(); + } + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("STOPPED") << backtrace << watches << locals << becauseOfException << exception.toString(); + sendMessage(reply); + + loop.exec(QEventLoop::ExcludeUserInputEvents); +} + +void JSDebuggerAgent::continueExec() +{ + loop.quit(); +} + +void JSDebuggerAgent::enabledChanged(bool on) +{ + engine()->setAgent(on ? this : 0); +} + +} // namespace QmlJSDebugger diff --git a/share/qtcreator/qml/qmljsdebugger/private_headers.pri b/share/qtcreator/qml/qmljsdebugger/private_headers.pri new file mode 100644 index 0000000000..fc35396178 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/private_headers.pri @@ -0,0 +1,17 @@ +# Try to find location of Qt private headers (see README) +isEmpty(QT_PRIVATE_HEADERS) { + QT_PRIVATE_HEADERS = $$[QT_INSTALL_HEADERS] +} + +INCLUDEPATH += \ + $${QT_PRIVATE_HEADERS} \ + $${QT_PRIVATE_HEADERS}/QtCore \ + $${QT_PRIVATE_HEADERS}/QtGui \ + $${QT_PRIVATE_HEADERS}/QtScript \ + $${QT_PRIVATE_HEADERS}/QtDeclarative +DEPENDPATH += \ + $${QT_PRIVATE_HEADERS} \ + $${QT_PRIVATE_HEADERS}/QtCore \ + $${QT_PRIVATE_HEADERS}/QtGui \ + $${QT_PRIVATE_HEADERS}/QtScript \ + $${QT_PRIVATE_HEADERS}/QtDeclarative diff --git a/share/qtcreator/qml/qmljsdebugger/qdeclarativeobserverservice.cpp b/share/qtcreator/qml/qmljsdebugger/qdeclarativeobserverservice.cpp new file mode 100644 index 0000000000..16b5145e74 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/qdeclarativeobserverservice.cpp @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "qdeclarativeobserverservice.h" + +#include +#include + +#include + +namespace QmlJSDebugger { + +Q_GLOBAL_STATIC(QDeclarativeObserverService, serviceInstance) + +QDeclarativeObserverService::QDeclarativeObserverService() + : QDeclarativeDebugService(QLatin1String("QDeclarativeObserverMode")) +{ +} + +QDeclarativeObserverService *QDeclarativeObserverService::instance() +{ + return serviceInstance(); +} + +void QDeclarativeObserverService::enabledChanged(bool enabled) +{ + emit debuggingClientChanged(enabled); +} + +void QDeclarativeObserverService::messageReceived(const QByteArray &message) +{ + QDataStream ds(message); + + QByteArray type; + ds >> type; + + if (type == "SET_CURRENT_OBJECTS") { + int itemCount = 0; + ds >> itemCount; + + QList 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") { + emit colorPickerToolRequested(); + } else if (toolName == "SELECT") { + emit selectToolRequested(); + } else if (toolName == "SELECT_MARQUEE") { + emit selectMarqueeToolRequested(); + } else if (toolName == "ZOOM") { + emit zoomToolRequested(); + } + } else if (type == "SET_DESIGN_MODE") { + bool inDesignMode; + ds >> inDesignMode; + emit designModeBehaviorChanged(inDesignMode); + } else if (type == "CREATE_OBJECT") { + QString qml; + int parentId; + QString filename; + QStringList imports; + ds >> qml >> parentId >> imports >> filename; + emit objectCreationRequested(qml, objectForId(parentId), imports, filename); + } else if (type == "DESTROY_OBJECT") { + int debugId; + ds >> debugId; + if (QObject* obj = objectForId(debugId)) + obj->deleteLater(); + } else if (type == "MOVE_OBJECT") { + int debugId, newParent; + ds >> debugId >> newParent; + emit objectReparentRequested(objectForId(debugId), objectForId(newParent)); + } else if (type == "OBJECT_ID_LIST") { + int itemCount; + ds >> itemCount; + m_stringIdForObjectId.clear(); + for(int i = 0; i < itemCount; ++i) { + int itemDebugId; + QString itemIdString; + ds >> itemDebugId + >> itemIdString; + + m_stringIdForObjectId.insert(itemDebugId, itemIdString); + } + } else if (type == "SET_CONTEXT_PATH_IDX") { + int contextPathIndex; + ds >> contextPathIndex; + emit contextPathIndexChanged(contextPathIndex); + } else if (type == "CLEAR_COMPONENT_CACHE") { + emit clearComponentCacheRequested(); + } +} + +void QDeclarativeObserverService::setDesignModeBehavior(bool inDesignMode) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << QByteArray("SET_DESIGN_MODE") + << inDesignMode; + + sendMessage(message); +} + +void QDeclarativeObserverService::setCurrentObjects(QList 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 QDeclarativeObserverService::setCurrentTool(QmlJSDebugger::Constants::DesignTool toolId) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << QByteArray("TOOL_CHANGED") + << toolId; + + sendMessage(message); +} + +void QDeclarativeObserverService::setAnimationSpeed(qreal slowdownFactor) +{ + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << QByteArray("ANIMATION_SPEED_CHANGED") + << slowdownFactor; + + sendMessage(message); +} + +void QDeclarativeObserverService::reloaded() +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << QByteArray("RELOADED"); + + sendMessage(message); +} + +void QDeclarativeObserverService::selectedColorChanged(const QColor &color) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << QByteArray("COLOR_CHANGED") + << color; + + sendMessage(message); +} + +void QDeclarativeObserverService::contextPathUpdated(const QStringList &contextPath) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << QByteArray("CONTEXT_PATH_UPDATED") + << contextPath; + + sendMessage(message); +} + +QString QDeclarativeObserverService::idStringForObject(QObject *obj) const +{ + int id = idForObject(obj); + QString idString = m_stringIdForObjectId.value(id, QString()); + return idString; +} + +} // namespace QmlJSDebugger diff --git a/share/qtcreator/qml/qmljsdebugger/qdeclarativeviewobserver.cpp b/share/qtcreator/qml/qmljsdebugger/qdeclarativeviewobserver.cpp new file mode 100644 index 0000000000..81cd9b018b --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/qdeclarativeviewobserver.cpp @@ -0,0 +1,804 @@ +/************************************************************************** +** +** 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 "qdeclarativeviewobserver.h" +#include "qdeclarativeviewobserver_p.h" +#include "qdeclarativeobserverservice.h" +#include "selectiontool.h" +#include "zoomtool.h" +#include "colorpickertool.h" +#include "layeritem.h" +#include "boundingrecthighlighter.h" +#include "subcomponenteditortool.h" +#include "qmltoolbar.h" +#include "jsdebuggeragent.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace QmlJSDebugger { + +const int SceneChangeUpdateInterval = 5000; + +QDeclarativeViewObserverPrivate::QDeclarativeViewObserverPrivate(QDeclarativeViewObserver *q) : + q(q), + designModeBehavior(false), + executionPaused(false), + slowdownFactor(1.0f), + jsDebuggerAgent(0), + toolbar(0) +{ +} + +QDeclarativeViewObserverPrivate::~QDeclarativeViewObserverPrivate() +{ +} + +QDeclarativeViewObserver::QDeclarativeViewObserver(QDeclarativeView *view, QObject *parent) : + QObject(parent), data(new QDeclarativeViewObserverPrivate(this)) +{ + data->view = view; + data->manipulatorLayer = new LayerItem(view->scene()); + data->selectionTool = new SelectionTool(this); + data->zoomTool = new ZoomTool(this); + data->colorPickerTool = new ColorPickerTool(this); + data->boundingRectHighlighter = new BoundingRectHighlighter(this); + data->subcomponentEditorTool = new SubcomponentEditorTool(this); + data->currentTool = data->selectionTool; + + data->view->setMouseTracking(true); + data->view->viewport()->installEventFilter(this); + + data->debugService = QDeclarativeObserverService::instance(); + connect(data->debugService, SIGNAL(designModeBehaviorChanged(bool)), SLOT(setDesignModeBehavior(bool))); + connect(data->debugService, SIGNAL(reloadRequested()), SLOT(_q_reloadView())); + connect(data->debugService, + SIGNAL(currentObjectsChanged(QList)), + SLOT(_q_onCurrentObjectsChanged(QList))); + connect(data->debugService, SIGNAL(animationSpeedChangeRequested(qreal)), SLOT(changeAnimationSpeed(qreal))); + connect(data->debugService, SIGNAL(colorPickerToolRequested()), SLOT(_q_changeToColorPickerTool())); + connect(data->debugService, SIGNAL(selectMarqueeToolRequested()), SLOT(_q_changeToMarqueeSelectTool())); + connect(data->debugService, SIGNAL(selectToolRequested()), SLOT(_q_changeToSingleSelectTool())); + connect(data->debugService, SIGNAL(zoomToolRequested()), SLOT(_q_changeToZoomTool())); + connect(data->debugService, + SIGNAL(objectCreationRequested(QString,QObject*,QStringList,QString)), + SLOT(_q_createQmlObject(QString,QObject*,QStringList,QString))); + connect(data->debugService, + SIGNAL(objectReparentRequested(QObject *, QObject *)), + SLOT(_q_reparentQmlObject(QObject *, QObject *))); + connect(data->debugService, SIGNAL(contextPathIndexChanged(int)), SLOT(_q_changeContextPathIndex(int))); + connect(data->debugService, SIGNAL(clearComponentCacheRequested()), SLOT(_q_clearComponentCache())); + connect(data->view, SIGNAL(statusChanged(QDeclarativeView::Status)), SLOT(_q_onStatusChanged(QDeclarativeView::Status))); + + connect(data->colorPickerTool, SIGNAL(selectedColorChanged(QColor)), SIGNAL(selectedColorChanged(QColor))); + connect(data->colorPickerTool, SIGNAL(selectedColorChanged(QColor)), + data->debugService, SLOT(selectedColorChanged(QColor))); + + connect(data->subcomponentEditorTool, SIGNAL(cleared()), SIGNAL(inspectorContextCleared())); + connect(data->subcomponentEditorTool, SIGNAL(contextPushed(QString)), SIGNAL(inspectorContextPushed(QString))); + connect(data->subcomponentEditorTool, SIGNAL(contextPopped()), SIGNAL(inspectorContextPopped())); + connect(data->subcomponentEditorTool, SIGNAL(contextPathChanged(QStringList)), data->debugService, SLOT(contextPathUpdated(QStringList))); + + data->createToolbar(); + + data->_q_changeToSingleSelectTool(); + + // always start debug mode - that's what this design view is for. + setDebugMode(true); +} + +QDeclarativeViewObserver::~QDeclarativeViewObserver() +{ +} + +void QDeclarativeViewObserver::setObserverContext(int contextIndex) +{ + if (data->subcomponentEditorTool->contextIndex() != contextIndex) { + QGraphicsObject *object = data->subcomponentEditorTool->setContext(contextIndex); + if (object) + data->debugService->setCurrentObjects(QList() << object); + } +} + +void QDeclarativeViewObserverPrivate::_q_reloadView() +{ + subcomponentEditorTool->clear(); + clearHighlight(); + emit q->reloadRequested(); +} + +void QDeclarativeViewObserverPrivate::clearEditorItems() +{ + clearHighlight(); + setSelectedItems(QList()); +} + +bool QDeclarativeViewObserver::eventFilter(QObject *obj, QEvent *event) + { + switch (event->type()) { + case QEvent::Leave: { + if (leaveEvent(event)) + return true; + break; + } + case QEvent::MouseButtonPress: { + if (mousePressEvent(static_cast(event))) + return true; + break; + } + case QEvent::MouseMove: { + if (mouseMoveEvent(static_cast(event))) + return true; + break; + } + case QEvent::MouseButtonRelease: { + if (mouseReleaseEvent(static_cast(event))) + return true; + break; + } + case QEvent::KeyPress: { + if (keyPressEvent(static_cast(event))) + return true; + break; + } + case QEvent::KeyRelease: { + if (keyReleaseEvent(static_cast(event))) + return true; + break; + } + case QEvent::MouseButtonDblClick: { + if (mouseDoubleClickEvent(static_cast(event))) + return true; + break; + } + case QEvent::Wheel: { + if (wheelEvent(static_cast(event))) + return true; + break; + } + default: { + break; + } + } //switch + + // standard event processing + return QObject::eventFilter(obj, event); +} + +bool QDeclarativeViewObserver::leaveEvent(QEvent * /*event*/) +{ + if (!data->designModeBehavior) + return false; + data->clearHighlight(); + return true; +} + +bool QDeclarativeViewObserver::mousePressEvent(QMouseEvent *event) +{ + if (!data->designModeBehavior) + return false; + data->cursorPos = event->pos(); + data->currentTool->mousePressEvent(event); + return true; +} + +bool QDeclarativeViewObserver::mouseMoveEvent(QMouseEvent *event) +{ + if (!data->designModeBehavior) { + data->clearEditorItems(); + return false; + } + data->cursorPos = event->pos(); + + QList selItems = data->selectableItems(event->pos()); + if (!selItems.isEmpty()) { + declarativeView()->setToolTip(AbstractFormEditorTool::titleForItem(selItems.first())); + } else { + declarativeView()->setToolTip(QString()); + } + if (event->buttons()) { + data->subcomponentEditorTool->mouseMoveEvent(event); + data->currentTool->mouseMoveEvent(event); + } else { + data->subcomponentEditorTool->hoverMoveEvent(event); + data->currentTool->hoverMoveEvent(event); + } + return true; +} + +bool QDeclarativeViewObserver::mouseReleaseEvent(QMouseEvent *event) +{ + if (!data->designModeBehavior) + return false; + data->subcomponentEditorTool->mouseReleaseEvent(event); + + data->cursorPos = event->pos(); + data->currentTool->mouseReleaseEvent(event); + + data->debugService->setCurrentObjects(AbstractFormEditorTool::toObjectList(selectedItems())); + return true; +} + +bool QDeclarativeViewObserver::keyPressEvent(QKeyEvent *event) +{ + if (!data->designModeBehavior) { + return false; + } + data->currentTool->keyPressEvent(event); + return true; +} + +bool QDeclarativeViewObserver::keyReleaseEvent(QKeyEvent *event) +{ + if (!data->designModeBehavior) { + return false; + } + + switch(event->key()) { + case Qt::Key_V: + data->_q_changeToSingleSelectTool(); + break; +// disabled because multiselection does not do anything useful without design mode +// case Qt::Key_M: +// data->_q_changeToMarqueeSelectTool(); +// break; + case Qt::Key_I: + data->_q_changeToColorPickerTool(); + break; + case Qt::Key_Z: + data->_q_changeToZoomTool(); + break; + case Qt::Key_Enter: + case Qt::Key_Return: + if (!data->selectedItems().isEmpty()) + data->subcomponentEditorTool->setCurrentItem(data->selectedItems().first()); + break; + case Qt::Key_Space: + if (data->executionPaused) { + continueExecution(data->slowdownFactor); + } else { + pauseExecution(); + } + break; + default: + break; + } + + data->currentTool->keyReleaseEvent(event); + return true; +} + +void QDeclarativeViewObserverPrivate::_q_createQmlObject(const QString &qml, QObject *parent, const QStringList &importList, const QString &filename) +{ + if (!parent) + return; + + QString imports; + foreach(const QString &s, importList) { + imports += s + "\n"; + } + + QDeclarativeContext *parentContext = view->engine()->contextForObject(parent); + QDeclarativeComponent component(view->engine(), q); + QByteArray constructedQml = QString(imports + qml).toLatin1(); + + component.setData(constructedQml, filename); + QObject *newObject = component.create(parentContext); + if (newObject) { + newObject->setParent(parent); + QDeclarativeItem *parentItem = qobject_cast(parent); + QDeclarativeItem *newItem = qobject_cast(newObject); + if (parentItem && newItem) { + newItem->setParentItem(parentItem); + } + } +} + +void QDeclarativeViewObserverPrivate::_q_reparentQmlObject(QObject *object, QObject *newParent) +{ + if (!newParent) + return; + + object->setParent(newParent); + QDeclarativeItem *newParentItem = qobject_cast(newParent); + QDeclarativeItem *item = qobject_cast(object); + if (newParentItem && item) { + item->setParentItem(newParentItem); + } +} + +void QDeclarativeViewObserverPrivate::_q_clearComponentCache() +{ + view->engine()->clearComponentCache(); +} + +QGraphicsItem *QDeclarativeViewObserverPrivate::currentRootItem() const +{ + return subcomponentEditorTool->currentRootItem(); +} + +bool QDeclarativeViewObserver::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (!data->designModeBehavior) + return false; + + if (data->currentToolMode != Constants::SelectionToolMode + && data->currentToolMode != Constants::MarqueeSelectionToolMode) + return true; + + QGraphicsItem *itemToEnter = 0; + QList itemList = data->view->items(event->pos()); + data->filterForSelection(itemList); + + if (data->selectedItems().isEmpty() && !itemList.isEmpty()) { + itemToEnter = itemList.first(); + } else if (!data->selectedItems().isEmpty() && !itemList.isEmpty()) { + itemToEnter = itemList.first(); + } + + if (itemToEnter) + itemToEnter = data->subcomponentEditorTool->firstChildOfContext(itemToEnter); + + data->subcomponentEditorTool->setCurrentItem(itemToEnter); + data->subcomponentEditorTool->mouseDoubleClickEvent(event); + + if ((event->buttons() & Qt::LeftButton) && itemToEnter) { + QGraphicsObject *objectToEnter = itemToEnter->toGraphicsObject(); + if (objectToEnter) + data->debugService->setCurrentObjects(QList() << objectToEnter); + } + + return true; +} + +bool QDeclarativeViewObserver::wheelEvent(QWheelEvent *event) +{ + if (!data->designModeBehavior) + return false; + data->currentTool->wheelEvent(event); + return true; +} + +void QDeclarativeViewObserverPrivate::enterContext(QGraphicsItem *itemToEnter) +{ + QGraphicsItem *itemUnderCurrentContext = itemToEnter; + if (itemUnderCurrentContext) + itemUnderCurrentContext = subcomponentEditorTool->firstChildOfContext(itemToEnter); + + if (itemUnderCurrentContext) + subcomponentEditorTool->setCurrentItem(itemToEnter); +} + +void QDeclarativeViewObserver::setDesignModeBehavior(bool value) +{ + emit designModeBehaviorChanged(value); + + data->toolbar->setDesignModeBehavior(value); + data->debugService->setDesignModeBehavior(value); + + data->designModeBehavior = value; + if (data->subcomponentEditorTool) { + data->subcomponentEditorTool->clear(); + data->clearHighlight(); + data->setSelectedItems(QList()); + + if (data->view->rootObject()) + data->subcomponentEditorTool->pushContext(data->view->rootObject()); + } + + if (!data->designModeBehavior) + data->clearEditorItems(); +} + +bool QDeclarativeViewObserver::designModeBehavior() +{ + return data->designModeBehavior; +} + +void QDeclarativeViewObserverPrivate::changeTool(Constants::DesignTool tool, Constants::ToolFlags /*flags*/) +{ + switch(tool) { + case Constants::SelectionToolMode: + _q_changeToSingleSelectTool(); + break; + case Constants::NoTool: + default: + currentTool = 0; + break; + } +} + +void QDeclarativeViewObserverPrivate::setSelectedItemsForTools(QList items) +{ + currentSelection.clear(); + foreach(QGraphicsItem *item, items) { + if (item) { + QGraphicsObject *obj = item->toGraphicsObject(); + if (obj) + currentSelection << obj; + } + } + currentTool->updateSelectedItems(); +} + +void QDeclarativeViewObserverPrivate::setSelectedItems(QList items) +{ + setSelectedItemsForTools(items); + debugService->setCurrentObjects(AbstractFormEditorTool::toObjectList(items)); +} + +QList QDeclarativeViewObserverPrivate::selectedItems() +{ + QList selection; + foreach(const QWeakPointer &selectedObject, currentSelection) { + if (selectedObject.isNull()) { + currentSelection.removeOne(selectedObject); + } else { + selection << selectedObject.data(); + } + } + + return selection; +} + +void QDeclarativeViewObserver::setSelectedItems(QList items) +{ + data->setSelectedItems(items); +} + +QList QDeclarativeViewObserver::selectedItems() +{ + return data->selectedItems(); +} + +QDeclarativeView *QDeclarativeViewObserver::declarativeView() +{ + return data->view; +} + +void QDeclarativeViewObserverPrivate::clearHighlight() +{ + boundingRectHighlighter->clear(); +} + +void QDeclarativeViewObserverPrivate::highlight(QGraphicsObject * item, ContextFlags flags) +{ + highlight(QList() << item, flags); +} + +void QDeclarativeViewObserverPrivate::highlight(QList items, ContextFlags flags) +{ + if (items.isEmpty()) + return; + + QList objectList; + foreach(QGraphicsItem *item, items) { + QGraphicsItem *child = item; + if (flags & ContextSensitive) + child = subcomponentEditorTool->firstChildOfContext(item); + + if (child) { + QGraphicsObject *childObject = child->toGraphicsObject(); + if (childObject) + objectList << childObject; + } + } + + boundingRectHighlighter->highlight(objectList); +} + +bool QDeclarativeViewObserverPrivate::mouseInsideContextItem() const +{ + return subcomponentEditorTool->containsCursor(cursorPos.toPoint()); +} + +QList QDeclarativeViewObserverPrivate::selectableItems(const QPointF &scenePos) const +{ + QList itemlist = view->scene()->items(scenePos); + return filterForCurrentContext(itemlist); +} + +QList QDeclarativeViewObserverPrivate::selectableItems(const QPoint &pos) const +{ + QList itemlist = view->items(pos); + return filterForCurrentContext(itemlist); +} + +QList QDeclarativeViewObserverPrivate::selectableItems(const QRectF &sceneRect, Qt::ItemSelectionMode selectionMode) const +{ + QList itemlist = view->scene()->items(sceneRect, selectionMode); + + return filterForCurrentContext(itemlist); +} + +void QDeclarativeViewObserverPrivate::_q_changeToSingleSelectTool() +{ + currentToolMode = Constants::SelectionToolMode; + selectionTool->setRubberbandSelectionMode(false); + + changeToSelectTool(); + + emit q->selectToolActivated(); + debugService->setCurrentTool(Constants::SelectionToolMode); +} + +void QDeclarativeViewObserverPrivate::changeToSelectTool() +{ + if (currentTool == selectionTool) + return; + + currentTool->clear(); + currentTool = selectionTool; + currentTool->clear(); + currentTool->updateSelectedItems(); +} + +void QDeclarativeViewObserverPrivate::_q_changeToMarqueeSelectTool() +{ + changeToSelectTool(); + currentToolMode = Constants::MarqueeSelectionToolMode; + selectionTool->setRubberbandSelectionMode(true); + + emit q->marqueeSelectToolActivated(); + debugService->setCurrentTool(Constants::MarqueeSelectionToolMode); +} + +void QDeclarativeViewObserverPrivate::_q_changeToZoomTool() +{ + currentToolMode = Constants::ZoomMode; + currentTool->clear(); + currentTool = zoomTool; + currentTool->clear(); + + emit q->zoomToolActivated(); + debugService->setCurrentTool(Constants::ZoomMode); +} + +void QDeclarativeViewObserverPrivate::_q_changeToColorPickerTool() +{ + if (currentTool == colorPickerTool) + return; + + currentToolMode = Constants::ColorPickerMode; + currentTool->clear(); + currentTool = colorPickerTool; + currentTool->clear(); + + emit q->colorPickerActivated(); + debugService->setCurrentTool(Constants::ColorPickerMode); +} + +void QDeclarativeViewObserverPrivate::_q_changeContextPathIndex(int index) +{ + subcomponentEditorTool->setContext(index); +} + +void QDeclarativeViewObserver::changeAnimationSpeed(qreal slowdownFactor) +{ + data->slowdownFactor = slowdownFactor; + + if (data->slowdownFactor != 0) { + continueExecution(data->slowdownFactor); + } else { + pauseExecution(); + } +} + +void QDeclarativeViewObserver::continueExecution(qreal slowdownFactor) +{ + Q_ASSERT(slowdownFactor > 0); + + data->slowdownFactor = slowdownFactor; + static const qreal animSpeedSnapDelta = 0.01f; + bool useStandardSpeed = (qAbs(1.0f - data->slowdownFactor) < animSpeedSnapDelta); + + QUnifiedTimer *timer = QUnifiedTimer::instance(); + timer->setSlowdownFactor(data->slowdownFactor); + timer->setSlowModeEnabled(!useStandardSpeed); + data->executionPaused = false; + + emit executionStarted(data->slowdownFactor); + data->debugService->setAnimationSpeed(data->slowdownFactor); +} + +void QDeclarativeViewObserver::pauseExecution() +{ + QUnifiedTimer *timer = QUnifiedTimer::instance(); + timer->setSlowdownFactor(0); + timer->setSlowModeEnabled(true); + data->executionPaused = true; + + emit executionPaused(); + data->debugService->setAnimationSpeed(0); +} + +void QDeclarativeViewObserverPrivate::_q_applyChangesFromClient() +{ + +} + + +QList QDeclarativeViewObserverPrivate::filterForSelection(QList &itemlist) const +{ + foreach(QGraphicsItem *item, itemlist) { + if (isEditorItem(item) || !subcomponentEditorTool->isChildOfContext(item)) + itemlist.removeOne(item); + } + + return itemlist; +} + +QList QDeclarativeViewObserverPrivate::filterForCurrentContext(QList &itemlist) const +{ + foreach(QGraphicsItem *item, itemlist) { + + if (isEditorItem(item) || !subcomponentEditorTool->isDirectChildOfContext(item)) { + + // if we're a child, but not directly, replace with the parent that is directly in context. + if (QGraphicsItem *contextParent = subcomponentEditorTool->firstChildOfContext(item)) { + if (contextParent != item) { + if (itemlist.contains(contextParent)) { + itemlist.removeOne(item); + } else { + itemlist.replace(itemlist.indexOf(item), contextParent); + } + } + } else { + itemlist.removeOne(item); + } + } + } + + return itemlist; +} + +bool QDeclarativeViewObserverPrivate::isEditorItem(QGraphicsItem *item) const +{ + return (item->type() == Constants::EditorItemType + || item->type() == Constants::ResizeHandleItemType + || item->data(Constants::EditorItemDataKey).toBool()); +} + +void QDeclarativeViewObserverPrivate::_q_onStatusChanged(QDeclarativeView::Status status) +{ + if (status == QDeclarativeView::Ready) { + if (view->rootObject()) { + if (subcomponentEditorTool->contextIndex() != -1) + subcomponentEditorTool->clear(); + subcomponentEditorTool->pushContext(view->rootObject()); + emit q->executionStarted(1.0f); + + } + debugService->reloaded(); + } +} + +void QDeclarativeViewObserverPrivate::_q_onCurrentObjectsChanged(QList objects) +{ + QList items; + QList gfxObjects; + foreach(QObject *obj, objects) { + QDeclarativeItem* declarativeItem = qobject_cast(obj); + if (declarativeItem) { + items << declarativeItem; + QGraphicsObject *gfxObj = declarativeItem->toGraphicsObject(); + if (gfxObj) + gfxObjects << gfxObj; + } + } + setSelectedItemsForTools(items); + clearHighlight(); + highlight(gfxObjects, QDeclarativeViewObserverPrivate::IgnoreContext); +} + +QString QDeclarativeViewObserver::idStringForObject(QObject *obj) +{ + return QDeclarativeObserverService::instance()->idStringForObject(obj); +} + +// adjusts bounding boxes on edges of screen to be visible +QRectF QDeclarativeViewObserver::adjustToScreenBoundaries(const QRectF &boundingRectInSceneSpace) +{ + int marginFromEdge = 1; + QRectF boundingRect(boundingRectInSceneSpace); + if (qAbs(boundingRect.left()) - 1 < 2) { + boundingRect.setLeft(marginFromEdge); + } + + QRect rect = data->view->rect(); + if (boundingRect.right() >= rect.right() ) { + boundingRect.setRight(rect.right() - marginFromEdge); + } + + if (qAbs(boundingRect.top()) - 1 < 2) { + boundingRect.setTop(marginFromEdge); + } + + if (boundingRect.bottom() >= rect.bottom() ) { + boundingRect.setBottom(rect.bottom() - marginFromEdge); + } + + return boundingRect; +} + +QToolBar *QDeclarativeViewObserver::toolbar() const +{ + return data->toolbar; +} + +void QDeclarativeViewObserverPrivate::createToolbar() +{ + toolbar = new QmlToolbar(q->declarativeView()); + QObject::connect(q, SIGNAL(selectedColorChanged(QColor)), toolbar, SLOT(setColorBoxColor(QColor))); + + QObject::connect(q, SIGNAL(designModeBehaviorChanged(bool)), toolbar, SLOT(setDesignModeBehavior(bool))); + + QObject::connect(toolbar, SIGNAL(designModeBehaviorChanged(bool)), q, SLOT(setDesignModeBehavior(bool))); + QObject::connect(toolbar, SIGNAL(animationSpeedChanged(qreal)), q, SLOT(changeAnimationSpeed(qreal))); + QObject::connect(toolbar, SIGNAL(colorPickerSelected()), q, SLOT(_q_changeToColorPickerTool())); + QObject::connect(toolbar, SIGNAL(zoomToolSelected()), q, SLOT(_q_changeToZoomTool())); + QObject::connect(toolbar, SIGNAL(selectToolSelected()), q, SLOT(_q_changeToSingleSelectTool())); + QObject::connect(toolbar, SIGNAL(marqueeSelectToolSelected()), q, SLOT(_q_changeToMarqueeSelectTool())); + + QObject::connect(toolbar, SIGNAL(applyChangesFromQmlFileSelected()), q, SLOT(_q_applyChangesFromClient())); + + QObject::connect(q, SIGNAL(executionStarted(qreal)), toolbar, SLOT(setAnimationSpeed(qreal))); + QObject::connect(q, SIGNAL(executionPaused()), toolbar, SLOT(setAnimationSpeed())); + + QObject::connect(q, SIGNAL(selectToolActivated()), toolbar, SLOT(activateSelectTool())); + + // disabled features + //connect(d->m_toolbar, SIGNAL(applyChangesToQmlFileSelected()), SLOT(applyChangesToClient())); + //connect(q, SIGNAL(resizeToolActivated()), d->m_toolbar, SLOT(activateSelectTool())); + //connect(q, SIGNAL(moveToolActivated()), d->m_toolbar, SLOT(activateSelectTool())); + + QObject::connect(q, SIGNAL(colorPickerActivated()), toolbar, SLOT(activateColorPicker())); + QObject::connect(q, SIGNAL(zoomToolActivated()), toolbar, SLOT(activateZoom())); + QObject::connect(q, SIGNAL(marqueeSelectToolActivated()), toolbar, SLOT(activateMarqueeSelectTool())); +} + +void QDeclarativeViewObserver::setDebugMode(bool isDebugMode) +{ + if (isDebugMode && !data->jsDebuggerAgent) + data->jsDebuggerAgent = new JSDebuggerAgent(QDeclarativeEnginePrivate::getScriptEngine(data->view->engine())); +} + +} //namespace QmlJSDebugger + +#include diff --git a/share/qtcreator/qml/qmljsdebugger/qdeclarativeviewobserver_p.h b/share/qtcreator/qml/qmljsdebugger/qdeclarativeviewobserver_p.h new file mode 100644 index 0000000000..a276c4350e --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/qdeclarativeviewobserver_p.h @@ -0,0 +1,141 @@ +/************************************************************************** +** +** 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 QDECLARATIVEDESIGNVIEW_P_H +#define QDECLARATIVEDESIGNVIEW_P_H + +#include +#include +#include + +#include "qdeclarativeviewobserver.h" +#include "qdeclarativeobserverservice.h" + +namespace QmlJSDebugger { + +class JSDebuggerAgent; +class QDeclarativeViewObserver; +class SelectionTool; +class ZoomTool; +class ColorPickerTool; +class LayerItem; +class BoundingRectHighlighter; +class SubcomponentEditorTool; +class QmlToolbar; +class CrumblePath; +class AbstractFormEditorTool; + +class QDeclarativeViewObserverPrivate +{ +public: + + enum ContextFlags { + IgnoreContext, + ContextSensitive + }; + + QDeclarativeViewObserverPrivate(QDeclarativeViewObserver *); + ~QDeclarativeViewObserverPrivate(); + + QDeclarativeView *view; + QDeclarativeViewObserver *q; + QDeclarativeObserverService *debugService; + + QPointF cursorPos; + QList > currentSelection; + + Constants::DesignTool currentToolMode; + AbstractFormEditorTool *currentTool; + + SelectionTool *selectionTool; + ZoomTool *zoomTool; + ColorPickerTool *colorPickerTool; + SubcomponentEditorTool *subcomponentEditorTool; + LayerItem *manipulatorLayer; + + BoundingRectHighlighter *boundingRectHighlighter; + + bool designModeBehavior; + + bool executionPaused; + qreal slowdownFactor; + + JSDebuggerAgent *jsDebuggerAgent; + + QmlToolbar *toolbar; + + void clearEditorItems(); + void createToolbar(); + void changeToSelectTool(); + QList filterForCurrentContext(QList &itemlist) const; + QList filterForSelection(QList &itemlist) const; + + QList selectableItems(const QPoint &pos) const; + QList selectableItems(const QPointF &scenePos) const; + QList selectableItems(const QRectF &sceneRect, Qt::ItemSelectionMode selectionMode) const; + + void setSelectedItemsForTools(QList items); + void setSelectedItems(QList items); + QList selectedItems(); + + void changeTool(Constants::DesignTool tool, + Constants::ToolFlags flags = Constants::NoToolFlags); + + void clearHighlight(); + void highlight(QList item, ContextFlags flags = ContextSensitive); + void highlight(QGraphicsObject *item, ContextFlags flags = ContextSensitive); + + bool mouseInsideContextItem() const; + bool isEditorItem(QGraphicsItem *item) const; + + QGraphicsItem *currentRootItem() const; + + void enterContext(QGraphicsItem *itemToEnter); + + void _q_reloadView(); + void _q_onStatusChanged(QDeclarativeView::Status status); + void _q_onCurrentObjectsChanged(QList objects); + void _q_applyChangesFromClient(); + void _q_createQmlObject(const QString &qml, QObject *parent, + const QStringList &imports, const QString &filename = QString()); + void _q_reparentQmlObject(QObject *, QObject *); + + void _q_changeToSingleSelectTool(); + void _q_changeToMarqueeSelectTool(); + void _q_changeToZoomTool(); + void _q_changeToColorPickerTool(); + void _q_changeContextPathIndex(int index); + void _q_clearComponentCache(); + + static QDeclarativeViewObserverPrivate *get(QDeclarativeViewObserver *v) { return v->d_func(); } +}; + +} // namespace QmlJSDebugger + +#endif // QDECLARATIVEDESIGNVIEW_P_H diff --git a/share/qtcreator/qml/qmljsdebugger/qmljsdebugger-lib.pri b/share/qtcreator/qml/qmljsdebugger/qmljsdebugger-lib.pri new file mode 100644 index 0000000000..f8e482e38c --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/qmljsdebugger-lib.pri @@ -0,0 +1,35 @@ +QT += declarative script +INCLUDEPATH += $$PWD $$PWD/include editor +DEPENDPATH += $$PWD $$PWD/include editor + +contains(CONFIG, dll) { + DEFINES += BUILD_QMLJSDEBUGGER_LIB +} else { + DEFINES += BUILD_QMLJSDEBUGGER_STATIC_LIB +} + +include($$PWD/private_headers.pri) + +## Input +HEADERS += \ + $$PWD/include/jsdebuggeragent.h \ + $$PWD/include/qmljsdebugger_global.h + +SOURCES += \ + $$PWD/jsdebuggeragent.cpp + +contains(DEFINES, QMLOBSERVER) { + include($$PWD/editor/editor.pri) + + HEADERS += \ + $$PWD/include/qdeclarativeviewobserver.h \ + $$PWD/include/qdeclarativeobserverservice.h \ + $$PWD/include/qmlobserverconstants.h \ + $$PWD/qdeclarativeviewobserver_p.h + + SOURCES += \ + $$PWD/qdeclarativeviewobserver.cpp \ + $$PWD/qdeclarativeobserverservice.cpp +} + +OTHER_FILES += $$PWD/qmljsdebugger.pri diff --git a/share/qtcreator/qml/qmljsdebugger/qmljsdebugger.pri b/share/qtcreator/qml/qmljsdebugger/qmljsdebugger.pri new file mode 100644 index 0000000000..a4abeb9cd5 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/qmljsdebugger.pri @@ -0,0 +1,5 @@ +INCLUDEPATH += $$PWD/include +DEPENDPATH += $PPWD/include +QT += declarative script + +LIBS *= -l$$qtLibraryName(QmlJSDebugger) diff --git a/share/qtcreator/qml/qmljsdebugger/qmljsdebugger.pro b/share/qtcreator/qml/qmljsdebugger/qmljsdebugger.pro new file mode 100644 index 0000000000..5f3eb50958 --- /dev/null +++ b/share/qtcreator/qml/qmljsdebugger/qmljsdebugger.pro @@ -0,0 +1,10 @@ +TEMPLATE = lib +CONFIG+=dll +TARGET = QmlJSDebugger + +DEFINES += QMLOBSERVER + +unix:QMAKE_CXXFLAGS_DEBUG += -O3 + +include(../../../src/qtcreatorlibrary.pri) +include(qmljsdebugger-lib.pri) diff --git a/share/qtcreator/qml/qmlobserver/Info_mac.plist b/share/qtcreator/qml/qmlobserver/Info_mac.plist new file mode 100644 index 0000000000..80ca6a3526 --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/Info_mac.plist @@ -0,0 +1,18 @@ + + + + + CFBundleIconFile + @ICON@ + CFBundleIdentifier + com.nokia.qt.qml + CFBundlePackageType + APPL + CFBundleGetInfoString + Created by Qt/QMake + CFBundleSignature + @TYPEINFO@ + CFBundleExecutable + @EXECUTABLE@ + + diff --git a/share/qtcreator/qml/qmlobserver/LGPL_EXCEPTION.TXT b/share/qtcreator/qml/qmlobserver/LGPL_EXCEPTION.TXT new file mode 100644 index 0000000000..8d0f85eba4 --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/LGPL_EXCEPTION.TXT @@ -0,0 +1,3 @@ +Nokia Qt LGPL Exception version 1.0 + +As a special exception to the GNU Lesser General Public License version 2.1, the object code form of a "work that uses the Library" may incorporate material from a header file that is part of the Library. You may distribute such object code under terms of your choice, provided that the incorporated material (i) does not exceed more than 5% of the total size of the Library; and (ii) is limited to numerical parameters, data structure layouts, accessors, macros, inline functions and templates. \ No newline at end of file diff --git a/share/qtcreator/qml/qmlobserver/LICENSE.LGPL b/share/qtcreator/qml/qmlobserver/LICENSE.LGPL new file mode 100644 index 0000000000..602bfc9463 --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/LICENSE.LGPL @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/share/qtcreator/qml/qmlobserver/content/Browser.qml b/share/qtcreator/qml/qmlobserver/content/Browser.qml new file mode 100644 index 0000000000..ff2bb47647 --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/content/Browser.qml @@ -0,0 +1,284 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 +import Qt.labs.folderlistmodel 1.0 + +Rectangle { + id: root + property bool keyPressed: false + property variant folders: folders1 + property variant view: view1 + width: 320 + height: 480 + color: palette.window + + FolderListModel { + id: folders1 + nameFilters: [ "*.qml" ] + folder: qmlViewerFolder + } + FolderListModel { + id: folders2 + nameFilters: [ "*.qml" ] + folder: qmlViewerFolder + } + + SystemPalette { id: palette } + + function down(path) { + if (folders == folders1) { + view = view2 + folders = folders2; + view1.state = "exitLeft"; + } else { + view = view1 + folders = folders1; + view2.state = "exitLeft"; + } + view.x = root.width; + view.state = "current"; + view.focus = true; + folders.folder = path; + } + function up() { + var path = folders.parentFolder; + if (folders == folders1) { + view = view2 + folders = folders2; + view1.state = "exitRight"; + } else { + view = view1 + folders = folders1; + view2.state = "exitRight"; + } + view.x = -root.width; + view.state = "current"; + view.focus = true; + folders.folder = path; + } + + Component { + id: folderDelegate + Rectangle { + id: wrapper + function launch() { + if (folders.isFolder(index)) { + down(filePath); + } else { + qmlViewer.launch(filePath); + } + } + width: root.width + height: 52 + color: "transparent" + Rectangle { + id: highlight; visible: false + anchors.fill: parent + gradient: Gradient { + GradientStop { id: t1; position: 0.0; color: palette.highlight } + GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) } + } + } + Item { + width: 48; height: 48 + Image { source: "images/folder.png"; anchors.centerIn: parent; visible: folders.isFolder(index)} + } + Text { + id: nameText + anchors.fill: parent; verticalAlignment: Text.AlignVCenter + text: fileName + anchors.leftMargin: 54 + font.pixelSize: 32 + color: (wrapper.ListView.isCurrentItem && root.keyPressed) ? palette.highlightedText : palette.windowText + elide: Text.ElideRight + } + MouseArea { + id: mouseRegion + anchors.fill: parent + onClicked: { if (folders == wrapper.ListView.view.model) launch() } + } + states: [ + State { + name: "pressed" + when: mouseRegion.pressed + PropertyChanges { target: highlight; visible: true } + PropertyChanges { target: nameText; color: palette.highlightedText } + } + ] + } + } + + ListView { + id: view1 + anchors.top: titleBar.bottom + anchors.bottom: parent.bottom + x: 0 + width: parent.width + model: folders1 + delegate: folderDelegate + highlight: Rectangle { color: palette.highlight; visible: root.keyPressed && view1.count != 0 } + highlightMoveSpeed: 1000 + pressDelay: 100 + focus: true + state: "current" + states: [ + State { + name: "current" + PropertyChanges { target: view1; x: 0 } + }, + State { + name: "exitLeft" + PropertyChanges { target: view1; x: -root.width } + }, + State { + name: "exitRight" + PropertyChanges { target: view1; x: root.width } + } + ] + transitions: [ + Transition { + to: "current" + SequentialAnimation { + NumberAnimation { properties: "x"; duration: 250 } + } + }, + Transition { + NumberAnimation { properties: "x"; duration: 250 } + NumberAnimation { properties: "x"; duration: 250 } + } + ] + Keys.onPressed: { root.keyPressed = true; } + } + + ListView { + id: view2 + anchors.top: titleBar.bottom + anchors.bottom: parent.bottom + x: parent.width + width: parent.width + model: folders2 + delegate: folderDelegate + highlight: Rectangle { color: palette.highlight; visible: root.keyPressed && view2.count != 0 } + highlightMoveSpeed: 1000 + pressDelay: 100 + states: [ + State { + name: "current" + PropertyChanges { target: view2; x: 0 } + }, + State { + name: "exitLeft" + PropertyChanges { target: view2; x: -root.width } + }, + State { + name: "exitRight" + PropertyChanges { target: view2; x: root.width } + } + ] + transitions: [ + Transition { + to: "current" + SequentialAnimation { + NumberAnimation { properties: "x"; duration: 250 } + } + }, + Transition { + NumberAnimation { properties: "x"; duration: 250 } + } + ] + Keys.onPressed: { root.keyPressed = true; } + } + + Keys.onPressed: { + root.keyPressed = true; + if (event.key == Qt.Key_Return || event.key == Qt.Key_Select || event.key == Qt.Key_Right) { + view.currentItem.launch(); + event.accepted = true; + } else if (event.key == Qt.Key_Left) { + up(); + } + } + + BorderImage { + source: "images/titlebar.sci"; + width: parent.width; + height: 52 + y: -7 + id: titleBar + + Rectangle { + id: upButton + width: 48 + height: titleBar.height - 7 + color: "transparent" + + Image { anchors.centerIn: parent; source: "images/up.png" } + MouseArea { id: upRegion; anchors.centerIn: parent + width: 56 + height: 56 + onClicked: if (folders.parentFolder != "") up() + } + states: [ + State { + name: "pressed" + when: upRegion.pressed + PropertyChanges { target: upButton; color: palette.highlight } + } + ] + } + Rectangle { + color: "gray" + x: 48 + width: 1 + height: 44 + } + + Text { + anchors.left: upButton.right; anchors.right: parent.right; height: parent.height + anchors.leftMargin: 4; anchors.rightMargin: 4 + text: folders.folder + color: "white" + elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter + font.pixelSize: 32 + } + } +} diff --git a/share/qtcreator/qml/qmlobserver/content/images/folder.png b/share/qtcreator/qml/qmlobserver/content/images/folder.png new file mode 100644 index 0000000000..e53e2ad464 Binary files /dev/null and b/share/qtcreator/qml/qmlobserver/content/images/folder.png differ diff --git a/share/qtcreator/qml/qmlobserver/content/images/titlebar.png b/share/qtcreator/qml/qmlobserver/content/images/titlebar.png new file mode 100644 index 0000000000..51c90082d0 Binary files /dev/null and b/share/qtcreator/qml/qmlobserver/content/images/titlebar.png differ diff --git a/share/qtcreator/qml/qmlobserver/content/images/titlebar.sci b/share/qtcreator/qml/qmlobserver/content/images/titlebar.sci new file mode 100644 index 0000000000..0418d94cd6 --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/content/images/titlebar.sci @@ -0,0 +1,5 @@ +border.left: 10 +border.top: 12 +border.bottom: 12 +border.right: 10 +source: titlebar.png diff --git a/share/qtcreator/qml/qmlobserver/content/images/up.png b/share/qtcreator/qml/qmlobserver/content/images/up.png new file mode 100644 index 0000000000..b05f8025d0 Binary files /dev/null and b/share/qtcreator/qml/qmlobserver/content/images/up.png differ diff --git a/share/qtcreator/qml/qmlobserver/deviceorientation.cpp b/share/qtcreator/qml/qmlobserver/deviceorientation.cpp new file mode 100644 index 0000000000..e7c70d5fde --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/deviceorientation.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "deviceorientation.h" + +QT_USE_NAMESPACE + +class DefaultDeviceOrientation : public DeviceOrientation +{ + Q_OBJECT +public: + DefaultDeviceOrientation() : DeviceOrientation(), m_orientation(DeviceOrientation::Portrait) {} + + Orientation orientation() const { + return m_orientation; + } + + void setOrientation(Orientation o) { + if (o != m_orientation) { + m_orientation = o; + emit orientationChanged(); + } + } + + Orientation m_orientation; +}; + +DeviceOrientation* DeviceOrientation::instance() +{ + static DefaultDeviceOrientation *o = 0; + if (!o) + o = new DefaultDeviceOrientation; + return o; +} + +#include "deviceorientation.moc" + diff --git a/share/qtcreator/qml/qmlobserver/deviceorientation.h b/share/qtcreator/qml/qmlobserver/deviceorientation.h new file mode 100644 index 0000000000..3bad5bec01 --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/deviceorientation.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ORIENTATION_H +#define ORIENTATION_H + +#include + +QT_BEGIN_NAMESPACE + +class DeviceOrientationPrivate; +class DeviceOrientation : public QObject +{ + Q_OBJECT + Q_ENUMS(Orientation) +public: + enum Orientation { + UnknownOrientation, + Portrait, + Landscape, + PortraitInverted, + LandscapeInverted + }; + + virtual Orientation orientation() const = 0; + virtual void setOrientation(Orientation) = 0; + + static DeviceOrientation *instance(); + +signals: + void orientationChanged(); + +protected: + DeviceOrientation() {} + +private: + DeviceOrientationPrivate *d_ptr; + friend class DeviceOrientationPrivate; +}; + +QT_END_NAMESPACE + +#endif diff --git a/share/qtcreator/qml/qmlobserver/deviceorientation_maemo5.cpp b/share/qtcreator/qml/qmlobserver/deviceorientation_maemo5.cpp new file mode 100644 index 0000000000..e942579b70 --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/deviceorientation_maemo5.cpp @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "deviceorientation.h" +#include + +#include +#include + +class MaemoOrientation : public DeviceOrientation +{ + Q_OBJECT +public: + MaemoOrientation() + : o(UnknownOrientation) + { + // enable the orientation sensor + QDBusConnection::systemBus().call( + QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH, + MCE_REQUEST_IF, MCE_ACCELEROMETER_ENABLE_REQ)); + + // query the initial orientation + QDBusMessage reply = QDBusConnection::systemBus().call( + QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH, + MCE_REQUEST_IF, MCE_DEVICE_ORIENTATION_GET)); + if (reply.type() == QDBusMessage::ErrorMessage) { + qWarning("Unable to retrieve device orientation: %s", qPrintable(reply.errorMessage())); + } else { + o = toOrientation(reply.arguments().value(0).toString()); + } + + // connect to the orientation change signal + QDBusConnection::systemBus().connect(QString(), MCE_SIGNAL_PATH, MCE_SIGNAL_IF, + MCE_DEVICE_ORIENTATION_SIG, + this, + SLOT(deviceOrientationChanged(QString))); + } + + ~MaemoOrientation() + { + // disable the orientation sensor + QDBusConnection::systemBus().call( + QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH, + MCE_REQUEST_IF, MCE_ACCELEROMETER_DISABLE_REQ)); + } + + inline Orientation orientation() const + { + return o; + } + + void setOrientation(Orientation o) + { + } + +private Q_SLOTS: + void deviceOrientationChanged(const QString &newOrientation) + { + o = toOrientation(newOrientation); + + emit orientationChanged(); +// printf("%d\n", o); + } + +private: + static Orientation toOrientation(const QString &nativeOrientation) + { + if (nativeOrientation == MCE_ORIENTATION_LANDSCAPE) + return Landscape; + else if (nativeOrientation == MCE_ORIENTATION_LANDSCAPE_INVERTED) + return LandscapeInverted; + else if (nativeOrientation == MCE_ORIENTATION_PORTRAIT) + return Portrait; + else if (nativeOrientation == MCE_ORIENTATION_PORTRAIT_INVERTED) + return PortraitInverted; + return UnknownOrientation; + } + +private: + Orientation o; +}; + +DeviceOrientation* DeviceOrientation::instance() +{ + static MaemoOrientation *o = new MaemoOrientation; + return o; +} + +#include "deviceorientation_maemo5.moc" diff --git a/share/qtcreator/qml/qmlobserver/loggerwidget.cpp b/share/qtcreator/qml/qmlobserver/loggerwidget.cpp new file mode 100644 index 0000000000..8aa029f3d0 --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/loggerwidget.cpp @@ -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 +#include +#include +#include +#include +#include +#ifdef Q_WS_MAEMO_5 +# include +# include +# 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(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 diff --git a/share/qtcreator/qml/qmlobserver/loggerwidget.h b/share/qtcreator/qml/qmlobserver/loggerwidget.h new file mode 100644 index 0000000000..13c319f91a --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/loggerwidget.h @@ -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 +#include + +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 diff --git a/share/qtcreator/qml/qmlobserver/main.cpp b/share/qtcreator/qml/qmlobserver/main.cpp new file mode 100644 index 0000000000..f04640d970 --- /dev/null +++ b/share/qtcreator/qml/qmlobserver/main.cpp @@ -0,0 +1,471 @@ +/**************************************************************************** +** +** 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 +#include +#include +#include +#include +#include +#include "qdeclarativetester.h" + +QT_USE_NAMESPACE + +QtMsgHandler systemMsgOutput = 0; + +#if defined (Q_OS_SYMBIAN) +#include +#include +#include +#include + +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 logger; + +QString warnings; +void showWarnings() +{ + if (!warnings.isEmpty()) { + int argc = 0; char **argv = 0; + QApplication application(argc, argv); // QApplication() in main has been destroyed already. + Q_UNUSED(application) + 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] "); + 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 ..................... 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 ........................ set recording frame rate"); + qWarning(" -record arg .............................. add a recording process argument"); + qWarning(" -autorecord [from-] ...... set recording to start and stop"); + qWarning(" -devicekeys .............................. use numeric keys (see F1)"); + qWarning(" -dragthreshold .................... set mouse drag threshold size"); + qWarning(" -netcache ......................... set disk cache to size bytes"); + qWarning(" -translation ........... set the language to run in"); + qWarning(" -I ........................... prepend to the module import search path,"); + qWarning(" display path if is empty"); + qWarning(" -P ........................... prepend to the plugin search path"); + qWarning(" -opengl .................................. use a QGLWidget for the viewport"); + qWarning(" -script ........................... set the script to use"); + qWarning(" -scriptopts |help ............... set the script options to use"); + + qWarning(" "); + qWarning(" Press F1 for interactive help"); + exit(1); +} + +void scriptOptsUsage() +{ + qWarning("Usage: qmlviewer -scriptopts