From 56cec4cf9a8b04c979ced28cab89ce6232d4184a Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 15 Sep 2009 14:12:08 +0200 Subject: QCursor support for Symbian OS Reviewed-By: Jason Barron Reviewed-By: Alessandro Portale Summary: QT_NO_CURSOR is now not defined for symbian builds Existing QCursor APIs are all supported New public API, QApplication::setNavigationMode, to allow the navigation mode to be set. I.E. on an S60 3.2 phone, some applications will want a virtual mouse cursor (web browser), while others are designed for keypad navigation. Symbian HAL is used for detecting input capabilities. Fix DND, code cleanup & comment QCursor visibility now uses a refcount, and is called from DND and the setNavigationMode so they are both simpler and don't interfere with each other. QApplication::setNavigationMode New public API for configuring cursor/keypad navi style. This links in with ongoing work on the 4-way keypad navi branch, but 2-way and 4-way modes both act as 2-way mode until that is integrated Some of the demos/examples have cursor switched on (those that were not usable with keypad) Virtual mouse support for non touch, non mouse phones (tested on N78) add *.d and .metadata (carbide debug file / workspace dir) to .gitignore System pointers are unavailable when using sprite workaround, so the system cursor shapes are compiled into qtgui as resources. MAC port does this also for shapes that aren't standard on the MAC. Refactor Drag'n'Drop to use QCursor Add test case to check all system cursor shapes Simply a mainwindow containing a label widget for each cursor shape, with the cursor property set appropriately QCursor(QBitmap,QBitmap) supported Fixed problem with the image & mask being inverted when using the QCursor constructor that takes two mono bitmaps. add .make.cache files to .gitignore Correct implementation of QApplication::setOverrideCursor QApplication::restoreOverrideCursor and QApplication::setOverrideCursor are now working correctly on Symbian platform. Performance will be slower compared with other platforms, because the Symbian window server has a cursor associated with each native window. Add test case for custom cursors Create a pixmap cursor and associate it with a widget. No changes to production code, since test passed 1st time ;) Add manual test for QCursor Make cursor independent of construction order Updated to work around window server issue where contruction order affects what cursor is displayed in child windows. Also changed to effectiveWinId following review comments Also fixed a problem which would make qcursor not link if configured with QT_NO_CURSOR Moved some multiply declared extern functions from cpp to _p.h files Implemented Symbian versions of the cursor functions. Merged in work I'd done based on tower. Fill in bits of stub functions based on windows port Removed QT_NO_CURSOR from list of config options forced on symbian Recompiled configure.exe Added stub functions for the missing functions in s60 port --- .gitignore | 2 + configure.exe | Bin 1165824 -> 2038784 bytes demos/deform/main.cpp | 3 + demos/embedded/anomaly/src/Main.cpp | 3 + demos/embedded/embeddedsvgviewer/main.cpp | 3 + demos/embedded/flightinfo/flightinfo.pro | 2 +- demos/embedded/lightmaps/lightmaps.pro | 2 +- demos/embedded/weatherinfo/weatherinfo.pro | 2 +- demos/pathstroke/main.cpp | 3 + examples/animation/animatedtiles/main.cpp | 3 + examples/draganddrop/fridgemagnets/main.cpp | 3 + src/corelib/global/qglobal.h | 5 + src/corelib/global/qnamespace.h | 8 + src/corelib/global/qnamespace.qdoc | 26 ++ src/gui/image/qpixmap_s60.cpp | 10 +- src/gui/kernel/qapplication.cpp | 90 +++- src/gui/kernel/qapplication.h | 4 +- src/gui/kernel/qapplication_p.h | 16 +- src/gui/kernel/qapplication_s60.cpp | 307 +++++++++++++- src/gui/kernel/qapplication_x11.cpp | 2 - src/gui/kernel/qcursor.h | 18 +- src/gui/kernel/qcursor_p.h | 14 +- src/gui/kernel/qcursor_qws.cpp | 2 - src/gui/kernel/qcursor_s60.cpp | 471 ++++++++++++++++++++- src/gui/kernel/qcursor_win.cpp | 2 - src/gui/kernel/qcursor_x11.cpp | 3 +- src/gui/kernel/qdnd_p.h | 7 +- src/gui/kernel/qdnd_s60.cpp | 148 +++---- src/gui/kernel/qt_s60_p.h | 23 + src/gui/kernel/qwidget.cpp | 1 - src/gui/kernel/qwidget_s60.cpp | 77 +++- src/gui/kernel/qwidget_win.cpp | 2 - src/gui/kernel/symbian.pri | 1 + src/gui/symbian/images/blank.png | Bin 0 -> 91 bytes src/gui/symbian/images/busy12.png | Bin 0 -> 253 bytes src/gui/symbian/images/busy3.png | Bin 0 -> 251 bytes src/gui/symbian/images/busy6.png | Bin 0 -> 253 bytes src/gui/symbian/images/busy9.png | Bin 0 -> 255 bytes src/gui/symbian/images/closehand.png | Bin 0 -> 190 bytes src/gui/symbian/images/cross.png | Bin 0 -> 145 bytes src/gui/symbian/images/forbidden.png | Bin 0 -> 256 bytes src/gui/symbian/images/handpoint.png | Bin 0 -> 230 bytes src/gui/symbian/images/ibeam.png | Bin 0 -> 176 bytes src/gui/symbian/images/openhand.png | Bin 0 -> 201 bytes src/gui/symbian/images/pointer.png | Bin 0 -> 222 bytes src/gui/symbian/images/sizeall.png | Bin 0 -> 188 bytes src/gui/symbian/images/sizebdiag.png | Bin 0 -> 192 bytes src/gui/symbian/images/sizefdiag.png | Bin 0 -> 197 bytes src/gui/symbian/images/sizehor.png | Bin 0 -> 175 bytes src/gui/symbian/images/sizever.png | Bin 0 -> 171 bytes src/gui/symbian/images/splith.png | Bin 0 -> 206 bytes src/gui/symbian/images/splitv.png | Bin 0 -> 205 bytes src/gui/symbian/images/uparrow.png | Bin 0 -> 157 bytes src/gui/symbian/images/wait1.png | Bin 0 -> 219 bytes src/gui/symbian/images/wait10.png | Bin 0 -> 220 bytes src/gui/symbian/images/wait11.png | Bin 0 -> 220 bytes src/gui/symbian/images/wait12.png | Bin 0 -> 213 bytes src/gui/symbian/images/wait2.png | Bin 0 -> 219 bytes src/gui/symbian/images/wait3.png | Bin 0 -> 210 bytes src/gui/symbian/images/wait4.png | Bin 0 -> 215 bytes src/gui/symbian/images/wait5.png | Bin 0 -> 217 bytes src/gui/symbian/images/wait6.png | Bin 0 -> 213 bytes src/gui/symbian/images/wait7.png | Bin 0 -> 215 bytes src/gui/symbian/images/wait8.png | Bin 0 -> 217 bytes src/gui/symbian/images/wait9.png | Bin 0 -> 209 bytes src/gui/symbian/images/whatsthis.png | Bin 0 -> 254 bytes src/gui/symbian/symbianresources.qrc | 37 ++ src/qbase.pri | 8 + src/testlib/qtest.h | 2 +- src/testlib/qtestcase.cpp | 2 +- tests/manual/qcursor/allcursors/allcursors.pro | 16 + tests/manual/qcursor/allcursors/main.cpp | 13 + tests/manual/qcursor/allcursors/mainwindow.cpp | 43 ++ tests/manual/qcursor/allcursors/mainwindow.h | 28 ++ tests/manual/qcursor/allcursors/mainwindow.ui | 210 +++++++++ .../qcursor/grab_override/data/monkey_on_64x64.png | Bin 0 -> 3479 bytes .../manual/qcursor/grab_override/grab_override.pro | 18 + tests/manual/qcursor/grab_override/images.qrc | 6 + tests/manual/qcursor/grab_override/main.cpp | 13 + tests/manual/qcursor/grab_override/mainwindow.cpp | 100 +++++ tests/manual/qcursor/grab_override/mainwindow.h | 35 ++ tests/manual/qcursor/grab_override/mainwindow.ui | 97 +++++ tests/manual/qcursor/qcursor.pro | 3 + tools/configure/configureapp.cpp | 1 - 84 files changed, 1719 insertions(+), 176 deletions(-) create mode 100644 src/gui/symbian/images/blank.png create mode 100644 src/gui/symbian/images/busy12.png create mode 100644 src/gui/symbian/images/busy3.png create mode 100644 src/gui/symbian/images/busy6.png create mode 100644 src/gui/symbian/images/busy9.png create mode 100644 src/gui/symbian/images/closehand.png create mode 100644 src/gui/symbian/images/cross.png create mode 100644 src/gui/symbian/images/forbidden.png create mode 100644 src/gui/symbian/images/handpoint.png create mode 100644 src/gui/symbian/images/ibeam.png create mode 100644 src/gui/symbian/images/openhand.png create mode 100644 src/gui/symbian/images/pointer.png create mode 100644 src/gui/symbian/images/sizeall.png create mode 100644 src/gui/symbian/images/sizebdiag.png create mode 100644 src/gui/symbian/images/sizefdiag.png create mode 100644 src/gui/symbian/images/sizehor.png create mode 100644 src/gui/symbian/images/sizever.png create mode 100644 src/gui/symbian/images/splith.png create mode 100644 src/gui/symbian/images/splitv.png create mode 100644 src/gui/symbian/images/uparrow.png create mode 100644 src/gui/symbian/images/wait1.png create mode 100644 src/gui/symbian/images/wait10.png create mode 100644 src/gui/symbian/images/wait11.png create mode 100644 src/gui/symbian/images/wait12.png create mode 100644 src/gui/symbian/images/wait2.png create mode 100644 src/gui/symbian/images/wait3.png create mode 100644 src/gui/symbian/images/wait4.png create mode 100644 src/gui/symbian/images/wait5.png create mode 100644 src/gui/symbian/images/wait6.png create mode 100644 src/gui/symbian/images/wait7.png create mode 100644 src/gui/symbian/images/wait8.png create mode 100644 src/gui/symbian/images/wait9.png create mode 100644 src/gui/symbian/images/whatsthis.png create mode 100644 src/gui/symbian/symbianresources.qrc create mode 100644 tests/manual/qcursor/allcursors/allcursors.pro create mode 100644 tests/manual/qcursor/allcursors/main.cpp create mode 100644 tests/manual/qcursor/allcursors/mainwindow.cpp create mode 100644 tests/manual/qcursor/allcursors/mainwindow.h create mode 100644 tests/manual/qcursor/allcursors/mainwindow.ui create mode 100644 tests/manual/qcursor/grab_override/data/monkey_on_64x64.png create mode 100644 tests/manual/qcursor/grab_override/grab_override.pro create mode 100644 tests/manual/qcursor/grab_override/images.qrc create mode 100644 tests/manual/qcursor/grab_override/main.cpp create mode 100644 tests/manual/qcursor/grab_override/mainwindow.cpp create mode 100644 tests/manual/qcursor/grab_override/mainwindow.h create mode 100644 tests/manual/qcursor/grab_override/mainwindow.ui create mode 100644 tests/manual/qcursor/qcursor.pro diff --git a/.gitignore b/.gitignore index 282c8bc..feb1ea4 100644 --- a/.gitignore +++ b/.gitignore @@ -174,6 +174,7 @@ doc/qch doc-build .rcc .pch +.metadata # Symbian build system generated files # --------------------- @@ -199,6 +200,7 @@ plugin_commonU.def .project .cproject .make.cache +*.d qtc-debugging-helper src/corelib/lib diff --git a/configure.exe b/configure.exe index 4c095d2..2c5b717 100755 Binary files a/configure.exe and b/configure.exe differ diff --git a/demos/deform/main.cpp b/demos/deform/main.cpp index cb92a21..6110a76 100644 --- a/demos/deform/main.cpp +++ b/demos/deform/main.cpp @@ -68,5 +68,8 @@ int main(int argc, char **argv) else deformWidget.show(); +#ifdef QT_KEYPAD_NAVIGATION + QApplication::setNavigationMode(Qt::NavigationModeCursorAuto); +#endif return app.exec(); } diff --git a/demos/embedded/anomaly/src/Main.cpp b/demos/embedded/anomaly/src/Main.cpp index f9610d3..cf32420 100644 --- a/demos/embedded/anomaly/src/Main.cpp +++ b/demos/embedded/anomaly/src/Main.cpp @@ -67,5 +67,8 @@ int main(int argc, char *argv[]) app.setStyle("windows"); #endif +#ifdef QT_KEYPAD_NAVIGATION + QApplication::setNavigationMode(Qt::NavigationModeCursorAuto); +#endif return app.exec(); } diff --git a/demos/embedded/embeddedsvgviewer/main.cpp b/demos/embedded/embeddedsvgviewer/main.cpp index 10c7d76..9c91fb7 100644 --- a/demos/embedded/embeddedsvgviewer/main.cpp +++ b/demos/embedded/embeddedsvgviewer/main.cpp @@ -64,5 +64,8 @@ int main(int argc, char** argv) viewer.showFullScreen(); +#ifdef QT_KEYPAD_NAVIGATION + QApplication::setNavigationMode(Qt::NavigationModeCursorAuto); +#endif return app.exec(); } diff --git a/demos/embedded/flightinfo/flightinfo.pro b/demos/embedded/flightinfo/flightinfo.pro index 461c701..2f36cb8 100644 --- a/demos/embedded/flightinfo/flightinfo.pro +++ b/demos/embedded/flightinfo/flightinfo.pro @@ -9,6 +9,6 @@ symbian { include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) TARGET.UID3 = 0xA000CF74 HEADERS += $$QT_SOURCE_TREE/examples/network/ftp/sym_iap_util.h - LIBS += -lesock -lconnmon + LIBS += -lesock -lconnmon -linsock TARGET.CAPABILITY = NetworkServices } diff --git a/demos/embedded/lightmaps/lightmaps.pro b/demos/embedded/lightmaps/lightmaps.pro index 137183a..d4168b1 100644 --- a/demos/embedded/lightmaps/lightmaps.pro +++ b/demos/embedded/lightmaps/lightmaps.pro @@ -6,7 +6,7 @@ symbian { include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) TARGET.UID3 = 0xA000CF75 HEADERS += $$QT_SOURCE_TREE/examples/network/ftp/sym_iap_util.h - LIBS += -lesock -lconnmon + LIBS += -lesock -lconnmon -linsock TARGET.CAPABILITY = NetworkServices TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 } diff --git a/demos/embedded/weatherinfo/weatherinfo.pro b/demos/embedded/weatherinfo/weatherinfo.pro index 0a579b0..7bff6e9 100644 --- a/demos/embedded/weatherinfo/weatherinfo.pro +++ b/demos/embedded/weatherinfo/weatherinfo.pro @@ -8,6 +8,6 @@ symbian { include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) TARGET.UID3 = 0xA000CF77 HEADERS += $$QT_SOURCE_TREE/examples/network/ftp/sym_iap_util.h - LIBS += -lesock -lconnmon + LIBS += -lesock -lconnmon -linsock TARGET.CAPABILITY = NetworkServices } diff --git a/demos/pathstroke/main.cpp b/demos/pathstroke/main.cpp index 7c4ad83..60520f1 100644 --- a/demos/pathstroke/main.cpp +++ b/demos/pathstroke/main.cpp @@ -65,5 +65,8 @@ int main(int argc, char **argv) else pathStrokeWidget.show(); +#ifdef QT_KEYPAD_NAVIGATION + QApplication::setNavigationMode(Qt::NavigationModeCursorAuto); +#endif return app.exec(); } diff --git a/examples/animation/animatedtiles/main.cpp b/examples/animation/animatedtiles/main.cpp index dfdaf73..ca52f47 100644 --- a/examples/animation/animatedtiles/main.cpp +++ b/examples/animation/animatedtiles/main.cpp @@ -274,6 +274,9 @@ int main(int argc, char **argv) timer.setSingleShot(true); rootState->addTransition(&timer, SIGNAL(timeout()), ellipseState); +#ifdef QT_KEYPAD_NAVIGATION + QApplication::setNavigationMode(Qt::NavigationModeCursorAuto); +#endif return app.exec(); } diff --git a/examples/draganddrop/fridgemagnets/main.cpp b/examples/draganddrop/fridgemagnets/main.cpp index eed8f70..6cff7c5c 100644 --- a/examples/draganddrop/fridgemagnets/main.cpp +++ b/examples/draganddrop/fridgemagnets/main.cpp @@ -51,6 +51,9 @@ int main(int argc, char *argv[]) smallScreen = true; QApplication app(argc, argv); +#ifdef QT_KEYPAD_NAVIGATION + QApplication::setNavigationMode(Qt::NavigationModeCursorAuto); +#endif DragWidget window; if (smallScreen) window.showFullScreen(); diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 897dcea..6a781e8 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2386,6 +2386,11 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf(); #if defined(Q_OS_SYMBIAN) +#ifdef SYMBIAN_GRAPHICS_USE_GCE +//RWsPointerCursor is fixed, so don't use low performance sprites +#define Q_SYMBIAN_FIXED_POINTER_CURSORS +#endif + //Symbian does not support data imports from a DLL #define Q_NO_DATA_RELOCATION diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index c8e30d4..c39e602 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1618,6 +1618,14 @@ public: GestureFinished = 3 }; + enum NavigationMode + { + NavigationModeNone, + NavigationModeKeypadTabOrder, + NavigationModeKeypadDirectional, + NavigationModeCursorAuto, + NavigationModeCursorForceVisible + }; } #ifdef Q_MOC_RUN ; diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 52fed47..314dfb2 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2781,3 +2781,29 @@ \sa QGesture */ + +/*! + \enum Qt::NavigationMode + \since 4.6 + + This enum type describes the mode for moving focus. + + \value NavigationModeNone Only the touch screen is used. + \value NavigationModeKeypadTabOrder Qt::Key_Up and Qt::Key_Down are used to change focus. + \value NavigationModeKeypadDirectional Qt::Key_Up, Qt::Key_Down, Qt::Key_Left and Qt::Key_Right are used to change focus. + \value NavigationModeCursorAuto The mouse cursor is used to change focus, + it is displayed only on non touchscreen devices. + The keypad is used to implement a virtual cursor, unless + the device has an analog mouse type of input device (e.g. touchpad). + This is the recommended setting for an application such as a web browser that + needs pointer control on both touch and non-touch devices. + \value NavigationModeCursorForceVisible The mouse cursor is used to change focus, + it is displayed regardless of device type. + The keypad is used to implement a virtual cursor, unless + the device has an analog mouse type of input device (e.g. touchpad) + + \note: in 4.6, cursor navigation is only implemented for Symbian OS. + On other platforms, it behaves as NavigationModeNone. + \sa QApplication::setNavigationMode + \sa QApplication::navigationMode +*/ diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 493e440..666e557 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -178,7 +178,12 @@ CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const return 0; } - const QImage converted = img.convertToFormat(destFormat); + QImage converted = img.convertToFormat(destFormat); + + //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid + //So invert mono bitmaps so that masks work correctly. + if (mode == EGray2) + converted.invertPixels(); bitmap->LockHeap(); const uchar *sptr = converted.bits(); @@ -220,6 +225,9 @@ QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap) image.setNumColors(2); image.setColor(0, QColor(Qt::color0).rgba()); image.setColor(1, QColor(Qt::color1).rgba()); + //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid + //So invert mono bitmaps so that masks work correctly. + image.invertPixels(); } else if (displayMode == EGray256) { for (int i=0; i < 256; ++i) image.setColor(i, qRgb(i, i, i)); diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index a19e022..1fd2d39 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -458,10 +458,10 @@ bool QApplicationPrivate::widgetCount = false; bool QApplicationPrivate::inSizeMove = false; #endif #ifdef QT_KEYPAD_NAVIGATION -# if defined(Q_OS_SYMBIAN) -bool QApplicationPrivate::keypadNavigation = true; +# ifdef Q_OS_SYMBIAN +Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional; # else -bool QApplicationPrivate::keypadNavigation = false; +Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadTabOrder; # endif QWidget *QApplicationPrivate::oldEditFocus = 0; #endif @@ -2521,12 +2521,6 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool Creates the proper Enter/Leave event when widget \a enter is entered and widget \a leave is left. */ -#if defined(Q_WS_WIN) - extern void qt_win_set_cursor(QWidget *, bool); -#elif defined(Q_WS_X11) - extern void qt_x11_enforce_cursor(QWidget *, bool); -#endif - void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) { #if 0 if (leave) { @@ -2676,6 +2670,8 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) { qt_win_set_cursor(cursorWidget, true); #elif defined(Q_WS_X11) qt_x11_enforce_cursor(cursorWidget, true); +#elif defined(Q_WS_S60) + qt_symbian_set_cursor(cursorWidget, true); #endif } } @@ -4777,10 +4773,36 @@ void QApplicationPrivate::emitLastWindowClosed() #ifdef QT_KEYPAD_NAVIGATION /*! - Sets whether Qt should use focus navigation suitable for use with a - minimal keypad. + Sets what kind of focus navigation Qt should use. + + This feature is available in Qt for Embedded Linux, Symbian and Windows CE + only. + + \note On Windows CE this feature is disabled by default for touch device + mkspecs. To enable keypad navigation, build Qt with + QT_KEYPAD_NAVIGATION defined. + + \note On Symbian, setting the mode to Qt::NavigationModeCursorAuto will enable a + virtual mouse cursor on non touchscreen devices, which is controlled + by the cursor keys if there is no analog pointer device. + On other platforms and on touchscreen devices, it has the same + meaning as Qt::NavigationModeNone. + + \since 4.6 + + \sa keypadNavigationEnabled() +*/ +void QApplication::setNavigationMode(Qt::NavigationMode mode) +{ +#ifdef Q_OS_SYMBIAN + QApplicationPrivate::setNavigationMode(mode); +#else + QApplicationPrivate::navigationMode = mode; +#endif +} - If \a enable is true, Qt::Key_Up and Qt::Key_Down are used to change focus. +/*! + Returns what kind of focus navigation Qt is using. This feature is available in Qt for Embedded Linux, Symbian and Windows CE only. @@ -4788,12 +4810,47 @@ void QApplicationPrivate::emitLastWindowClosed() \note On Windows CE this feature is disabled by default for touch device mkspecs. To enable keypad navigation, build Qt with QT_KEYPAD_NAVIGATION defined. + + \note On Symbian, the default mode is Qt::NavigationModeNone for touch + devices, and Qt::NavigationModeKeypadDirectional. + + \since 4.6 \sa keypadNavigationEnabled() */ +Qt::NavigationMode QApplication::navigationMode() +{ + return QApplicationPrivate::navigationMode; +} + +/*! + Sets whether Qt should use focus navigation suitable for use with a + minimal keypad. + + This feature is available in Qt for Embedded Linux, Symbian and Windows CE + only. + + + \note On Windows CE this feature is disabled by default for touch device + mkspecs. To enable keypad navigation, build Qt with + QT_KEYPAD_NAVIGATION defined. + + \deprecated + + \sa setNavigationMode() +*/ void QApplication::setKeypadNavigationEnabled(bool enable) { - QApplicationPrivate::keypadNavigation = enable; + if (enable) { +#ifdef Q_OS_SYMBIAN + QApplication::setNavigationMode(Qt::NavigationModeKeypadDirectional); +#else + QApplication::setNavigationMode(Qt::NavigationModeKeypadTabOrder); +#endif + } + else { + QApplication::setNavigationMode(Qt::NavigationModeNone); + } } /*! @@ -4806,12 +4863,15 @@ void QApplication::setKeypadNavigationEnabled(bool enable) \note On Windows CE this feature is disabled by default for touch device mkspecs. To enable keypad navigation, build Qt with QT_KEYPAD_NAVIGATION defined. + + \deprecated - \sa setKeypadNavigationEnabled() + \sa navigationMode() */ bool QApplication::keypadNavigationEnabled() { - return QApplicationPrivate::keypadNavigation; + return QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadTabOrder || + QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadDirectional; } #endif diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index 216cfff..0562251 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -272,8 +272,10 @@ public: static bool quitOnLastWindowClosed(); #ifdef QT_KEYPAD_NAVIGATION - static void setKeypadNavigationEnabled(bool); + static Q_DECL_DEPRECATED void setKeypadNavigationEnabled(bool); static bool keypadNavigationEnabled(); + static void setNavigationMode(Qt::NavigationMode mode); + static Qt::NavigationMode navigationMode(); #endif Q_SIGNALS: diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index c33eb1a..707caaa 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -71,6 +71,9 @@ #include "QtGui/qscreen_qws.h" #include #endif +#ifdef Q_OS_SYMBIAN +#include +#endif QT_BEGIN_NAMESPACE @@ -492,8 +495,8 @@ public: static int app_compile_version; #ifdef QT_KEYPAD_NAVIGATION - static bool keypadNavigation; static QWidget *oldEditFocus; + static Qt::NavigationMode navigationMode; #endif #if defined(Q_WS_MAC) || defined(Q_WS_X11) @@ -511,7 +514,9 @@ public: QWidget *native, QWidget **buttonDown, QPointer &lastMouseReceiver, bool spontaneous = true); #ifdef Q_OS_SYMBIAN + static void setNavigationMode(Qt::NavigationMode mode); static TUint resolveS60ScanCode(TInt scanCode, TUint keysym); + QSet nativeWindows; #endif #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) void sendSyntheticEnterLeave(QWidget *widget); @@ -595,6 +600,15 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, QTouchEvent::DeviceType deviceType, const QList &touchPoints); +#if defined(Q_WS_WIN) + extern void qt_win_set_cursor(QWidget *, bool); +#elif defined(Q_WS_X11) + extern void qt_x11_enforce_cursor(QWidget *, bool); + extern void qt_x11_enforce_cursor(QWidget *); +#elif defined(Q_OS_SYMBIAN) + extern void qt_symbian_set_cursor(QWidget *, bool); +#endif + QT_END_NAMESPACE #endif // QAPPLICATION_P_H diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 00932a0..fd889fc 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -73,6 +73,9 @@ #include "private/qstylesheetstyle_p.h" +#include +#include + QT_BEGIN_NAMESPACE #if defined(QT_DEBUG) @@ -151,21 +154,21 @@ void QS60Beep::ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration) void QS60Beep::Play() { - if(iState!=EBeepNotPrepared){ - if(iState==EBeepPlaying) { + if (iState != EBeepNotPrepared) { + if (iState == EBeepPlaying) { iToneUtil->CancelPlay(); - iState=EBeepPrepared; + iState = EBeepPrepared; } } iToneUtil->Play(); - iState=EBeepPlaying; + iState = EBeepPlaying; } void QS60Beep::MatoPrepareComplete(TInt aError) { - if(aError==KErrNone) { - iState=EBeepPrepared; + if (aError == KErrNone) { + iState = EBeepPrepared; } } @@ -320,8 +323,9 @@ void QSymbianControl::ConstructL(bool topLevel, bool desktop) { if (!desktop) { - if (topLevel) + if (topLevel) { CreateWindowL(S60->windowGroup()); + } SetFocusing(true); m_longTapDetector = QLongTapTimer::NewL(this); @@ -330,6 +334,8 @@ void QSymbianControl::ConstructL(bool topLevel, bool desktop) QSymbianControl::~QSymbianControl() { + if (S60->curWin == this) + S60->curWin = 0; S60->appUi()->RemoveFromStack(this); delete m_longTapDetector; } @@ -392,14 +398,15 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent) TPoint controlScreenPos = PositionRelativeToScreen(); QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos; - if (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick) + if (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick || type == QEvent::MouseMove) { - // get the button press target + // get the widget where the event happened alienWidget = qwidget->childAt(widgetPos); if (!alienWidget) alienWidget = qwidget; S60->mousePressTarget = alienWidget; } + alienWidget = S60->mousePressTarget; if (alienWidget != S60->lastPointerEventTarget) @@ -412,12 +419,30 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent) button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(pEvent.iModifiers)); events.append(Event(S60->lastPointerEventTarget,mEventLeave)); } - QMouseEvent mEventEnter(QEvent::Enter, alienWidget->mapFromGlobal(globalPos), globalPos, - button, QApplicationPrivate::mouse_buttons, mapToQtModifiers(pEvent.iModifiers)); - - events.append(Event(alienWidget,mEventEnter)); + if (alienWidget) { + QMouseEvent mEventEnter(QEvent::Enter, alienWidget->mapFromGlobal(globalPos), + globalPos, button, QApplicationPrivate::mouse_buttons, mapToQtModifiers( + pEvent.iModifiers)); + + events.append(Event(alienWidget, mEventEnter)); +#ifndef QT_NO_CURSOR + S60->curWin = alienWidget->effectiveWinId(); + if (!QApplication::overrideCursor()) { +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors) + qt_symbian_set_pointer_sprite(alienWidget->cursor()); + else +#endif + qt_symbian_setWindowCursor(alienWidget->cursor(), S60->curWin); + } +#endif + } } S60->lastCursorPos = globalPos; +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors) + qt_symbian_move_cursor_sprite(); +#endif S60->lastPointerEventPos = widgetPos; S60->lastPointerEventTarget = alienWidget; if (alienWidget) @@ -494,6 +519,82 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod // Special S60 keys. keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym); } + +#ifndef QT_NO_CURSOR + if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) { + //translate keys to pointer + if (keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down || keyCode == Qt::Key_Select) { + /*Explanation about virtualMouseAccel: + Tapping an arrow key allows precise pixel positioning + Holding an arrow key down, acceleration is applied to allow cursor + to be quickly moved to another part of the screen by key repeats. + */ + if (S60->virtualMouseLastKey == keyCode) { + S60->virtualMouseAccel *= 2; + if (S60->virtualMouseAccel > S60->virtualMouseMaxAccel) + S60->virtualMouseAccel = S60->virtualMouseMaxAccel; + } + else + S60->virtualMouseAccel = 1; + S60->virtualMouseLastKey = keyCode; + + QPoint pos = QCursor::pos(); + TPointerEvent fakeEvent; + TInt x = pos.x(); + TInt y = pos.y(); + if (type == EEventKeyUp) { + if (keyCode == Qt::Key_Select) + fakeEvent.iType = TPointerEvent::EButton1Up; + S60->virtualMouseAccel = 1; + S60->virtualMouseLastKey = 0; + } + else if (type == EEventKey) { + switch (keyCode) { + case Qt::Key_Left: + x -= S60->virtualMouseAccel; + fakeEvent.iType = TPointerEvent::EMove; + break; + case Qt::Key_Right: + x += S60->virtualMouseAccel; + fakeEvent.iType = TPointerEvent::EMove; + break; + case Qt::Key_Up: + y -= S60->virtualMouseAccel; + fakeEvent.iType = TPointerEvent::EMove; + break; + case Qt::Key_Down: + y += S60->virtualMouseAccel; + fakeEvent.iType = TPointerEvent::EMove; + break; + case Qt::Key_Select: + fakeEvent.iType = TPointerEvent::EButton1Down; + break; + } + } + //clip to screen size (window server allows a sprite hotspot to be outside the screen) + if (x < 0) + x = 0; + else if (x >= S60->screenWidthInPixels) + x = S60->screenWidthInPixels - 1; + if (y < 0) + y = 0; + else if (y >= S60->screenHeightInPixels) + y = S60->screenHeightInPixels - 1; + TPoint epos(x, y); + TPoint cpos = epos - PositionRelativeToScreen(); + fakeEvent.iModifiers = keyEvent.iModifiers; + fakeEvent.iPosition = cpos; + fakeEvent.iParentPosition = epos; + HandlePointerEvent(fakeEvent); + return EKeyWasConsumed; + } + else { + S60->virtualMouseLastKey = keyCode; + S60->virtualMouseAccel = 1; + } + } +#endif + Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers); QKeyEventEx qKeyEvent(type == EEventKeyUp ? QEvent::KeyRelease : QEvent::KeyPress, keyCode, mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods), @@ -557,7 +658,7 @@ TKeyResponse QSymbianControl::sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent) #if !defined(QT_NO_IM) && defined(Q_WS_S60) if (widget && widget->isEnabled() && widget->testAttribute(Qt::WA_InputMethodEnabled)) { QInputContext *qic = widget->inputContext(); - if(qic && qic->filterEvent(keyEvent)) + if (qic && qic->filterEvent(keyEvent)) return EKeyWasConsumed; } #endif // !defined(QT_NO_IM) && defined(Q_WS_S60) @@ -574,11 +675,10 @@ TCoeInputCapabilities QSymbianControl::InputCapabilities() const { QWidget *w = 0; - if(qwidget->hasFocus()) { + if (qwidget->hasFocus()) w = qwidget; - } else { + else w = qwidget->focusWidget(); - } QCoeFepInputContext *ic; if (w && w->isEnabled() && w->testAttribute(Qt::WA_InputMethodEnabled) @@ -749,6 +849,70 @@ void qt_init(QApplicationPrivate * /* priv */, int) TSecureId securId = me.SecureId(); S60->uid = securId.operator TUid(); + // enable focus events - used to re-enable mouse after focus changed between mouse and non mouse app, + // and for dimming behind modal windows + S60->windowGroup().EnableFocusChangeEvents(); + + //Check if mouse interaction is supported (either EMouse=1 in the HAL, or EMachineUID is one of the phones known to support this) + const TInt KMachineUidSamsungI8510 = 0x2000C51E; + const TInt KMachineUidSamsungI550 = 0x2000A678; + TInt machineUID; + TInt mouse; + TInt touch; + TInt err; + err = HAL::Get(HALData::EMouse, mouse); + if (err != KErrNone) + mouse = 0; + err = HAL::Get(HALData::EMachineUid, machineUID); + if (err != KErrNone) + machineUID = 0; + err = HAL::Get(HALData::EPen, touch); + if (err != KErrNone) + touch = 0; + if (mouse || machineUID == KMachineUidSamsungI8510) { + S60->hasTouchscreen = false; + S60->virtualMouseRequired = false; + } + else if (!touch) { + S60->hasTouchscreen = false; + S60->virtualMouseRequired = true; + } + else { + S60->hasTouchscreen = true; + S60->virtualMouseRequired = false; + } + + if (touch) { + QApplicationPrivate::navigationMode = Qt::NavigationModeNone; + } else { + QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional; + } + + //Check if window server pointer cursors are supported or not +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + //In generic binary, use the HAL and OS version + //Any other known good phones should be added here. + if (machineUID == KMachineUidSamsungI8510 || (QSysInfo::symbianVersion() != QSysInfo::SV_9_4 + && QSysInfo::symbianVersion() != QSysInfo::SV_9_3 && QSysInfo::symbianVersion() + != QSysInfo::SV_9_2)) { + S60->brokenPointerCursors = false; + qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup()); + } + else + S60->brokenPointerCursors = true; +#endif + + if (S60->mouseInteractionEnabled) { +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors) { + qt_symbian_set_pointer_sprite(Qt::ArrowCursor); + qt_symbian_show_pointer_sprite(); + } + else +#endif + S60->wsSession().SetPointerCursorMode(EPointerCursorNormal); + } + /* ### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag int argc = priv->argc; @@ -785,6 +949,9 @@ void qt_cleanup() // it dies. delete QApplicationPrivate::inputContext; QApplicationPrivate::inputContext = 0; + + //Change mouse pointer back + S60->wsSession().SetPointerCursorMode(EPointerCursorNone); if (S60->qtOwnsS60Environment) { CEikonEnv* coe = CEikonEnv::Static(); @@ -1016,9 +1183,8 @@ void QApplication::beep() TTimeIntervalMicroSeconds duration(500000); QS60Beep* beep=NULL; TRAPD(err, beep=QS60Beep::NewL(frequency, duration)); - if(!err) { + if (!err) beep->Play(); - } delete beep; beep=NULL; } @@ -1108,7 +1274,31 @@ int QApplication::s60ProcessEvent(TWsEvent *event) return 1; } break; - default: + case EEventFocusGained: + RDebug::Printf("focus gained %x", control); + //re-enable mouse interaction + if (S60->mouseInteractionEnabled) { +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors) + qt_symbian_show_pointer_sprite(); + else +#endif + S60->wsSession().SetPointerCursorMode(EPointerCursorNormal); + } + break; + case EEventFocusLost: + RDebug::Printf("focus lost %x", control); + //disable mouse as may be moving to application that does not support it + if (S60->mouseInteractionEnabled) { +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors) + qt_symbian_hide_pointer_sprite(); + else +#endif + S60->wsSession().SetPointerCursorMode(EPointerCursorNone); + } + break; + default: break; } @@ -1279,4 +1469,81 @@ void QSessionManager::cancel() } #endif //QT_NO_SESSIONMANAGER + +#ifdef QT_KEYPAD_NAVIGATION +/* + * Show/Hide the mouse cursor depending on phone type and chosen mode + */ +void QApplicationPrivate::setNavigationMode(Qt::NavigationMode mode) +{ +#ifndef QT_NO_CURSOR + const bool wasCursorOn = (QApplicationPrivate::navigationMode == Qt::NavigationModeCursorAuto + && !S60->hasTouchscreen) + || QApplicationPrivate::navigationMode == Qt::NavigationModeCursorForceVisible; + const bool isCursorOn = (mode == Qt::NavigationModeCursorAuto + && !S60->hasTouchscreen) + || mode == Qt::NavigationModeCursorForceVisible; + + if (!wasCursorOn && isCursorOn) { + //Show the cursor, when changing from another mode to cursor mode + qt_symbian_set_cursor_visible(true); + } + else if (wasCursorOn && !isCursorOn) { + //Hide the cursor, when leaving cursor mode + qt_symbian_set_cursor_visible(false); + } +#endif + QApplicationPrivate::navigationMode = mode; +} +#endif + +#ifndef QT_NO_CURSOR +/***************************************************************************** + QApplication cursor stack + *****************************************************************************/ + +void QApplication::setOverrideCursor(const QCursor &cursor) +{ + qApp->d_func()->cursor_list.prepend(cursor); + qt_symbian_setGlobalCursor(cursor); +} + +void QApplication::restoreOverrideCursor() +{ + if (qApp->d_func()->cursor_list.isEmpty()) + return; + qApp->d_func()->cursor_list.removeFirst(); + + if (!qApp->d_func()->cursor_list.isEmpty()) { + qt_symbian_setGlobalCursor(qApp->d_func()->cursor_list.first()); + } + else { + //determine which widget has focus + QWidget *w = QApplication::widgetAt(QCursor::pos()); +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors) { + qt_symbian_set_pointer_sprite(w ? w->cursor() : Qt::ArrowCursor); + } + else +#endif + { + //because of the internals of window server, we need to force the cursor + //to be set in all child windows too, otherwise when the cursor is over + //the child window it may show a widget cursor or arrow cursor instead, + //depending on construction order. + QListIterator iter(QWidgetPrivate::mapper->uniqueKeys()); + while (iter.hasNext()) { + CCoeControl *ctrl = iter.next(); + ctrl->DrawableWindow()->ClearPointerCursor(); + } + if (w) + qt_symbian_setWindowCursor(w->cursor(), w->effectiveWinId()); + else + qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup()); + } + } +} + +#endif // QT_NO_CURSOR + QT_END_NAMESPACE diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 1ce799c..601cd11 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -2820,8 +2820,6 @@ void QApplicationPrivate::applyX11SpecificCommandLineArguments(QWidget *main_wid QApplication cursor stack *****************************************************************************/ -extern void qt_x11_enforce_cursor(QWidget * w); - void QApplication::setOverrideCursor(const QCursor &cursor) { qApp->d_func()->cursor_list.prepend(cursor); diff --git a/src/gui/kernel/qcursor.h b/src/gui/kernel/qcursor.h index 389a110..2b2aa4a 100644 --- a/src/gui/kernel/qcursor.h +++ b/src/gui/kernel/qcursor.h @@ -72,13 +72,19 @@ private: #ifndef QT_NO_CURSOR -struct QCursorData; +class QCursorData; class QBitmap; class QPixmap; #if defined(Q_WS_MAC) void qt_mac_set_cursor(const QCursor *c, const QPoint &p); #endif +#if defined(Q_OS_SYMBIAN) +extern void qt_symbian_show_pointer_sprite(); +extern void qt_symbian_hide_pointer_sprite(); +extern void qt_symbian_set_pointer_sprite(const QCursor& cursor); +extern void qt_symbian_move_cursor_sprite(); +#endif class Q_GUI_EXPORT QCursor { @@ -103,7 +109,7 @@ public: static QPoint pos(); static void setPos(int x, int y); inline static void setPos(const QPoint &p) { setPos(p.x(), p.y()); } - + #ifdef qdoc HCURSOR_or_HANDLE handle() const; QCursor(HCURSOR cursor); @@ -122,6 +128,8 @@ public: Qt::HANDLE handle() const; #elif defined(Q_WS_QWS) int handle() const; +#elif defined(Q_OS_SYMBIAN) + Qt::HANDLE handle() const; #endif #endif @@ -131,6 +139,12 @@ private: friend void *qt_mac_nsCursorForQCursor(const QCursor &c); friend void qt_mac_set_cursor(const QCursor *c, const QPoint &p); #endif +#if defined(Q_OS_SYMBIAN) + friend void qt_symbian_show_pointer_sprite(); + friend void qt_symbian_hide_pointer_sprite(); + friend void qt_symbian_set_pointer_sprite(const QCursor& cursor); + friend void qt_symbian_move_cursor_sprite(); +#endif }; #ifdef QT3_SUPPORT diff --git a/src/gui/kernel/qcursor_p.h b/src/gui/kernel/qcursor_p.h index aa4f4b2..12166c8 100644 --- a/src/gui/kernel/qcursor_p.h +++ b/src/gui/kernel/qcursor_p.h @@ -64,6 +64,8 @@ # include "private/qt_x11_p.h" # elif defined(Q_WS_WIN) # include "QtCore/qt_windows.h" +# elif defined(Q_OS_SYMBIAN) +# include "private/qt_s60_p.h" #endif QT_BEGIN_NAMESPACE @@ -74,7 +76,8 @@ class QMacAnimateCursor; #endif class QBitmap; -struct QCursorData { +class QCursorData { +public: QCursorData(Qt::CursorShape s = Qt::ArrowCursor); ~QCursorData(); @@ -111,12 +114,21 @@ struct QCursorData { } curs; void initCursorFromBitmap(); void initCursorFromPixmap(); +#elif defined Q_OS_SYMBIAN + void loadShapeFromResource(RWsSpriteBase& target, QString resource, int hx, int hy, int interval=0); + void constructShapeSprite(RWsSpriteBase& target); + void constructCursorSprite(RWsSpriteBase& target); + RWsPointerCursor pcurs; + RWsSprite scurs; + RPointerArray nativeSpriteMembers; #endif static bool initialized; void update(); static QCursorData *setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY); }; +extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp + QT_END_NAMESPACE #endif // QCURSOR_P_H diff --git a/src/gui/kernel/qcursor_qws.cpp b/src/gui/kernel/qcursor_qws.cpp index eda826b..0eeb187 100644 --- a/src/gui/kernel/qcursor_qws.cpp +++ b/src/gui/kernel/qcursor_qws.cpp @@ -78,8 +78,6 @@ QCursorData::~QCursorData() Global cursors *****************************************************************************/ -extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp - int QCursor::handle() const { return d->id; diff --git a/src/gui/kernel/qcursor_s60.cpp b/src/gui/kernel/qcursor_s60.cpp index b812994..757eaa8 100644 --- a/src/gui/kernel/qcursor_s60.cpp +++ b/src/gui/kernel/qcursor_s60.cpp @@ -40,12 +40,22 @@ ****************************************************************************/ #include +#include +#include +#include #include #include +#include +#include +#include +#include -#ifdef QT_NO_CURSOR QT_BEGIN_NAMESPACE +static QCursor cursorSprite; +static int cursorSpriteVisible; + +//pos and setpos are required whether cursors are configured or not. QPoint QCursor::pos() { return S60->lastCursorPos; @@ -53,8 +63,467 @@ QPoint QCursor::pos() void QCursor::setPos(int x, int y) { + //clip to screen size (window server allows a sprite hotspot to be outside the screen) + if (x < 0) + x=0; + else if (x >= S60->screenWidthInPixels) + x = S60->screenWidthInPixels - 1; + if (y < 0) + y = 0; + else if (y >= S60->screenHeightInPixels) + y = S60->screenHeightInPixels - 1; + +#ifndef QT_NO_CURSOR +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors && cursorSpriteVisible) + cursorSprite.d->scurs.SetPosition(TPoint(x,y)); + else +#endif + S60->wsSession().SetPointerCursorPosition(TPoint(x, y)); +#endif S60->lastCursorPos = QPoint(x, y); + //send a fake mouse move event, so that enter/leave events go to the widget hierarchy + QWidget *w = QApplication::topLevelAt(S60->lastCursorPos); + if (w) { + CCoeControl* ctrl = w->effectiveWinId(); + TPoint epos(x, y); + TPoint cpos = epos - ctrl->PositionRelativeToScreen(); + TPointerEvent fakeEvent; + fakeEvent.iType = TPointerEvent::EMove; + fakeEvent.iModifiers = 0U; + fakeEvent.iPosition = cpos; + fakeEvent.iParentPosition = epos; + ctrl->HandlePointerEventL(fakeEvent); + } +} + +#ifndef QT_NO_CURSOR +/* + * Request cursor to be turned on or off. + * Reference counted, so 2 on + 1 off = on, for example + */ +void qt_symbian_set_cursor_visible(bool visible) { + if (visible) + cursorSpriteVisible++; + else + cursorSpriteVisible--; + Q_ASSERT(cursorSpriteVisible >=0); + + if (cursorSpriteVisible && !S60->mouseInteractionEnabled) { +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors) + qt_symbian_show_pointer_sprite(); + else +#endif + S60->wsSession().SetPointerCursorMode(EPointerCursorNormal); + } else if (!cursorSpriteVisible && S60->mouseInteractionEnabled) { +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors) + qt_symbian_hide_pointer_sprite(); + else +#endif + S60->wsSession().SetPointerCursorMode(EPointerCursorNone); + } + S60->mouseInteractionEnabled = ((cursorSpriteVisible > 0) ? true : false); +} + +/* + * Check if the cursor is on or off + */ +bool qt_symbian_is_cursor_visible() { + return S60->mouseInteractionEnabled; +} + +QCursorData::QCursorData(Qt::CursorShape s) : + cshape(s), bm(0), bmm(0), hx(0), hy(0), pcurs() +{ + ref = 1; +} + +QCursorData::~QCursorData() +{ + for(int i=0;iiBitmap; + delete nativeSpriteMembers[i]->iMaskBitmap; + } + nativeSpriteMembers.ResetAndDestroy(); + pcurs.Close(); + delete bm; + delete bmm; +} + +/* Create a bitmap cursor, this is called by public constructors in the + * generic QCursor code. + */ +QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) +{ + if (!QCursorData::initialized) + QCursorData::initialize(); + if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) { + qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)"); + QCursorData *c = qt_cursorTable[0]; + c->ref.ref(); + return c; + } + QCursorData *d = new QCursorData; + d->bm = new QBitmap(bitmap); + d->bmm = new QBitmap(mask); + d->cshape = Qt::BitmapCursor; + d->hx = hotX >= 0 ? hotX : bitmap.width() / 2; + d->hy = hotY >= 0 ? hotY : bitmap.height() / 2; + return d; +} + +/* + * returns an opaque native handle to a cursor. + * It happens to be the address of the native handle, as window server handles + * are not POD types. Note there is no QCursor(HANDLE) constructor on Symbian, + * Mac or QWS. + */ +Qt::HANDLE QCursor::handle() const +{ + if (d->pcurs.WsHandle()) + return reinterpret_cast (&(d->pcurs)); + +#ifdef Q_SYMBIAN_HAS_SYSTEM_CURSORS + // don't construct shape cursors, QApplication_s60 will use the system cursor instead + if (!(d->bm)) + return 0; +#endif + + d->pcurs = RWsPointerCursor(S60->wsSession()); + d->pcurs.Construct(0); + d->constructCursorSprite(d->pcurs); + d->pcurs.Activate(); + + return reinterpret_cast (&(d->pcurs)); +} + +#ifndef Q_SYMBIAN_HAS_SYSTEM_CURSORS +/* + * Loads a single cursor shape from resources and appends it to a native sprite. + * Animated cursors (e.g. the busy cursor) have multiple members. + */ +void QCursorData::loadShapeFromResource(RWsSpriteBase& target, QString resource, int hx, int hy, int interval) +{ + QPixmap pix; + CFbsBitmap* native; + QScopedPointer member(new TSpriteMember); + member->iInterval = interval; + member->iInvertMask = false; + member->iMaskBitmap = 0; // all shapes are RGBA + member->iDrawMode = CGraphicsContext::EDrawModePEN; + member->iOffset = TPoint(-hx, -hy); + QString res(QLatin1String(":/trolltech/symbian/cursors/images/%1.png")); + pix.load(res.arg(resource)); + native = pix.toSymbianCFbsBitmap(); + member->iBitmap = native; + qt_symbian_throwIfError(nativeSpriteMembers.Append(member.data())); + target.AppendMember(*(member.take())); +} + +//TODO: after 4.6, connect with style & skins? +/* + * Constructs the native cursor from resources compiled into QtGui + * This is needed only when the platform doesn't have system cursors. + * + * System cursors are higher performance, since they are constructed once + * and shared by all applications by specifying the shape number. + * Due to symbian platform security considerations, and the fact most + * existing phones have a broken RWsPointerCursor, system cursors are not + * being used. + */ +void QCursorData::constructShapeSprite(RWsSpriteBase& target) +{ + int i; + switch (cshape) { + default: + qWarning("QCursorData::constructShapeSprite unknown shape %d", cshape); + //fall through and give arrow cursor + case Qt::ArrowCursor: + loadShapeFromResource(target, QLatin1String("pointer"), 1, 1); + break; + case Qt::UpArrowCursor: + loadShapeFromResource(target, QLatin1String("uparrow"), 4, 0); + break; + case Qt::CrossCursor: + loadShapeFromResource(target, QLatin1String("cross"), 7, 7); + break; + case Qt::WaitCursor: + for (i = 1; i <= 12; i++) { + loadShapeFromResource(target, QString(QLatin1String("wait%1")).arg(i), 7, 7, 1000000); + } + break; + case Qt::IBeamCursor: + loadShapeFromResource(target, QLatin1String("ibeam"), 3, 10); + break; + case Qt::SizeVerCursor: + loadShapeFromResource(target, QLatin1String("sizever"), 4, 8); + break; + case Qt::SizeHorCursor: + loadShapeFromResource(target, QLatin1String("sizehor"), 8, 4); + break; + case Qt::SizeBDiagCursor: + loadShapeFromResource(target, QLatin1String("sizebdiag"), 8, 8); + break; + case Qt::SizeFDiagCursor: + loadShapeFromResource(target, QLatin1String("sizefdiag"), 8, 8); + break; + case Qt::SizeAllCursor: + loadShapeFromResource(target, QLatin1String("sizeall"), 7, 7); + break; + case Qt::BlankCursor: + loadShapeFromResource(target, QLatin1String("blank"), 0, 0); + break; + case Qt::SplitVCursor: + loadShapeFromResource(target, QLatin1String("splitv"), 7, 7); + break; + case Qt::SplitHCursor: + loadShapeFromResource(target, QLatin1String("splith"), 7, 7); + break; + case Qt::PointingHandCursor: + loadShapeFromResource(target, QLatin1String("handpoint"), 5, 0); + break; + case Qt::ForbiddenCursor: + loadShapeFromResource(target, QLatin1String("forbidden"), 7, 7); + break; + case Qt::WhatsThisCursor: + loadShapeFromResource(target, QLatin1String("whatsthis"), 1, 1); + break; + case Qt::BusyCursor: + loadShapeFromResource(target, QLatin1String("busy3"), 1, 1, 1000000); + loadShapeFromResource(target, QLatin1String("busy6"), 1, 1, 1000000); + loadShapeFromResource(target, QLatin1String("busy9"), 1, 1, 1000000); + loadShapeFromResource(target, QLatin1String("busy12"), 1, 1, 1000000); + break; + case Qt::OpenHandCursor: + loadShapeFromResource(target, QLatin1String("openhand"), 7, 7); + break; + case Qt::ClosedHandCursor: + loadShapeFromResource(target, QLatin1String("closehand"), 7, 7); + break; + } +} +#endif + +/* + * Common code between the sprite workaround and standard modes of operation. + * RWsSpriteBase is the base class for both RWsSprite and RWsPointerCursor. + * It is called from both handle() and qt_s60_show_pointer_sprite() + */ +void QCursorData::constructCursorSprite(RWsSpriteBase& target) +{ + int count = nativeSpriteMembers.Count(); + if (count) { + // already constructed + for (int i = 0; i < count; i++) + target.AppendMember(*(nativeSpriteMembers[i])); + + return; + } + if (pixmap.isNull() && !bm) { +#ifndef Q_SYMBIAN_HAS_SYSTEM_CURSORS + //shape cursor + constructShapeSprite(target); +#endif + return; + } + QScopedPointer member(new TSpriteMember); + if (pixmap.isNull()) { + //construct mono cursor + member->iBitmap = bm->toSymbianCFbsBitmap(); + member->iMaskBitmap = bmm->toSymbianCFbsBitmap(); + } + else { + //construct normal cursor + member->iBitmap = pixmap.toSymbianCFbsBitmap(); + if (pixmap.hasAlphaChannel()) { + member->iMaskBitmap = 0; //use alpha blending + } + else if (pixmap.hasAlpha()) { + member->iMaskBitmap = pixmap.mask().toSymbianCFbsBitmap(); + } + else { + member->iMaskBitmap = pixmap.createHeuristicMask().toSymbianCFbsBitmap(); + } + } + + member->iDrawMode = CGraphicsContext::EDrawModePEN; + member->iInvertMask = EFalse; + member->iInterval = 0; + member->iOffset = TPoint(-(hx), -(hy)); //Symbian hotspot coordinates are negative + qt_symbian_throwIfError(nativeSpriteMembers.Append(member.data())); + target.AppendMember(*(member.take())); +} + +/* + * shows the pointer sprite by constructing a native handle, and registering + * it with the window server. + * Only used when the sprite workaround is in use. + */ +void qt_symbian_show_pointer_sprite() +{ + if (cursorSprite.d) { + if (cursorSprite.d->scurs.WsHandle()) + cursorSprite.d->scurs.Close(); + } else { + cursorSprite = QCursor(Qt::ArrowCursor); + } + + cursorSprite.d->scurs = RWsSprite(S60->wsSession()); + QPoint pos = QCursor::pos(); + cursorSprite.d->scurs.Construct(S60->windowGroup(), TPoint(pos.x(), pos.y()), ESpriteNoChildClip | ESpriteNoShadows); + + cursorSprite.d->constructCursorSprite(cursorSprite.d->scurs); + cursorSprite.d->scurs.Activate(); +} + +/* + * hides the pointer sprite by closing the native handle. + * Only used when the sprite workaround is in use. + */ +void qt_symbian_hide_pointer_sprite() +{ + if (cursorSprite.d) { + cursorSprite.d->scurs.Close(); + } +} + +/* + * Changes the cursor sprite to the cursor specified. + * Only used when the sprite workaround is in use. + */ +void qt_symbian_set_pointer_sprite(const QCursor& cursor) +{ + if (S60->mouseInteractionEnabled) + qt_symbian_hide_pointer_sprite(); + cursorSprite = cursor; + if (S60->mouseInteractionEnabled) + qt_symbian_show_pointer_sprite(); +} + +/* + * When using sprites as a workaround on phones that have a broken + * RWsPointerCursor, this function is called in response to pointer events + * and when QCursor::setPos() is called. + * Performance is worse than a real pointer cursor, due to extra context + * switches vs. the window server moving the cursor by itself. + */ +void qt_symbian_move_cursor_sprite() +{ + if (S60->mouseInteractionEnabled) { + cursorSprite.d->scurs.SetPosition(TPoint(S60->lastCursorPos.x(), S60->lastCursorPos.y())); + } +} + +/* + * Translate from Qt::CursorShape to OS system pointer cursor list index. + * Currently we control the implementation of the system pointer cursor list, + * so this function is trivial. That may not always be the case. + */ +TInt qt_symbian_translate_cursor_shape(Qt::CursorShape shape) +{ + return (TInt) shape; +} + +/* + Internal function called from QWidget::setCursor() + force is true if this function is called from dispatchEnterLeave, it means that the + mouse is actually directly under this widget. +*/ +void qt_symbian_set_cursor(QWidget *w, bool force) +{ + static QPointer lastUnderMouse = 0; + if (force) { + lastUnderMouse = w; + } + else if (w->testAttribute(Qt::WA_WState_Created) && lastUnderMouse + && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) { + w = lastUnderMouse; + } + + if (!S60->curWin && w && w->internalWinId()) + return; + QWidget* cW = w && !w->internalWinId() ? w : QWidget::find(S60->curWin); + if (!cW || cW->window() != w->window() || !cW->isVisible() || !cW->underMouse() + || QApplication::overrideCursor()) + return; + +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors) + qt_symbian_set_pointer_sprite(cW->cursor()); + else +#endif + qt_symbian_setWindowCursor(cW->cursor(), w->effectiveWinId()); } +/* + * Makes the specified cursor appear above a specific native window group + * Called from QSymbianControl and QApplication::restoreOverrideCursor + * + * Window server is needed for this, so there is no equivalent when using + * the sprite workaround. + */ +void qt_symbian_setWindowGroupCursor(const QCursor &cursor, RWindowTreeNode &node) +{ + Qt::HANDLE handle = cursor.handle(); + if (handle) { + RWsPointerCursor *pcurs = reinterpret_cast (handle); + node.SetCustomPointerCursor(*pcurs); + } +#ifdef Q_SYMBIAN_HAS_SYSTEM_CURSORS + else { + TInt shape = qt_symbian_translate_cursor_shape(cursor.shape()); + node.SetPointerCursor(shape); + } +#else + qWarning("qt_s60_setWindowGroupCursor - null handle"); +#endif +} + +/* + * Makes the specified cursor appear above a specific native window + * Called from QSymbianControl and QApplication::restoreOverrideCursor + * + * Window server is needed for this, so there is no equivalent when using + * the sprite workaround. + */ +void qt_symbian_setWindowCursor(const QCursor &cursor, const CCoeControl* wid) +{ + //find the window for this control + while (!wid->OwnsWindow()) { + wid = wid->Parent(); + if (!wid) + return; + } + RWindowTreeNode *node = wid->DrawableWindow(); + qt_symbian_setWindowGroupCursor(cursor, *node); +} + +/* + * Makes the specified cursor appear everywhere. + * Called from QApplication::setOverrideCursor + */ +void qt_symbian_setGlobalCursor(const QCursor &cursor) +{ +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + if (S60->brokenPointerCursors) { + qt_symbian_set_pointer_sprite(cursor); + } else +#endif + { + //because of the internals of window server, we need to force the cursor + //to be set in all child windows too, otherwise when the cursor is over + //the child window it may show a widget cursor or arrow cursor instead, + //depending on construction order. + QListIterator iter(QWidgetPrivate::mapper->uniqueKeys()); + while(iter.hasNext()) + { + CCoeControl *ctrl = iter.next(); + RWindowTreeNode *node = ctrl->DrawableWindow(); + qt_symbian_setWindowGroupCursor(cursor, *node); + } + } +} QT_END_NAMESPACE #endif // QT_NO_CURSOR diff --git a/src/gui/kernel/qcursor_win.cpp b/src/gui/kernel/qcursor_win.cpp index 430f587..26cde1a 100644 --- a/src/gui/kernel/qcursor_win.cpp +++ b/src/gui/kernel/qcursor_win.cpp @@ -50,8 +50,6 @@ QT_BEGIN_NAMESPACE -extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp - /***************************************************************************** Internal QCursorData class *****************************************************************************/ diff --git a/src/gui/kernel/qcursor_x11.cpp b/src/gui/kernel/qcursor_x11.cpp index d8cc2fc..3e53f04 100644 --- a/src/gui/kernel/qcursor_x11.cpp +++ b/src/gui/kernel/qcursor_x11.cpp @@ -63,8 +63,6 @@ QT_BEGIN_NAMESPACE // Define QT_USE_APPROXIMATE_CURSORS when compiling if you REALLY want to // use the ugly X11 cursors. -extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp - /***************************************************************************** Internal QCursorData class *****************************************************************************/ @@ -100,6 +98,7 @@ QCursor::QCursor(Qt::HANDLE cursor) d = new QCursorData(Qt::CustomCursor); d->hcurs = cursor; } + #endif QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h index 4ee484c..b635685 100644 --- a/src/gui/kernel/qdnd_p.h +++ b/src/gui/kernel/qdnd_p.h @@ -58,6 +58,7 @@ #include "QtGui/qmime.h" #include "QtGui/qdrag.h" #include "QtGui/qpixmap.h" +#include "QtGui/qcursor.h" #include "QtCore/qpoint.h" #include "private/qobject_p.h" #ifdef Q_WS_MAC @@ -265,7 +266,11 @@ private: #ifdef Q_WS_QWS Qt::DropAction currentActionForOverrideCursor; #endif - +#ifdef Q_OS_SYMBIAN +#ifndef QT_NO_CURSOR + QCursor overrideCursor; +#endif +#endif QWidget *currentDropTarget; static QDragManager *instance; diff --git a/src/gui/kernel/qdnd_s60.cpp b/src/gui/kernel/qdnd_s60.cpp index fb2e426..2456185 100644 --- a/src/gui/kernel/qdnd_s60.cpp +++ b/src/gui/kernel/qdnd_s60.cpp @@ -50,11 +50,14 @@ #include "qevent.h" #include "qpainter.h" #include "qdnd_p.h" +#include "qt_s60_p.h" #include // pointer cursor #include #include +#include + QT_BEGIN_NAMESPACE //### artistic impression of Symbians default DnD cursor ? @@ -89,82 +92,24 @@ static bool qt_symbian_dnd_dragging = false; static Qt::KeyboardModifiers oldstate; -class QShapedPixmapWidget -{ -public: - QShapedPixmapWidget(RWsSession aWsSession,RWindowTreeNode* aNode) - { - sprite = RWsSprite(aWsSession); - cursorSprite.iBitmap = 0; - cursorSprite.iMaskBitmap = 0; - cursorSprite.iInvertMask = EFalse; - cursorSprite.iOffset = TPoint(0,0); - cursorSprite.iInterval = TTimeIntervalMicroSeconds32(0); - cursorSprite.iDrawMode = CGraphicsContext::EDrawModePEN; - sprite.Construct(*aNode,TPoint(0,0), ESpriteNoShadows | ESpriteNoChildClip); - sprite.AppendMember(cursorSprite); - sprite.Activate(); - } - ~QShapedPixmapWidget() - { - sprite.Close(); - cursorSprite.iBitmap = 0; - delete cursorBitmap; - cursorBitmap = 0; //redundant... - } - void disableCursor() - { - cursorSprite.iBitmap = 0; - sprite.UpdateMember(0,cursorSprite); - } - void enableCursor() - { - cursorSprite.iBitmap = cursorBitmap; - sprite.UpdateMember(0,cursorSprite); - } - void setPixmap(QPixmap pm) - { - //### heaplock centralized. - QImage temp = pm.toImage(); - QSize size = pm.size(); - temp.bits(); - CFbsBitmap *curbm = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new - curbm->Create(TSize(size.width(),size.height()),EColor16MA); - curbm->LockHeap(ETrue); - memcpy((uchar*)curbm->DataAddress(),temp.bits(),temp.numBytes()); - curbm->UnlockHeap(ETrue); - delete cursorSprite.iBitmap; - cursorSprite.iBitmap = curbm; - cursorBitmap = curbm; - sprite.UpdateMember(0,cursorSprite); - } - CFbsBitmap *cursorBitmap; - RWsPointerCursor pointerCursor; - RWsSprite sprite; - TSpriteMember cursorSprite; - -}; - - -static QShapedPixmapWidget *qt_symbian_dnd_deco = 0; - void QDragManager::updatePixmap() { - if (qt_symbian_dnd_deco) { - QPixmap pm; - QPoint pm_hot(default_pm_hotx,default_pm_hoty); - if (drag_object) { - pm = drag_object->pixmap(); - if (!pm.isNull()) - pm_hot = drag_object->hotSpot(); - } - if (pm.isNull()) { - if (!defaultPm) - defaultPm = new QPixmap(default_pm); - pm = *defaultPm; - } - qt_symbian_dnd_deco->setPixmap(pm); + QPixmap pm; + QPoint pm_hot(default_pm_hotx,default_pm_hoty); + if (drag_object) { + pm = drag_object->pixmap(); + if (!pm.isNull()) + pm_hot = drag_object->hotSpot(); + } + if (pm.isNull()) { + if (!defaultPm) + defaultPm = new QPixmap(default_pm); + pm = *defaultPm; } +#ifndef QT_NO_CURSOR + QCursor cursor(pm, pm_hot.x(), pm_hot.y()); + overrideCursor = cursor; +#endif } void QDragManager::timerEvent(QTimerEvent *) { } @@ -174,6 +119,16 @@ void QDragManager::move(const QPoint&) { void QDragManager::updateCursor() { +#ifndef QT_NO_CURSOR + QCursor cursor = willDrop ? overrideCursor : Qt::ForbiddenCursor; + if (!restoreCursor) { + QApplication::setOverrideCursor(cursor); + restoreCursor = true; + } + else { + QApplication::changeOverrideCursor(cursor); + } +#endif } @@ -210,20 +165,19 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e) // map the Coords relative to the window. if (!cw) return true; - TPoint windowPos = cw->effectiveWinId()->PositionRelativeToScreen(); - qt_symbian_dnd_deco->sprite.SetPosition(TPoint(me->globalX()- windowPos.iX,me->globalY()- windowPos.iY)); while (cw && !cw->acceptDrops() && !cw->isWindow()) cw = cw->parentWidget(); + bool oldWillDrop = willDrop; if (object->target() != cw) { if (object->target()) { QDragLeaveEvent dle; QApplication::sendEvent(object->target(), &dle); willDrop = false; global_accepted_action = Qt::IgnoreAction; - updateCursor(); - restoreCursor = true; + if (oldWillDrop != willDrop) + updateCursor(); object->d_func()->target = 0; } if (cw && cw->acceptDrops()) { @@ -233,8 +187,8 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e) QApplication::sendEvent(object->target(), &dee); willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction; global_accepted_action = willDrop ? dee.dropAction() : Qt::IgnoreAction; - updateCursor(); - restoreCursor = true; + if (oldWillDrop != willDrop) + updateCursor(); } } else if (cw) { QDragMoveEvent dme(cw->mapFromGlobal(me->globalPos()), possible_actions, dropData, @@ -246,8 +200,10 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e) QApplication::sendEvent(cw, &dme); willDrop = dme.isAccepted(); global_accepted_action = willDrop ? dme.dropAction() : Qt::IgnoreAction; - updatePixmap(); - updateCursor(); + if (oldWillDrop != willDrop) { + updatePixmap(); + updateCursor(); + } } if (global_accepted_action != prevAction) emitActionChanged(global_accepted_action); @@ -259,7 +215,7 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e) { qApp->removeEventFilter(this); if (restoreCursor) { - qt_symbian_dnd_deco->disableCursor(); + QApplication::restoreOverrideCursor(); willDrop = false; restoreCursor = false; } @@ -305,23 +261,15 @@ Qt::DropAction QDragManager::drag(QDrag *o) } object = drag_object = o; - RWsSession winSession = o->source()->effectiveWinId()->ControlEnv()->WsSession(); - Q_ASSERT(!qt_symbian_dnd_deco); - qt_symbian_dnd_deco = new QShapedPixmapWidget(winSession, o->source()->effectiveWinId()->DrawableWindow()); oldstate = Qt::NoModifier; // #### Should use state that caused the drag willDrop = false; updatePixmap(); updateCursor(); - restoreCursor = true; - object->d_func()->target = 0; - TPoint windowPos = source()->effectiveWinId()->PositionRelativeToScreen(); - qt_symbian_dnd_deco->sprite.SetPosition(TPoint(QCursor::pos().x()- windowPos.iX ,QCursor::pos().y() - windowPos.iY)); + qt_symbian_set_cursor_visible(true); //force cursor on even for touch phone - QPoint hotspot = drag_object->hotSpot(); - qt_symbian_dnd_deco->cursorSprite.iOffset = TPoint(- hotspot.x(),- hotspot.y()); - qt_symbian_dnd_deco->sprite.UpdateMember(0,qt_symbian_dnd_deco->cursorSprite); + object->d_func()->target = 0; qApp->installEventFilter(this); @@ -334,11 +282,11 @@ Qt::DropAction QDragManager::drag(QDrag *o) delete eventLoop; eventLoop = 0; - delete qt_symbian_dnd_deco; - qt_symbian_dnd_deco = 0; + qt_symbian_set_cursor_visible(false); + + overrideCursor = QCursor(); //deref the cursor data qt_symbian_dnd_dragging = false; - return global_accepted_action; } @@ -358,8 +306,10 @@ void QDragManager::cancel(bool deleteSource) drag_object = object = 0; } - delete qt_symbian_dnd_deco; - qt_symbian_dnd_deco = 0; + if (restoreCursor) { + QApplication::restoreOverrideCursor(); + restoreCursor = false; + } global_accepted_action = Qt::IgnoreAction; } @@ -367,6 +317,10 @@ void QDragManager::cancel(bool deleteSource) void QDragManager::drop() { + if (restoreCursor) { + QApplication::restoreOverrideCursor(); + restoreCursor = false; + } } QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index d85023b..794d15a 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -83,6 +83,7 @@ const TInt KInternalStatusPaneChange = 0x50000000; class QS60Data { public: + QS60Data(); TUid uid; int screenDepth; QPoint lastCursorPos; @@ -95,6 +96,16 @@ public: int screenHeightInTwips; int defaultDpiX; int defaultDpiY; + WId curWin; + int virtualMouseLastKey; + int virtualMouseAccel; + int virtualMouseMaxAccel; +#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS + bool brokenPointerCursors; +#endif + bool hasTouchscreen; + bool mouseInteractionEnabled; + bool virtualMouseRequired; int qtOwnsS60Environment : 1; static inline void updateScreenSize(); static inline RWsSession& wsSession(); @@ -164,6 +175,11 @@ private: bool m_previousEventLongTap; }; +inline QS60Data::QS60Data() +{ + memclr(this, sizeof(QS60Data)); //zero init data +} + inline void QS60Data::updateScreenSize() { TPixelsTwipsAndRotation params; @@ -173,6 +189,8 @@ inline void QS60Data::updateScreenSize() S60->screenHeightInPixels = params.iPixelSize.iHeight; S60->screenWidthInTwips = params.iTwipsSize.iWidth; S60->screenHeightInTwips = params.iTwipsSize.iHeight; + + S60->virtualMouseMaxAccel = qMax(S60->screenHeightInPixels, S60->screenWidthInPixels) / 20; TReal inches = S60->screenHeightInTwips / (TReal)KTwipsPerInch; S60->defaultDpiY = S60->screenHeightInPixels / inches; @@ -286,6 +304,11 @@ static inline QImage::Format qt_TDisplayMode2Format(TDisplayMode mode) return format; } +void qt_symbian_setWindowCursor(const QCursor &cursor, const CCoeControl* wid); +void qt_symbian_setWindowGroupCursor(const QCursor &cursor, RWindowTreeNode &node); +void qt_symbian_setGlobalCursor(const QCursor &cursor); +void qt_symbian_set_cursor_visible(bool visible); +bool qt_symbian_is_cursor_visible(); QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index fd89cb9..c86012d 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -3048,7 +3048,6 @@ void QWidgetPrivate::setEnabled_helper(bool enable) if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) { // enforce the windows behavior of clearing the cursor on // disabled widgets - extern void qt_x11_enforce_cursor(QWidget * w); // defined in qwidget_x11.cpp qt_x11_enforce_cursor(q); } #endif diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 744d20f..522ce33 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -188,7 +188,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) if (isResize) data.window_state &= ~Qt::WindowMaximized; - if(q->isWindow()) { + if (q->isWindow()) { if (w == 0 || h == 0) { q->setAttribute(Qt::WA_OutsideWSRange, true); if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) @@ -287,7 +287,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de TSize screenSize = S60->screenDevice()->SizeInPixels(); data.crect.setRect(0, 0, screenSize.iWidth, screenSize.iHeight); q->setAttribute(Qt::WA_DontShowOnScreen); - } else if(topLevel && !q->testAttribute(Qt::WA_Resized)){ + } else if (topLevel && !q->testAttribute(Qt::WA_Resized)){ int width = sw; int height = sh; if (extra) { @@ -300,7 +300,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de CCoeControl *destroyw = 0; createExtra(); - if(window) { + if (window) { if (destroyOldWindow) destroyw = data.winid; id = window; @@ -416,7 +416,7 @@ void QWidgetPrivate::hide_sys() deactivateWidgetCleanup(); WId id = q->internalWinId(); if (q->isWindow() && id) { - if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged() + if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged() id->SetFocus(false); id->MakeVisible(false); if (QWidgetBackingStore *bs = maybeBackingStore()) @@ -432,7 +432,7 @@ void QWidgetPrivate::setFocus_sys() { Q_Q(QWidget); if (q->testAttribute(Qt::WA_WState_Created) && q->window()->windowType() != Qt::Popup) - if(!q->effectiveWinId()->IsFocused()) // Avoid unnecessry calls to FocusChanged() + if (!q->effectiveWinId()->IsFocused()) // Avoid unnecessry calls to FocusChanged() q->effectiveWinId()->SetFocus(true); } @@ -482,7 +482,7 @@ void QWidgetPrivate::lower_sys() if (q->internalWinId() && tlwExtra) { tlwExtra->rwindow->SetOrdinalPosition(-1); } - if(!q->isWindow()) + if (!q->isWindow()) invalidateBuffer(q->rect()); } @@ -499,7 +499,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget* w) QTLWExtra *tlwExtraSibling = w->d_func()->maybeTopData(); if (q->internalWinId() && tlwExtra && w->internalWinId() && tlwExtraSibling) tlwExtra->rwindow->SetOrdinalPosition(tlwExtraSibling->rwindow->OrdinalPosition() + 1); - if(!q->isWindow() || !w->internalWinId()) + if (!q->isWindow() || !w->internalWinId()) invalidateBuffer(q->rect()); } @@ -553,7 +553,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) // destroyed when emitting the child remove event below. See QWorkspace. if (wasCreated && old_winid) { old_winid->MakeVisible(false); - if(old_winid->IsFocused()) // Avoid unnecessary calls to FocusChanged() + if (old_winid->IsFocused()) // Avoid unnecessary calls to FocusChanged() old_winid->SetFocus(false); old_winid->SetParent(0); } @@ -660,7 +660,7 @@ CFbsBitmap* qt_pixmapToNativeBitmap(QPixmap pixmap, bool invert) fbsBitmap->LockHeap(); QImage image = pixmap.toImage(); - if(invert) + if (invert) image.invertPixels(); int height = pixmap.size().height(); @@ -764,8 +764,8 @@ void QWidgetPrivate::setWindowTitle_sys(const QString &caption) if (q->isWindow()) { Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); CAknTitlePane* titlePane = S60->titlePane(); - if(titlePane) { - if(caption.isEmpty()) { + if (titlePane) { + if (caption.isEmpty()) { QT_TRAP_THROWING(titlePane->SetTextToDefaultL()); } else { QT_TRAP_THROWING(titlePane->SetTextL(qt_QString2TPtrC(caption))); @@ -996,7 +996,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) // The window decoration visibility has to be changed before doing actual // window state change since in that order the availableGeometry will return // directly the right size and we will avoid unnecessarty redraws - if((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen) || + if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen) || oldstate == Qt::WindowNoState) { CEikStatusPane* statusPane = S60->statusPane(); CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer(); @@ -1061,7 +1061,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) if (newstate & Qt::WindowMinimized) { if (isVisible()) { WId id = effectiveWinId(); - if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged() + if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged() id->SetFocus(false); id->MakeVisible(false); } @@ -1069,7 +1069,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) if (isVisible()) { WId id = effectiveWinId(); id->MakeVisible(true); - if(!id->IsFocused()) // Avoid unnecessary calls to FocusChanged() + if (!id->IsFocused()) // Avoid unnecessary calls to FocusChanged() id->SetFocus(true); } const QRect normalGeometry = geometry(); @@ -1111,6 +1111,10 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) } #endif + if (QWidgetPrivate::mouseGrabber == this) + releaseMouse(); + if (QWidgetPrivate::keyboardGrabber == this) + releaseKeyboard(); setAttribute(Qt::WA_WState_Created, false); QObjectList childList = children(); for (int i = 0; i < childList.size(); ++i) { // destroy all widget children @@ -1119,12 +1123,8 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) static_cast(obj)->destroy(destroySubWindows, destroySubWindows); } - if (QWidgetPrivate::mouseGrabber == this) - releaseMouse(); - if (QWidgetPrivate::keyboardGrabber == this) - releaseKeyboard(); if (destroyWindow && !(windowType() == Qt::Desktop) && id) { - if(id->IsFocused()) // Avoid unnecessry calls to FocusChanged() + if (id->IsFocused()) // Avoid unnecessry calls to FocusChanged() id->SetFocus(false); id->ControlEnv()->AppUi()->RemoveFromStack(id); @@ -1192,8 +1192,28 @@ void QWidget::grabMouse() WId id = effectiveWinId(); id->SetPointerCapture(true); QWidgetPrivate::mouseGrabber = this; + +#ifndef QT_NO_CURSOR + QApplication::setOverrideCursor(cursor()); +#endif + } +} + +#ifndef QT_NO_CURSOR +void QWidget::grabMouse(const QCursor &cursor) +{ + if (!qt_nograb()) { + if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this) + QWidgetPrivate::mouseGrabber->releaseMouse(); + Q_ASSERT(testAttribute(Qt::WA_WState_Created)); + WId id = effectiveWinId(); + id->SetPointerCapture(true); + QWidgetPrivate::mouseGrabber = this; + + QApplication::setOverrideCursor(cursor); } } +#endif void QWidget::releaseMouse() { @@ -1202,6 +1222,8 @@ void QWidget::releaseMouse() WId id = effectiveWinId(); id->SetPointerCapture(false); QWidgetPrivate::mouseGrabber = 0; + + QApplication::restoreOverrideCursor(); } } @@ -1215,4 +1237,21 @@ void QWidget::activateWindow() id->SetFocus(true); } } + +#ifndef QT_NO_CURSOR + +void QWidgetPrivate::setCursor_sys(const QCursor &cursor) +{ + Q_UNUSED(cursor); + Q_Q(QWidget); + qt_symbian_set_cursor(q, false); +} + +void QWidgetPrivate::unsetCursor_sys() +{ + Q_Q(QWidget); + qt_symbian_set_cursor(q, false); +} +#endif + QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index c9ebccf..211e9d4 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -722,8 +722,6 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const void QWidgetPrivate::updateSystemBackground() {} -extern void qt_win_set_cursor(QWidget *, bool); // qapplication_win.cpp - #ifndef QT_NO_CURSOR void QWidgetPrivate::setCursor_sys(const QCursor &cursor) { diff --git a/src/gui/kernel/symbian.pri b/src/gui/kernel/symbian.pri index d267a53..5497ccb 100644 --- a/src/gui/kernel/symbian.pri +++ b/src/gui/kernel/symbian.pri @@ -1,3 +1,4 @@ symbian { contains(QT_CONFIG, s60): LIBS+= $$QMAKE_LIBS_S60 + RESOURCES += symbian/symbianresources.qrc } diff --git a/src/gui/symbian/images/blank.png b/src/gui/symbian/images/blank.png new file mode 100644 index 0000000..bd396de Binary files /dev/null and b/src/gui/symbian/images/blank.png differ diff --git a/src/gui/symbian/images/busy12.png b/src/gui/symbian/images/busy12.png new file mode 100644 index 0000000..909e70f Binary files /dev/null and b/src/gui/symbian/images/busy12.png differ diff --git a/src/gui/symbian/images/busy3.png b/src/gui/symbian/images/busy3.png new file mode 100644 index 0000000..983f5d8 Binary files /dev/null and b/src/gui/symbian/images/busy3.png differ diff --git a/src/gui/symbian/images/busy6.png b/src/gui/symbian/images/busy6.png new file mode 100644 index 0000000..b2e8780 Binary files /dev/null and b/src/gui/symbian/images/busy6.png differ diff --git a/src/gui/symbian/images/busy9.png b/src/gui/symbian/images/busy9.png new file mode 100644 index 0000000..e093d01 Binary files /dev/null and b/src/gui/symbian/images/busy9.png differ diff --git a/src/gui/symbian/images/closehand.png b/src/gui/symbian/images/closehand.png new file mode 100644 index 0000000..05534f5 Binary files /dev/null and b/src/gui/symbian/images/closehand.png differ diff --git a/src/gui/symbian/images/cross.png b/src/gui/symbian/images/cross.png new file mode 100644 index 0000000..50da7aa Binary files /dev/null and b/src/gui/symbian/images/cross.png differ diff --git a/src/gui/symbian/images/forbidden.png b/src/gui/symbian/images/forbidden.png new file mode 100644 index 0000000..a3a0fd6 Binary files /dev/null and b/src/gui/symbian/images/forbidden.png differ diff --git a/src/gui/symbian/images/handpoint.png b/src/gui/symbian/images/handpoint.png new file mode 100644 index 0000000..a221548 Binary files /dev/null and b/src/gui/symbian/images/handpoint.png differ diff --git a/src/gui/symbian/images/ibeam.png b/src/gui/symbian/images/ibeam.png new file mode 100644 index 0000000..ace2fad Binary files /dev/null and b/src/gui/symbian/images/ibeam.png differ diff --git a/src/gui/symbian/images/openhand.png b/src/gui/symbian/images/openhand.png new file mode 100644 index 0000000..6f232f0 Binary files /dev/null and b/src/gui/symbian/images/openhand.png differ diff --git a/src/gui/symbian/images/pointer.png b/src/gui/symbian/images/pointer.png new file mode 100644 index 0000000..677404e Binary files /dev/null and b/src/gui/symbian/images/pointer.png differ diff --git a/src/gui/symbian/images/sizeall.png b/src/gui/symbian/images/sizeall.png new file mode 100644 index 0000000..2950067 Binary files /dev/null and b/src/gui/symbian/images/sizeall.png differ diff --git a/src/gui/symbian/images/sizebdiag.png b/src/gui/symbian/images/sizebdiag.png new file mode 100644 index 0000000..f565a3a Binary files /dev/null and b/src/gui/symbian/images/sizebdiag.png differ diff --git a/src/gui/symbian/images/sizefdiag.png b/src/gui/symbian/images/sizefdiag.png new file mode 100644 index 0000000..9493f12 Binary files /dev/null and b/src/gui/symbian/images/sizefdiag.png differ diff --git a/src/gui/symbian/images/sizehor.png b/src/gui/symbian/images/sizehor.png new file mode 100644 index 0000000..217bf39 Binary files /dev/null and b/src/gui/symbian/images/sizehor.png differ diff --git a/src/gui/symbian/images/sizever.png b/src/gui/symbian/images/sizever.png new file mode 100644 index 0000000..2c99038 Binary files /dev/null and b/src/gui/symbian/images/sizever.png differ diff --git a/src/gui/symbian/images/splith.png b/src/gui/symbian/images/splith.png new file mode 100644 index 0000000..343bed5 Binary files /dev/null and b/src/gui/symbian/images/splith.png differ diff --git a/src/gui/symbian/images/splitv.png b/src/gui/symbian/images/splitv.png new file mode 100644 index 0000000..69ee416 Binary files /dev/null and b/src/gui/symbian/images/splitv.png differ diff --git a/src/gui/symbian/images/uparrow.png b/src/gui/symbian/images/uparrow.png new file mode 100644 index 0000000..92dd933 Binary files /dev/null and b/src/gui/symbian/images/uparrow.png differ diff --git a/src/gui/symbian/images/wait1.png b/src/gui/symbian/images/wait1.png new file mode 100644 index 0000000..5aebaab Binary files /dev/null and b/src/gui/symbian/images/wait1.png differ diff --git a/src/gui/symbian/images/wait10.png b/src/gui/symbian/images/wait10.png new file mode 100644 index 0000000..3b549b0 Binary files /dev/null and b/src/gui/symbian/images/wait10.png differ diff --git a/src/gui/symbian/images/wait11.png b/src/gui/symbian/images/wait11.png new file mode 100644 index 0000000..24a943f Binary files /dev/null and b/src/gui/symbian/images/wait11.png differ diff --git a/src/gui/symbian/images/wait12.png b/src/gui/symbian/images/wait12.png new file mode 100644 index 0000000..15afd4d Binary files /dev/null and b/src/gui/symbian/images/wait12.png differ diff --git a/src/gui/symbian/images/wait2.png b/src/gui/symbian/images/wait2.png new file mode 100644 index 0000000..f2022b2 Binary files /dev/null and b/src/gui/symbian/images/wait2.png differ diff --git a/src/gui/symbian/images/wait3.png b/src/gui/symbian/images/wait3.png new file mode 100644 index 0000000..5b73e57 Binary files /dev/null and b/src/gui/symbian/images/wait3.png differ diff --git a/src/gui/symbian/images/wait4.png b/src/gui/symbian/images/wait4.png new file mode 100644 index 0000000..17a0339 Binary files /dev/null and b/src/gui/symbian/images/wait4.png differ diff --git a/src/gui/symbian/images/wait5.png b/src/gui/symbian/images/wait5.png new file mode 100644 index 0000000..16a5c23 Binary files /dev/null and b/src/gui/symbian/images/wait5.png differ diff --git a/src/gui/symbian/images/wait6.png b/src/gui/symbian/images/wait6.png new file mode 100644 index 0000000..2870093 Binary files /dev/null and b/src/gui/symbian/images/wait6.png differ diff --git a/src/gui/symbian/images/wait7.png b/src/gui/symbian/images/wait7.png new file mode 100644 index 0000000..54f75a1 Binary files /dev/null and b/src/gui/symbian/images/wait7.png differ diff --git a/src/gui/symbian/images/wait8.png b/src/gui/symbian/images/wait8.png new file mode 100644 index 0000000..1d370c7 Binary files /dev/null and b/src/gui/symbian/images/wait8.png differ diff --git a/src/gui/symbian/images/wait9.png b/src/gui/symbian/images/wait9.png new file mode 100644 index 0000000..c28096f Binary files /dev/null and b/src/gui/symbian/images/wait9.png differ diff --git a/src/gui/symbian/images/whatsthis.png b/src/gui/symbian/images/whatsthis.png new file mode 100644 index 0000000..3386ef0 Binary files /dev/null and b/src/gui/symbian/images/whatsthis.png differ diff --git a/src/gui/symbian/symbianresources.qrc b/src/gui/symbian/symbianresources.qrc new file mode 100644 index 0000000..0a4fc36 --- /dev/null +++ b/src/gui/symbian/symbianresources.qrc @@ -0,0 +1,37 @@ + + + images/blank.png + images/busy3.png + images/busy6.png + images/busy9.png + images/busy12.png + images/closehand.png + images/cross.png + images/forbidden.png + images/handpoint.png + images/ibeam.png + images/openhand.png + images/pointer.png + images/sizeall.png + images/sizebdiag.png + images/sizefdiag.png + images/sizehor.png + images/sizever.png + images/splith.png + images/splitv.png + images/uparrow.png + images/wait1.png + images/wait2.png + images/wait3.png + images/wait4.png + images/wait5.png + images/wait6.png + images/wait7.png + images/wait8.png + images/wait9.png + images/wait10.png + images/wait11.png + images/wait12.png + images/whatsthis.png + + diff --git a/src/qbase.pri b/src/qbase.pri index 27e4992..4639ca1 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -101,7 +101,15 @@ symbian { "DEFFILE ../s60installs/eabi/$${TARGET}.def" \ "$${LITERAL_HASH}endif" + #with defBlock enabled, removed exported symbols are treated as errors + #and there is binary compatibility between successive builds. + #with defBlock disabled, binary compatibility is broken every time you build #MMP_RULES += defBlock + + #with EXPORTUNFROZEN enabled, new exports are included in the dll without + #needing to run abld freeze, however binary compatibility is only maintained + #for symbols that are frozen (and only if defBlock is also enabled) + #the downside of EXPORTUNFROZEN is that the linker gets run twice MMP_RULES += EXPORTUNFROZEN } load(armcc_warnings) diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 5171d3a..f2d865b 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -252,7 +252,7 @@ int main(int argc, char *argv[]) \ #include #ifdef QT_KEYPAD_NAVIGATION -# define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setKeypadNavigationEnabled(false); +# define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setNavigationMode(Qt::NavigationModeNone); #else # define QTEST_DISABLE_KEYPAD_NAVIGATION #endif diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index b7b2327..74c3af9 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -311,7 +311,7 @@ QT_BEGIN_NAMESPACE Example: \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 11 - \sa QTEST_APPLESS_MAIN(), QTest::qExec(), QApplication::setKeypadNavigationEnabled() + \sa QTEST_APPLESS_MAIN(), QTest::qExec(), QApplication::setNavigationMode() */ /*! \macro QTEST_APPLESS_MAIN(TestClass) diff --git a/tests/manual/qcursor/allcursors/allcursors.pro b/tests/manual/qcursor/allcursors/allcursors.pro new file mode 100644 index 0000000..8e7da30 --- /dev/null +++ b/tests/manual/qcursor/allcursors/allcursors.pro @@ -0,0 +1,16 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2009-08-05T17:13:23 +# +#------------------------------------------------- + +TARGET = tst_allcursors +TEMPLATE = app + + +SOURCES += main.cpp\ + mainwindow.cpp + +HEADERS += mainwindow.h + +FORMS += mainwindow.ui diff --git a/tests/manual/qcursor/allcursors/main.cpp b/tests/manual/qcursor/allcursors/main.cpp new file mode 100644 index 0000000..9fb7510 --- /dev/null +++ b/tests/manual/qcursor/allcursors/main.cpp @@ -0,0 +1,13 @@ +#include +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.showFullScreen(); +#ifdef QT_KEYPAD_NAVIGATION + QApplication::setNavigationMode(Qt::NavigationModeCursorForceVisible); +#endif + return a.exec(); +} diff --git a/tests/manual/qcursor/allcursors/mainwindow.cpp b/tests/manual/qcursor/allcursors/mainwindow.cpp new file mode 100644 index 0000000..0046ddb --- /dev/null +++ b/tests/manual/qcursor/allcursors/mainwindow.cpp @@ -0,0 +1,43 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include +#include +#include +#include +#include +#include + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), ui(new Ui::MainWindow) +{ + ui->setupUi(this); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::keyPressEvent(QKeyEvent* event) +{ + QPoint off(0, 0); + switch (event->key()) { + case Qt::Key_Up: + off.setY(-4); + break; + case Qt::Key_Down: + off.setY(4); + break; + case Qt::Key_Left: + off.setX(-4); + break; + case Qt::Key_Right: + off.setX(4); + break; + default: + return QMainWindow::keyPressEvent(event); + } + off += QCursor::pos(); + QCursor::setPos(off); +} diff --git a/tests/manual/qcursor/allcursors/mainwindow.h b/tests/manual/qcursor/allcursors/mainwindow.h new file mode 100644 index 0000000..e5c731c --- /dev/null +++ b/tests/manual/qcursor/allcursors/mainwindow.h @@ -0,0 +1,28 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class QTimer; + +namespace Ui +{ + class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private: + void keyPressEvent(QKeyEvent* event); + +private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/tests/manual/qcursor/allcursors/mainwindow.ui b/tests/manual/qcursor/allcursors/mainwindow.ui new file mode 100644 index 0000000..55ff78c --- /dev/null +++ b/tests/manual/qcursor/allcursors/mainwindow.ui @@ -0,0 +1,210 @@ + + + MainWindow + + + + 0 + 0 + 240 + 320 + + + + MainWindow + + + + + + + Arrow + + + + + + + UpArrowCursor + + + up arrow + + + + + + + CrossCursor + + + cross + + + + + + + WaitCursor + + + wait + + + + + + + IBeamCursor + + + ibeam + + + + + + + SizeVerCursor + + + sizever + + + + + + + SizeHorCursor + + + sizehor + + + + + + + SizeFDiagCursor + + + sizebdiag + + + + + + + SizeBDiagCursor + + + sizefdiag + + + + + + + SizeAllCursor + + + sizeall + + + + + + + BlankCursor + + + blank + + + + + + + SplitVCursor + + + splitv + + + + + + + SplitHCursor + + + splith + + + + + + + PointingHandCursor + + + pointhand + + + + + + + ForbiddenCursor + + + forbidden + + + + + + + WhatsThisCursor + + + whatsthis + + + + + + + BusyCursor + + + busy + + + + + + + OpenHandCursor + + + openhand + + + + + + + ClosedHandCursor + + + closehand + + + + + + + + + diff --git a/tests/manual/qcursor/grab_override/data/monkey_on_64x64.png b/tests/manual/qcursor/grab_override/data/monkey_on_64x64.png new file mode 100644 index 0000000..990f604 Binary files /dev/null and b/tests/manual/qcursor/grab_override/data/monkey_on_64x64.png differ diff --git a/tests/manual/qcursor/grab_override/grab_override.pro b/tests/manual/qcursor/grab_override/grab_override.pro new file mode 100644 index 0000000..c0f69be --- /dev/null +++ b/tests/manual/qcursor/grab_override/grab_override.pro @@ -0,0 +1,18 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2009-08-05T17:13:23 +# +#------------------------------------------------- + +TARGET = t_cursors +TEMPLATE = app + + +SOURCES += main.cpp\ + mainwindow.cpp + +HEADERS += mainwindow.h + +FORMS += mainwindow.ui + +RESOURCES += images.qrc diff --git a/tests/manual/qcursor/grab_override/images.qrc b/tests/manual/qcursor/grab_override/images.qrc new file mode 100644 index 0000000..1d0cb92 --- /dev/null +++ b/tests/manual/qcursor/grab_override/images.qrc @@ -0,0 +1,6 @@ + + + + data/monkey_on_64x64.png + + diff --git a/tests/manual/qcursor/grab_override/main.cpp b/tests/manual/qcursor/grab_override/main.cpp new file mode 100644 index 0000000..9fb7510 --- /dev/null +++ b/tests/manual/qcursor/grab_override/main.cpp @@ -0,0 +1,13 @@ +#include +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.showFullScreen(); +#ifdef QT_KEYPAD_NAVIGATION + QApplication::setNavigationMode(Qt::NavigationModeCursorForceVisible); +#endif + return a.exec(); +} diff --git a/tests/manual/qcursor/grab_override/mainwindow.cpp b/tests/manual/qcursor/grab_override/mainwindow.cpp new file mode 100644 index 0000000..27dd0e7 --- /dev/null +++ b/tests/manual/qcursor/grab_override/mainwindow.cpp @@ -0,0 +1,100 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include +#include +#include +#include +#include + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), ui(new Ui::MainWindow) +{ + ui->setupUi(this); + QPixmap pix(":/data/monkey_on_64x64.png"); + + QImage mask(16, 16, QImage::Format_MonoLSB); + QImage bw(16, 16, QImage::Format_MonoLSB); + mask.fill(0); + bw.fill(0); + for (int x = 0; x < 16; x++) { + bw.setPixel(x, x, 1); + bw.setPixel(x, 15 - x, 1); + mask.setPixel(x, x, 1); + mask.setPixel(x, 15 - x, 1); + if (x > 0 && x < 15) { + mask.setPixel(x - 1, x, 1); + mask.setPixel(x + 1, x, 1); + mask.setPixel(x - 1, 15 - x, 1); + mask.setPixel(x + 1, 15 - x, 1); + } + } + + ccurs = QCursor(pix); + bcurs = QCursor(QBitmap::fromImage(bw), QBitmap::fromImage(mask)); + ui->label->setCursor(ccurs); + + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(toggleOverrideCursor())); + timer->start(2000); + + override = 0; +} + +MainWindow::~MainWindow() +{ + delete timer; + delete ui; +} + +void MainWindow::toggleOverrideCursor() +{ + switch (override) { + case 0: + QApplication::setOverrideCursor(Qt::BusyCursor); + break; + case 1: + QApplication::restoreOverrideCursor(); + break; + case 2: + ui->label->grabMouse(Qt::ForbiddenCursor); + break; + case 3: + case 5: + ui->label->releaseMouse(); + break; + case 4: + ui->label->grabMouse(); + break; + case 6: + ui->label->setCursor(bcurs); + break; + case 7: + ui->label->setCursor(ccurs); + break; + } + override = (override + 1) % 8; +} + +void MainWindow::keyPressEvent(QKeyEvent* event) +{ + QPoint off(0, 0); + switch (event->key()) { + case Qt::Key_Up: + off.setY(-4); + break; + case Qt::Key_Down: + off.setY(4); + break; + case Qt::Key_Left: + off.setX(-4); + break; + case Qt::Key_Right: + off.setX(4); + break; + default: + return QMainWindow::keyPressEvent(event); + } + off += QCursor::pos(); + QCursor::setPos(off); +} diff --git a/tests/manual/qcursor/grab_override/mainwindow.h b/tests/manual/qcursor/grab_override/mainwindow.h new file mode 100644 index 0000000..0b1f694 --- /dev/null +++ b/tests/manual/qcursor/grab_override/mainwindow.h @@ -0,0 +1,35 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class QTimer; + +namespace Ui +{ + class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private slots: + void toggleOverrideCursor(); + +private: + void keyPressEvent(QKeyEvent* event); + + Ui::MainWindow *ui; + QTimer *timer; + int override; + + QCursor ccurs; + QCursor bcurs; +}; + +#endif // MAINWINDOW_H diff --git a/tests/manual/qcursor/grab_override/mainwindow.ui b/tests/manual/qcursor/grab_override/mainwindow.ui new file mode 100644 index 0000000..bf35536 --- /dev/null +++ b/tests/manual/qcursor/grab_override/mainwindow.ui @@ -0,0 +1,97 @@ + + + MainWindow + + + + 0 + 0 + 240 + 320 + + + + MainWindow + + + + + + + QFrame::NoFrame + + + 1 + + + Qt::Vertical + + + + QFrame::Box + + + Custom + + + + + QFrame::NoFrame + + + 1 + + + Qt::Horizontal + + + + ForbiddenCursor + + + QFrame::Box + + + Forbidden + + + + + WaitCursor + + + QFrame::Box + + + Wait + + + + + + + + + + + 0 + 0 + 240 + 21 + + + + + + TopToolBarArea + + + false + + + + + + + + diff --git a/tests/manual/qcursor/qcursor.pro b/tests/manual/qcursor/qcursor.pro new file mode 100644 index 0000000..af082a4 --- /dev/null +++ b/tests/manual/qcursor/qcursor.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs + +SUBDIRS = allcursors grab_override diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index ecccfb4..c8e369e 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2788,7 +2788,6 @@ static void applyTemporarySymbianFlags(QStringList &qconfigList) // This is removed because it uses UNIX signals which are not implemented yet qconfigList += "QT_NO_CRASHHANDLER"; qconfigList += "QT_NO_PRINTER"; - qconfigList += "QT_NO_CURSOR"; qconfigList += "QT_NO_SYSTEMTRAYICON"; } -- cgit v0.12 From ff3ce998bea1ef49c2e9548fb54e37292a121ec8 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 15 Sep 2009 14:53:43 +0200 Subject: Change compile options for configure so it can be built using msvc2008 Use the -MT command line option so it links statically with libc. The reason for this is that not all windows versions have the DLL "out of the box". Reviewed-by: Marius Storm-Olsen --- tools/configure/configure.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 06e9fe0..243183c 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -12,9 +12,13 @@ win32-g++ : LIBS += -luuid win32-msvc* { QMAKE_CFLAGS_RELEASE -= -MD + QMAKE_CFLAGS_RELEASE += -MT QMAKE_CFLAGS_DEBUG -= -MDd + QMAKE_CFLAGS_DEBUG += -MTd QMAKE_CXXFLAGS_RELEASE -= -MD + QMAKE_CXXFLAGS_RELEASE += -MT QMAKE_CXXFLAGS_DEBUG -= -MDd + QMAKE_CXXFLAGS_DEBUG += -MTd } PRECOMPILED_HEADER = configure_pch.h -- cgit v0.12 From dc6e88c0dc5be96423498850c519afbad6e13989 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 15 Sep 2009 13:29:04 +0200 Subject: Fix QGraphicsView::scrollAfterResize autotest on Mac. The auto-test was failing because it calculate the scrollbar indent using style primitives. It's very fragile and doesn't work on MacOS style (and may not work on other style too). Since we don't test style stuff here, we can just apply the plastique style for this test. Reviewed-by:TrustMe --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 6c1ac54..3bed9ce 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -3072,9 +3072,11 @@ void tst_QGraphicsView::scrollAfterResize_data() QTest::addColumn("x2"); QTest::addColumn("x3"); - int frameWidth = qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - int extent = qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent); - int inside = qApp->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents); + QPlastiqueStyle *style = new QPlastiqueStyle; + + int frameWidth = style->pixelMetric(QStyle::PM_DefaultFrameWidth); + int extent = style->pixelMetric(QStyle::PM_ScrollBarExtent); + int inside = style->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents); int viewportWidth = 300; int scrollBarIndent = viewportWidth - extent - (inside ? 4 : 2)*frameWidth; @@ -3096,6 +3098,7 @@ void tst_QGraphicsView::scrollAfterResize() QFETCH(QTransform, x3); QGraphicsView view; + view.setStyle(new QPlastiqueStyle); if (reverse) view.setLayoutDirection(Qt::RightToLeft); -- cgit v0.12 From 5af2150b1a8a2e8ca89c52c796da6112cac98231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 15 Sep 2009 15:11:01 +0200 Subject: Increased performance of blurpicker example with GL 2 engine. Slightly increase threshold for when to shrink an FBO, and reduce the number of calls to glBindFramebuffer. Reviewed-by: Tom --- src/opengl/qpixmapdata_gl.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index d5398a9..5eff237 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -98,7 +98,7 @@ QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5))); // wasting too much space? - if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 2.5) + if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4) sz = requestSize; if (sz != fboSize) { @@ -183,12 +183,11 @@ void QGLPixmapGLPaintDevice::endPaint() data->copyBackFromRenderFbo(false); - data->m_renderFbo->release(); - qgl_fbo_pool()->release(data->m_renderFbo); - data->m_renderFbo = 0; - // Base's endPaint will restore the previous FBO binding QGLPaintDevice::endPaint(); + + qgl_fbo_pool()->release(data->m_renderFbo); + data->m_renderFbo = 0; } QGLContext* QGLPixmapGLPaintDevice::context() const @@ -466,8 +465,8 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const if (!ctx->d_ptr->fbo) glGenFramebuffers(1, &ctx->d_ptr->fbo); - glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); - glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture.id, 0); const int x0 = 0; @@ -475,7 +474,8 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const const int y0 = 0; const int y1 = h; - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle()); + if (!m_renderFbo->isBound()) + glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle()); glDisable(GL_SCISSOR_TEST); -- cgit v0.12 From 9b42435b18ba7a593524bcd9fb0936e08a5a2462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 10 Sep 2009 18:31:39 +0200 Subject: I don't think this was intentional... Wonder how it survived for so long. Reviewed-by: Peter Hartmann --- src/corelib/tools/qhash.h | 1 - src/corelib/tools/qmap.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 06f6688..b65f1d3 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -52,7 +52,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -#undef QT_QHASH_DEBUG QT_MODULE(Core) class QBitArray; diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 18d1f5c..c1be49a 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -51,7 +51,6 @@ #endif #include -#undef QT_MAP_DEBUG QT_BEGIN_HEADER -- cgit v0.12 From 76311598fa9d7681316e590797bc402889dcb909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 15 Sep 2009 17:01:18 +0200 Subject: Increasing a timeout on QProcess tests Not a proper fix, but let's see if this increases reliability of the results. --- tests/auto/qprocess/tst_qprocess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index 0291f66..cff6487 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -1164,7 +1164,7 @@ void tst_QProcess::softExitInSlots() SoftExitProcess proc(i); proc.start(appName); proc.write("OLEBOLE", 8); // include the \0 - QTestEventLoop::instance().enterLoop(1); + QTestEventLoop::instance().enterLoop(10); QCOMPARE(proc.state(), QProcess::NotRunning); QVERIFY(proc.waitedForFinished); } -- cgit v0.12 From a17103fb41c8f53e29b4abe26a45b8ba2cd460a4 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 15 Sep 2009 17:17:07 +0200 Subject: Doc: Cleaned up the Designer main window and Embedded Linux pages. Reviewed-by: Trust Me --- doc/src/development/designer-manual.qdoc | 258 +++++++++++++-------- .../designer-adding-toolbar-action1.png | Bin 14911 -> 21640 bytes .../qtopiacore/qt-embedded-linux-architecture.sk | 5 +- doc/src/frameworks-technologies/gestures.qdoc | 36 +-- doc/src/getting-started/examples.qdoc | 53 +++-- doc/src/images/designer-action-editor.png | Bin 46233 -> 28378 bytes doc/src/images/designer-adding-menu-action.png | Bin 6168 -> 9962 bytes doc/src/images/designer-adding-toolbar-action.png | Bin 5644 -> 7428 bytes doc/src/images/qt-embedded-linux-architecture.png | Bin 22979 -> 23199 bytes 9 files changed, 223 insertions(+), 129 deletions(-) diff --git a/doc/src/development/designer-manual.qdoc b/doc/src/development/designer-manual.qdoc index ff05228..bdadcf7 100644 --- a/doc/src/development/designer-manual.qdoc +++ b/doc/src/development/designer-manual.qdoc @@ -1520,26 +1520,34 @@ \target CreatingAMenu - \table - \row - \i \inlineimage designer-creating-menu1.png - \i \inlineimage designer-creating-menu2.png - \i \bold{Creating a Menu} - - Double-click the placeholder item to begin editing. The menu text, - displayed using a line edit, can be modified. - - \row - \i \inlineimage designer-creating-menu3.png - \i \inlineimage designer-creating-menu4.png - \i Insert the required text for the new menu. Inserting an - ampersand character (&) causes the letter following it to be - used as a mnemonic for the menu. - - Press \key Return or \key Enter to accept the new text, or press - \key Escape to reject it. You can undo the editing operation later if - required. - \endtable + \raw HTML +
+ \endraw + \inlineimage designer-creating-menu1.png + \inlineimage designer-creating-menu2.png + \br + \inlineimage designer-creating-menu3.png + \inlineimage designer-creating-menu4.png + \raw HTML +
+ \endraw + + \section2 Creating a Menu + + Double-click the placeholder item to begin editing. The menu text, + displayed using a line edit, can be modified. + + Insert the required text for the new menu. Inserting an + ampersand character (&) causes the letter following it to be + used as a mnemonic for the menu. + + Press \key Return or \key Enter to accept the new text, or press + \key Escape to reject it. You can undo the editing operation later if + required. + + \raw HTML +
+ \endraw Menus can also be rearranged in the menu bar simply by dragging and dropping them in the preferred location. A vertical red line indicates the @@ -1550,31 +1558,40 @@ navigating the menu structure in the usual way. \target CreatingAMenuEntry + \raw HTML +
+ \endraw + \inlineimage designer-creating-menu-entry1.png + \inlineimage designer-creating-menu-entry2.png + \br + \inlineimage designer-creating-menu-entry3.png + \inlineimage designer-creating-menu-entry4.png + \raw HTML +
+ \endraw \table - \row - \i \inlineimage designer-creating-menu-entry1.png - \i \inlineimage designer-creating-menu-entry2.png - \i \bold{Creating a Menu Entry} - Double-click the \gui{new action} placeholder to begin editing, or - double-click \gui{new separator} to insert a new separator line after - the last entry in the menu. + \section2 Creating a Menu Entry - The menu entry's text is displayed using a line edit, and can be - modified. + Double-click the \gui{new action} placeholder to begin editing, or + double-click \gui{new separator} to insert a new separator line after + the last entry in the menu. - \row - \i \inlineimage designer-creating-menu-entry3.png - \i \inlineimage designer-creating-menu-entry4.png - \i Insert the required text for the new entry, optionally using - the ampersand character (&) to mark the letter to use as a - mnemonic for the entry. + The menu entry's text is displayed using a line edit, and can be + modified. - Press \key Return or \key Enter to accept the new text, or press - \key Escape to reject it. The action created for this menu entry will - be accessible via the \l{#TheActionEditor}{Action Editor}, and any - associated keyboard shortcut can be set there. - \endtable + Insert the required text for the new entry, optionally using + the ampersand character (&) to mark the letter to use as a + mnemonic for the entry. + + Press \key Return or \key Enter to accept the new text, or press + \key Escape to reject it. The action created for this menu entry will + be accessible via the \l{#TheActionEditor}{Action Editor}, and any + associated keyboard shortcut can be set there. + + \raw HTML +
+ \endraw Just like with menus, entries can be moved around simply by dragging and dropping them in the preferred location. When an entry is dragged over a @@ -1582,53 +1599,92 @@ menu entries are based on actions, they can also be dropped onto toolbars, where they will be displayed as toolbar buttons. - \section1 Toolbars + \raw HTML +
+ \endraw + \inlineimage designer-creating-toolbar.png + \raw HTML +
+ \endraw - ### SCREENSHOT + \section2 Creating and Removing a Toolbar - Toolbars ared added to a main window in a similar way to the menu bar: + Toolbars are added to a main window in a similar way to the menu bar: Select the \gui{Add Tool Bar} option from the form's context menu. Alternatively, if there is an existing toolbar in the main window, you can click the arrow on its right end to create a new toolbar. - Toolbar buttons are created using the action system to populate each - toolbar, rather than by using specific button widgets from the widget box. - Since actions can be represented by menu entries and toolbar buttons, they - can be moved between menus and toolbars. To share an action between a menu - and a toolbar, drag its icon from the \l{#TheActionEditor}{Action Editor} - to the toolbar rather than from the menu where its entry is located. + Toolbars are removed from the form via an entry in the toolbar's context + menu. + + \raw HTML +
+ \endraw - New actions for menus and toolbars can be created in the - \l{#TheActionEditor}{Action Editor}. + \section2 Adding and Removing Toolbar Buttons + Toolbar buttons are created as actions in the + \l{#TheActionEditor}{Action Editor} and dragged onto the toolbar. + Since actions can be represented by menu entries and toolbar buttons, + they can be moved between menus and toolbars. + + \target AddingAnAction + \raw HTML +
+ \endraw + \inlineimage designer-adding-toolbar-action.png + \inlineimage designer-removing-toolbar-action.png + \raw HTML +
+ \endraw + + To share an action between a menu and a toolbar, drag its icon from the + action editor to the toolbar rather than from the menu where its entry is + located. See \l{#Adding an Action}{Adding an Action} for more information + about this process. + + Toolbar buttons are removed via the toolbar's context menu. + + \raw HTML +
+ \endraw \section1 Actions With the menu bar and the toolbars in place, it's time to populate them - with action: \QD provides an action editor to simplify the creation and - management of actions. - + with actions. New actions for both menus and toolbars are created in the + action editor window, simplifying the creation and management of actions. \target TheActionEditor - \table - \row - \i \inlineimage designer-action-editor.png - \i \bold{The Action Editor} + \raw HTML +
+ \endraw + \inlineimage designer-action-editor.png + \raw HTML +
+ \endraw - Enable the action editor by opening the \gui Tools menu, and switching - on the \gui{Action Editor} option. + \section2 The Action Editor - The action editor allows you to create \gui New actions and \gui Delete - actions. It also provides a search function, \gui Filter, using the - action's text. + Enable the action editor by opening the \gui Tools menu, and switching + on the \gui{Action Editor} option. - \QD's action editor can be viewed in the classic \gui{Icon View} and - \gui{Detailed View}. The screenshot below shows the action editor in - \gui{Detailed View}. You can also copy and paste actions between menus, - toolbars and forms. - \endtable + The action editor allows you to create \gui New actions and \gui Delete + actions. It also provides a search function, \gui Filter, using the + action's text. + + \QD's action editor can be viewed in the classic \gui{Icon View} and + \gui{Detailed View}. The screenshot below shows the action editor in + \gui{Detailed View}. You can also copy and paste actions between menus, + toolbars and forms. + + \raw HTML +
+ \endraw + + \section2 Creating an Action To create an action, use the action editor's \gui New button, which will then pop up an input dialog. Provide the new action with a \gui Text -- @@ -1641,23 +1697,33 @@ Once the action is created, it can be used wherever actions are applicable. + \raw HTML +
+ \endraw \target AddingAnAction - \table - \row - \i \inlineimage designer-adding-menu-action.png - \i \inlineimage designer-adding-toolbar-action.png - \i \bold{Adding an Action} + \raw HTML +
+ \endraw + \inlineimage designer-adding-menu-action.png + \inlineimage designer-adding-toolbar-action.png + \raw HTML +
+ \endraw - To add an action to a menu or a toolbar, simply press the left mouse - button over the action in the action editor, and drag it to the - preferred location. + \section2 Adding an Action - \QD provides highlighted guide lines that tell you where the action - will be added. Release the mouse button to add the action when you have - found the right spot. - \endtable + To add an action to a menu or a toolbar, simply press the left mouse + button over the action in the action editor, and drag it to the + preferred location. + + \QD provides highlighted guide lines that tell you where the action + will be added. Release the mouse button to add the action when you have + found the right spot. + \raw HTML +
+ \endraw \section1 Dock Widgets @@ -1668,21 +1734,29 @@ and choose an appropriate value for its \gui{dockWidgetArea} property. \target AddingADockWidget - \table - \row - \i \inlineimage designer-adding-dockwidget.png - \i \bold{Adding a Dock Widget} - To add a dock widget, simply drag one from the \gui Containers section - of the widget box, and drop it onto the main form area. Just like other - widgets, its properties can be modified with the \gui{Property Editor}. + \raw HTML +
+ \endraw + \inlineimage designer-adding-dockwidget.png + \raw HTML +
+ \endraw - Dock widgets can be optionally floated as indpendent tool windows. - Hence, it is useful to give them window titles by setting their - \gui{windowTitle} property. This also helps to identify them on the - form. + \section2 Adding a Dock Widget - \endtable + To add a dock widget, simply drag one from the \gui Containers section + of the widget box, and drop it onto the main form area. Just like other + widgets, its properties can be modified with the \gui{Property Editor}. + + Dock widgets can be optionally floated as indpendent tool windows. + Hence, it is useful to give them window titles by setting their + \gui{windowTitle} property. This also helps to identify them on the + form. + + \raw HTML +
+ \endraw */ diff --git a/doc/src/diagrams/designer-manual/designer-adding-toolbar-action1.png b/doc/src/diagrams/designer-manual/designer-adding-toolbar-action1.png index 6b82373..4d28722 100644 Binary files a/doc/src/diagrams/designer-manual/designer-adding-toolbar-action1.png and b/doc/src/diagrams/designer-manual/designer-adding-toolbar-action1.png differ diff --git a/doc/src/diagrams/qtopiacore/qt-embedded-linux-architecture.sk b/doc/src/diagrams/qtopiacore/qt-embedded-linux-architecture.sk index ee60589..3c00b17 100644 --- a/doc/src/diagrams/qtopiacore/qt-embedded-linux-architecture.sk +++ b/doc/src/diagrams/qtopiacore/qt-embedded-linux-architecture.sk @@ -295,6 +295,9 @@ txt('Graphics',(222.876,42.6)) G_() fp((1,1,1)) Fn('Helvetica') -txt('Qt for Embedded Linux',(85.802,85.126)) +txt('Qt for Embedded Linux',(85.802,86.934)) +le() +lw(1) +r(280,0,0,-125,7.5,157.5) guidelayer('Guide Lines',1,0,0,1,(0,0,1)) grid((0,0,2.5,2.5),1,(0,0,1),'Grid') diff --git a/doc/src/frameworks-technologies/gestures.qdoc b/doc/src/frameworks-technologies/gestures.qdoc index a0eab21..b9b7771 100644 --- a/doc/src/frameworks-technologies/gestures.qdoc +++ b/doc/src/frameworks-technologies/gestures.qdoc @@ -63,16 +63,16 @@ QPanGesture, QPinchGesture, and QSwipeGesture. These standard classes are ready to use, and each exposes functions and properties that give gesture-specific information about the user's - input. This is described in the section \l{Using Standard Gestures - With Widgets}. + input. This is described in the \l{Using Standard Gestures With Widgets} + section. QGesture is also designed to be subclassed and extended so that support for new gestures can be implemented by developers. Adding support for a new gesture involves implementing code to recognize - the gesture from incoming events. This is described in the section - \l{Creating Your Own Gesture Recognizer}. + the gesture from incoming events. This is described in the + \l{Creating Your Own Gesture Recognizer} section. - \section1 Using Standard Gestures With Widgets + \section1 Using Standard Gestures with Widgets Gesture objects are applied directly to widgets and other controls that accept user input \mdash these are the \e{target objects}. When a gesture object is @@ -91,11 +91,10 @@ \snippet examples/gestures/imageviewer/imagewidget.cpp connect swipe gesture - Here, the \l{QGesture::} {triggered()} signal is used to inform - the application that a gesture was used. More precise monitoring - of a gesture can be implemented by connecting its \l{QGesture::} - {started()}, \l{QGesture::} {canceled()} and \l{QGesture::} - {finished()} signals to slots. + Here, the \l{QGesture::}{triggered()} signal is used to inform the application + that a gesture was used. More precise monitoring of a gesture can be implemented + by connecting its \l{QGesture::}{started()}, \l{QGesture::}{canceled()} and + \l{QGesture::}{finished()} signals to slots. Responding to a signal is simply a matter of obtaining the gesture that sent it and examining the information it contains. @@ -132,9 +131,18 @@ likely scenario. To find how to connect a source of events to automatically feed into the recognizer see the QGesture documentation. - Recognizers based on QGesture can emit any of the following signals: + Recognizers based on QGesture can emit any of the following signals to + indicate their progress in recognizing user input: - \snippet doc/src/snippets/gestures/qgesture.h qgesture-signals + \list + \o \l{QGesture::}{triggered()} is emitted when a gesture is recognized. + \o \l{QGesture::}{started()} indicates that the gesture object has started + to recognize user input. + \o \l{QGesture::}{finished()} is emitted when the gesture object has + recognized the user input as a gesture, and finished handling it. + \o \l{QGesture::}{canceled()} indicates that the gesture was canceled, + either by the user or by the application. + \endlist These signals are emitted when the state changes with the call to \l{QGesture::}{updateState()}, more than one signal may @@ -224,8 +232,4 @@ \o The signals are caught by the defined slots in ImageWidget \o The widget logic changes and an update() results in a paint event. \endlist - - - */ - diff --git a/doc/src/getting-started/examples.qdoc b/doc/src/getting-started/examples.qdoc index 81a8363..1ed1b30 100644 --- a/doc/src/getting-started/examples.qdoc +++ b/doc/src/getting-started/examples.qdoc @@ -1051,7 +1051,7 @@ \previouspage State Machine Examples \contentspage Qt Examples - \nextpage Qt for Embedded Linux Examples + \nextpage Gestures Examples \image animation-examples.png Animation @@ -1066,10 +1066,40 @@ */ /*! + \page examples-gestures.html + \title Gestures Examples + + \previouspage Animation Framework Examples + \contentspage Qt Examples + \nextpage D-Bus Examples + + \list + \o \l{gestures/imageviewer}{Image Viewer} + \endlist +*/ + +/*! + \page examples-dbus.html + \title D-Bus Examples + + \previouspage Gestures Examples + \contentspage Qt Examples + \nextpage Qt for Embedded Linux Examples + + \list + \o \l{dbus/dbus-chat}{Chat} + \o \l{dbus/complexpingpong}{Complex Ping Pong} + \o \l{dbus/listnames}{List Names} + \o \l{dbus/pingpong}{Ping Pong} + \o \l{dbus/remotecontrolledcar}{Remote Controlled Car} + \endlist +*/ + +/*! \page examples-embeddedlinux.html \title Qt for Embedded Linux Examples - \previouspage Animation Framework Examples + \previouspage D-Bus Examples \contentspage Qt Examples \nextpage ActiveQt Examples @@ -1094,7 +1124,7 @@ \previouspage Qt for Embedded Linux Examples \contentspage Qt Examples - \nextpage D-Bus Examples + \nextpage Qt Quarterly \image activeqt-examples.png ActiveQt @@ -1111,20 +1141,3 @@ \o \l{activeqt/wrapper}{Wrapper}\raisedaster \endlist */ - -/*! - \page examples-dbus.html - \title D-Bus Examples - - \previouspage ActiveQt Examples - \contentspage Qt Examples - \nextpage Qt Quarterly - - \list - \o \l{dbus/dbus-chat}{Chat} - \o \l{dbus/complexpingpong}{Complex Ping Pong} - \o \l{dbus/listnames}{List Names} - \o \l{dbus/pingpong}{Ping Pong} - \o \l{dbus/remotecontrolledcar}{Remote Controlled Car} - \endlist -*/ diff --git a/doc/src/images/designer-action-editor.png b/doc/src/images/designer-action-editor.png index 7d17573..1e99706 100644 Binary files a/doc/src/images/designer-action-editor.png and b/doc/src/images/designer-action-editor.png differ diff --git a/doc/src/images/designer-adding-menu-action.png b/doc/src/images/designer-adding-menu-action.png index cf2a9c9..595dd8e 100644 Binary files a/doc/src/images/designer-adding-menu-action.png and b/doc/src/images/designer-adding-menu-action.png differ diff --git a/doc/src/images/designer-adding-toolbar-action.png b/doc/src/images/designer-adding-toolbar-action.png index e2201cb..404ad0d 100644 Binary files a/doc/src/images/designer-adding-toolbar-action.png and b/doc/src/images/designer-adding-toolbar-action.png differ diff --git a/doc/src/images/qt-embedded-linux-architecture.png b/doc/src/images/qt-embedded-linux-architecture.png index abf5bd8..b5e3b6c 100644 Binary files a/doc/src/images/qt-embedded-linux-architecture.png and b/doc/src/images/qt-embedded-linux-architecture.png differ -- cgit v0.12 From 74d5999800d16e73b67e9b747fb22cec3366c548 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 15 Sep 2009 17:21:24 +0200 Subject: Doc: Created a new Drawing Utility Functions page. Reviewed-by: Trust Me Inspired-by: Olivier Goffart's earlier change Pain-by: Git --- src/gui/painting/qdrawutil.cpp | 35 ++++++++++++++++++++--------------- src/gui/painting/qpainter.cpp | 3 ++- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp index 7be8e04..c4a9373 100644 --- a/src/gui/painting/qdrawutil.cpp +++ b/src/gui/painting/qdrawutil.cpp @@ -49,10 +49,17 @@ QT_BEGIN_NAMESPACE /*! + \headerfile + \title Drawing Utility Functions + + \sa QPainter +*/ + +/*! \fn void qDrawShadeLine(QPainter *painter, int x1, int y1, int x2, int y2, const QPalette &palette, bool sunken, int lineWidth, int midLineWidth) - \relates QPainter + \relates Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2) shaded line using the given \a painter. Note that nothing is @@ -166,7 +173,7 @@ void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2, const QPalette &palette, bool sunken, int lineWidth, int midLineWidth, const QBrush *fill) - \relates QPainter + \relates Draws the shaded rectangle beginning at (\a x, \a y) with the given \a width and \a height using the provided \a painter. @@ -270,7 +277,7 @@ void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, \fn void qDrawShadePanel(QPainter *painter, int x, int y, int width, int height, const QPalette &palette, bool sunken, int lineWidth, const QBrush *fill) - \relates QPainter + \relates Draws the shaded panel beginning at (\a x, \a y) with the given \a width and \a height using the provided \a painter and the given \a @@ -406,7 +413,7 @@ static void qDrawWinShades(QPainter *p, \fn void qDrawWinButton(QPainter *painter, int x, int y, int width, int height, const QPalette &palette, bool sunken, const QBrush *fill) - \relates QPainter + \relates Draws the Windows-style button specified by the given point (\a x, \a y}, \a width and \a height using the provided \a painter with a @@ -444,7 +451,7 @@ void qDrawWinButton(QPainter *p, int x, int y, int w, int h, \fn void qDrawWinPanel(QPainter *painter, int x, int y, int width, int height, const QPalette &palette, bool sunken, const QBrush *fill) - \relates QPainter + \relates Draws the Windows-style panel specified by the given point(\a x, \a y), \a width and \a height using the provided \a painter with a @@ -483,7 +490,7 @@ void qDrawWinPanel(QPainter *p, int x, int y, int w, int h, /*! \fn void qDrawPlainRect(QPainter *painter, int x, int y, int width, int height, const QColor &lineColor, int lineWidth, const QBrush *fill) - \relates QPainter + \relates Draws the plain rectangle beginning at (\a x, \a y) with the given \a width and \a height, using the specified \a painter, \a lineColor @@ -532,7 +539,7 @@ void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c, /*! \fn void qDrawShadeLine(QPainter *painter, const QPoint &p1, const QPoint &p2, const QPalette &palette, bool sunken, int lineWidth, int midLineWidth) - \relates QPainter + \relates \overload Draws a horizontal or vertical shaded line between \a p1 and \a p2 @@ -572,7 +579,7 @@ void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2, /*! \fn void qDrawShadeRect(QPainter *painter, const QRect &rect, const QPalette &palette, bool sunken, int lineWidth, int midLineWidth, const QBrush *fill) - \relates QPainter + \relates \overload Draws the shaded rectangle specified by \a rect using the given \a painter. @@ -612,7 +619,7 @@ void qDrawShadeRect(QPainter *p, const QRect &r, /*! \fn void qDrawShadePanel(QPainter *painter, const QRect &rect, const QPalette &palette, bool sunken, int lineWidth, const QBrush *fill) - \relates QPainter + \relates \overload Draws the shaded panel at the rectangle specified by \a rect using the @@ -648,7 +655,7 @@ void qDrawShadePanel(QPainter *p, const QRect &r, /*! \fn void qDrawWinButton(QPainter *painter, const QRect &rect, const QPalette &palette, bool sunken, const QBrush *fill) - \relates QPainter + \relates \overload Draws the Windows-style button at the rectangle specified by \a rect using @@ -706,7 +713,7 @@ void qDrawWinPanel(QPainter *p, const QRect &r, /*! \fn void qDrawPlainRect(QPainter *painter, const QRect &rect, const QColor &lineColor, int lineWidth, const QBrush *fill) - \relates QPainter + \relates \overload Draws the plain rectangle specified by \a rect using the given \a painter, @@ -1044,7 +1051,7 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs, Holds the rules used to draw a pixmap or image split into nine segments, similar to \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}. - \sa Qt::TileRule, QMargins, qDrawBorderPixmap + \sa Qt::TileRule, QMargins */ /*! \fn QTileRules::QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule) @@ -1060,7 +1067,7 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs, /*! \fn void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap) \since 4.6 - \relates QPainter + \relates Draws the given \a pixmap into the given \a target rectangle, using the given \a painter. The pixmap will be split into nine segments and drawn @@ -1156,8 +1163,6 @@ static inline void qDrawHorizontallyRoundedPixmap(QPainter *painter, const QRect /*! \since 4.6 - \relates QPainter - Draws the indicated \a sourceRect rectangle from the given \a pixmap into the given \a targetRect rectangle, using the given \a painter. The pixmap will be split into nine segments according to the given \a targetMargins diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index beda9d6..b3aef71 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1317,7 +1317,8 @@ void QPainterPrivate::updateState(QPainterState *newState) Another workaround is to convert the paths to polygons first and then draw the polygons instead. - \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example} + \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example}, + {Drawing Utility Functions} */ /*! -- cgit v0.12 From f5b1f78ca9353eff60a87c50eb6c720e810e59bb Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 15 Sep 2009 17:49:37 +0200 Subject: Doc: Added missing files for the Designer manual. Reviewed-by: Trust Me Overcomplicated-workflow-by: Git --- doc/src/diagrams/designer-adding-actions.txt | 15 --------------- doc/src/diagrams/designer-adding-dynamic-property.png | Bin 9568 -> 0 bytes .../designer-manual/designer-adding-actions.txt | 15 +++++++++++++++ .../designer-adding-dynamic-property.png | Bin 0 -> 9568 bytes doc/src/images/designer-creating-toolbar.png | Bin 0 -> 18194 bytes doc/src/images/designer-removing-toolbar-action.png | Bin 0 -> 15500 bytes doc/src/images/designer-removing-toolbar.png | Bin 0 -> 13074 bytes 7 files changed, 15 insertions(+), 15 deletions(-) delete mode 100644 doc/src/diagrams/designer-adding-actions.txt delete mode 100644 doc/src/diagrams/designer-adding-dynamic-property.png create mode 100644 doc/src/diagrams/designer-manual/designer-adding-actions.txt create mode 100644 doc/src/diagrams/designer-manual/designer-adding-dynamic-property.png create mode 100644 doc/src/images/designer-creating-toolbar.png create mode 100644 doc/src/images/designer-removing-toolbar-action.png create mode 100644 doc/src/images/designer-removing-toolbar.png diff --git a/doc/src/diagrams/designer-adding-actions.txt b/doc/src/diagrams/designer-adding-actions.txt deleted file mode 100644 index 4124ecc..0000000 --- a/doc/src/diagrams/designer-adding-actions.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Cropping and fading the Qt Designer action images. - -cropimage.py designer-adding-menu-action1.png designer-adding-menu-action1-crop.png left 57 -cropimage.py designer-adding-menu-action1-crop.png designer-adding-menu-action1-crop.png top 41 -cropimage.py designer-adding-menu-action1-crop.png designer-adding-menu-action1-crop.png right -180 -cropimage.py designer-adding-menu-action1-crop.png designer-adding-menu-action1-crop.png bottom -124 -fadeedges.py designer-adding-menu-action1-crop.png ../images/designer-adding-menu-action.png right,bottom 16 -rm designer-adding-menu-action1-crop.png - -cropimage.py designer-adding-toolbar-action1.png designer-adding-toolbar-action1-crop.png left 57 -cropimage.py designer-adding-toolbar-action1-crop.png designer-adding-toolbar-action1-crop.png top 41 -cropimage.py designer-adding-toolbar-action1-crop.png designer-adding-toolbar-action1-crop.png right -144 -cropimage.py designer-adding-toolbar-action1-crop.png designer-adding-toolbar-action1-crop.png bottom -124 -fadeedges.py designer-adding-toolbar-action1-crop.png ../images/designer-adding-toolbar-action.png right,bottom 16 -rm designer-adding-toolbar-action1-crop.png diff --git a/doc/src/diagrams/designer-adding-dynamic-property.png b/doc/src/diagrams/designer-adding-dynamic-property.png deleted file mode 100644 index 8e81dd9..0000000 Binary files a/doc/src/diagrams/designer-adding-dynamic-property.png and /dev/null differ diff --git a/doc/src/diagrams/designer-manual/designer-adding-actions.txt b/doc/src/diagrams/designer-manual/designer-adding-actions.txt new file mode 100644 index 0000000..4124ecc --- /dev/null +++ b/doc/src/diagrams/designer-manual/designer-adding-actions.txt @@ -0,0 +1,15 @@ +# Cropping and fading the Qt Designer action images. + +cropimage.py designer-adding-menu-action1.png designer-adding-menu-action1-crop.png left 57 +cropimage.py designer-adding-menu-action1-crop.png designer-adding-menu-action1-crop.png top 41 +cropimage.py designer-adding-menu-action1-crop.png designer-adding-menu-action1-crop.png right -180 +cropimage.py designer-adding-menu-action1-crop.png designer-adding-menu-action1-crop.png bottom -124 +fadeedges.py designer-adding-menu-action1-crop.png ../images/designer-adding-menu-action.png right,bottom 16 +rm designer-adding-menu-action1-crop.png + +cropimage.py designer-adding-toolbar-action1.png designer-adding-toolbar-action1-crop.png left 57 +cropimage.py designer-adding-toolbar-action1-crop.png designer-adding-toolbar-action1-crop.png top 41 +cropimage.py designer-adding-toolbar-action1-crop.png designer-adding-toolbar-action1-crop.png right -144 +cropimage.py designer-adding-toolbar-action1-crop.png designer-adding-toolbar-action1-crop.png bottom -124 +fadeedges.py designer-adding-toolbar-action1-crop.png ../images/designer-adding-toolbar-action.png right,bottom 16 +rm designer-adding-toolbar-action1-crop.png diff --git a/doc/src/diagrams/designer-manual/designer-adding-dynamic-property.png b/doc/src/diagrams/designer-manual/designer-adding-dynamic-property.png new file mode 100644 index 0000000..8e81dd9 Binary files /dev/null and b/doc/src/diagrams/designer-manual/designer-adding-dynamic-property.png differ diff --git a/doc/src/images/designer-creating-toolbar.png b/doc/src/images/designer-creating-toolbar.png new file mode 100644 index 0000000..32a949a Binary files /dev/null and b/doc/src/images/designer-creating-toolbar.png differ diff --git a/doc/src/images/designer-removing-toolbar-action.png b/doc/src/images/designer-removing-toolbar-action.png new file mode 100644 index 0000000..12c68a1 Binary files /dev/null and b/doc/src/images/designer-removing-toolbar-action.png differ diff --git a/doc/src/images/designer-removing-toolbar.png b/doc/src/images/designer-removing-toolbar.png new file mode 100644 index 0000000..a65b170 Binary files /dev/null and b/doc/src/images/designer-removing-toolbar.png differ -- cgit v0.12 From fec8f32f86fe60a4012c67b1b5b110dc3f816c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 15 Sep 2009 18:04:55 +0200 Subject: Fix macplist autotest This goes to show that once a test is running no one will look at the results... --- tests/auto/macplist/tst_macplist.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auto/macplist/tst_macplist.cpp b/tests/auto/macplist/tst_macplist.cpp index 7a2b1d8..aa52b95 100644 --- a/tests/auto/macplist/tst_macplist.cpp +++ b/tests/auto/macplist/tst_macplist.cpp @@ -171,7 +171,6 @@ void tst_MacPlist::test_plist() QVERIFY(dir.cdUp()); QVERIFY(dir.cdUp()); QVERIFY(dir.cdUp()); - QVERIFY(dir.cdUp()); QVERIFY(dir.cd(QLatin1String("app"))); QVERIFY(dir.cd(QLatin1String("app.app"))); QVERIFY(dir.cd(QLatin1String("Contents"))); -- cgit v0.12 From e727dafd5e1f28901176e42008ebc0a334d052e6 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 15 Sep 2009 18:41:51 +0200 Subject: Slightly better code for the test. Then the test doesn't leak. Reviewed-by:ogoffart --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 3bed9ce..5cb9173 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -3072,11 +3072,11 @@ void tst_QGraphicsView::scrollAfterResize_data() QTest::addColumn("x2"); QTest::addColumn("x3"); - QPlastiqueStyle *style = new QPlastiqueStyle; + QPlastiqueStyle style; - int frameWidth = style->pixelMetric(QStyle::PM_DefaultFrameWidth); - int extent = style->pixelMetric(QStyle::PM_ScrollBarExtent); - int inside = style->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents); + int frameWidth = style.pixelMetric(QStyle::PM_DefaultFrameWidth); + int extent = style.pixelMetric(QStyle::PM_ScrollBarExtent); + int inside = style.styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents); int viewportWidth = 300; int scrollBarIndent = viewportWidth - extent - (inside ? 4 : 2)*frameWidth; @@ -3097,8 +3097,9 @@ void tst_QGraphicsView::scrollAfterResize() QFETCH(QTransform, x2); QFETCH(QTransform, x3); + QPlastiqueStyle style; QGraphicsView view; - view.setStyle(new QPlastiqueStyle); + view.setStyle(&style); if (reverse) view.setLayoutDirection(Qt::RightToLeft); -- cgit v0.12 From a9086411e13a247c30992c4f6ab85620bffba895 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 15 Sep 2009 17:48:12 +0200 Subject: Stabilize tst_QComboBox::task260974_menuItemRectangleForComboBoxPopup --- tests/auto/qcombobox/tst_qcombobox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index 810be04..da97c7d 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -2371,7 +2371,7 @@ void tst_QComboBox::task260974_menuItemRectangleForComboBoxPopup() comboBox.showPopup(); QTest::qWait(100); - QVERIFY(style.discoveredRect.width() <= comboBox.width()); + QTRY_VERIFY(style.discoveredRect.width() <= comboBox.width()); } } -- cgit v0.12 From d58494bf7b136c2c41f0fd219038c316f954f76f Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 14 Sep 2009 11:23:09 -0700 Subject: Fix a bug in surfaceForWidget I had the logic of the assert wrong with the isAncestorOf call. Reviewed-by: Donald Carr --- src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index ff9f7bd..ccbaf21 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -411,7 +411,8 @@ IDirectFBSurface *QDirectFBWindowSurface::surfaceForWidget(const QWidget *widget *rect = QRect(widget->mapTo(win, QPoint(0, 0)), widget->size()); } } - Q_ASSERT(win == widget || widget->isAncestorOf(win)); + + Q_ASSERT(win == widget || win->isAncestorOf(widget)); return dfbSurface; } -- cgit v0.12 From 6b359f3bc3b87a7e5e2b971712ec8a4b8afccdc9 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 14 Sep 2009 11:02:11 -0700 Subject: Export two functions for getting a surface in dfb When building DirectFB as part of QtGui and not as a plugin this patch will export two global functions for getting a surface given a widget. Reviewed-by: Donald Carr --- src/plugins/gfxdrivers/directfb/directfb.pro | 2 +- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro index d397050..0706f01 100644 --- a/src/plugins/gfxdrivers/directfb/directfb.pro +++ b/src/plugins/gfxdrivers/directfb/directfb.pro @@ -11,5 +11,5 @@ SOURCES += qdirectfbscreenplugin.cpp QMAKE_CXXFLAGS += $$QT_CFLAGS_DIRECTFB LIBS += $$QT_LIBS_DIRECTFB -DEFINES += $$QT_DEFINES_DIRECTFB +DEFINES += $$QT_DEFINES_DIRECTFB QT_DIRECTFB_PLUGIN contains(gfx-plugins, directfb):DEFINES += QT_QWS_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 4413858..79a401c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1687,6 +1687,19 @@ IDirectFBSurface *QDirectFBScreen::subSurfaceForWidget(const QWidget *widget, co } #endif +#ifndef QT_DIRECTFB_PLUGIN +Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_widget(const QWidget *widget, QRect *rect) +{ + return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->surfaceForWidget(widget, rect) : 0; +} +#ifdef QT_DIRECTFB_SUBSURFACE +Q_GUI_EXPORT IDirectFBSurface *qt_directfb_subsurface_for_widget(const QWidget *widget, const QRect &area) +{ + return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->subSurfaceForWidget(widget, area) : 0; +} +#endif +#endif + QT_END_NAMESPACE #include "qdirectfbscreen.moc" -- cgit v0.12 From d67d287c0fdff332cda673a18e0bb1617c3d2e17 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 15 Sep 2009 11:28:07 -0700 Subject: Export a function for getting a IDirectFBWindow This function is only exported when DirectFB is built into QtGui. Reviewed-by: Donald Carr --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 20 ++++++++++++++++++++ src/plugins/gfxdrivers/directfb/qdirectfbscreen.h | 5 +++-- .../gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 12 ++++++++---- .../gfxdrivers/directfb/qdirectfbwindowsurface.h | 3 +++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 79a401c..0f7a6de 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1652,6 +1652,19 @@ void QDirectFBScreen::waitIdle() d_ptr->dfb->WaitIdle(d_ptr->dfb); } +#ifdef QT_DIRECTFB_WM +IDirectFBWindow *QDirectFBScreen::windowForWidget(const QWidget *widget) const +{ + if (widget) { + const QWSWindowSurface *surface = static_cast(widget->windowSurface()); + if (surface && surface->key() == QLatin1String("directfb")) { + return static_cast(surface)->directFBWindow(); + } + } + return 0; +} +#endif + IDirectFBSurface * QDirectFBScreen::surfaceForWidget(const QWidget *widget, QRect *rect) const { Q_ASSERT(widget); @@ -1698,6 +1711,13 @@ Q_GUI_EXPORT IDirectFBSurface *qt_directfb_subsurface_for_widget(const QWidget * return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->subSurfaceForWidget(widget, area) : 0; } #endif +#ifdef QT_DIRECTFB_WM +Q_GUI_EXPORT IDirectFBWindow *qt_directfb_window_for_widget(const QWidget *widget) +{ + return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->windowForWidget(widget) : 0; +} + +#endif #endif QT_END_NAMESPACE diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index 79a01d3..febb2b2 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -174,9 +174,10 @@ public: #ifdef QT_DIRECTFB_SUBSURFACE IDirectFBSurface *subSurfaceForWidget(const QWidget *widget, const QRect &area = QRect()) const; #endif - IDirectFB *dfb(); -#ifdef QT_NO_DIRECTFB_WM +#ifdef QT_DIRECTFB_WM + IDirectFBWindow *windowForWidget(const QWidget *widget) const; +#else IDirectFBSurface *primarySurface(); #endif #ifndef QT_NO_DIRECTFB_LAYER diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index ccbaf21..4cebc96 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -113,13 +113,17 @@ bool QDirectFBWindowSurface::isValid() const #ifdef QT_DIRECTFB_WM void QDirectFBWindowSurface::raise() { - if (dfbWindow) { - dfbWindow->RaiseToTop(dfbWindow); - } else if (sibling && (!sibling->sibling || sibling->dfbWindow)) { - sibling->raise(); + if (IDirectFBWindow *window = directFBWindow()) { + window->RaiseToTop(window); } } +IDirectFBWindow *QDirectFBWindowSurface::directFBWindow() const +{ + return (dfbWindow ? dfbWindow : (sibling ? sibling->dfbWindow : 0)); +} + + void QDirectFBWindowSurface::createWindow(const QRect &rect) { IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h index 036830a..0dd3a3b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -93,6 +93,9 @@ public: IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const; IDirectFBSurface *directFBSurface() const; +#ifdef QT_DIRECTFB_WM + IDirectFBWindow *directFBWindow() const; +#endif private: void updateFormat(); void releaseSurface(); -- cgit v0.12 From 115dc0d8337049b54dd9e7527cb68ace841e6df3 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 16 Sep 2009 08:31:47 +1000 Subject: Compilation fix for OpenGL/ES 2.0 Matrix functions do not exist under OpenGL/ES 2.0. Reviewed-by: trustme --- src/opengl/qpixmapdata_gl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 5eff237..4351c0b 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -162,12 +162,14 @@ void QGLPixmapGLPaintDevice::beginPaint() glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); +#if !defined(QT_OPENGL_ES_2) glMatrixMode(GL_MODELVIEW_MATRIX); glLoadIdentity(); glMatrixMode(GL_PROJECTION_MATRIX); glLoadIdentity(); glOrtho(0, data->width(), data->height(), 0, -999999, 999999); +#endif glViewport(0, 0, data->width(), data->height()); -- cgit v0.12 From 669afa2337ad5791502fe3af2e3de648cb60ea9b Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 16 Sep 2009 08:40:46 +1000 Subject: Fix glMatrixMode() arguments for desktop OpenGL The defines are GL_MODELVIEW/GL_PROJECTION, not GL_MODELVIEW_MATRIX/etc. The _MATRIX defines are for fetching the matrix, not setting it. Reviewed-by: trustme --- src/opengl/qpixmapdata_gl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 4351c0b..3bc0d4f 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -163,10 +163,10 @@ void QGLPixmapGLPaintDevice::beginPaint() glDisable(GL_BLEND); #if !defined(QT_OPENGL_ES_2) - glMatrixMode(GL_MODELVIEW_MATRIX); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glMatrixMode(GL_PROJECTION_MATRIX); + glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, data->width(), data->height(), 0, -999999, 999999); #endif -- cgit v0.12