diff --git a/config.tests/unix/iconv/iconv.pro b/config.tests/unix/iconv/iconv.pro index 876c6f3589e..39375a57146 100644 --- a/config.tests/unix/iconv/iconv.pro +++ b/config.tests/unix/iconv/iconv.pro @@ -1,3 +1,3 @@ SOURCES = iconv.cpp CONFIG -= qt dylib app_bundle -mac|win32-g++*|qnx-*-qcc:LIBS += -liconv +mac|win32-g++*|qnx:LIBS += -liconv diff --git a/configure b/configure index 0009a22e042..7ef52e5af28 100755 --- a/configure +++ b/configure @@ -263,8 +263,6 @@ fi # window system detection #------------------------------------------------------------------------------- -PLATFORM_X11=no -PLATFORM_QPA=yes BUILD_ON_MAC=no PLATFORM_MAC=no if [ -d /System/Library/Frameworks/Carbon.framework ]; then @@ -335,16 +333,6 @@ earlyArgParse() VAR=`echo $1 | sed "s,^--no-\(.*\),\1,"` VAL=no ;; - -embedded-lite|-qpa) - VAR=qpa - # this option may or may not be followed by an argument - if [ -z "$2" ] || echo "$2" | grep '^-' >/dev/null 2>&1; then - VAL=auto - else - shift; - VAL=$1 - fi - ;; -h|help|--help|-help) if [ "$VAL" = "yes" ]; then OPT_HELP="$VAL" @@ -374,16 +362,6 @@ earlyArgParse() UNKNOWN_OPT=no case "$VAR" in - qpa) - if [ "$PLATFORM_QPA" != "no" ]; then - if [ "$PLATFORM_QPA" = "maybe" ]; then - PLATFORM_X11=no - PLATFORM_QPA=yes - fi - else - echo "No license exists to enable Qt QPA. Disabling." - fi - ;; developer-build) CFG_DEV="yes" ;; @@ -431,7 +409,6 @@ if [ -f "$relpath"/LICENSE.PREVIEW.COMMERCIAL ] && [ $COMMERCIAL_USER = "yes" ]; elif [ $COMMERCIAL_USER = "yes" ]; then # one of commercial editions [ "$PLATFORM_MAC" = "maybe" ] && PLATFORM_MAC=yes - [ "$PLATFORM_QPA" = "maybe" ] && PLATFORM_QPA=no # read in the license file if [ -f "$LICENSE_FILE" ]; then @@ -524,7 +501,7 @@ elif [ $COMMERCIAL_USER = "yes" ]; then ;; esac ### EMBEDDED_QPA logic missing ### - case "$PlatformCode,$PLATFORM_MAC,$PLATFORM_QWS" in + case "$PlatformCode,$PLATFORM_MAC" in X9,* | XC,* | XU,* | XW,* | XM,*) # Qt All-OS LICENSE_EXTENSION="-ALLOS" @@ -533,11 +510,11 @@ elif [ $COMMERCIAL_USER = "yes" ]; then # Qt for Embedded Linux LICENSE_EXTENSION="-EMBEDDED" ;; - 6M,*,no | N7,*,no | N9,*,no | NX,*,no) + 6M,* | N7,* | N9,* | NX,*) # Embedded no-deploy LICENSE_EXTENSION="-EMBEDDED" ;; - FM,*,no | LM,yes,* | ZM,no,no) + FM,* | LM,yes | ZM,no) # Desktop LICENSE_EXTENSION="-DESKTOP" ;; @@ -703,13 +680,13 @@ CFG_SSE=auto CFG_FONTCONFIG=auto CFG_LIBFREETYPE=auto CFG_SQL_AVAILABLE= -QT_DEFAULT_BUILD_PARTS="libs examples tests" +QT_DEFAULT_BUILD_PARTS="libs examples" CFG_BUILD_PARTS="" CFG_NOBUILD_PARTS="" CFG_RELEASE_QMAKE=no CFG_AUDIO_BACKEND=auto CFG_V8SNAPSHOT=auto -CFG_DECLARATIVE_DEBUG=yes +CFG_QML_DEBUG=yes CFG_JAVASCRIPTCORE_JIT=auto # Target architecture @@ -910,17 +887,12 @@ while [ "$#" -gt 0 ]; do VAL=no ;; #Qt style yes options - -profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-xinput2|-egl|-reduce-exports|-pch|-separate-debug-info|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-xcb|-eglfs|-nis|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-debug-and-release|-exceptions|-harfbuzz|-prefix-install|-silent|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-phonon-backend|-audio-backend|-declarative-debug|-javascript-jit|-rpath|-force-pkg-config|-icu|-force-asserts|-testcocoon) + -profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-xinput2|-egl|-reduce-exports|-pch|-separate-debug-info|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-xcb|-eglfs|-nis|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-debug-and-release|-exceptions|-harfbuzz|-prefix-install|-silent|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-phonon-backend|-audio-backend|-qml-debug|-javascript-jit|-rpath|-force-pkg-config|-icu|-force-asserts|-testcocoon) VAR=`echo $1 | sed "s,^-\(.*\),\1,"` VAL=yes ;; #Qt style options that pass an argument -qconfig) - if [ "$PLATFORM_QPA" != "yes" ]; then - echo - echo "WARNING: -qconfig is only tested and supported on Qt for Embedded Linux." - echo - fi CFG_QCONFIG="$VAL" VAR=`echo $1 | sed "s,^-\(.*\),\1,"` shift @@ -946,16 +918,6 @@ while [ "$#" -gt 0 ]; do VAR=fatal_error VAL=no ;; - -embedded-lite|-qpa) - VAR=qpa - # this option may or may not be followed by an argument - if [ -z "$2" ] || echo "$2" | grep '^-' >/dev/null 2>&1; then - VAL=auto - else - shift; - VAL=$1 - fi - ;; -opengl) VAR=opengl # this option may or may not be followed by an argument @@ -1166,10 +1128,6 @@ while [ "$#" -gt 0 ]; do sxe) CFG_SXE="$VAL" ;; - embedded-lite|qpa) - PLATFORM_X11=no - PLATFORM_QPA=yes - ;; sse) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_SSE="$VAL" @@ -1199,11 +1157,6 @@ while [ "$#" -gt 0 ]; do make) CFG_BUILD_PARTS="$CFG_BUILD_PARTS $VAL" ;; - x11) - PLATFORM_QPA=no - PLATFORM_MAC=no - PLATFORM_X11=yes - ;; sdk) if [ "$BUILD_ON_MAC" = "yes" ]; then CFG_SDK="$VAL" @@ -1786,12 +1739,12 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; - declarative-debug) + qml-debug) if [ "$VAL" = "yes" ]; then - CFG_DECLARATIVE_DEBUG="yes" + CFG_QML_DEBUG="yes" else if [ "$VAL" = "no" ]; then - CFG_DECLARATIVE_DEBUG="no" + CFG_QML_DEBUG="no" else UNKNOWN_OPT=yes fi @@ -2074,9 +2027,9 @@ if [ "$OPT_SHADOW" = "yes" ]; then [ "$OPT_VERBOSE" = "yes" ] && echo "Performing shadow build..." fi -if [ "$PLATFORM_X11" = "yes" -o "$PLATFORM_QPA" = "yes" ] && [ "$CFG_DEBUG_RELEASE" = "yes" ]; then +if [ "$PLATFORM_MAC" = "no" -a "$CFG_DEBUG_RELEASE" = "yes" ]; then echo - echo "WARNING: -debug-and-release is not supported anymore on Qt/X11 and Qt for Embedded Linux" + echo "WARNING: -debug-and-release is not supported outside of Mac OS X." echo "Qt can be built in release mode with separate debug information, so" echo "-debug-and-release is not necessary anymore" echo @@ -2120,6 +2073,10 @@ if [ "$OPT_SHADOW" = "yes" ]; then fi done + # save a pre-existing mkspecs/modules dir + test -d "$outpath/mkspecs/modules" && \ + mv "$outpath/mkspecs/modules" "$outpath/mkspecs-modules" + # symlink the mkspecs directory mkdir -p "$outpath/mkspecs" rm -rf "$outpath"/mkspecs/* @@ -2139,7 +2096,12 @@ if [ "$OPT_SHADOW" = "yes" ]; then ShadowMkspecs features # The modules dir is special, too. - ShadowMkspecs modules + if test -d "$outpath/mkspecs-modules"; then + rm -rf "$outpath/mkspecs/modules" + mv "$outpath/mkspecs-modules" "$outpath/mkspecs/modules" + else + ShadowMkspecs modules + fi # symlink the doc directory rm -rf "$outpath/doc" @@ -2147,7 +2109,7 @@ if [ "$OPT_SHADOW" = "yes" ]; then fi # symlink fonts to be able to run application from build directory -if [ "$PLATFORM_QPA" = "yes" ] && [ ! -d "${outpath}/lib/fonts" ]; then +if [ ! -d "${outpath}/lib/fonts" ]; then if [ "$PLATFORM" = "$XPLATFORM" ]; then mkdir -p "${outpath}/lib" ln -s "${relpath}/lib/fonts" "${outpath}/lib/fonts" @@ -2190,26 +2152,22 @@ if [ -z "$PLATFORM" ]; then PLATFORM_NOTES= case "$UNAME_SYSTEM:$UNAME_RELEASE" in Darwin:*) - if [ "$PLATFORM_QPA" = "yes" ]; then - OSX_VERSION=`uname -r | cut -d. -f1` - if [ "$OSX_VERSION" -ge 11 ]; then - # We're on Lion or above. Check if we have a supported Clang version - case "$(clang -v 2>&1 | grep -Po '(?<=version )\d[\d.]+')" in - 3.*) - PLATFORM=macx-clang - PLATFORM_NOTES="\n - Also available for Mac OS X: macx-g++\n" - ;; - *) - PLATFORM=macx-g++ - ;; - esac - else - PLATFORM=macx-g++ - fi - else - PLATFORM=darwin-g++ - fi - ;; + OSX_VERSION=`uname -r | cut -d. -f1` + if [ "$OSX_VERSION" -ge 11 ]; then + # We're on Lion or above. Check if we have a supported Clang version + case "$(clang -v 2>&1 | grep -Po '(?<=version )\d[\d.]+')" in + 3.*) + PLATFORM=macx-clang + PLATFORM_NOTES="\n - Also available for Mac OS X: macx-g++\n" + ;; + *) + PLATFORM=macx-g++ + ;; + esac + else + PLATFORM=macx-g++ + fi + ;; AIX:*) #PLATFORM=aix-g++ #PLATFORM=aix-g++-64 @@ -2431,12 +2389,6 @@ if [ '!' -f "${XQMAKESPEC}/qplatformdefs.h" ]; then exit 2 fi -# now look at the configs and figure out what platform we are config'd for -[ "$PLATFORM_QPA" != "yes" ] \ - && [ -n "`getXQMakeConf QMAKE_LIBS_X11`" ] \ - && PLATFORM_X11=yes -### echo "$XQMAKESPEC" | grep mkspecs/qws >/dev/null 2>&1 && PLATFORM_QWS=yes - if [ "$UNAME_SYSTEM" = "SunOS" ]; then # Solaris 2.5 and 2.6 have libposix4, which was renamed to librt for Solaris 7 and up if echo $UNAME_RELEASE | grep "^5\.[5|6]" >/dev/null 2>&1; then @@ -2562,15 +2514,10 @@ if [ "$XPLATFORM_SYMBIAN_SBSV2" = "no" ]; then fi fi -SYSROOT_FLAG= if [ -n "$CFG_SYSROOT" ]; then - if compilerSupportsFlag --sysroot="$CFG_SYSROOT"; then - [ "$OPT_VERBOSE" = "yes" ] && echo "Setting sysroot to: $CFG_SYSROOT" - SYSROOT_FLAG="--sysroot=$CFG_SYSROOT" - else - echo >&2 "The compiler doesn't support the --sysroot flag, I can't set the sysroot" - exit 1 - fi + SYSROOT_FLAG="--sysroot=$CFG_SYSROOT" +else + SYSROOT_FLAG= fi export SYSROOT_FLAG # used by config.tests/unix/compile.test @@ -2592,12 +2539,6 @@ if [ "$BUILD_ON_MAC" = "yes" ] && [ "$CFG_MAC_DWARF2" = "auto" ]; then fi fi -# don't autodetect support for separate debug info on objcopy when -# cross-compiling as lots of toolchains seems to have problems with this -if [ "$QT_CROSS_COMPILE" = "yes" ] && [ "$CFG_SEPARATE_DEBUG_INFO" = "auto" ]; then - CFG_SEPARATE_DEBUG_INFO="no" -fi - # auto-detect support for separate debug info in objcopy if [ "$CFG_SEPARATE_DEBUG_INFO" != "no" ] && [ "$CFG_SHARED" = "yes" ]; then TEST_COMPILER_CFLAGS=`getXQMakeConf QMAKE_CFLAGS` @@ -2667,13 +2608,15 @@ else CFG_FRAMEWORK=no fi -# x11 tests are done after qmake is built - - #setup the build parts if [ -z "$CFG_BUILD_PARTS" ]; then CFG_BUILD_PARTS="$QT_DEFAULT_BUILD_PARTS" + # build tests by default, if a developer build + if [ "$CFG_DEV" = "yes" ]; then + CFG_BUILD_PARTS="$CFG_BUILD_PARTS tests" + fi + # don't build tools by default when cross-compiling if [ "$PLATFORM" != "$XPLATFORM" ]; then CFG_BUILD_PARTS=`echo "$CFG_BUILD_PARTS" | sed "s, tools,,g"` @@ -2909,6 +2852,30 @@ if [ "$OPT_HELP" = "yes" ]; then X2N=" " fi + if [ "$CFG_DBUS" = "no" ]; then + DBY=" " + DBN="+" + else + DBY="+" + DBN=" " + fi + + if [ "$CFG_SEPARATE_DEBUG_INFO" = "no" ]; then + SBY=" " + SBN="*" + else + SBY="*" + SBN=" " + fi + + if [ "$CFG_GLIB" = "no" ]; then + GBY=" " + GBN="+" + else + GBY="+" + GBN=" " + fi + cat <] [-prefix-install] [-bindir ] [-libdir ] [-docdir ] [-headerdir ] [-plugindir ] [-importdir ] [-datadir ] @@ -2929,7 +2896,7 @@ Usage: $relconf [-h] [-prefix ] [-prefix-install] [-bindir ] [-libdir [-qtnamespace ] [-qtlibinfix ] [-separate-debug-info] [-no-phonon-backend] [-phonon-backend] [-no-media-backend] [-media-backend] [-no-audio-backend] [-audio-backend] - [-no-javascript-jit] [-javascript-jit] [-no-declarative-debug] [-declarative-debug] + [-no-javascript-jit] [-javascript-jit] [-no-qml-debug] [-qml-debug] [-no-optimized-qmake] [-optimized-qmake] [-no-openssl] [-openssl] [-openssl-linked] [-no-gtkstyle] [-gtkstyle] @@ -2940,24 +2907,15 @@ Usage: $relconf [-h] [-prefix ] [-prefix-install] [-bindir ] [-libdir Installation options: - -qpa ................ This will enable the QPA build. - QPA is a window system agnostic implementation of Qt. - These are optional, but you may specify install directories. -prefix ...... This will install everything relative to (default $QT_INSTALL_PREFIX) -EOF -if [ "$PLATFORM_QPA" = "yes" ]; then -cat < ....... Tests will be installed to (default PREFIX/tests) -EOF -if [ "$PLATFORM_QWS" = "yes" -o "$PLATFORM_QPA" = "yes" ]; then -cat < .. Host executables will be installed to (default HOSTPREFIX/bin) -hostdatadir . Data used by qmake will be installed to (default HOSTPREFIX) -EOF -fi -cat < Sets an alternate graphics system. Available options are: - raster - Software rasterizer - opengl - Rendering via OpenGL, Experimental! - openvg - Rendering via OpenVG, Experimental! - -EOF -fi - -cat << EOF -no-sse2 ........... Do not compile with use of SSE2 instructions. -no-sse3 ........... Do not compile with use of SSE3 instructions. @@ -3197,28 +3119,6 @@ Additional options: -device-option ... Add device specific options for the device mkspec (experimental) -EOF - -if [ "$CFG_SEPARATE_DEBUG_INFO" = "auto" ]; then - if [ "$QT_CROSS_COMPILE" = "yes" ]; then - SBY="" - SBN="*" - else - SBY="*" - SBN=" " - fi -elif [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then - SBY="*" - SBN=" " -else - SBY=" " - SBN="*" -fi - -if [ "$PLATFORM_X11" = "yes" -o "$PLATFORM_QPA" = "yes" ]; then - - cat << EOF - $SBN -no-separate-debug-info . Do not store debug information in a separate file. $SBY -separate-debug-info .... Strip debug information into a separate .debug file. @@ -3228,12 +3128,33 @@ if [ "$PLATFORM_X11" = "yes" -o "$PLATFORM_QPA" = "yes" ]; then $EGLFSN -no-eglfs .......... Do not compile EGLFS (EGL Full Screen/Single Surface) support. $EGLFSY -eglfs ............. Compile EGLFS support. + -xplatform target ... The target platform when cross-compiling. + + -sysroot ...... Sets as the target compiler's and qmake's sysroot. + + -no-feature- Do not compile in . + -feature- .. Compile in . The available features + are described in src/corelib/global/qfeatures.txt + + -no-freetype ........ Do not compile in Freetype2 support. + -qt-freetype ........ Use the libfreetype bundled with Qt. + * -system-freetype .... Use libfreetype from the operating system. + See http://www.freetype.org/ + + -qconfig local ...... Use src/corelib/global/qconfig-local.h rather than the + default ($CFG_QCONFIG). + + -no-opengl .......... Do not support OpenGL. + -opengl ....... Enable OpenGL support + With no parameter, this will attempt to auto-detect + OpenGL ES 2, or regular desktop OpenGL. + Use es2 for to override auto-detection. + + $GBN -no-glib ........... Do not compile Glib support. + $GBY -glib .............. Compile Glib support. EOF -fi # X11 - if [ "$XPLATFORM_MAEMO" = "yes" ]; then - cat << EOF $X2N -no-xinput2......... Do not compile XInput2 support. @@ -3243,186 +3164,6 @@ EOF fi -if [ "$PLATFORM_X11" = "yes" ]; then - if [ "$CFG_SM" = "no" ]; then - SMY=" " - SMN="*" - else - SMY="*" - SMN=" " - fi - if [ "$CFG_XSHAPE" = "no" ]; then - SHY=" " - SHN="*" - else - SHY="*" - SHN=" " - fi - if [ "$CFG_XVIDEO" = "no" ]; then - XVY=" " - XVN="*" - else - XVY="*" - XVN=" " - fi - if [ "$CFG_XINERAMA" = "no" ]; then - XAY=" " - XAN="*" - else - XAY="*" - XAN=" " - fi - if [ "$CFG_FONTCONFIG" = "no" ]; then - FCGY=" " - FCGN="*" - else - FCGY="*" - FCGN=" " - fi - if [ "$CFG_XCURSOR" = "no" ]; then - XCY=" " - XCN="*" - else - XCY="*" - XCN=" " - fi - if [ "$CFG_XFIXES" = "no" ]; then - XFY=" " - XFN="*" - else - XFY="*" - XFN=" " - fi - if [ "$CFG_XRANDR" = "no" ]; then - XZY=" " - XZN="*" - else - XZY="*" - XZN=" " - fi - if [ "$CFG_XRENDER" = "no" ]; then - XRY=" " - XRN="*" - else - XRY="*" - XRN=" " - fi - if [ "$CFG_MITSHM" = "no" ]; then - XMY=" " - XMN="*" - else - XMY="*" - XMN=" " - fi - if [ "$CFG_XINPUT" = "no" ]; then - XIY=" " - XIN="*" - else - XIY="*" - XIN=" " - fi - if [ "$CFG_XKB" = "no" ]; then - XKY=" " - XKN="*" - else - XKY="*" - XKN=" " - fi - if [ "$CFG_IM" = "no" ]; then - IMY=" " - IMN="*" - else - IMY="*" - IMN=" " - fi - cat << EOF - -Qt/X11 only: - - -no-gtkstyle ....... Do not build the GTK theme integration. - + -gtkstyle .......... Build the GTK theme integration. - - * -no-nas-sound ...... Do not compile in NAS sound support. - -system-nas-sound .. Use NAS libaudio from the operating system. - See http://radscan.com/nas.html - - -no-opengl ......... Do not support OpenGL. - + -opengl ...... Enable OpenGL support. - With no parameter, this will auto-detect the "best" - OpenGL API to use. If desktop OpenGL is available, it - will be used. Use desktop or es2 for - to force the use of the Desktop OpenGL or - OpenGL ES 2 APIs instead. - - -no-openvg ........ Do not support OpenVG. - + -openvg ........... Enable OpenVG support. - Requires EGL support, typically supplied by an OpenGL - or other graphics implementation. - - $SMN -no-sm ............. Do not support X Session Management. - $SMY -sm ................ Support X Session Management, links in -lSM -lICE. - - $SHN -no-xshape ......... Do not compile XShape support. - $SHY -xshape ............ Compile XShape support. - Requires X11/extensions/shape.h. - - $XVN -no-xvideo ......... Do not compile XVideo support. - $XVY -xvideo ............ Compile XVideo support. - Requires X11/extensions/Xv.h & Xvlib.h. - - $SHN -no-xsync .......... Do not compile XSync support. - $SHY -xsync ............. Compile XSync support. - Requires X11/extensions/sync.h. - - $XAN -no-xinerama ....... Do not compile Xinerama (multihead) support. - $XAY -xinerama .......... Compile Xinerama support. - Requires X11/extensions/Xinerama.h and libXinerama. - By default, Xinerama support will be compiled if - available and the shared libraries are dynamically - loaded at runtime. - - $XCN -no-xcursor ........ Do not compile Xcursor support. - $XCY -xcursor ........... Compile Xcursor support. - Requires X11/Xcursor/Xcursor.h and libXcursor. - By default, Xcursor support will be compiled if - available and the shared libraries are dynamically - loaded at runtime. - - $XFN -no-xfixes ......... Do not compile Xfixes support. - $XFY -xfixes ............ Compile Xfixes support. - Requires X11/extensions/Xfixes.h and libXfixes. - By default, Xfixes support will be compiled if - available and the shared libraries are dynamically - loaded at runtime. - - $XZN -no-xrandr ......... Do not compile Xrandr (resize and rotate) support. - $XZY -xrandr ............ Compile Xrandr support. - Requires X11/extensions/Xrandr.h and libXrandr. - - $XRN -no-xrender ........ Do not compile Xrender support. - $XRY -xrender ........... Compile Xrender support. - Requires X11/extensions/Xrender.h and libXrender. - - $XMN -no-mitshm ......... Do not compile MIT-SHM support. - $XMY -mitshm ............ Compile MIT-SHM support. - Requires sys/ipc.h, sys/shm.h and X11/extensions/XShm.h - - $FCGN -no-fontconfig ..... Do not compile FontConfig (anti-aliased font) support. - $FCGY -fontconfig ........ Compile FontConfig support. - Requires fontconfig/fontconfig.h, libfontconfig, - freetype.h and libfreetype. - - $XIN -no-xinput ......... Do not compile Xinput support. - $XIY -xinput ............ Compile Xinput support. This also enabled tablet support - which requires IRIX with wacom.h and libXi or - XFree86 with X11/extensions/XInput.h and libXi. - - $XKN -no-xkb ............ Do not compile XKB (X KeyBoard extension) support. - $XKY -xkb ............... Compile XKB support. - -EOF -fi - if [ "$BUILD_ON_MAC" = "yes" ]; then cat << EOF @@ -3445,52 +3186,6 @@ Qt/Mac only: * -no-harfbuzz ....... Disable HarfBuzz on Mac. It can still be enabled by setting QT_ENABLE_HARFBUZZ environment variable. -EOF -fi - -if [ "$PLATFORM_QPA" = "yes" ]; then - cat << EOF -Qt for QPA only: -EOF -fi - -if [ "$PLATFORM_QPA" = "yes" ]; then - cat << EOF - - -xplatform target ... The target platform when cross-compiling. - - -no-feature- Do not compile in . - -feature- .. Compile in . The available features - are described in src/corelib/global/qfeatures.txt - - -no-freetype ........ Do not compile in Freetype2 support. - -qt-freetype ........ Use the libfreetype bundled with Qt. - * -system-freetype .... Use libfreetype from the operating system. - See http://www.freetype.org/ - - -qconfig local ...... Use src/corelib/global/qconfig-local.h rather than the - default ($CFG_QCONFIG). - - -no-opengl .......... Do not support OpenGL. - -opengl ....... Enable OpenGL ES support - With no parameter, this will attempt to auto-detect - OpenGL ES 2, or regular desktop OpenGL. - Use es2 for to override auto-detection. -EOF -fi - -if [ "$PLATFORM_QPA" = "yes" -o "$PLATFORM_X11" = "yes" ]; then - if [ "$CFG_GLIB" = "no" ]; then - GBY=" " - GBN="+" - else - GBY="+" - GBN=" " - fi - cat << EOF - $GBN -no-glib ........... Do not compile Glib support. - $GBY -glib .............. Compile Glib support. - EOF fi @@ -3503,17 +3198,8 @@ fi # Help # LICENSING, INTERACTIVE PART # ----------------------------------------------------------------------------- -if [ "$PLATFORM_QPA" = "yes" ]; then - Platform="Qt Lighthouse" -elif [ "$XPLATFORM_MINGW" = "yes" ]; then - Platform="Qt for Windows" -elif [ -n "`getXQMakeConf grep QMAKE_LIBS_X11`" ]; then - PLATFORM_X11=yes - Platform="Qt for Linux/X11" -fi - echo -echo "This is the $Platform ${EditionString} Edition." +echo "This is the Qt ${EditionString} Edition." echo if [ "$Edition" = "OpenSource" ]; then @@ -3944,9 +3630,7 @@ fi if [ "$OPT_VERBOSE" = "yes" ]; then echo "System architecture: '$CFG_ARCH'" - if [ "$PLATFORM_QPA" = "yes" ]; then - echo "Host architecture: '$CFG_HOST_ARCH'" - fi + echo "Host architecture: '$CFG_HOST_ARCH'" fi #------------------------------------------------------------------------------- @@ -4471,125 +4155,98 @@ if [ "$CFG_DBUS" != "no" ]; then fi fi -# X11/Lighthouse -if [ "$PLATFORM_X11" = "yes" -o "$PLATFORM_QPA" = "yes" ]; then - - # auto-detect Glib support - if [ "$CFG_GLIB" != "no" ]; then - if [ -n "$PKG_CONFIG" ]; then - QT_CFLAGS_GLIB=`$PKG_CONFIG --cflags glib-2.0 gthread-2.0 2>/dev/null` - QT_LIBS_GLIB=`$PKG_CONFIG --libs glib-2.0 gthread-2.0 2>/dev/null` - fi - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/glib "Glib" $L_FLAGS $I_FLAGS $l_FLAGS $QT_CFLAGS_GLIB $QT_LIBS_GLIB $X11TESTS_FLAGS ; then - CFG_GLIB=yes - QMakeVar set QT_CFLAGS_GLIB "$QT_CFLAGS_GLIB" - QMakeVar set QT_LIBS_GLIB "$QT_LIBS_GLIB" +# auto-detect Glib support +if [ "$CFG_GLIB" != "no" ]; then + if [ -n "$PKG_CONFIG" ]; then + QT_CFLAGS_GLIB=`$PKG_CONFIG --cflags glib-2.0 gthread-2.0 2>/dev/null` + QT_LIBS_GLIB=`$PKG_CONFIG --libs glib-2.0 gthread-2.0 2>/dev/null` + fi + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/glib "Glib" $L_FLAGS $I_FLAGS $l_FLAGS $QT_CFLAGS_GLIB $QT_LIBS_GLIB; then + CFG_GLIB=yes + QMakeVar set QT_CFLAGS_GLIB "$QT_CFLAGS_GLIB" + QMakeVar set QT_LIBS_GLIB "$QT_LIBS_GLIB" + else + if [ "$CFG_GLIB" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then + echo "Glib support cannot be enabled due to functionality tests!" + echo " Turn on verbose messaging (-v) to $0 to see the final report." + echo " If you believe this message is in error you may use the continue" + echo " switch (-continue) to $0 to continue." + exit 101 else - if [ "$CFG_GLIB" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Glib support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_GLIB=no - fi + CFG_GLIB=no fi fi +fi - # ### Vestige - if [ "$CFG_GLIB" = "yes" -a "$CFG_GSTREAMER" != "no" ]; then - if [ -n "$PKG_CONFIG" ]; then - QT_CFLAGS_GSTREAMER=`$PKG_CONFIG --cflags gstreamer-0.10 gstreamer-plugins-base-0.10 2>/dev/null` - QT_LIBS_GSTREAMER=`$PKG_CONFIG --libs gstreamer-0.10 gstreamer-plugins-base-0.10 2>/dev/null` - fi - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/gstreamer "GStreamer" $L_FLAGS $I_FLAGS $l_FLAGS $QT_CFLAGS_GSTREAMER $QT_LIBS_GSTREAMER $X11TESTS_FLAGS; then - CFG_GSTREAMER=yes - QMakeVar set QT_CFLAGS_GSTREAMER "$QT_CFLAGS_GSTREAMER" - QMakeVar set QT_LIBS_GSTREAMER "$QT_LIBS_GSTREAMER" +# ### Vestige +if [ "$CFG_GLIB" = "yes" -a "$CFG_GSTREAMER" != "no" ]; then + if [ -n "$PKG_CONFIG" ]; then + QT_CFLAGS_GSTREAMER=`$PKG_CONFIG --cflags gstreamer-0.10 gstreamer-plugins-base-0.10 2>/dev/null` + QT_LIBS_GSTREAMER=`$PKG_CONFIG --libs gstreamer-0.10 gstreamer-plugins-base-0.10 2>/dev/null` + fi + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/gstreamer "GStreamer" $L_FLAGS $I_FLAGS $l_FLAGS $QT_CFLAGS_GSTREAMER $QT_LIBS_GSTREAMER; then + CFG_GSTREAMER=yes + QMakeVar set QT_CFLAGS_GSTREAMER "$QT_CFLAGS_GSTREAMER" + QMakeVar set QT_LIBS_GSTREAMER "$QT_LIBS_GSTREAMER" + else + if [ "$CFG_GSTREAMER" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then + echo "Gstreamer support cannot be enabled due to functionality tests!" + echo " Turn on verbose messaging (-v) to $0 to see the final report." + echo " If you believe this message is in error you may use the continue" + echo " switch (-continue) to $0 to continue." + exit 101 else - if [ "$CFG_GSTREAMER" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Gstreamer support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_GSTREAMER=no - fi + CFG_GSTREAMER=no fi - elif [ "$CFG_GLIB" = "no" ]; then - CFG_GSTREAMER=no fi +elif [ "$CFG_GLIB" = "no" ]; then + CFG_GSTREAMER=no +fi - # auto-detect libicu support - if [ "$CFG_ICU" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/icu "ICU" $L_FLAGS $I_FLAGS $l_FLAGS; then - [ "$CFG_ICU" = "auto" ] && CFG_ICU=yes +# auto-detect libicu support +if [ "$CFG_ICU" != "no" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/icu "ICU" $L_FLAGS $I_FLAGS $l_FLAGS; then + [ "$CFG_ICU" = "auto" ] && CFG_ICU=yes + else + if [ "$CFG_ICU" = "auto" ]; then + CFG_ICU=no + elif [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then + # CFG_ICU is "yes" + + echo "The ICU library support cannot be enabled." + echo " Turn on verbose messaging (-v) to $0 to see the final report." + echo " If you believe this message is in error you may use the continue" + echo " switch (-continue) to $0 to continue." + exit 101 + fi + fi +fi + +# Auto-detect PulseAudio support +if [ "$CFG_PULSEAUDIO" != "no" ]; then + if [ -n "$PKG_CONFIG" ]; then + QT_CFLAGS_PULSEAUDIO=`$PKG_CONFIG --cflags libpulse '>=' 0.9.10 libpulse-mainloop-glib 2>/dev/null` + QT_LIBS_PULSEAUDIO=`$PKG_CONFIG --libs libpulse '>=' 0.9.10 libpulse-mainloop-glib 2>/dev/null` + fi + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/pulseaudio "PulseAudio" $L_FLAGS $I_FLAGS $l_FLAGS $QT_CFLAGS_PULSEAUDIO $QT_LIBS_PULSEAUDIO; then + CFG_PULSEAUDIO=yes + QMakeVar set QT_CFLAGS_PULSEAUDIO "$QT_CFLAGS_PULSEAUDIO" + QMakeVar set QT_LIBS_PULSEAUDIO "$QT_LIBS_PULSEAUDIO" + else + if [ "$CFG_PULSEAUDIO" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then + echo "PulseAudio support cannot be enabled due to functionality tests!" + echo " Turn on verbose messaging (-v) to $0 to see the final report." + echo " If you believe this message is in error you may use the continue" + echo " switch (-continue) to $0 to continue." + exit 101 else - if [ "$CFG_ICU" = "auto" ]; then - CFG_ICU=no - elif [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - # CFG_ICU is "yes" - - echo "The ICU library support cannot be enabled." - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - fi + CFG_PULSEAUDIO=no fi fi - - # Auto-detect PulseAudio support - if [ "$CFG_PULSEAUDIO" != "no" ]; then - if [ -n "$PKG_CONFIG" ]; then - QT_CFLAGS_PULSEAUDIO=`$PKG_CONFIG --cflags libpulse '>=' 0.9.10 libpulse-mainloop-glib 2>/dev/null` - QT_LIBS_PULSEAUDIO=`$PKG_CONFIG --libs libpulse '>=' 0.9.10 libpulse-mainloop-glib 2>/dev/null` - fi - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/pulseaudio "PulseAudio" $L_FLAGS $I_FLAGS $l_FLAGS $QT_CFLAGS_PULSEAUDIO $QT_LIBS_PULSEAUDIO $X11TESTS_FLAGS; then - CFG_PULSEAUDIO=yes - QMakeVar set QT_CFLAGS_PULSEAUDIO "$QT_CFLAGS_PULSEAUDIO" - QMakeVar set QT_LIBS_PULSEAUDIO "$QT_LIBS_PULSEAUDIO" - else - if [ "$CFG_PULSEAUDIO" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "PulseAudio support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_PULSEAUDIO=no - fi - fi - fi -fi # X11/Lighthouse - -# X11 -if [ "$PLATFORM_X11" = "yes" -a "$CFG_GUI" != "no" ]; then - x11tests="$relpath/config.tests/x11" - X11TESTS_FLAGS= - - # work around broken X11 headers when using GCC 2.95 or later - NOTYPE=no - "$x11tests/notype.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" && NOTYPE=yes - if [ $NOTYPE = "yes" ]; then - QMakeVar add QMAKE_CXXFLAGS -fpermissive - X11TESTS_FLAGS="$X11TESTS_FLAGS -fpermissive" - fi - - # Check we actually have X11 :-) - "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xlib "XLib" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS - if [ $? != "0" ]; then - echo "Basic XLib functionality test failed!" - echo " You might need to modify the include and library search paths by editing" - echo " QMAKE_INCDIR_X11 and QMAKE_LIBDIR_X11 in ${XQMAKESPEC}." - exit 1 - fi fi # X11/MINGW OpenGL -if [ "$PLATFORM_X11" = "yes" -o "$XPLATFORM_MINGW" = "yes" ]; then +if [ "$XPLATFORM_MINGW" = "yes" ]; then # auto-detect OpenGL support (es2 = OpenGL ES 2.x) if [ "$CFG_GUI" = "no" ]; then if [ "$CFG_OPENGL" = "auto" ]; then @@ -4602,7 +4259,7 @@ if [ "$PLATFORM_X11" = "yes" -o "$XPLATFORM_MINGW" = "yes" ]; then fi fi if [ "$CFG_OPENGL" = "auto" ] || [ "$CFG_OPENGL" = "yes" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/opengl "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/opengl "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS; then CFG_OPENGL=desktop elif "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles2 "OpenGL ES 2.x" $L_FLAGS $I_FLAGS $l_FLAGS; then CFG_OPENGL=es2 @@ -4620,7 +4277,7 @@ if [ "$PLATFORM_X11" = "yes" -o "$XPLATFORM_MINGW" = "yes" ]; then hpux*) # HP-UX have buggy glx headers; check if we really need to define the GLXFBConfig struct. if [ "$CFG_OPENGL" = "desktop" ]; then - "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/glxfbconfig "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS + "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/glxfbconfig "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS if [ $? != "0" ]; then QMakeVar add DEFINES QT_DEFINE_GLXFBCONFIG_STRUCT fi @@ -4641,7 +4298,7 @@ if [ "$PLATFORM_X11" = "yes" -o "$XPLATFORM_MINGW" = "yes" ]; then fi elif [ "$CFG_OPENGL" = "desktop" ]; then # Desktop OpenGL support - "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/opengl "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS + "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/opengl "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS if [ $? != "0" ]; then echo "The OpenGL functionality test failed!" echo " You might need to modify the include and library search paths by editing" @@ -4652,7 +4309,7 @@ if [ "$PLATFORM_X11" = "yes" -o "$XPLATFORM_MINGW" = "yes" ]; then case "$PLATFORM" in hpux*) # HP-UX have buggy glx headers; check if we really need to define the GLXFBConfig struct. - "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/glxfbconfig "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS + "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/glxfbconfig "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS if [ $? != "0" ]; then QMakeVar add DEFINES QT_DEFINE_GLXFBCONFIG_STRUCT fi @@ -4663,275 +4320,6 @@ if [ "$PLATFORM_X11" = "yes" -o "$XPLATFORM_MINGW" = "yes" ]; then fi fi # X11/MINGW OpenGL -# X11 -if [ "$PLATFORM_X11" = "yes" ]; then - # auto-detect Xcursor support - if [ "$CFG_XCURSOR" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xcursor "Xcursor" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - if [ "$CFG_XCURSOR" != "runtime" ]; then - CFG_XCURSOR=yes; - fi - else - if [ "$CFG_XCURSOR" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Xcursor support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XCURSOR=no - fi - fi - fi - - # auto-detect Xfixes support - if [ "$CFG_XFIXES" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xfixes "Xfixes" $L_FLAGS $I_FLAGS $X11TESTS_FLAGS; then - if [ "$CFG_XFIXES" != "runtime" ]; then - CFG_XFIXES=yes; - fi - else - if [ "$CFG_XFIXES" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Xfixes support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XFIXES=no - fi - fi - fi - - # auto-detect Xrandr support (resize and rotate extension) - if [ "$CFG_XRANDR" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xrandr "Xrandr" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - if [ "$CFG_XRANDR" != "runtime" ]; then - CFG_XRANDR=yes - fi - else - if [ "$CFG_XRANDR" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Xrandr support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XRANDR=no - fi - fi - fi - - # auto-detect Xrender support - if [ "$CFG_XRENDER" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xrender "Xrender" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - CFG_XRENDER=yes - else - if [ "$CFG_XRENDER" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Xrender support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XRENDER=no - fi - fi - fi - - # auto-detect MIT-SHM support - if [ "$CFG_MITSHM" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/mitshm "mitshm" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - CFG_MITSHM=yes - else - if [ "$CFG_MITSHM" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "MITSHM support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_MITSHM=no - fi - fi - fi - - # auto-detect Session Management support - if [ "$CFG_SM" = "auto" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/sm "Session Management" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - CFG_SM=yes - else - if [ "$CFG_SM" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Session Management support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_SM=no - fi - fi - fi - - # auto-detect SHAPE support - if [ "$CFG_XSHAPE" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xshape "XShape" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - CFG_XSHAPE=yes - else - if [ "$CFG_XSHAPE" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "XShape support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XSHAPE=no - fi - fi - fi - - # auto-detect XVideo support - if [ "$CFG_XVIDEO" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xvideo "XVideo" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - CFG_XVIDEO=yes - else - if [ "$CFG_XVIDEO" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "XVideo support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XVIDEO=no - fi - fi - fi - - # auto-detect XSync support - if [ "$CFG_XSYNC" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xsync "XSync" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - CFG_XSYNC=yes - else - if [ "$CFG_XSYNC" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "XSync support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XSYNC=no - fi - fi - fi - - # auto-detect Xinerama support - if [ "$CFG_XINERAMA" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xinerama "Xinerama" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - if [ "$CFG_XINERAMA" != "runtime" ]; then - CFG_XINERAMA=yes - fi - else - if [ "$CFG_XINERAMA" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Xinerama support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XINERAMA=no - fi - fi - fi - - # auto-detect Xinput support - if [ "$CFG_XINPUT" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xinput "XInput" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - if [ "$CFG_XINPUT" != "runtime" ]; then - CFG_XINPUT=yes - fi - else - if [ "$CFG_XINPUT" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Tablet and Xinput support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XINPUT=no - fi - fi - fi - - # auto-detect XKB support - if [ "$CFG_XKB" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xkb "XKB" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - CFG_XKB=yes - else - if [ "$CFG_XKB" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "XKB support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XKB=no - fi - fi - fi - - if [ "$CFG_GLIB" = "yes" -a "$CFG_QGTKSTYLE" != "no" ]; then - if [ -n "$PKG_CONFIG" ]; then - QT_CFLAGS_QGTKSTYLE=`$PKG_CONFIG --cflags gtk+-2.0 ">=" 2.10 atk 2>/dev/null` - QT_LIBS_QGTKSTYLE=`$PKG_CONFIG --libs gobject-2.0 2>/dev/null` - fi - if [ -n "$QT_CFLAGS_QGTKSTYLE" ] ; then - CFG_QGTKSTYLE=yes - QMakeVar set QT_CFLAGS_QGTKSTYLE "$QT_CFLAGS_QGTKSTYLE" - QMakeVar set QT_LIBS_QGTKSTYLE "$QT_LIBS_QGTKSTYLE" - else - if [ "$CFG_QGTKSTYLE" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Gtk theme support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_QGTKSTYLE=no - fi - fi - elif [ "$CFG_GLIB" = "no" ]; then - CFG_QGTKSTYLE=no - fi -fi # X11 - -# auto-detect FontConfig support -if [ "$CFG_FONTCONFIG" != "no" ]; then - if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists fontconfig --exists freetype2 2>/dev/null; then - QT_CFLAGS_FONTCONFIG=`$PKG_CONFIG --cflags fontconfig --cflags freetype2 2>/dev/null` - QT_LIBS_FONTCONFIG=`$PKG_CONFIG --libs fontconfig --libs freetype2 2>/dev/null` - else - QT_CFLAGS_FONTCONFIG= - QT_LIBS_FONTCONFIG="-lfreetype -lfontconfig" - fi - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/fontconfig "FontConfig" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS $QT_CFLAGS_FONTCONFIG $QT_LIBS_FONTCONFIG; then - CFG_FONTCONFIG=yes - QMakeVar set QMAKE_CFLAGS_X11 "$QT_CFLAGS_FONTCONFIG \$\$QMAKE_CFLAGS_X11" - QMakeVar set QMAKE_LIBS_X11 "$QT_LIBS_FONTCONFIG \$\$QMAKE_LIBS_X11" - CFG_LIBFREETYPE=system - else - if [ "$CFG_FONTCONFIG" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "FontConfig support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_FONTCONFIG=no - fi - fi -fi - - if [ "$BUILD_ON_MAC" = "yes" ]; then if [ "$CFG_PHONON" != "no" ]; then # Always enable Phonon (unless it was explicitly disabled) @@ -4947,249 +4335,253 @@ if [ "$BUILD_ON_MAC" = "yes" ]; then fi fi -if [ "$PLATFORM_QPA" = "yes" ]; then - # auto-detect OpenGL support (es2 = OpenGL ES 2.x) - if [ "$CFG_OPENGL" = "auto" ] || [ "$CFG_OPENGL" = "yes" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengldesktop "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - CFG_OPENGL=desktop - elif "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles2 "OpenGL ES 2.x" $L_FLAGS $I_FLAGS $l_FLAGS; then - CFG_OPENGL=es2 - else - if [ "$CFG_OPENGL" = "yes" ]; then - echo "All the OpenGL functionality tests failed!" - echo " You might need to modify the include and library search paths by editing" - echo " QMAKE_INCDIR_OPENGL, QMAKE_LIBDIR_OPENGL and QMAKE_LIBS_OPENGL in" - echo " ${XQMAKESPEC}." - exit 1 - fi - CFG_OPENGL=no - fi - elif [ "$CFG_OPENGL" = "es2" ]; then - #OpenGL ES 2.x - if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists glesv2 2>/dev/null; then - QMAKE_INCDIR_OPENGL_ES2=`$PKG_CONFIG --cflags-only-I glesv2 2>/dev/null | sed -e 's,^-I,,g' -e 's, -I, ,g'` - QMAKE_LIBDIR_OPENGL_ES2=`$PKG_CONFIG --libs-only-L glesv2 2>/dev/null | sed -e 's,^-L,,g' -e 's, -L, ,g'` - QMAKE_LIBS_OPENGL_ES2=`$PKG_CONFIG --libs glesv2 2>/dev/null` - QMAKE_CFLAGS_OPENGL_ES2=`$PKG_CONFIG --cflags glesv2 2>/dev/null` - QMakeVar set QMAKE_INCDIR_OPENGL_ES2 "$QMAKE_INCDIR_OPENGL_ES2" - QMakeVar set QMAKE_LIBDIR_OPENGL_ES2 "$QMAKE_LIBDIR_OPENGL_ES2" - QMakeVar set QMAKE_LIBS_OPENGL_ES2 "$QMAKE_LIBS_OPENGL_ES2" - fi - - "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles2 "OpenGL ES 2.x" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_LIBS_OPENGL_ES2 $QMAKE_CFLAGS_OPENGL_ES2 - if [ $? != "0" ]; then - echo "The OpenGL ES 2.0 functionality test failed!" - echo " You might need to modify the include and library search paths by editing" - echo " QMAKE_INCDIR_OPENGL_ES2, QMAKE_LIBDIR_OPENGL_ES2 and QMAKE_LIBS_OPENGL_ES2 in" - echo " ${XQMAKESPEC}." - exit 1 - fi - elif [ "$CFG_OPENGL" = "desktop" ]; then - # Desktop OpenGL support - "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengldesktop "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS - if [ $? != "0" ]; then - echo "The OpenGL functionality test failed!" +# auto-detect OpenGL support (es2 = OpenGL ES 2.x) +if [ "$CFG_OPENGL" = "auto" ] || [ "$CFG_OPENGL" = "yes" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengldesktop "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_OPENGL=desktop + elif "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles2 "OpenGL ES 2.x" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_OPENGL=es2 + else + if [ "$CFG_OPENGL" = "yes" ]; then + echo "All the OpenGL functionality tests failed!" echo " You might need to modify the include and library search paths by editing" echo " QMAKE_INCDIR_OPENGL, QMAKE_LIBDIR_OPENGL and QMAKE_LIBS_OPENGL in" echo " ${XQMAKESPEC}." exit 1 fi + CFG_OPENGL=no + fi +elif [ "$CFG_OPENGL" = "es2" ]; then + #OpenGL ES 2.x + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists glesv2 2>/dev/null; then + QMAKE_INCDIR_OPENGL_ES2=`$PKG_CONFIG --cflags-only-I glesv2 2>/dev/null | sed -e 's,^-I,,g' -e 's, -I, ,g'` + QMAKE_LIBDIR_OPENGL_ES2=`$PKG_CONFIG --libs-only-L glesv2 2>/dev/null | sed -e 's,^-L,,g' -e 's, -L, ,g'` + QMAKE_LIBS_OPENGL_ES2=`$PKG_CONFIG --libs glesv2 2>/dev/null` + QMAKE_CFLAGS_OPENGL_ES2=`$PKG_CONFIG --cflags glesv2 2>/dev/null` + QMakeVar set QMAKE_INCDIR_OPENGL_ES2 "$QMAKE_INCDIR_OPENGL_ES2" + QMakeVar set QMAKE_LIBDIR_OPENGL_ES2 "$QMAKE_LIBDIR_OPENGL_ES2" + QMakeVar set QMAKE_LIBS_OPENGL_ES2 "$QMAKE_LIBS_OPENGL_ES2" fi - # auto-detect FontConfig support - if [ "$CFG_FONTCONFIG" != "no" ]; then - if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists fontconfig --exists freetype2 2>/dev/null; then - QT_CFLAGS_FONTCONFIG=`$PKG_CONFIG --cflags fontconfig --cflags freetype2 2>/dev/null` - QT_LIBS_FONTCONFIG=`$PKG_CONFIG --libs fontconfig --libs freetype2 2>/dev/null` - else - QT_CFLAGS_FONTCONFIG= - QT_LIBS_FONTCONFIG="-lfreetype -lfontconfig" - fi - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/fontconfig "FontConfig" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS $QT_CFLAGS_FONTCONFIG $QT_LIBS_FONTCONFIG; then - QT_CONFIG="$QT_CONFIG fontconfig" - QMakeVar set QMAKE_CFLAGS_FONTCONFIG "$QT_CFLAGS_FONTCONFIG" - QMakeVar set QMAKE_LIBS_FONTCONFIG "$QT_LIBS_FONTCONFIG" - CFG_LIBFREETYPE=system - fi - + "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles2 "OpenGL ES 2.x" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_LIBS_OPENGL_ES2 $QMAKE_CFLAGS_OPENGL_ES2 + if [ $? != "0" ]; then + echo "The OpenGL ES 2.0 functionality test failed!" + echo " You might need to modify the include and library search paths by editing" + echo " QMAKE_INCDIR_OPENGL_ES2, QMAKE_LIBDIR_OPENGL_ES2 and QMAKE_LIBS_OPENGL_ES2 in" + echo " ${XQMAKESPEC}." + exit 1 fi - - # Save these for a check later - ORIG_CFG_XCB="$CFG_XCB" - ORIG_CFG_EGLFS="$CFG_EGLFS" - - if [ "$CFG_LIBUDEV" != "no" ]; then - if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists libudev 2>/dev/null; then - QMAKE_INCDIR_LIBUDEV=`$PKG_CONFIG --cflags-only-I libudev 2>/dev/null | sed -e 's,^-I,,g' -e 's, -I, ,g'` - QMAKE_LIBS_LIBUDEV=`$PKG_CONFIG --libs libudev 2>/dev/null` - QMakeVar set QMAKE_INCDIR_LIBUDEV "$QMAKE_INCDIR_LIBUDEV" - QMakeVar set QMAKE_LIBS_LIBUDEV "$QMAKE_LIBS_LIBUDEV" - fi - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/libudev "libudev" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_INCDIR_LIBUDEV $QMAKE_LIBS_LIBUDEV; then - CFG_LIBUDEV=yes - QT_CONFIG="$QT_CONFIG libudev" - elif [ "$CFG_LIBUDEV" = "yes" ]; then - echo "The libudev functionality test failed!" - exit 1 - else - CFG_LIBUDEV=no - QMakeVar add DEFINES QT_NO_LIBUDEV - fi +elif [ "$CFG_OPENGL" = "desktop" ]; then + # Desktop OpenGL support + "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengldesktop "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS + if [ $? != "0" ]; then + echo "The OpenGL functionality test failed!" + echo " You might need to modify the include and library search paths by editing" + echo " QMAKE_INCDIR_OPENGL, QMAKE_LIBDIR_OPENGL and QMAKE_LIBS_OPENGL in" + echo " ${XQMAKESPEC}." + exit 1 fi +fi - if [ "$CFG_EVDEV" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/evdev "evdev" $L_FLAGS $I_FLAGS $l_FLAGS; then - CFG_EVDEV=yes - QT_CONFIG="$QT_CONFIG evdev" - elif [ "$CFG_EVDEV" = "yes" ]; then - echo "The evdev functionality test failed!" - exit 1 - else - CFG_EVDEV=no - QMakeVar add DEFINES QT_NO_EVDEV - fi - fi - - # Check we actually have X11 :-) - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xlib "XLib" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - QT_CONFIG="$QT_CONFIG xlib" - fi - - # auto-detect Xrender support - if [ "$CFG_XRENDER" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xrender "Xrender" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - CFG_XRENDER=yes - QT_CONFIG="$QT_CONFIG xrender" - else - if [ "$CFG_XRENDER" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Xrender support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XRENDER=no - fi - fi - fi - - if [ "$CFG_XCB" != "no" ]; then - if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xcb >= 1.5" 2>/dev/null; then - QMAKE_CFLAGS_XCB="`$PKG_CONFIG --cflags xcb 2>/dev/null`" - QMAKE_LIBS_XCB="`$PKG_CONFIG --libs xcb 2>/dev/null`" - fi - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb "xcb" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then - CFG_XCB=yes - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-render "xcb-render" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then - QT_CONFIG="$QT_CONFIG xcb-render" - fi - - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-poll-for-queued-event "xcb-poll-for-queued-event" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then - CFG_XCB_LIMITED=no - QT_CONFIG="$QT_CONFIG xcb-poll-for-queued-event" - fi - - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-xlib "xcb-xlib" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then - QT_CONFIG="$QT_CONFIG xcb-xlib" - fi - - if [ "$XPLATFORM_MAEMO" = "yes" ]; then - # auto-detect XInput2/Xinput support - if [ "$CFG_XINPUT2" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xinput2 "XInput2" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then - CFG_XINPUT2=yes - CFG_XINPUT=no - else - if [ "$CFG_XINPUT2" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "XInput2 support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XINPUT2=no - fi - fi - fi - fi - else - if [ "$CFG_XCB" = "yes" ]; then - echo "The XCB test failed!" - echo " You might need to install dependency packages." - echo " See src/plugins/platforms/xcb/README." - exit 1 - fi - CFG_XCB=no - QMakeVar add DEFINES QT_NO_XCB - fi - fi - - # Detect libxkbcommon - if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists xkbcommon 2>/dev/null; then - QMAKE_CFLAGS_XKBCOMMON="`$PKG_CONFIG --cflags xkbcommon 2>/dev/null`" - QMAKE_LIBS_XKBCOMMON="`$PKG_CONFIG --libs xkbcommon 2>/dev/null`" - QMAKE_CFLAGS_XCB="$QMAKE_CFLAGS_XCB $QMAKE_CFLAGS_XKBCOMMON" - QMAKE_LIBS_XCB="$QMAKE_LIBS_XCB $QMAKE_LIBS_XKBCOMMON" +# auto-detect FontConfig support +if [ "$CFG_FONTCONFIG" != "no" ]; then + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists fontconfig --exists freetype2 2>/dev/null; then + QT_CFLAGS_FONTCONFIG=`$PKG_CONFIG --cflags fontconfig --cflags freetype2 2>/dev/null` + QT_LIBS_FONTCONFIG=`$PKG_CONFIG --libs fontconfig --libs freetype2 2>/dev/null` else - QMAKE_DEFINES_XCB=QT_NO_XCB_XKB + QT_CFLAGS_FONTCONFIG= + QT_LIBS_FONTCONFIG="-lfreetype -lfontconfig" fi - - # EGL Support - if [ "$CFG_EGL" != "no" ]; then - if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists egl 2>/dev/null; then - QMAKE_INCDIR_EGL=`$PKG_CONFIG --cflags-only-I egl 2>/dev/null | sed -e 's,^-I,,g' -e 's, -I, ,g'` - QMAKE_LIBS_EGL=`$PKG_CONFIG --libs egl 2>/dev/null` - QMAKE_CFLAGS_EGL=`$PKG_CONFIG --cflags egl 2>/dev/null` - QMakeVar set QMAKE_INCDIR_EGL "$QMAKE_INCDIR_EGL" - QMakeVar set QMAKE_LIBS_EGL "$QMAKE_LIBS_EGL" - fi # detect EGL support - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" "config.tests/qpa/egl" "EGL" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_EGL $QMAKE_LIBS_EGL; then - CFG_EGL=yes - elif [ "$CFG_EGL" = "yes" ]; then - echo " The EGL functionality test failed; EGL is required by some QPA plugins to manage contexts & surfaces." - echo " You might need to modify the include and library search paths by editing" - echo " QMAKE_INCDIR_EGL, QMAKE_LIBDIR_EGL and QMAKE_LIBS_EGL in ${XQMAKESPEC}." - exit 1 - else - CFG_EGL=no - fi - fi - - if [ "$CFG_EGLFS" != "no" ]; then - CFG_EGLFS="$CFG_EGL" - fi - - if [ -n "$QMAKE_CFLAGS_XCB" ] || [ -n "$QMAKE_LIBS_XCB" ]; then - QMakeVar set QMAKE_CFLAGS_XCB "$QMAKE_CFLAGS_XCB" - QMakeVar set QMAKE_LIBS_XCB "$QMAKE_LIBS_XCB" - QMakeVar set QMAKE_DEFINES_XCB "$QMAKE_DEFINES_XCB" - fi - - if [ "$BUILD_ON_MAC" = "yes" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/mac/coreservices "CoreServices" $L_FLAGS $I_FLAGS $l_FLAGS $MAC_CONFIG_TEST_COMMANDLINE; then - QT_CONFIG="$QT_CONFIG coreservices" - else - QMakeVar add DEFINES QT_NO_CORESERVICES - fi - fi - - if [ "$PLATFORM_QPA" = "yes" ] && [ "$BUILD_ON_MAC" = "no" ] && [ "$XPLATFORM_MINGW" = "no" ]; then - if [ "$CFG_XCB" = "no" ] && [ "$CFG_EGLFS" = "no" ]; then - if [ "$QPA_PLATFORM_GUARD" = "yes" ] && - ( [ "$ORIG_CFG_XCB" = "auto" ] || [ "$ORIG_CFG_EGLFS" = "auto" ] ); then - echo "No QPA platform plugin enabled!" - echo " If you really want to build without a QPA platform plugin you must pass" - echo " -no-xcb and -no-eglfs to configure. Doing this will" - echo " produce a Qt that cannot run GUI applications." - echo " The dependencies needed for xcb to build are listed in" - echo " src/plugins/platforms/xcb/README" - exit 1 - fi - fi + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/fontconfig "FontConfig" $L_FLAGS $I_FLAGS $l_FLAGS $QT_CFLAGS_FONTCONFIG $QT_LIBS_FONTCONFIG; then + QT_CONFIG="$QT_CONFIG fontconfig" + QMakeVar set QMAKE_CFLAGS_FONTCONFIG "$QT_CFLAGS_FONTCONFIG" + QMakeVar set QMAKE_LIBS_FONTCONFIG "$QT_LIBS_FONTCONFIG" + CFG_LIBFREETYPE=system fi fi +# Save these for a check later +ORIG_CFG_XCB="$CFG_XCB" +ORIG_CFG_EGLFS="$CFG_EGLFS" + +if [ "$CFG_LIBUDEV" != "no" ]; then + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists libudev 2>/dev/null; then + QMAKE_INCDIR_LIBUDEV=`$PKG_CONFIG --cflags-only-I libudev 2>/dev/null | sed -e 's,^-I,,g' -e 's, -I, ,g'` + QMAKE_LIBS_LIBUDEV=`$PKG_CONFIG --libs libudev 2>/dev/null` + QMakeVar set QMAKE_INCDIR_LIBUDEV "$QMAKE_INCDIR_LIBUDEV" + QMakeVar set QMAKE_LIBS_LIBUDEV "$QMAKE_LIBS_LIBUDEV" + fi + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/libudev "libudev" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_INCDIR_LIBUDEV $QMAKE_LIBS_LIBUDEV; then + CFG_LIBUDEV=yes + QT_CONFIG="$QT_CONFIG libudev" + elif [ "$CFG_LIBUDEV" = "yes" ]; then + echo "The libudev functionality test failed!" + exit 1 + else + CFG_LIBUDEV=no + QMakeVar add DEFINES QT_NO_LIBUDEV + fi +fi + +if [ "$CFG_EVDEV" != "no" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/evdev "evdev" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_EVDEV=yes + QT_CONFIG="$QT_CONFIG evdev" + elif [ "$CFG_EVDEV" = "yes" ]; then + echo "The evdev functionality test failed!" + exit 1 + else + CFG_EVDEV=no + QMakeVar add DEFINES QT_NO_EVDEV + fi +fi + +# Check we actually have X11 :-) +if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xlib "XLib" $L_FLAGS $I_FLAGS $l_FLAGS; then + QT_CONFIG="$QT_CONFIG xlib" +fi + +# auto-detect Xrender support +if [ "$CFG_XRENDER" != "no" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xrender "Xrender" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_XRENDER=yes + QT_CONFIG="$QT_CONFIG xrender" + else + if [ "$CFG_XRENDER" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then + echo "Xrender support cannot be enabled due to functionality tests!" + echo " Turn on verbose messaging (-v) to $0 to see the final report." + echo " If you believe this message is in error you may use the continue" + echo " switch (-continue) to $0 to continue." + exit 101 + else + CFG_XRENDER=no + fi + fi +fi + +if [ "$CFG_XCB" != "no" ]; then + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xcb >= 1.5" 2>/dev/null; then + QMAKE_CFLAGS_XCB="`$PKG_CONFIG --cflags xcb 2>/dev/null`" + QMAKE_LIBS_XCB="`$PKG_CONFIG --libs xcb 2>/dev/null`" + fi + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb "xcb" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then + CFG_XCB=yes + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-render "xcb-render" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then + QT_CONFIG="$QT_CONFIG xcb-render" + fi + + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-poll-for-queued-event "xcb-poll-for-queued-event" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then + CFG_XCB_LIMITED=no + QT_CONFIG="$QT_CONFIG xcb-poll-for-queued-event" + fi + + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/xcb-xlib "xcb-xlib" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then + QT_CONFIG="$QT_CONFIG xcb-xlib" + fi + + if [ "$XPLATFORM_MAEMO" = "yes" ]; then + # auto-detect XInput2/Xinput support + if [ "$CFG_XINPUT2" != "no" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xinput2 "XInput2" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_XINPUT2=yes + CFG_XINPUT=no + else + if [ "$CFG_XINPUT2" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then + echo "XInput2 support cannot be enabled due to functionality tests!" + echo " Turn on verbose messaging (-v) to $0 to see the final report." + echo " If you believe this message is in error you may use the continue" + echo " switch (-continue) to $0 to continue." + exit 101 + else + CFG_XINPUT2=no + fi + fi + fi + fi + else + if [ "$CFG_XCB" = "yes" ]; then + echo "The XCB test failed!" + echo " You might need to install dependency packages." + echo " See src/plugins/platforms/xcb/README." + exit 1 + fi + CFG_XCB=no + QMakeVar add DEFINES QT_NO_XCB + fi +fi + +# Detect libxkbcommon +if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists xkbcommon 2>/dev/null; then + QMAKE_CFLAGS_XKBCOMMON="`$PKG_CONFIG --cflags xkbcommon 2>/dev/null`" + QMAKE_LIBS_XKBCOMMON="`$PKG_CONFIG --libs xkbcommon 2>/dev/null`" + QMAKE_CFLAGS_XCB="$QMAKE_CFLAGS_XCB $QMAKE_CFLAGS_XKBCOMMON" + QMAKE_LIBS_XCB="$QMAKE_LIBS_XCB $QMAKE_LIBS_XKBCOMMON" +else + QMAKE_DEFINES_XCB=QT_NO_XCB_XKB +fi + +# EGL Support +if [ "$CFG_EGL" != "no" ] && [ "$CFG_OPENGL" != "desktop" ]; then + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists egl 2>/dev/null; then + QMAKE_INCDIR_EGL=`$PKG_CONFIG --cflags-only-I egl 2>/dev/null | sed -e 's,^-I,,g' -e 's, -I, ,g'` + QMAKE_LIBS_EGL=`$PKG_CONFIG --libs egl 2>/dev/null` + QMAKE_CFLAGS_EGL=`$PKG_CONFIG --cflags egl 2>/dev/null` + QMakeVar set QMAKE_INCDIR_EGL "$QMAKE_INCDIR_EGL" + QMakeVar set QMAKE_LIBS_EGL "$QMAKE_LIBS_EGL" + fi # detect EGL support + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" "config.tests/qpa/egl" "EGL" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_EGL $QMAKE_LIBS_EGL; then + CFG_EGL=yes + elif [ "$CFG_EGL" = "yes" ]; then + echo " The EGL functionality test failed; EGL is required by some QPA plugins to manage contexts & surfaces." + echo " You might need to modify the include and library search paths by editing" + echo " QMAKE_INCDIR_EGL, QMAKE_LIBDIR_EGL and QMAKE_LIBS_EGL in ${XQMAKESPEC}." + exit 1 + else + CFG_EGL=no + fi +elif [ "$CFG_OPENGL" = "desktop" ]; then + if [ "$CFG_EGL" = "yes" ]; then + echo "EGL support was requested but Qt is being configured for desktop OpenGL." + echo "Either disable EGL support or enable OpenGL ES support." + exit 101 + fi + CFG_EGL=no +fi + +if [ "$CFG_EGLFS" != "no" ]; then + CFG_EGLFS="$CFG_EGL" +fi + +if [ -n "$QMAKE_CFLAGS_XCB" ] || [ -n "$QMAKE_LIBS_XCB" ]; then + QMakeVar set QMAKE_CFLAGS_XCB "$QMAKE_CFLAGS_XCB" + QMakeVar set QMAKE_LIBS_XCB "$QMAKE_LIBS_XCB" + QMakeVar set QMAKE_DEFINES_XCB "$QMAKE_DEFINES_XCB" +fi + +if [ "$BUILD_ON_MAC" = "yes" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/mac/coreservices "CoreServices" $L_FLAGS $I_FLAGS $l_FLAGS $MAC_CONFIG_TEST_COMMANDLINE; then + QT_CONFIG="$QT_CONFIG coreservices" + else + QMakeVar add DEFINES QT_NO_CORESERVICES + fi +fi + +if [ "$BUILD_ON_MAC" = "no" ] && [ "$XPLATFORM_MINGW" = "no" ]; then + if [ "$CFG_XCB" = "no" ] && [ "$CFG_EGLFS" = "no" ]; then + if [ "$QPA_PLATFORM_GUARD" = "yes" ] && + ( [ "$ORIG_CFG_XCB" = "auto" ] || [ "$ORIG_CFG_EGLFS" = "auto" ] ); then + echo "No QPA platform plugin enabled!" + echo " If you really want to build without a QPA platform plugin you must pass" + echo " -no-xcb and -no-eglfs to configure. Doing this will" + echo " produce a Qt that cannot run GUI applications." + echo " The dependencies needed for xcb to build are listed in" + echo " src/plugins/platforms/xcb/README" + exit 1 + fi +fi + fi + [ "$XPLATFORM_MINGW" = "yes" ] && [ "$CFG_PHONON" != "no" ] && CFG_PHONON="yes" # freetype support @@ -5531,12 +4923,12 @@ elif [ "$CFG_SHARED" = "no" ]; then QMAKE_OUTDIR="${QMAKE_OUTDIR}-static" QMAKE_CONFIG="$QMAKE_CONFIG static" fi -if [ "$PLATFORM_QPA" = "yes" ]; then - QMAKE_CONFIG="$QMAKE_CONFIG qpa" - QT_CONFIG="$QT_CONFIG qpa" - QTCONFIG_CONFIG="$QTCONFIG_CONFIG qpa" - rm -f "src/.moc/$QMAKE_OUTDIR/allmoc.cpp" # needs remaking if config changes -fi + +#FIXME: qpa is implicit this should all be removed +QMAKE_CONFIG="$QMAKE_CONFIG qpa" +QT_CONFIG="$QT_CONFIG qpa" +QTCONFIG_CONFIG="$QTCONFIG_CONFIG qpa" +rm -f "src/.moc/$QMAKE_OUTDIR/allmoc.cpp" # needs remaking if config changes if [ "$XPLATFORM_MINGW" != "yes" ]; then # Do not set this here for Windows. Let qmake do it so @@ -5670,62 +5062,6 @@ fi [ "$CFG_XCB" = "yes" ] && QT_CONFIG="$QT_CONFIG xcb" [ "$CFG_XINPUT2" = "yes" ] && QT_CONFIG="$QT_CONFIG xinput2" -if [ "$PLATFORM_X11" = "yes" ]; then - [ "$CFG_SM" = "yes" ] && QT_CONFIG="$QT_CONFIG x11sm" - - # for some reason, the following libraries are not always built shared, - # so *every* program/lib (including Qt) has to link against them - if [ "$CFG_XSHAPE" = "yes" ]; then - QT_CONFIG="$QT_CONFIG xshape" - fi - if [ "$CFG_XVIDEO" = "yes" ]; then - QT_CONFIG="$QT_CONFIG xvideo" - fi - if [ "$CFG_XSYNC" = "yes" ]; then - QT_CONFIG="$QT_CONFIG xsync" - fi - if [ "$CFG_XINERAMA" = "yes" ]; then - QT_CONFIG="$QT_CONFIG xinerama" - QMakeVar set QMAKE_LIBS_X11 '-lXinerama $$QMAKE_LIBS_X11' - fi - if [ "$CFG_XCURSOR" = "yes" ]; then - QT_CONFIG="$QT_CONFIG xcursor" - QMakeVar set QMAKE_LIBS_X11 '-lXcursor $$QMAKE_LIBS_X11' - fi - if [ "$CFG_XFIXES" = "yes" ]; then - QT_CONFIG="$QT_CONFIG xfixes" - QMakeVar set QMAKE_LIBS_X11 '-lXfixes $$QMAKE_LIBS_X11' - fi - if [ "$CFG_XRANDR" = "yes" ]; then - QT_CONFIG="$QT_CONFIG xrandr" - if [ "$CFG_XRENDER" != "yes" ]; then - # libXrandr uses 1 function from libXrender, so we always have to have it :/ - QMakeVar set QMAKE_LIBS_X11 '-lXrandr -lXrender $$QMAKE_LIBS_X11' - else - QMakeVar set QMAKE_LIBS_X11 '-lXrandr $$QMAKE_LIBS_X11' - fi - fi - if [ "$CFG_XRENDER" = "yes" ]; then - QT_CONFIG="$QT_CONFIG xrender" - QMakeVar set QMAKE_LIBS_X11 '-lXrender $$QMAKE_LIBS_X11' - fi - if [ "$CFG_MITSHM" = "yes" ]; then - QT_CONFIG="$QT_CONFIG mitshm" - fi - if [ "$CFG_FONTCONFIG" = "yes" ]; then - QT_CONFIG="$QT_CONFIG fontconfig" - fi - if [ "$CFG_XINPUT" = "yes" ]; then - QMakeVar set QMAKE_LIBS_X11 '-lXi $$QMAKE_LIBS_X11' - fi - if [ "$CFG_XINPUT" = "yes" ]; then - QT_CONFIG="$QT_CONFIG xinput tablet" - fi - if [ "$CFG_XKB" = "yes" ]; then - QT_CONFIG="$QT_CONFIG xkb" - fi -fi - [ '!' -z "$D_FLAGS" ] && QMakeVar add DEFINES "$D_FLAGS" [ '!' -z "$L_FLAGS" ] && QMakeVar add QMAKE_LIBDIR_FLAGS "$L_FLAGS" [ '!' -z "$l_FLAGS" ] && QMakeVar add LIBS "$l_FLAGS" @@ -5983,8 +5319,8 @@ if [ "$CFG_V8SNAPSHOT" = "yes" ]; then fi # ### Vestige -if [ "$CFG_DECLARATIVE_DEBUG" = "no" ]; then - QCONFIG_FLAGS="$QCONFIG_FLAGS QDECLARATIVE_NO_DEBUG_PROTOCOL" +if [ "$CFG_QML_DEBUG" = "no" ]; then + QCONFIG_FLAGS="$QCONFIG_FLAGS QT_QML_NO_DEBUGGER" fi if [ "$CFG_EXCEPTIONS" = "no" ]; then @@ -6097,10 +5433,8 @@ if [ "$CFG_DEV" = "yes" ]; then echo "#define QT_BUILD_INTERNAL" >>"$outpath/src/corelib/global/qconfig.h.new" fi -if [ "$PLATFORM_QPA" = "yes" ]; then - # Add QPA to config.h - QCONFIG_FLAGS="$QCONFIG_FLAGS Q_WS_QPA QT_NO_QWS_QPF QT_NO_QWS_QPF2" -fi +# Add QPA to config.h +QCONFIG_FLAGS="$QCONFIG_FLAGS Q_WS_QPA QT_NO_QWS_QPF QT_NO_QWS_QPF2" if [ "${CFG_USE_FLOATMATH}" = "yes" ]; then QCONFIG_FLAGS="${QCONFIG_FLAGS} QT_USE_MATH_H_FLOATS" @@ -6475,9 +5809,7 @@ else fi echo "Architecture: $CFG_ARCH" -if [ "$PLATFORM_QPA" = "yes" ]; then - echo "Host architecture: $CFG_HOST_ARCH" -fi +echo "Host architecture: $CFG_HOST_ARCH" if [ -n "$PLATFORM_NOTES" ]; then echo "Platform notes:" @@ -6515,7 +5847,7 @@ if [ "$CFG_JAVASCRIPTCORE_JIT" = "auto" ]; then else echo "JavaScriptCore JIT ..... $CFG_JAVASCRIPTCORE_JIT" fi -echo "Declarative debugging ...$CFG_DECLARATIVE_DEBUG" +echo "QML debugging .......... $CFG_QML_DEBUG" echo "PCH support ............ $CFG_PRECOMPILE" if [ "$CFG_ARCH" = "i386" -o "$CFG_ARCH" = "x86_64" ]; then echo "SSE2/SSE3/SSSE3......... ${CFG_SSE2}/${CFG_SSE3}/${CFG_SSSE3}" @@ -6569,22 +5901,21 @@ if [ "$CFG_OPENVG" ]; then echo "OpenVG support ......... $CFG_OPENVG" fi fi -if [ "$PLATFORM_X11" = "yes" ]; then - echo "NAS sound support ...... $CFG_NAS" - echo "XShape support ......... $CFG_XSHAPE" - echo "XVideo support ......... $CFG_XVIDEO" - echo "XSync support .......... $CFG_XSYNC" - echo "Xinerama support ....... $CFG_XINERAMA" - echo "Xcursor support ........ $CFG_XCURSOR" - echo "Xfixes support ......... $CFG_XFIXES" - echo "Xrandr support ......... $CFG_XRANDR" - echo "Xi support ............. $CFG_XINPUT" - echo "MIT-SHM support ........ $CFG_MITSHM" - echo "FontConfig support ..... $CFG_FONTCONFIG" - echo "XKB Support ............ $CFG_XKB" - echo "immodule support ....... $CFG_IM" - echo "GTK theme support ...... $CFG_QGTKSTYLE" -fi + +echo "XShape support ......... $CFG_XSHAPE" +echo "XVideo support ......... $CFG_XVIDEO" +echo "XSync support .......... $CFG_XSYNC" +echo "Xinerama support ....... $CFG_XINERAMA" +echo "Xcursor support ........ $CFG_XCURSOR" +echo "Xfixes support ......... $CFG_XFIXES" +echo "Xrandr support ......... $CFG_XRANDR" +echo "Xi support ............. $CFG_XINPUT" +echo "MIT-SHM support ........ $CFG_MITSHM" +echo "FontConfig support ..... $CFG_FONTCONFIG" +echo "XKB Support ............ $CFG_XKB" +echo "immodule support ....... $CFG_IM" +echo "GTK theme support ...... $CFG_QGTKSTYLE" + [ "$CFG_SQL_mysql" != "no" ] && echo "MySQL support .......... $CFG_SQL_mysql" [ "$CFG_SQL_psql" != "no" ] && echo "PostgreSQL support ..... $CFG_SQL_psql" [ "$CFG_SQL_odbc" != "no" ] && echo "ODBC support ........... $CFG_SQL_odbc" diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index cfb83a40934..5ffeb1996ce 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -246,7 +246,7 @@ information about a particular change. - QSystemLocale has been removed from the public API. -- QSqlQueryModel::indexInQuery() is now virtual. See note below under QSql. +- QSqlQueryModel::indexInQuery() is now virtual. See note below under QtSql. - QSqlDriver::subscribeToNotification, unsubscribeFromNotification, subscribedToNotifications, isIdentifierEscaped, and stripDelimiters @@ -506,6 +506,11 @@ now that QSqlDriver subclasses can reimplement these directly. * Database Drivers * **************************************************************************** +sqlite +------ +* QVariant::Bool type now mapped to integers 0/1 in SQL instead of strings +'true' and 'false'. Sqlite does not have a boolean column type and it is +customary to use integer. QTBUG-23895 **************************************************************************** * Platform Specific Changes * diff --git a/examples/network/multicastreceiver/receiver.cpp b/examples/network/multicastreceiver/receiver.cpp index 64488174104..041812f56a2 100644 --- a/examples/network/multicastreceiver/receiver.cpp +++ b/examples/network/multicastreceiver/receiver.cpp @@ -52,7 +52,7 @@ Receiver::Receiver(QWidget *parent) quitButton = new QPushButton(tr("&Quit")); udpSocket = new QUdpSocket(this); - udpSocket->bind(45454, QUdpSocket::ShareAddress); + udpSocket->bind(QHostAddress::AnyIPv4, 45454, QUdpSocket::ShareAddress); udpSocket->joinMulticastGroup(groupAddress); connect(udpSocket, SIGNAL(readyRead()), diff --git a/mkspecs/cmake/Qt5BasicConfig.cmake.in b/mkspecs/cmake/Qt5BasicConfig.cmake.in index 0334b6f6e2b..a04d2b4d4e2 100644 --- a/mkspecs/cmake/Qt5BasicConfig.cmake.in +++ b/mkspecs/cmake/Qt5BasicConfig.cmake.in @@ -1,5 +1,5 @@ -get_filename_component(_qt5_install_prefix \"${CMAKE_CURRENT_LIST_DIR}/$${CMAKE_RELATIVE_INSTALL_DIR}\" ABSOLUTE) +get_filename_component(_qt5$${CMAKE_MODULE_NAME}_install_prefix \"${CMAKE_CURRENT_LIST_DIR}/$${CMAKE_RELATIVE_INSTALL_DIR}\" ABSOLUTE) set(Qt5$${CMAKE_MODULE_NAME}_VERSION_MAJOR "$$eval(QT.$${MODULE}.MAJOR_VERSION)") set(Qt5$${CMAKE_MODULE_NAME}_VERSION_MINOR "$$eval(QT.$${MODULE}.MINOR_VERSION)") @@ -8,7 +8,7 @@ set(Qt5$${CMAKE_MODULE_NAME}_VERSION_PATCH "$$eval(QT.$${MODULE}.PATCH_VERSION)" set(Qt5$${CMAKE_MODULE_NAME}_LIBRARIES Qt5::$${CMAKE_MODULE_NAME}) !!IF isEmpty(CMAKE_INCLUDE_DIR_IS_ABSOLUTE) -set(Qt5$${CMAKE_MODULE_NAME}_INCLUDE_DIRS \"${_qt5_install_prefix}/$$CMAKE_INCLUDE_DIR\" \"${_qt5_install_prefix}/$${CMAKE_INCLUDE_DIR}Qt$${CMAKE_MODULE_NAME}\") +set(Qt5$${CMAKE_MODULE_NAME}_INCLUDE_DIRS \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$$CMAKE_INCLUDE_DIR\" \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_INCLUDE_DIR}Qt$${CMAKE_MODULE_NAME}\") !!ELSE set(Qt5$${CMAKE_MODULE_NAME}_INCLUDE_DIRS \"$$CMAKE_INCLUDE_DIR\" \"$${CMAKE_INCLUDE_DIR}Qt$${CMAKE_MODULE_NAME}\") !!ENDIF @@ -35,6 +35,8 @@ if (Qt5$${CMAKE_MODULE_NAME}_EXECUTABLE_COMPILE_FLAGS) list(REMOVE_DUPLICATES Qt5$${CMAKE_MODULE_NAME}_EXECUTABLE_COMPILE_FLAGS) endif() +set(Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES "$${CMAKE_QT5_MODULE_DEPS}") + !!IF !isEmpty(CMAKE_STATIC_TYPE) # For static builds, we also list the dependencies of # Qt so that consumers can build. @@ -84,8 +86,6 @@ list(APPEND Qt5Gui_LIB_DEPENDENCIES ${JPEG_LIBRARIES}) !!ENDIF # Static -list(APPEND Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES "$${CMAKE_QT5_MODULE_DEPS}") - if (NOT _Qt5$${CMAKE_MODULE_NAME}_target) set(_Qt5$${CMAKE_MODULE_NAME}_target 1) !!IF !isEmpty(CMAKE_STATIC_TYPE) @@ -98,29 +98,29 @@ if (NOT _Qt5$${CMAKE_MODULE_NAME}_target) !!ENDIF endif() -!!IF !isEmpty(debug_type) +!!IF !isEmpty(CMAKE_DEBUG_TYPE) set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES_DEBUG \"${Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}\" !!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) - IMPORTED_LOCATION_DEBUG \"${_qt5_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_LIB_FILE_LOCATION_DEBUG}\" + IMPORTED_LOCATION_DEBUG \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_LIB_FILE_LOCATION_DEBUG}\" !!ELSE IMPORTED_LOCATION_DEBUG \"$${CMAKE_LIB_DIR}$${CMAKE_LIB_FILE_LOCATION_DEBUG}\" !!ENDIF ) !!IF !isEmpty(CMAKE_IMPLIB_FILE_LOCATION_DEBUG) set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES - IMPORTED_IMPLIB_DEBUG \"${_qt5_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" + IMPORTED_IMPLIB_DEBUG \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" ) !!ENDIF !!ENDIF -!!IF !isEmpty(release_type) +!!IF !isEmpty(CMAKE_RELEASE_TYPE) set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE \"${Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}\" !!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) - IMPORTED_LOCATION_RELEASE \"${_qt5_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_LIB_FILE_LOCATION_RELEASE}\" + IMPORTED_LOCATION_RELEASE \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_LIB_FILE_LOCATION_RELEASE}\" !!ELSE IMPORTED_LOCATION_RELEASE \"$${CMAKE_LIB_DIR}$${CMAKE_LIB_FILE_LOCATION_RELEASE}\" !!ENDIF @@ -128,7 +128,7 @@ set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES !!IF !isEmpty(CMAKE_IMPLIB_FILE_LOCATION_RELEASE) set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES !!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) - IMPORTED_IMPLIB_RELEASE \"${_qt5_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" + IMPORTED_IMPLIB_RELEASE \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" !!ELSE IMPORTED_IMPLIB_RELEASE \"$${CMAKE_LIB_DIR}$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" !!ENDIF diff --git a/mkspecs/common/qcc-base-qnx.conf b/mkspecs/common/qcc-base-qnx.conf index 11e8ca43a2a..ec0d27873d0 100644 --- a/mkspecs/common/qcc-base-qnx.conf +++ b/mkspecs/common/qcc-base-qnx.conf @@ -4,6 +4,8 @@ include(qcc-base.conf) +CONFIG += qnx + QMAKE_LFLAGS_SHLIB += -shared QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB QMAKE_LFLAGS_SONAME += -Wl,-soname, diff --git a/mkspecs/common/qcc-base.conf b/mkspecs/common/qcc-base.conf index a9e86efb756..a2aefc6cd31 100644 --- a/mkspecs/common/qcc-base.conf +++ b/mkspecs/common/qcc-base.conf @@ -3,11 +3,14 @@ # # - The QNX qcc compiler # -# The only difference between this and gcc-base.conf is that -pipe is removed -# as it's on by default in qcc (and has an analogous -nopipe option) +# The differences between this and gcc-base.conf are that +# +# 1) -pipe is removed as it's on by default in qcc (and has an analogous -nopipe option) +# 2) -Wno-psabi is added to silence harmless warnings about va_list mangling +# 3) -fstack-protector -fstack-protector-all is added to enable stack smashing protection # -QMAKE_CFLAGS += -Wno-psabi +QMAKE_CFLAGS += -Wno-psabi -fstack-protector -fstack-protector-all QMAKE_CFLAGS_DEPS += -M QMAKE_CFLAGS_WARN_ON += -Wall -W QMAKE_CFLAGS_WARN_OFF += -w diff --git a/src/plugins/platforms/xlib/qglxintegration.h b/mkspecs/devices/linux-arm-amlogic-8726M-g++/qeglfs_hooks_8726m.cpp similarity index 59% rename from src/plugins/platforms/xlib/qglxintegration.h rename to mkspecs/devices/linux-arm-amlogic-8726M-g++/qeglfs_hooks_8726m.cpp index 3aef49a52b7..06cb424e4f8 100644 --- a/src/plugins/platforms/xlib/qglxintegration.h +++ b/mkspecs/devices/linux-arm-amlogic-8726M-g++/qeglfs_hooks_8726m.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the qmake spec of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -39,45 +39,57 @@ ** ****************************************************************************/ -#ifndef Q_GLX_CONTEXT_H -#define Q_GLX_CONTEXT_H +#include "qeglfs_hooks.h" +#include +#include +#include +#include +#include +#include +#include -#include "qxlibwindow.h" - -#include -#include - -#include - -#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2) -#include - -QT_BEGIN_NAMESPACE - -class QGLXContext : public QPlatformOpenGLContext +void QEglFSHooks::platformInit() { -public: - QGLXContext(QXlibScreen *xd, const QSurfaceFormat &format, QPlatformOpenGLContext *share); - ~QGLXContext(); +} - QSurfaceFormat format() const; - void swapBuffers(QPlatformSurface *surface); - bool makeCurrent(QPlatformSurface *surface); - void doneCurrent(); - virtual void (*getProcAddress(const QByteArray& procName))(); +void QEglFSHooks::platformDestroy() +{ +} - GLXContext glxContext() const {return m_context;} +EGLNativeDisplayType QEglFSHooks::platformDisplay() const +{ + return EGL_DEFAULT_DISPLAY; +} - QSurfaceFormat surfaceFormat() const; +QSize QEglFSHooks::screenSize() const +{ + int fd = open("/dev/fb0", O_RDONLY); + if (fd == -1) { + qFatal("Failed to open fb to detect screen resolution!"); + } -private: - QXlibScreen *m_screen; - GLXContext m_context; - QSurfaceFormat m_windowFormat; -}; + struct fb_var_screeninfo vinfo; + if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) { + qFatal("Could not get variable screen info"); + } -QT_END_NAMESPACE + close(fd); -#endif //!defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2) + return QSize(vinfo.xres, vinfo.yres); +} -#endif +EGLNativeWindowType QEglFSHooks::createNativeWindow(const QSize &size) +{ + fbdev_window *window = new fbdev_window; + window->width = size.width(); + window->height = size.height(); + + return window; +} + +void QEglFSHooks::destroyNativeWindow(EGLNativeWindowType window) +{ + delete window; +} + +QEglFSHooks platform_hooks; diff --git a/mkspecs/devices/linux-arm-amlogic-8726M-g++/qmake.conf b/mkspecs/devices/linux-arm-amlogic-8726M-g++/qmake.conf new file mode 100644 index 00000000000..b0b02f32e6a --- /dev/null +++ b/mkspecs/devices/linux-arm-amlogic-8726M-g++/qmake.conf @@ -0,0 +1,36 @@ +# +# qmake configuration for linux-g++ +# + +MAKEFILE_GENERATOR = UNIX +TARGET_PLATFORM = unix +TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index +QT += core gui +QMAKE_INCREMENTAL_STYLE = sublib + +include(../../common/linux.conf) +include(../../common/gcc-base-unix.conf) +include(../../common/g++-unix.conf) + +load(device_config) + +isEmpty(CROSS_COMPILE): error("CROSS_COMPILE needs to be set via -device-option CROSS_COMPILE=") + +QMAKE_CC = $${CROSS_COMPILE}gcc +QMAKE_CXX = $${CROSS_COMPILE}g++ +QMAKE_LINK = $${QMAKE_CXX} +QMAKE_LINK_SHLIB = $${QMAKE_CXX} + +QMAKE_AR = $${CROSS_COMPILE}ar cqs +QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy +QMAKE_STRIP = $${CROSS_COMPILE}strip + +QMAKE_CFLAGS_RELEASE += -O2 -mfloat-abi=softfp -mfpu=neon -mcpu=cortex-a9 +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE + +deviceSanityCheckCompiler() + +EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/qeglfs_hooks_8726m.cpp + +load(qt_config) diff --git a/mkspecs/devices/linux-arm-amlogic-8726M-g++/qplatformdefs.h b/mkspecs/devices/linux-arm-amlogic-8726M-g++/qplatformdefs.h new file mode 100644 index 00000000000..e2464172231 --- /dev/null +++ b/mkspecs/devices/linux-arm-amlogic-8726M-g++/qplatformdefs.h @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../linux-g++/qplatformdefs.h" + diff --git a/mkspecs/devices/linux-mipsel-broadcom-97425-g++/qmake.conf b/mkspecs/devices/linux-mipsel-broadcom-97425-g++/qmake.conf new file mode 100644 index 00000000000..866fad639bc --- /dev/null +++ b/mkspecs/devices/linux-mipsel-broadcom-97425-g++/qmake.conf @@ -0,0 +1,65 @@ +# +# qmake configuration for linux-mipsel-broadcom-97425-g++ +# + +MAKEFILE_GENERATOR = UNIX +TARGET_PLATFORM = unix +TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index +QT += core gui +QMAKE_INCREMENTAL_STYLE = sublib + +include(../../common/linux.conf) +include(../../common/gcc-base-unix.conf) +include(../../common/g++-unix.conf) + +load(device_config) + +# Modify the defaults we loaded above +CROSS_COMPILE = mipsel-linux- +QMAKE_CC = $${CROSS_COMPILE}gcc +QMAKE_CXX = $${CROSS_COMPILE}g++ +QMAKE_LINK = $${QMAKE_CXX} +QMAKE_LINK_SHLIB = $${QMAKE_CXX} + +QMAKE_AR = $${CROSS_COMPILE}ar cqs +QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy +QMAKE_STRIP = $${CROSS_COMPILE}strip + +QMAKE_CFLAGS_RELEASE += -O2 +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE + +#TODO: Clean Qt to work with uclibc not calling itself GLIBC. +#QMAKE_CFLAGS += -D__FORCE_NOGLIBC +#QMAKE_CXXFLAGS += -D__FORCE_NOGLIBC + + +BRCM_PLATFORM = 97425 + +# Sanity checks +deviceSanityCheckCompiler() +isEmpty(B_REFSW_DEBUG):error("B_REFSW_DEBUG needs to be set via -device-option B_REFSW_DEBUG=(y|n).") +isEmpty(BRCM_ROCKFORD_PATH):error("BRCM_ROCKFORD_PATH needs to be set via -device-option BRCM_ROCKFORD_PATH=path.") +isEmpty(BRCM_APPLIBS_PATH):error("BRCM_APPLIBS_PATH needs to be set via -device-option BRCM_APPLIBS_PATH=path.") + +# Figure the kind of directfb build used. +BRCM_BUILD_TYPE = debug +contains(B_REFSW_DEBUG, [Nn]) { + BRCM_BUILD_TYPE = release +} + +QMAKE_INCDIR_OPENGL_ES2 = $${BRCM_ROCKFORD_PATH}/middleware/v3d/interface/khronos/include +QMAKE_LIBDIR_OPENGL_ES2 = $${BRCM_ROCKFORD_PATH}/middleware/v3d/lib_$${BRCM_PLATFORM}_$${BRCM_BUILD_TYPE} +QMAKE_LIBS_OPENGL_ES2 = -lv3ddriver -lrt + +INCLUDEPATH += $${BRCM_APPLIBS_PATH}/opensource/zlib/zlib-1.2.3 +QMAKE_LIBDIR += $${BRCM_APPLIBS_PATH}/opensource/zlib/zlib-1.2.3 + +# DirectFB, needs to be changed once -directfb is added to configure +DIRECTFB_INCLUDEPATH = $${BRCM_APPLIBS_PATH}/opensource/directfb/bin/DirectFB-1.4.15_multi_$${BRCM_BUILD_TYPE}_build.97425B1/usr/local/include/directfb $${BRCM_ROCKFORD_PATH}/middleware/platform/directfb +DIRECTFB_LIBS = -L$${BRCM_APPLIBS_PATH}/opensource/directfb/bin/DirectFB-1.4.15_multi_$${BRCM_BUILD_TYPE}_build.97425B1/usr/local/lib -L$${BRCM_ROCKFORD_PATH}/middleware/platform/directfb/lib_$${BRCM_PLATFORM}_$${BRCM_BUILD_TYPE} -ldirectfb -lfusion -ldirect -lpthread -lnexus -ldbpl -lz + + +QMAKE_LFLAGS += -Wl,-rpath-link,$$QMAKE_LIBDIR_OPENGL_ES2 -Wl,-rpath-link,$${BRCM_APPLIBS_PATH}/opensource/zlib/zlib-1.2.3 + +load(qt_config) diff --git a/mkspecs/devices/linux-mipsel-broadcom-97425-g++/qplatformdefs.h b/mkspecs/devices/linux-mipsel-broadcom-97425-g++/qplatformdefs.h new file mode 100644 index 00000000000..9e6b0f5bccd --- /dev/null +++ b/mkspecs/devices/linux-mipsel-broadcom-97425-g++/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../linux-g++/qplatformdefs.h" diff --git a/mkspecs/devices/linux-rasp-pi-g++/qeglfs_hooks.cpp b/mkspecs/devices/linux-rasp-pi-g++/qeglfs_hooks.cpp new file mode 100644 index 00000000000..2cbd297a906 --- /dev/null +++ b/mkspecs/devices/linux-rasp-pi-g++/qeglfs_hooks.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfs_hooks.h" + +#include + +#if 0 //fb size query +#include +#include +#include +#include +#include +#include +#endif + +static DISPMANX_DISPLAY_HANDLE_T dispman_display = 0; +static DISPMANX_UPDATE_HANDLE_T dispman_update = 0; + +void QEglFSHooks::platformInit() +{ + bcm_host_init(); +} + +EGLNativeDisplayType QEglFSHooks::platformDisplay() const +{ + dispman_display = vc_dispmanx_display_open(0/* LCD */); + return EGL_DEFAULT_DISPLAY; +} + +void QEglFSHooks::platformDestroy() +{ + vc_dispmanx_display_close(dispman_display); +} + +QSize QEglFSHooks::screenSize() const +{ + //both mechanisms work +#if 1 + uint32_t width, height; + graphics_get_display_size(0 /* LCD */, &width, &height); + return QSize(width, height); +#else + int fd = open("/dev/fb0", O_RDONLY); + if (fd == -1) { + fprintf(stderr, "Failed to open fb to detect screen resolution!\n"); + return QSize(); + } + + struct fb_var_screeninfo vinfo; + if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) = -1) { + fprintf(stderr, "Could not query screen info variable\n"); + close(fd); + return QSize(); + } + + close(fd); + + return QSize(vinfo.xres, vinfo.yres); +#endif +} + +EGLNativeWindowType QEglFSHooks::createNativeWindow(const QSize &size) +{ + VC_RECT_T dst_rect; + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = size.width(); + dst_rect.height = size.height(); + + VC_RECT_T src_rect; + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = size.width() << 16; + src_rect.height = size.height() << 16; + + dispman_update = vc_dispmanx_update_start(0); + + VC_DISPMANX_ALPHA_T alpha; + alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; + alpha.opacity = 0xFF; + alpha.mask = 0; + + DISPMANX_ELEMENT_HANDLE_T dispman_element = vc_dispmanx_element_add( + dispman_update, dispman_display, 0, &dst_rect, 0, &src_rect, + DISPMANX_PROTECTION_NONE, &alpha, (DISPMANX_CLAMP_T *)NULL, (DISPMANX_TRANSFORM_T)0); + + vc_dispmanx_update_submit_sync(dispman_update); + + EGL_DISPMANX_WINDOW_T *eglWindow = new EGL_DISPMANX_WINDOW_T; + eglWindow->element = dispman_element; + eglWindow->width = size.width(); + eglWindow->height = size.height(); + + return eglWindow; +} + +void QEglFSHooks::destroyNativeWindow(EGLNativeWindowType window) +{ + EGL_DISPMANX_WINDOW_T *eglWindow = static_cast(window); + vc_dispmanx_element_remove(dispman_update, eglWindow->element); + delete eglWindow; +} + +QEglFSHooks platform_hooks; diff --git a/mkspecs/devices/linux-rasp-pi-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi-g++/qmake.conf new file mode 100644 index 00000000000..326d6b3b61e --- /dev/null +++ b/mkspecs/devices/linux-rasp-pi-g++/qmake.conf @@ -0,0 +1,56 @@ +# +# qmake configuration for Broadcom's Raspberry PI +# http://wiki.qt-project.org/Devices/RaspberryPi + +!exists($$[QT_SYSROOT]/usr/include/libudev.h) { + message("Keyboard support requires udev") + message("Install libudev-dev in your rootfs") + error() +} + +MAKEFILE_GENERATOR = UNIX +TARGET_PLATFORM = unix +TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index +QT += core gui +QMAKE_INCREMENTAL_STYLE = sublib + +include(../../common/linux.conf) +include(../../common/gcc-base-unix.conf) +include(../../common/g++-unix.conf) + +load(device_config) + +QMAKE_CC = $${CROSS_COMPILE}gcc +QMAKE_CXX = $${CROSS_COMPILE}g++ +QMAKE_LINK = $${QMAKE_CXX} +QMAKE_LINK_SHLIB = $${QMAKE_CXX} + +# modifications to linux.conf +QMAKE_AR = $${CROSS_COMPILE}ar cqs +QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy +QMAKE_STRIP = $${CROSS_COMPILE}strip + +#Circular dependency in GLES2 <-> EGL requires the following abomination +QMAKE_LIBS_EGL = -L$$[QT_SYSROOT]/opt/vc/lib -lWFC -lGLESv2 -lEGL -lbcm_host -lopenmaxil +QMAKE_LIBS_OPENGL_ES2 = $${QMAKE_LIBS_EGL} +QMAKE_LIBS_OPENVG = $${QMAKE_LIBS_EGL} + +QMAKE_INCDIR_EGL = $$[QT_SYSROOT]/opt/vc/include +QMAKE_INCDIR_OPENGL_ES2 = $${QMAKE_INCDIR_EGL} + +QMAKE_CFLAGS_RELEASE += \ + -mfloat-abi=softfp \ + -mfpu=vfp \ + -mtune=arm1176jzf-s \ + -march=armv6zk \ + -mabi=aapcs-linux + +QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE + +EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/qeglfs_hooks.cpp + +# Sanity check +deviceSanityCheckCompiler() + +load(qt_config) diff --git a/mkspecs/devices/linux-rasp-pi-g++/qplatformdefs.h b/mkspecs/devices/linux-rasp-pi-g++/qplatformdefs.h new file mode 100644 index 00000000000..62cbb049dd2 --- /dev/null +++ b/mkspecs/devices/linux-rasp-pi-g++/qplatformdefs.h @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../linux-g++/qplatformdefs.h" + +#define QT_QPA_DEFAULT_PLATFORM_NAME "eglfs" diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index 6a8045ab3bb..b8809a236b3 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -17,10 +17,6 @@ defineReplace(cmakeModuleList) { CMAKE_MODULE_NAME = $$cmakeModuleName($${MODULE}) -CMAKE_MODULE_DEPS = $$cmakeModuleList($$eval(QT.$${MODULE}.depends)) -CMAKE_PARTIAL_MODULE_DEPS = $$replace(CMAKE_MODULE_DEPS, ";", ";Qt5::") -!isEmpty(CMAKE_PARTIAL_MODULE_DEPS):CMAKE_QT5_MODULE_DEPS = "Qt5::$${CMAKE_PARTIAL_MODULE_DEPS}" - CMAKE_QT_INSTALL_PREFIX = $$replace($$list($$[QT_INSTALL_PREFIX]), \\\\, /)/ CMAKE_QT_INSTALL_PREFIX_ESCAPED = "^$$re_escape($$CMAKE_QT_INSTALL_PREFIX)" @@ -114,11 +110,11 @@ macx { } } -debug_type = -release_type = +CMAKE_DEBUG_TYPE = +CMAKE_RELEASE_TYPE = -debug_and_release|debug:debug_type = debug -debug_and_release|release:release_type = release +debug_and_release|debug:CMAKE_DEBUG_TYPE = debug +debug_and_release|release:CMAKE_RELEASE_TYPE = release INSTALLS += cmake_qt5_module_files diff --git a/mkspecs/features/declarative_debug.prf b/mkspecs/features/declarative_debug.prf index 59e45f662f4..9125fcf33fe 100644 --- a/mkspecs/features/declarative_debug.prf +++ b/mkspecs/features/declarative_debug.prf @@ -1 +1,2 @@ DEFINES += QT_DECLARATIVE_DEBUG +warning("CONFIG+=declarative_debug is deprecated. Use qml_debug instead!") diff --git a/mkspecs/features/device_config.prf b/mkspecs/features/device_config.prf index 56059e13cfd..90bf9150e9e 100644 --- a/mkspecs/features/device_config.prf +++ b/mkspecs/features/device_config.prf @@ -25,3 +25,14 @@ exists($$DEVICE_PRI):include($$DEVICE_PRI) unset(DEVICE_PRI) unset(DIR) +# Provide a function to be used by mkspecs +defineTest(deviceSanityCheckCompiler) { + # Check if the binary exists, e.g. with an absolute path + exists($$QMAKE_CXX):return() + + # Check if the compiler is in the path + system("which $$QMAKE_CXX > /dev/null"):return() + + error("Compiler $$QMAKE_CXX not found") +} + diff --git a/mkspecs/features/qml_debug.prf b/mkspecs/features/qml_debug.prf new file mode 100644 index 00000000000..72f4f2202a6 --- /dev/null +++ b/mkspecs/features/qml_debug.prf @@ -0,0 +1 @@ +DEFINES += QT_QML_DEBUG diff --git a/mkspecs/features/qt_module_config.prf b/mkspecs/features/qt_module_config.prf index 75156a1f448..ac0b635f2f5 100644 --- a/mkspecs/features/qt_module_config.prf +++ b/mkspecs/features/qt_module_config.prf @@ -42,7 +42,7 @@ CONFIG -= fix_output_dirs win32|mac:!macx-xcode:CONFIG += debug_and_release linux*:QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF -!isEmpty(MODULE):CONFIG += create_cmake +!isEmpty(DESTDIR):CONFIG += create_cmake contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols unix:contains(QT_CONFIG, reduce_relocations):CONFIG += bsymbolic_functions diff --git a/mkspecs/unsupported/qnx-armv7le-qcc/qmake.conf b/mkspecs/unsupported/qnx-armv7le-qcc/qmake.conf index ea206e28ec3..ac6da270615 100644 --- a/mkspecs/unsupported/qnx-armv7le-qcc/qmake.conf +++ b/mkspecs/unsupported/qnx-armv7le-qcc/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release link_prl qnx +CONFIG += qt warn_on release link_prl QT += core gui include(../../common/g++-unix.conf) diff --git a/qmake/generators/win32/borland_bmake.cpp b/qmake/generators/win32/borland_bmake.cpp index bf1041f9f59..4c4ddf642e4 100644 --- a/qmake/generators/win32/borland_bmake.cpp +++ b/qmake/generators/win32/borland_bmake.cpp @@ -139,6 +139,7 @@ void BorlandMakefileGenerator::writeBuildRulesPart(QTextStream &t) { if (project->first("TEMPLATE") == "aux") { t << "first:" << endl; + t << "all:" << endl; return; } diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index c088e8e480c..e62221e636e 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -433,6 +433,7 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t) { if (project->first("TEMPLATE") == "aux") { t << "first:" << endl; + t << "all:" << endl; return; } diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index b48dd4230ac..db6651cb884 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -344,6 +344,7 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t) { if (project->first("TEMPLATE") == "aux") { t << "first:" << endl; + t << "all:" << endl; return; } diff --git a/qmake/project.cpp b/qmake/project.cpp index 1f936a04c2a..c491e9b1b73 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -1721,7 +1721,8 @@ QMakeProject::doProjectExpand(QString func, QList args_list, function_blocks.push(defined); QStringList ret; defined->exec(args_list, this, place, ret); - Q_ASSERT(function_blocks.pop() == defined); + bool correct = function_blocks.pop() == defined; + Q_ASSERT(correct); Q_UNUSED(correct); return ret; } @@ -2206,7 +2207,8 @@ QMakeProject::doProjectTest(QString func, QList args_list, QHashexec(args_list, this, place, ret); - Q_ASSERT(function_blocks.pop() == defined); + bool correct = function_blocks.pop() == defined; + Q_ASSERT(correct); Q_UNUSED(correct); if(ret.isEmpty()) { return true; diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-thai.c b/src/3rdparty/harfbuzz/src/harfbuzz-thai.c index bf6c35b19c4..3c0ffe83583 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-thai.c +++ b/src/3rdparty/harfbuzz/src/harfbuzz-thai.c @@ -263,8 +263,13 @@ static HB_Bool HB_ThaiConvertStringToGlyphIndices (HB_ShaperItem *item) // The only glyphs that should be passed to this function that cannot be mapped to // tis620 are the ones of type Inherited class. Pass these glyphs untouched. glyphString[slen++] = string[i]; - if (string[i] == 0x200D || string[i] == 0x200C) - item->attributes[slen-1].dontPrint = true; // Hide ZWJ and ZWNJ characters + if (string[i] == 0x200D || string[i] == 0x200C) { + // Check that we do not run out of bounds when setting item->attributes. If we do + // run out of bounds then this function will return false, the necessary amount of + // memory is reallocated, and this function will then be called again. + if (slen <= item->num_glyphs) + item->attributes[slen-1].dontPrint = true; // Hide ZWJ and ZWNJ characters + } } else { glyphString[slen++] = (HB_UChar16) thai_get_glyph_index (font_type, rglyphs[lgi]); } diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 5acc13c6f3d..aa31fbc2265 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -30,9 +30,6 @@ list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE) set(QT_LIBINFIX \"$${QT_LIBINFIX}\") !!ENDIF -set(QT_CONFIG \"$${CONFIG}\") -set(QT_QCONFIG \"$${QT_CONFIG}\") - !!IF !isEmpty(CMAKE_WINDOWS_BUILD) set(Qt5Core_QTMAIN_LIBRARIES Qt5::WinMain) @@ -41,22 +38,22 @@ if (NOT _Qt5WinMain_target) add_library(Qt5::WinMain STATIC IMPORTED) endif() -!!IF !isEmpty(debug_type) +!!IF !isEmpty(CMAKE_DEBUG_TYPE) set_property(TARGET Qt5::WinMain APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) set_target_properties(Qt5::WinMain PROPERTIES !!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) - IMPORTED_LOCATION_DEBUG "${_qt5_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_WINMAIN_FILE_LOCATION_DEBUG}" + IMPORTED_LOCATION_DEBUG "${_qt5_corelib_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_WINMAIN_FILE_LOCATION_DEBUG}" !!ELSE IMPORTED_LOCATION_DEBUG "$${CMAKE_LIB_DIR}$${CMAKE_WINMAIN_FILE_LOCATION_DEBUG}" !!ENDIF ) !!ENDIF -!!IF !isEmpty(release_type) +!!IF !isEmpty(CMAKE_RELEASE_TYPE) set_property(TARGET Qt5::WinMain APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) set_target_properties(Qt5::WinMain PROPERTIES !!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) - IMPORTED_LOCATION_RELEASE \"${_qt5_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_WINMAIN_FILE_LOCATION_RELEASE}\" + IMPORTED_LOCATION_RELEASE \"${_qt5_corelib_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_WINMAIN_FILE_LOCATION_RELEASE}\" !!ELSE IMPORTED_LOCATION_RELEASE \"$${CMAKE_LIB_DIR}$${CMAKE_WINMAIN_FILE_LOCATION_RELEASE}\" !!ENDIF diff --git a/src/corelib/codecs/codecs.pri b/src/corelib/codecs/codecs.pri index a6f8914516a..a8a78cec060 100644 --- a/src/corelib/codecs/codecs.pri +++ b/src/corelib/codecs/codecs.pri @@ -38,7 +38,7 @@ unix { contains(QT_CONFIG,iconv) { HEADERS += codecs/qiconvcodec_p.h SOURCES += codecs/qiconvcodec.cpp - qnx-*-qcc:LIBS_PRIVATE *= -liconv + qnx:LIBS_PRIVATE *= -liconv } else:contains(QT_CONFIG,gnu-libiconv) { HEADERS += codecs/qiconvcodec_p.h SOURCES += codecs/qiconvcodec.cpp diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index ef3d2816cc3..315f53cbb4e 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -90,6 +90,7 @@ # define Q_DECL_ALIGN(n) __declspec(align(n)) # define Q_ASSUME(expr) __assume(expr) # define Q_UNREACHABLE() __assume(0) +# define Q_NORETURN __declspec(noreturn) /* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */ # if defined(__INTEL_COMPILER) # define Q_CC_INTEL @@ -165,6 +166,7 @@ # define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) # define Q_LIKELY(expr) __builtin_expect(!!(expr), true) # define Q_UNLIKELY(expr) __builtin_expect(!!(expr), false) +# define Q_NORETURN __attribute__((__noreturn__)) # if !defined(QT_MOC_CPP) # define Q_PACKED __attribute__ ((__packed__)) # define Q_NO_PACKED_REFERENCE @@ -399,6 +401,10 @@ # error "Qt has not been tested with this compiler - see http://www.qt-project.org/" #endif +#ifndef Q_NORETURN +# define Q_NORETURN +#endif + /* * C++11 support * diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index f89b0b34210..81251618971 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2886,4 +2886,203 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) otherwise. */ +/*! + \macro qDebug(const char *message, ...) + \relates + + Calls the message handler with the debug message \a message. If no + message handler has been installed, the message is printed to + stderr. Under Windows, the message is sent to the console, if it is a + console application; otherwise, it is sent to the debugger. This + function does nothing if \c QT_NO_DEBUG_OUTPUT was defined + during compilation. + + + If you pass the function a format string and a list of arguments, + it works in similar way to the C printf() function. The format + should be a Latin-1 string. + + Example: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 24 + + If you include \c , a more convenient syntax is also + available: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 25 + + With this syntax, the function returns a QDebug object that is + configured to use the QtDebugMsg message type. It automatically + puts a single space between each item, and outputs a newline at + the end. It supports many C++ and Qt types. + + To suppress the output at run-time, install your own message handler + with qInstallMessageHandler(). + + \sa qWarning(), qCritical(), qFatal(), qInstallMessageHandler(), + {Debugging Techniques} +*/ + +/*! + \macro qWarning(const char *message, ...) + \relates + + Calls the message handler with the warning message \a message. If no + message handler has been installed, the message is printed to + stderr. Under Windows, the message is sent to the debugger. This + function does nothing if \c QT_NO_WARNING_OUTPUT was defined + during compilation; it exits if the environment variable \c + QT_FATAL_WARNINGS is defined. + + This function takes a format string and a list of arguments, + similar to the C printf() function. The format should be a Latin-1 + string. + + Example: + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 26 + + If you include , a more convenient syntax is + also available: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 27 + + This syntax inserts a space between each item, and + appends a newline at the end. + + To suppress the output at runtime, install your own message handler + with qInstallMessageHandler(). + + \sa qDebug(), qCritical(), qFatal(), qInstallMessageHandler(), + {Debugging Techniques} +*/ + +/*! + \macro qCritical(const char *message, ...) + \relates + + Calls the message handler with the critical message \a message. If no + message handler has been installed, the message is printed to + stderr. Under Windows, the message is sent to the debugger. + + This function takes a format string and a list of arguments, + similar to the C printf() function. The format should be a Latin-1 + string. + + Example: + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 28 + + If you include , a more convenient syntax is + also available: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 29 + + A space is inserted between the items, and a newline is + appended at the end. + + To suppress the output at runtime, install your own message handler + with qInstallMessageHandler(). + + \sa qDebug(), qWarning(), qFatal(), qInstallMessageHandler(), + {Debugging Techniques} +*/ + +/*! + \macro qFatal(const char *message, ...) + \relates + + Calls the message handler with the fatal message \a message. If no + message handler has been installed, the message is printed to + stderr. Under Windows, the message is sent to the debugger. + + If you are using the \b{default message handler} this function will + abort on Unix systems to create a core dump. On Windows, for debug builds, + this function will report a _CRT_ERROR enabling you to connect a debugger + to the application. + + This function takes a format string and a list of arguments, + similar to the C printf() function. + + Example: + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 30 + + To suppress the output at runtime, install your own message handler + with qInstallMessageHandler(). + + \sa qDebug(), qCritical(), qWarning(), qInstallMessageHandler(), + {Debugging Techniques} +*/ + +/*! + \typedef QtMsgHandler + \relates + \deprecated + + This is a typedef for a pointer to a function with the following + signature: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 7 + + This typedef is deprecated, you should use QMessageHandler instead. + \sa QtMsgType, QMessageHandler, qInstallMsgHandler(), qInstallMessageHandler() +*/ + +/*! + \typedef QMessageHandler + \relates + \since 5.0 + + This is a typedef for a pointer to a function with the following + signature: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 49 + + \sa QtMsgType, qInstallMessageHandler() +*/ + +/*! + \fn QMessageHandler qInstallMessageHandler(QMessageHandler handler) + \relates + \since 5.0 + + Installs a Qt message \a handler which has been defined + previously. Returns a pointer to the previous message handler + (which may be 0). + + The message handler is a function that prints out debug messages, + warnings, critical and fatal error messages. The Qt library (debug + mode) contains hundreds of warning messages that are printed + when internal errors (usually invalid function arguments) + occur. Qt built in release mode also contains such warnings unless + QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during + compilation. If you implement your own message handler, you get total + control of these messages. + + The default message handler prints the message to the standard + output under X11 or to the debugger under Windows. If it is a + fatal message, the application aborts immediately. + + Only one message handler can be defined, since this is usually + done on an application-wide basis to control debug output. + + To restore the message handler, call \c qInstallMessageHandler(0). + + Example: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 23 + + \sa QMessageHandler, QtMsgType, qDebug(), qWarning(), qCritical(), qFatal(), + {Debugging Techniques} +*/ + +/*! + \fn QtMsgHandler qInstallMsgHandler(QtMsgHandler handler) + \relates + \deprecated + + Installs a Qt message \a handler which has been defined + previously. This method is deprecated, use qInstallMessageHandler + instead. + \sa QtMsgHandler, qInstallMessageHandler +*/ + QT_END_NAMESPACE diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index fedc5eb9ecb..afefb11aa11 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -75,14 +75,14 @@ QT_BEGIN_NAMESPACE \brief The QMessageLogger class generates log messages. \since 5.0 - QMessageLogger is used to generate messages for the Qt logging framework. Most of the time - is transparently used through the qDebug(), qWarning(), qCritical, or qFatal() functions, + QMessageLogger is used to generate messages for the Qt logging framework. Usually one uses + it through qDebug(), qWarning(), qCritical, or qFatal() functions, which are actually macros that expand to QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug() et al. One example of direct use is to forward errors that stem from a scripting language, e.g. QML: - \snippet doc/src/snippets/code/qlogging/qlogging.cpp 1 + \snippet doc/src/snippets/code/qlogging/qloggingsnippet.cpp 1 \sa QMessageLogContext, qDebug(), qWarning(), qCritical(), qFatal() */ @@ -132,41 +132,6 @@ static void qt_message(QtMsgType msgType, const QMessageLogContext &context, con } #undef qDebug -/*! - \fn qDebug(const char *message, ...) - \relates - - Calls the message handler with the debug message \a msg. If no - message handler has been installed, the message is printed to - stderr. Under Windows, the message is sent to the console, if it is a - console application; otherwise, it is sent to the debugger. This - function does nothing if \c QT_NO_DEBUG_OUTPUT was defined - during compilation. - - If you pass the function a format string and a list of arguments, - it works in similar way to the C printf() function. The format - should be a Latin-1 string. - - Example: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 24 - - If you include \c , a more convenient syntax is also - available: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 25 - - With this syntax, the function returns a QDebug object that is - configured to use the QtDebugMsg message type. It automatically - puts a single space between each item, and outputs a newline at - the end. It supports many C++ and Qt types. - - To suppress the output at run-time, install your own message handler - with qInstallMessageHandler(). - - \sa qWarning(), qCritical(), qFatal(), qInstallMessageHandler(), - {Debugging Techniques} -*/ void QMessageLogger::debug(const char *msg, ...) { @@ -182,9 +147,7 @@ QDebug QMessageLogger::debug() { QDebug dbg = QDebug(QtDebugMsg); QMessageLogContext &ctxt = dbg.stream->context; - ctxt.file = context.file; - ctxt.line = context.line; - ctxt.function = context.function; + ctxt.copy(context); return dbg; } @@ -196,39 +159,6 @@ QNoDebug QMessageLogger::noDebug() #endif #undef qWarning -/*! - \fn qWarning(const char *message, ...) - \relates - - Calls the message handler with the warning message \a msg. If no - message handler has been installed, the message is printed to - stderr. Under Windows, the message is sent to the debugger. This - function does nothing if \c QT_NO_WARNING_OUTPUT was defined - during compilation; it exits if the environment variable \c - QT_FATAL_WARNINGS is defined. - - This function takes a format string and a list of arguments, - similar to the C printf() function. The format should be a Latin-1 - string. - - Example: - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 26 - - If you include , a more convenient syntax is - also available: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 27 - - This syntax inserts a space between each item, and - appends a newline at the end. - - To suppress the output at runtime, install your own message handler - with qInstallMessageHandler(). - - \sa qDebug(), qCritical(), qFatal(), qInstallMessageHandler(), - {Debugging Techniques} -*/ - void QMessageLogger::warning(const char *msg, ...) { va_list ap; @@ -242,43 +172,12 @@ QDebug QMessageLogger::warning() { QDebug dbg = QDebug(QtWarningMsg); QMessageLogContext &ctxt = dbg.stream->context; - ctxt.file = context.file; - ctxt.line = context.line; - ctxt.function = context.function; + ctxt.copy(context); return dbg; } #endif #undef qCritical -/*! - \fn qCritical(const char *message, ...) - \relates - - Calls the message handler with the critical message \a msg. If no - message handler has been installed, the message is printed to - stderr. Under Windows, the message is sent to the debugger. - - This function takes a format string and a list of arguments, - similar to the C printf() function. The format should be a Latin-1 - string. - - Example: - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 28 - - If you include , a more convenient syntax is - also available: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 29 - - A space is inserted between the items, and a newline is - appended at the end. - - To suppress the output at runtime, install your own message handler - with qInstallMessageHandler(). - - \sa qDebug(), qWarning(), qFatal(), qInstallMessageHandler(), - {Debugging Techniques} -*/ void QMessageLogger::critical(const char *msg, ...) { @@ -293,39 +192,12 @@ QDebug QMessageLogger::critical() { QDebug dbg = QDebug(QtCriticalMsg); QMessageLogContext &ctxt = dbg.stream->context; - ctxt.file = context.file; - ctxt.line = context.line; - ctxt.function = context.function; + ctxt.copy(context); return dbg; } #endif #undef qFatal -/*! - \fn qFatal(const char *message, ...) - \relates - - Calls the message handler with the fatal message \a msg. If no - message handler has been installed, the message is printed to - stderr. Under Windows, the message is sent to the debugger. - - If you are using the \b{default message handler} this function will - abort on Unix systems to create a core dump. On Windows, for debug builds, - this function will report a _CRT_ERROR enabling you to connect a debugger - to the application. - - This function takes a format string and a list of arguments, - similar to the C printf() function. - - Example: - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 30 - - To suppress the output at runtime, install your own message handler - with qInstallMessageHandler(). - - \sa qDebug(), qCritical(), qWarning(), qInstallMessageHandler(), - {Debugging Techniques} -*/ void QMessageLogger::fatal(const char *msg, ...) { @@ -491,6 +363,7 @@ Q_AUTOTEST_EXPORT QByteArray qCleanupFuncinfo(QByteArray info) } // tokens as recognized in QT_MESSAGE_PATTERN +static const char categoryTokenC[] = "%{category}"; static const char typeTokenC[] = "%{type}"; static const char messageTokenC[] = "%{message}"; static const char fileTokenC[] = "%{file}"; @@ -560,7 +433,9 @@ QMessagePattern::QMessagePattern() // placeholder if (lexeme == QLatin1String(typeTokenC)) { tokens[i] = typeTokenC; - } else if (lexeme == QLatin1String(messageTokenC)) + } else if (lexeme == QLatin1String(categoryTokenC)) + tokens[i] = categoryTokenC; + else if (lexeme == QLatin1String(messageTokenC)) tokens[i] = messageTokenC; else if (lexeme == QLatin1String(fileTokenC)) tokens[i] = fileTokenC; @@ -627,6 +502,8 @@ Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, const QMessageLogC const char *token = pattern->tokens[i]; if (token == messageTokenC) { message.append(str); + } else if (token == categoryTokenC) { + message.append(context.category); } else if (token == typeTokenC) { switch (type) { case QtDebugMsg: message.append("debug"); break; @@ -775,68 +652,6 @@ extern Q_CORE_EXPORT void qWinMessageHandler(QtMsgType t, const QMessageLogConte const char *str); #endif -/*! - \typedef QtMsgHandler - \relates - \deprecated - - This is a typedef for a pointer to a function with the following - signature: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 7 - - This typedef is deprecated, you should use QMessageHandler instead. - \sa QtMsgType, QMessageHandler, qInstallMsgHandler(), qInstallMessageHandler() -*/ - -/*! - \typedef QMessageHandler - \relates - \since 5.0 - - This is a typedef for a pointer to a function with the following - signature: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 49 - - \sa QtMsgType, qInstallMessageHandler() -*/ - -/*! - \fn QMessageHandler qInstallMessageHandler(QMessageHandler handler) - \relates - \since 5.0 - - Installs a Qt message \a handler which has been defined - previously. Returns a pointer to the previous message handler - (which may be 0). - - The message handler is a function that prints out debug messages, - warnings, critical and fatal error messages. The Qt library (debug - mode) contains hundreds of warning messages that are printed - when internal errors (usually invalid function arguments) - occur. Qt built in release mode also contains such warnings unless - QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during - compilation. If you implement your own message handler, you get total - control of these messages. - - The default message handler prints the message to the standard - output under X11 or to the debugger under Windows. If it is a - fatal message, the application aborts immediately. - - Only one message handler can be defined, since this is usually - done on an application-wide basis to control debug output. - - To restore the message handler, call \c qInstallMessageHandler(0). - - Example: - - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 23 - - \sa qDebug(), qWarning(), qCritical(), qFatal(), QtMsgType, - {Debugging Techniques} -*/ - QMessageHandler qInstallMessageHandler(QMessageHandler h) { if (!messageHandler) @@ -850,17 +665,6 @@ QMessageHandler qInstallMessageHandler(QMessageHandler h) return old; } -/*! - \fn QtMsgHandler qInstallMsgHandler(QtMsgHandler handler) - \relates - \deprecated - - Installs a Qt message \a handler which has been defined - previously. This method is deprecated, use qInstallMessageHandler - instead. - \sa QtMsgHandler, qInstallMessageHandler -*/ - QtMsgHandler qInstallMsgHandler(QtMsgHandler h) { //if handler is 0, set it to the @@ -876,4 +680,11 @@ QtMsgHandler qInstallMsgHandler(QtMsgHandler h) return old; } +void QMessageLogContext::copy(const QMessageLogContext &logContext) +{ + this->category = logContext.category; + this->file = logContext.file; + this->line = logContext.line; + this->function = logContext.function; +} QT_END_NAMESPACE diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h index 4de04bdc330..29313bd5823 100644 --- a/src/corelib/global/qlogging.h +++ b/src/corelib/global/qlogging.h @@ -66,15 +66,17 @@ class QMessageLogContext { Q_DISABLE_COPY(QMessageLogContext) public: - QMessageLogContext() : version(1), line(0), file(0), function(0) {} - Q_DECL_CONSTEXPR QMessageLogContext(const char *fileName, int lineNumber, - const char *functionName) - : version(1), line(lineNumber), file(fileName), function(functionName) {} + QMessageLogContext() : version(1), line(0), file(0), function(0), category(0) {} + Q_DECL_CONSTEXPR QMessageLogContext(const char *fileName, int lineNumber, const char *functionName, const char *categoryName) + : version(1), line(lineNumber), file(fileName), function(functionName), category(categoryName) {} + + void copy(const QMessageLogContext &logContext); int version; int line; const char *file; const char *function; + const char *category; private: friend class QMessageLogger; @@ -87,7 +89,9 @@ class Q_CORE_EXPORT QMessageLogger public: QMessageLogger() : context() {} Q_DECL_CONSTEXPR QMessageLogger(const char *file, int line, const char *function) - : context(file, line, function) {} + : context(file, line, function, "default") {} + Q_DECL_CONSTEXPR QMessageLogger(const char *file, int line, const char *function, const char *category) + : context(file, line, function, category) {} void debug(const char *msg, ...) #if defined(Q_CC_GNU) && !defined(__INSURE__) diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index 0228bc9404a..db5775d0214 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -191,7 +191,10 @@ # if !defined(MAC_OS_X_VERSION_10_7) # define MAC_OS_X_VERSION_10_7 MAC_OS_X_VERSION_10_6 + 1 # endif -# if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_7) +# if !defined(MAC_OS_X_VERSION_10_8) +# define MAC_OS_X_VERSION_10_8 MAC_OS_X_VERSION_10_7 + 1 +# endif +# if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_8) # warning "This version of Mac OS X is unsupported" # endif #endif diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 1dedc7c5c88..23bf3c5f4b3 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1741,11 +1741,16 @@ bool QDir::remove(const QString &fileName) true if successful; otherwise returns false. On most file systems, rename() fails only if \a oldName does not - exist, if \a newName and \a oldName are not on the same - partition or if a file with the new name already exists. + exist, or if a file with the new name already exists. However, there are also other reasons why rename() can fail. For example, on at least one file system rename() fails if \a newName points to an open file. + + If \a oldName is a file (not a directory) that can't be renamed + right away, Qt will try to copy \a oldName to \a newName and remove + \a oldName. + + \sa QFile::rename() */ bool QDir::rename(const QString &oldName, const QString &newName) { diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 433d4493e52..120c5a8c23b 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -577,6 +577,11 @@ QFile::remove(const QString &fileName) The file is closed before it is renamed. + If the rename operation fails, Qt will attempt to copy this file's + contents to \a newName, and then remove this file, keeping only + \a newName. If that copy operation fails or this file can't be removed, + the destination file \a newName is removed to restore the old state. + \sa setFileName() */ diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index e8ff6107ce4..00e116b58ff 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -612,6 +612,13 @@ QString QFileSystemEngine::tempPath() { #ifdef QT_UNIX_TEMP_PATH_OVERRIDE return QLatin1String(QT_UNIX_TEMP_PATH_OVERRIDE); +#elif defined(Q_OS_BLACKBERRY) + QString temp = QFile::decodeName(qgetenv("TEMP")); + if (temp.isEmpty()) { + qWarning("TEMP environment variable not set. Cannot determine temporary directory"); + return QString(); + } + return QDir::cleanPath(temp); #else QString temp = QFile::decodeName(qgetenv("TMPDIR")); if (temp.isEmpty()) diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp index f8cd2e780e8..579d569a01e 100644 --- a/src/corelib/io/qtemporarydir.cpp +++ b/src/corelib/io/qtemporarydir.cpp @@ -99,11 +99,11 @@ static char *mkdtemp(char *templateName) { static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - const int length = strlen(templateName); + const size_t length = strlen(templateName); char *XXXXXX = templateName + length - 6; - if ((length < 6) || strncmp(XXXXXX, "XXXXXX", 6)) + if ((length < 6u) || strncmp(XXXXXX, "XXXXXX", 6)) return 0; for (int i = 0; i < 256; ++i) { diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index f8f41c2e25d..831774e4569 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -745,7 +745,7 @@ public: Data *clone(Base *b, int reserve = 0) { int size = sizeof(Header) + b->size; - if (ref.load() == 1 && alloc >= size + reserve) + if (b == header->root() && ref.load() == 1 && alloc >= size + reserve) return this; if (reserve) { diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp index 6bae2001a11..d143215efd3 100644 --- a/src/corelib/json/qjsonarray.cpp +++ b/src/corelib/json/qjsonarray.cpp @@ -275,7 +275,7 @@ void QJsonArray::removeAt(int i) detach(); a->removeItems(i, 1); ++d->compactionCounter; - if (d->compactionCounter > 32 && d->compactionCounter >= (int)a->length/2) + if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u) compact(); } @@ -379,7 +379,7 @@ void QJsonArray::replace(int i, const QJsonValue &value) QJsonPrivate::Value::copyData(value, (char *)a + valueOffset, compressed); ++d->compactionCounter; - if (d->compactionCounter > 32 && d->compactionCounter >= (int)a->length/2) + if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u) compact(); } diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp index c2204bf6960..be241bc3fcc 100644 --- a/src/corelib/json/qjsondocument.cpp +++ b/src/corelib/json/qjsondocument.cpp @@ -224,23 +224,26 @@ const char *QJsonDocument::rawData(int *size) const */ QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidation validation) { + if (data.size() < (int)(sizeof(QJsonPrivate::Header) + sizeof(QJsonPrivate::Base))) + return QJsonDocument(); + QJsonPrivate::Header h; memcpy(&h, data.constData(), sizeof(QJsonPrivate::Header)); QJsonPrivate::Base root; memcpy(&root, data.constData() + sizeof(QJsonPrivate::Header), sizeof(QJsonPrivate::Base)); // do basic checks here, so we don't try to allocate more memory than we can. - if (data.size() < (int)(sizeof(QJsonPrivate::Header) + sizeof(QJsonPrivate::Base)) || - h.tag != QJsonDocument::BinaryFormatTag || h.version != 1u || + if (h.tag != QJsonDocument::BinaryFormatTag || h.version != 1u || sizeof(QJsonPrivate::Header) + root.size > (uint)data.size()) return QJsonDocument(); - char *raw = (char *)malloc(data.size()); + const uint size = sizeof(QJsonPrivate::Header) + root.size; + char *raw = (char *)malloc(size); if (!raw) return QJsonDocument(); - memcpy(raw, data.constData(), data.size()); - QJsonPrivate::Data *d = new QJsonPrivate::Data(raw, data.size()); + memcpy(raw, data.constData(), size); + QJsonPrivate::Data *d = new QJsonPrivate::Data(raw, size); if (validation != BypassValidation && !d->valid()) { delete d; diff --git a/src/corelib/json/qjsondocument.h b/src/corelib/json/qjsondocument.h index e39dc6a27c8..c67899192cd 100644 --- a/src/corelib/json/qjsondocument.h +++ b/src/corelib/json/qjsondocument.h @@ -63,14 +63,16 @@ struct Q_CORE_EXPORT QJsonParseError UnterminatedArray, MissingValueSeparator, IllegalValue, - EndOfNumber, + TerminationByNumber, IllegalNumber, - StringEscapeSequence, - StringUTF8Scan, - EndOfString, + IllegalEscapeSequence, + IllegalUTF8String, + UnterminatedString, MissingObject }; + QString errorString() const; + int offset; ParseError error; }; diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index e14000fac3f..e8800781958 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -335,7 +335,7 @@ void QJsonObject::remove(const QString &key) detach(); o->removeItems(index, 1); ++d->compactionCounter; - if (d->compactionCounter > 32 && d->compactionCounter >= (int)o->length/2) + if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) compact(); } @@ -361,7 +361,7 @@ QJsonValue QJsonObject::take(const QString &key) QJsonPrivate::Entry *e = o->entryAt(index); o->removeItems(index, 1); ++d->compactionCounter; - if (d->compactionCounter > 32 && d->compactionCounter >= (int)o->length/2) + if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) compact(); return QJsonValue(d, o, e->value); @@ -432,7 +432,7 @@ QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it) o->removeItems(index, 1); ++d->compactionCounter; - if (d->compactionCounter > 32 && d->compactionCounter >= (int)o->length/2) + if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) compact(); // iterator hasn't changed diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp index b1e6a5a5c7b..9b11c9ac3e7 100644 --- a/src/corelib/json/qjsonparser.cpp +++ b/src/corelib/json/qjsonparser.cpp @@ -39,6 +39,9 @@ ** ****************************************************************************/ +#ifndef QT_BOOTSTRAPPED +#include +#endif #include #include "qjsonparser_p.h" #include "qjson_p.h" @@ -57,6 +60,80 @@ static int indent = 0; QT_BEGIN_NAMESPACE +// error strings for the JSON parser +#define JSONERR_OK QT_TRANSLATE_NOOP("QJsonParseError", "no error occurred") +#define JSONERR_UNTERM_OBJ QT_TRANSLATE_NOOP("QJsonParseError", "unterminated object") +#define JSONERR_MISS_NSEP QT_TRANSLATE_NOOP("QJsonParseError", "missing name separator") +#define JSONERR_UNTERM_AR QT_TRANSLATE_NOOP("QJsonParseError", "unterminated array") +#define JSONERR_MISS_VSEP QT_TRANSLATE_NOOP("QJsonParseError", "missing value separator") +#define JSONERR_ILLEGAL_VAL QT_TRANSLATE_NOOP("QJsonParseError", "illegal value") +#define JSONERR_END_OF_NUM QT_TRANSLATE_NOOP("QJsonParseError", "invalid termination by number") +#define JSONERR_ILLEGAL_NUM QT_TRANSLATE_NOOP("QJsonParseError", "illegal number") +#define JSONERR_STR_ESC_SEQ QT_TRANSLATE_NOOP("QJsonParseError", "invalid escape sequence") +#define JSONERR_STR_UTF8 QT_TRANSLATE_NOOP("QJsonParseError", "invalid UTF8 string") +#define JSONERR_UTERM_STR QT_TRANSLATE_NOOP("QJsonParseError", "unterminated string") +#define JSONERR_MISS_OBJ QT_TRANSLATE_NOOP("QJsonParseError", "object is missing after a comma") + +/*! + \class QJsonParseError + \ingroup json + \reentrant + \since 5.0 + + \brief The QJsonParseError class is used to report errors during JSON parsing. +*/ + +/*! + Returns the human-readable message appropriate to the reported JSON parsing error. + */ +QString QJsonParseError::errorString() const +{ + const char *sz = ""; + switch (error) { + case NoError: + sz = JSONERR_OK; + break; + case UnterminatedObject: + sz = JSONERR_UNTERM_OBJ; + break; + case MissingNameSeparator: + sz = JSONERR_MISS_NSEP; + break; + case UnterminatedArray: + sz = JSONERR_UNTERM_AR; + break; + case MissingValueSeparator: + sz = JSONERR_MISS_VSEP; + break; + case IllegalValue: + sz = JSONERR_ILLEGAL_VAL; + break; + case TerminationByNumber: + sz = JSONERR_END_OF_NUM; + break; + case IllegalNumber: + sz = JSONERR_ILLEGAL_NUM; + break; + case IllegalEscapeSequence: + sz = JSONERR_STR_ESC_SEQ; + break; + case IllegalUTF8String: + sz = JSONERR_STR_UTF8; + break; + case UnterminatedString: + sz = JSONERR_UTERM_STR; + break; + case MissingObject: + sz = JSONERR_MISS_OBJ; + break; + } +#ifndef QT_BOOTSTRAPPED + return QCoreApplication::translate("QJsonParseError", sz); +#else + return QLatin1String(sz); +#endif +} + using namespace QJsonPrivate; Parser::Parser(const char *json, int length) @@ -524,7 +601,7 @@ bool Parser::parseNumber(QJsonPrivate::Value *val, int baseOffset) } if (json >= end) { - lastError = QJsonParseError::EndOfNumber; + lastError = QJsonParseError::TerminationByNumber; return false; } @@ -717,12 +794,12 @@ bool Parser::parseString(bool *latin1) break; else if (*json == '\\') { if (!scanEscapeSequence(json, end, &ch)) { - lastError = QJsonParseError::StringEscapeSequence; + lastError = QJsonParseError::IllegalEscapeSequence; return false; } } else { if (!scanUtf8Char(json, end, &ch)) { - lastError = QJsonParseError::StringUTF8Scan; + lastError = QJsonParseError::IllegalUTF8String; return false; } } @@ -737,14 +814,14 @@ bool Parser::parseString(bool *latin1) ++json; DEBUG << "end of string"; if (json >= end) { - lastError = QJsonParseError::EndOfString; + lastError = QJsonParseError::UnterminatedString; return false; } // no unicode string, we are done if (*latin1) { // write string length - *(QJsonPrivate::qle_ushort *)(data + stringPos) = current - outStart - sizeof(ushort); + *(QJsonPrivate::qle_ushort *)(data + stringPos) = ushort(current - outStart - sizeof(ushort)); int pos = reserveSpace((4 - current) & 3); while (pos & 3) data[pos++] = 0; @@ -764,12 +841,12 @@ bool Parser::parseString(bool *latin1) break; else if (*json == '\\') { if (!scanEscapeSequence(json, end, &ch)) { - lastError = QJsonParseError::StringEscapeSequence; + lastError = QJsonParseError::IllegalEscapeSequence; return false; } } else { if (!scanUtf8Char(json, end, &ch)) { - lastError = QJsonParseError::StringUTF8Scan; + lastError = QJsonParseError::IllegalUTF8String; return false; } } @@ -785,7 +862,7 @@ bool Parser::parseString(bool *latin1) ++json; if (json >= end) { - lastError = QJsonParseError::EndOfString; + lastError = QJsonParseError::UnterminatedString; return false; } diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 9c025d6d6f4..cf9b0cea4f9 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -337,14 +337,37 @@ void QAbstractEventDispatcher::closingDown() { } /*! - \typedef QAbstractEventDispatcher::TimerInfo + \class QAbstractEventDispatcher::TimerInfo - Typedef for QPair. The first component of - the pair is the timer ID; the second component is - the interval. + This struct represents information about a timer: + \l{QAbstractEventDispatcher::TimerInfo::timerId}{timerId}, + \l{QAbstractEventDispatcher::TimerInfo::interval}{interval}, and + \l{QAbstractEventDispatcher::TimerInfo::timerType}{timerType}. \sa registeredTimers() */ +/*! \fn QAbstractEventDispatcher::TimerInfo::TimerInfo(int timerId, int interval, Qt::TimerType timerType) + + Constructs a TimerInfo struct with the given \a timerId, \a interval, and + \a timerType. +*/ +/*! + \variable QAbstractEventDispatcher::TimerInfo::timerId + + The timer's unique id. +*/ +/*! + \variable QAbstractEventDispatcher::TimerInfo::interval + + The timer's interval. +*/ +/*! + \variable QAbstractEventDispatcher::TimerInfo::timerType + + The timer's type + + \sa Qt::TimerType +*/ /*! \typedef QAbstractEventDispatcher::EventFilter diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index c901bc142e3..7b26a01cbf5 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1950,7 +1950,9 @@ QString QCoreApplication::organizationDomain() using the empty constructor. This saves having to repeat this information each time a QSettings object is created. - \sa organizationName organizationDomain applicationVersion + If not set, the application name defaults to the executable name (since 5.0). + + \sa organizationName organizationDomain applicationVersion applicationFilePath */ void QCoreApplication::setApplicationName(const QString &application) { @@ -1958,6 +1960,15 @@ void QCoreApplication::setApplicationName(const QString &application) } QString QCoreApplication::applicationName() +{ + QString appname = coreappdata()->application; + if (appname.isEmpty() && QCoreApplication::self) + appname = QCoreApplication::self->d_func()->appName(); + return appname; +} + +// Exported for QDesktopServices (Qt4 behavior compatibility) +Q_CORE_EXPORT QString qt_applicationName_noFallback() { return coreappdata()->application; } diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index c1f7c8ab25b..7cc1f0e2860 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -109,7 +109,7 @@ Q_CORE_EXPORT QString qAppFileName() // get application file name size = MAX_PATH * i; b = reinterpret_cast(realloc(b, (size + 1) * sizeof(wchar_t))); if (b) - v = GetModuleFileName(NULL, b, size); + v = GetModuleFileName(NULL, b, DWORD(size)); } while (b && v == size); if (b) diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 4c98bad0f9c..5ad070d3b1c 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -141,6 +141,13 @@ template inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {} #endif // QT_NO_QOBJECT_CHECK +#if defined(Q_CC_INTEL) +// Cannot redefine the visibility of a method in an exported class +# define Q_DECL_HIDDEN_STATIC_METACALL +#else +# define Q_DECL_HIDDEN_STATIC_METACALL Q_DECL_HIDDEN +#endif + /* tmake ignore Q_OBJECT */ #define Q_OBJECT \ public: \ @@ -152,7 +159,7 @@ public: \ virtual int qt_metacall(QMetaObject::Call, int, void **); \ private: \ Q_DECL_HIDDEN static const QMetaObjectExtraData staticMetaObjectExtraData; \ - Q_DECL_HIDDEN static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); + Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); /* tmake ignore Q_OBJECT */ #define Q_OBJECT_FAKE Q_OBJECT diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index da6017127f2..c3f8422b281 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1544,7 +1544,6 @@ void QVariant::detach() \internal */ -// ### Qt 5: change typeName()(and froends= to return a QString. Suggestion from Harald. /*! Returns the name of the type stored in the variant. The returned strings describe the C++ datatype used to store the data: for diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h index 2f5c4f54ee6..6b778f3fb24 100644 --- a/src/corelib/kernel/qvariant_p.h +++ b/src/corelib/kernel/qvariant_p.h @@ -491,6 +491,7 @@ public: void delegate(const T*) { Filtered streamIt(m_debugStream, m_d); + Q_UNUSED(streamIt); } void delegate(const QMetaTypeSwitcher::NotBuiltinType*) diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp index 58ca046d9d4..8af1ab21618 100644 --- a/src/corelib/kernel/qwineventnotifier.cpp +++ b/src/corelib/kernel/qwineventnotifier.cpp @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE /*! \class QWinEventNotifier + \since 5.0 \brief The QWinEventNotifier class provides support for the Windows Wait functions. The QWinEventNotifier class makes it possible to use the wait diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index a7e14eed24f..2c84a937d57 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -430,7 +430,6 @@ QMimeType QMimeDatabase::mimeTypeForFile(const QString &fileName, MatchMode mode } /*! - \fn QMimeType QMimeDatabase::findMimeTypesByFileName(const QString &fileName) const; Returns the MIME types for the file name \a fileName. If the file name doesn't match any known pattern, an empty list is returned. diff --git a/src/corelib/mimetypes/qmimedatabase.h b/src/corelib/mimetypes/qmimedatabase.h index cfd1cfe33d7..eff706e1b5c 100644 --- a/src/corelib/mimetypes/qmimedatabase.h +++ b/src/corelib/mimetypes/qmimedatabase.h @@ -39,12 +39,10 @@ ** ****************************************************************************/ - #ifndef QMIMEDATABASE_H #define QMIMEDATABASE_H -#include "qmimetype.h" - +#include #include QT_BEGIN_NAMESPACE diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h index 7e98548a354..8f2db325138 100644 --- a/src/corelib/mimetypes/qmimedatabase_p.h +++ b/src/corelib/mimetypes/qmimedatabase_p.h @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #ifndef QMIMEDATABASE_P_H #define QMIMEDATABASE_P_H diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp index 1dee62f6d0b..8421516b5c8 100644 --- a/src/corelib/mimetypes/qmimemagicrule.cpp +++ b/src/corelib/mimetypes/qmimemagicrule.cpp @@ -267,7 +267,7 @@ QMimeMagicRule::QMimeMagicRule(QMimeMagicRule::Type theType, d->mask = QByteArray::fromHex(QByteArray::fromRawData(d->mask.constData() + 2, d->mask.size() - 2)); Q_ASSERT(d->mask.size() == d->pattern.size()); } else { - d->mask.fill(static_cast(0xff), d->pattern.size()); + d->mask.fill(char(-1), d->pattern.size()); } d->mask.squeeze(); d->matchFunction = matchString; diff --git a/src/corelib/mimetypes/qmimemagicrule_p.h b/src/corelib/mimetypes/qmimemagicrule_p.h index e35c1923f90..44f7d8f8f43 100644 --- a/src/corelib/mimetypes/qmimemagicrule_p.h +++ b/src/corelib/mimetypes/qmimemagicrule_p.h @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #ifndef QMIMEMAGICRULE_P_H #define QMIMEMAGICRULE_P_H diff --git a/src/corelib/mimetypes/qmimemagicrulematcher.cpp b/src/corelib/mimetypes/qmimemagicrulematcher.cpp index 8579d02b003..255ecba8e8f 100644 --- a/src/corelib/mimetypes/qmimemagicrulematcher.cpp +++ b/src/corelib/mimetypes/qmimemagicrulematcher.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #define QT_NO_CAST_FROM_ASCII #include "qmimemagicrulematcher_p.h" diff --git a/src/corelib/mimetypes/qmimemagicrulematcher_p.h b/src/corelib/mimetypes/qmimemagicrulematcher_p.h index 299f447a4c3..b2bb287207b 100644 --- a/src/corelib/mimetypes/qmimemagicrulematcher_p.h +++ b/src/corelib/mimetypes/qmimemagicrulematcher_p.h @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #ifndef QMIMEMAGICRULEMATCHER_P_H #define QMIMEMAGICRULEMATCHER_P_H diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp index ea10cbe70a8..5ee70e83b1c 100644 --- a/src/corelib/mimetypes/qmimetype.cpp +++ b/src/corelib/mimetypes/qmimetype.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #include "qmimetype.h" #include "qmimetype_p.h" diff --git a/src/corelib/mimetypes/qmimetype.h b/src/corelib/mimetypes/qmimetype.h index 172973e77aa..0b94977a03b 100644 --- a/src/corelib/mimetypes/qmimetype.h +++ b/src/corelib/mimetypes/qmimetype.h @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #ifndef QMIMETYPE_H #define QMIMETYPE_H diff --git a/src/corelib/mimetypes/qmimetype_p.h b/src/corelib/mimetypes/qmimetype_p.h index d8aadccf50a..f2c7f966ff7 100644 --- a/src/corelib/mimetypes/qmimetype_p.h +++ b/src/corelib/mimetypes/qmimetype_p.h @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #ifndef QMIMETYPE_P_H #define QMIMETYPE_P_H diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp index 4a2ec0a0b2d..cc03600cf11 100644 --- a/src/corelib/mimetypes/qmimetypeparser.cpp +++ b/src/corelib/mimetypes/qmimetypeparser.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #define QT_NO_CAST_FROM_ASCII #include "qmimetypeparser_p.h" @@ -93,9 +92,9 @@ static const char matchMaskAttributeC[] = "mask"; \sa QMimeTypeParser */ - /*! \class QMimeTypeParserBase + \internal \brief The QMimeTypeParserBase class parses for a sequence of in a generic way. Calls abstract handler function process for QMimeType it finds. diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index 480bc0da744..3f192ea4776 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -188,7 +188,8 @@ void QFactoryLoader::update() } if (!metaDataOk) { - library->unload(); + if (library->compatPlugin) + library->unload(); library->release(); continue; } diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h index 0538b93c366..e595613e8f0 100644 --- a/src/corelib/plugin/quuid.h +++ b/src/corelib/plugin/quuid.h @@ -84,6 +84,13 @@ public: Sha1 = 5 // 0 1 0 1 }; +#ifdef Q_COMPILER_INITIALIZER_LISTS // UNIFORM_INITIALIZATION + Q_DECL_CONSTEXPR QUuid() + : data1(0), data2(0), data3(0), data4{0,0,0,0,0,0,0,0} {} + + Q_DECL_CONSTEXPR QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8) + : data1(l), data2(w1), data3(w2), data4{b1, b2, b3, b4, b5, b6, b7, b8} {} +#else QUuid() { data1 = 0; @@ -106,6 +113,8 @@ public: data4[6] = b7; data4[7] = b8; } +#endif + #ifndef QT_NO_QUUID_STRING QUuid(const QString &); QUuid(const char *); @@ -142,6 +151,12 @@ public: #if defined(Q_OS_WIN) // On Windows we have a type GUID that is used by the platform API, so we // provide convenience operators to cast from and to this type. +#ifdef Q_COMPILER_INITIALIZER_LISTS // UNIFORM_INITIALIZATION + Q_DECL_CONSTEXPR QUuid(const GUID &guid) + : data1(guid.Data1), data2(guid.Data2), data3(guid.Data3), + data4{guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], + guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]} {} +#else QUuid(const GUID &guid) { data1 = guid.Data1; @@ -150,6 +165,7 @@ public: for(int i = 0; i < 8; i++) data4[i] = guid.Data4[i]; } +#endif QUuid &operator=(const GUID &guid) { diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index a0913e5dbcf..21ed8131dff 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -90,7 +90,7 @@ # endif #endif -#if defined(Q_OS_LINUX) +#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE) #include #endif @@ -110,7 +110,8 @@ QT_BEGIN_NAMESPACE enum { ThreadPriorityResetFlag = 0x80000000 }; -#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) +#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) && !defined(QT_LINUXBASE) +/* LSB doesn't have __thread, https://lsbbugs.linuxfoundation.org/show_bug.cgi?id=993 */ #define HAVE_TLS #endif #if defined(Q_CC_XLC) || defined (Q_CC_SUN) @@ -294,7 +295,7 @@ void *QThreadPrivate::start(void *arg) if (objectName.isEmpty()) objectName = thr->metaObject()->className(); -#if defined(Q_OS_LINUX) +#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE) prctl(PR_SET_NAME, (unsigned long)objectName.constData(), 0, 0, 0); #elif defined(Q_OS_MAC) pthread_setname_np(objectName.constData()); diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 38fb6ef8ddb..1cde07e330d 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -238,6 +238,7 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID) QThread *thread = data->thread; Q_ASSERT(thread); QThreadPrivate *thread_p = static_cast(QObjectPrivate::get(thread)); + Q_UNUSED(thread_p) Q_ASSERT(!thread_p->finished); thread_p->finish(thread); } diff --git a/src/corelib/thread/qwaitcondition.h b/src/corelib/thread/qwaitcondition.h index f6e41aef4ef..d3a24958f63 100644 --- a/src/corelib/thread/qwaitcondition.h +++ b/src/corelib/thread/qwaitcondition.h @@ -63,8 +63,8 @@ public: QWaitCondition(); ~QWaitCondition(); - bool wait(QMutex *mutex, unsigned long time = ULONG_MAX); - bool wait(QReadWriteLock *readWriteLock, unsigned long time = ULONG_MAX); + bool wait(QMutex *lockedMutex, unsigned long time = ULONG_MAX); + bool wait(QReadWriteLock *lockedReadWriteLock, unsigned long time = ULONG_MAX); void wakeOne(); void wakeAll(); diff --git a/src/corelib/thread/qwaitcondition.qdoc b/src/corelib/thread/qwaitcondition.qdoc index 8c93bd167df..81c095f3944 100644 --- a/src/corelib/thread/qwaitcondition.qdoc +++ b/src/corelib/thread/qwaitcondition.qdoc @@ -119,13 +119,13 @@ */ /*! - \fn bool QWaitCondition::wait(QMutex *mutex, unsigned long time) + \fn bool QWaitCondition::wait(QMutex *lockedMutex, unsigned long time) - Releases the locked \a mutex and waits on the wait condition. The - \a mutex must be initially locked by the calling thread. If \a - mutex is not in a locked state, this function returns - immediately. If \a mutex is a recursive mutex, this function - returns immediately. The \a mutex will be unlocked, and the + Releases the \a lockedMutex and waits on the wait condition. The + \a lockedMutex must be initially locked by the calling thread. If \a + lockedMutex is not in a locked state, this function returns + immediately. If \a lockedMutex is a recursive mutex, this function + returns immediately. The \a lockedMutex will be unlocked, and the calling thread will block until either of these conditions is met: \list @@ -137,7 +137,7 @@ wait timed out. \endlist - The mutex will be returned to the same locked state. This + The \a lockedMutex will be returned to the same locked state. This function is provided to allow the atomic transition from the locked state to the wait state. @@ -145,15 +145,15 @@ */ /*! - \fn bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) + \fn bool QWaitCondition::wait(QReadWriteLock *lockedReadWriteLock, unsigned long time) \since 4.4 - Releases the locked \a readWriteLock and waits on the wait - condition. The \a readWriteLock must be initially locked by the - calling thread. If \a readWriteLock is not in a locked state, this - function returns immediately. The \a readWriteLock must not be + Releases the \a lockedReadWriteLock and waits on the wait + condition. The \a lockedReadWriteLock must be initially locked by the + calling thread. If \a lockedReadWriteLock is not in a locked state, this + function returns immediately. The \a lockedReadWriteLock must not be locked recursively, otherwise this function will not release the - lock properly. The \a readWriteLock will be unlocked, and the + lock properly. The \a lockedReadWriteLock will be unlocked, and the calling thread will block until either of these conditions is met: \list @@ -165,7 +165,7 @@ wait timed out. \endlist - The \a readWriteLock will be returned to the same locked + The \a lcokedReadWriteLock will be returned to the same locked state. This function is provided to allow the atomic transition from the locked state to the wait state. diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h index 5486c60dfb0..5ccb5c0fd7b 100644 --- a/src/corelib/tools/qbitarray.h +++ b/src/corelib/tools/qbitarray.h @@ -72,7 +72,6 @@ public: inline int size() const { return (d.size() << 3) - *d.constData(); } inline int count() const { return (d.size() << 3) - *d.constData(); } int count(bool on) const; - // ### Qt 5: Store the number of set bits separately inline bool isEmpty() const { return d.isEmpty(); } inline bool isNull() const { return d.isNull(); } diff --git a/src/corelib/tools/qelapsedtimer_generic.cpp b/src/corelib/tools/qelapsedtimer_generic.cpp index 038a15bd37d..05214f0698a 100644 --- a/src/corelib/tools/qelapsedtimer_generic.cpp +++ b/src/corelib/tools/qelapsedtimer_generic.cpp @@ -150,8 +150,8 @@ qint64 QElapsedTimer::msecsSinceReference() const /*! Returns the number of milliseconds between this QElapsedTimer and \a other. If \a other was started before this object, the returned value - will be positive. If it was started later, the returned value will be - negative. + will be negative. If it was started later, the returned value will be + positive. The return value is undefined if this object or \a other were invalidated. @@ -166,7 +166,7 @@ qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const /*! Returns the number of seconds between this QElapsedTimer and \a other. If \a other was started before this object, the returned value will be - positive. If it was started later, the returned value will be negative. + negative. If it was started later, the returned value will be positive. The return value is undefined if this object or \a other were invalidated. diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp index eaa20b304a8..27264f7e729 100644 --- a/src/corelib/tools/qregularexpression.cpp +++ b/src/corelib/tools/qregularexpression.cpp @@ -2153,30 +2153,30 @@ QDebug operator<<(QDebug debug, const QRegularExpression &re) */ QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOptions) { - QStringList flags; + QByteArray flags; if (patternOptions == QRegularExpression::NoPatternOption) { - flags << QLatin1String("NoPatternOption"); + flags = "NoPatternOption"; } else { + flags.reserve(200); // worst case... if (patternOptions & QRegularExpression::CaseInsensitiveOption) - flags << QLatin1String("CaseInsensitiveOption"); + flags.append("CaseInsensitiveOption|"); if (patternOptions & QRegularExpression::DotMatchesEverythingOption) - flags << QLatin1String("DotMatchesEverythingOption"); + flags.append("DotMatchesEverythingOption|"); if (patternOptions & QRegularExpression::MultilineOption) - flags << QLatin1String("MultilineOption"); + flags.append("MultilineOption|"); if (patternOptions & QRegularExpression::ExtendedPatternSyntaxOption) - flags << QLatin1String("ExtendedPatternSyntaxOption"); + flags.append("ExtendedPatternSyntaxOption|"); if (patternOptions & QRegularExpression::InvertedGreedinessOption) - flags << QLatin1String("InvertedGreedinessOption"); + flags.append("InvertedGreedinessOption|"); if (patternOptions & QRegularExpression::DontCaptureOption) - flags << QLatin1String("DontCaptureOption"); + flags.append("DontCaptureOption|"); if (patternOptions & QRegularExpression::UseUnicodePropertiesOption) - flags << QLatin1String("UseUnicodePropertiesOption"); + flags.append("UseUnicodePropertiesOption|"); + flags.chop(1); } - debug.nospace() << "QRegularExpression::PatternOptions(" - << qPrintable(flags.join(QLatin1String("|"))) - << ")"; + debug.nospace() << "QRegularExpression::PatternOptions(" << flags << ")"; return debug.space(); } diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc index 139b0179660..b03cce884df 100644 --- a/src/corelib/tools/qset.qdoc +++ b/src/corelib/tools/qset.qdoc @@ -588,16 +588,6 @@ \sa subtract(), operator-=(), operator|(), operator&() */ -/*! - \fn QSet QSet::operator-(const QSet &other) - \fn QSet QSet::operator|(const QSet &other) - \fn QSet QSet::operator+(const QSet &other) - \fn QSet QSet::operator&(const QSet &other) - \internal - - These will go away in Qt 5. -*/ - /*! \class QSet::iterator \since 4.2 diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index c4eef389712..2bb439d7036 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5349,7 +5349,7 @@ QString QString::toUpper() const return *this; } -// ### Qt 5: Consider whether this function shouldn't be removed See task 202871. +// ### Qt 6: Consider whether this function shouldn't be removed See task 202871. /*! Safely builds a formatted string from the format string \a cformat and an arbitrary list of arguments. diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 7b1da210951..ed3ee28f4f1 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -650,6 +650,7 @@ void QAccessible::updateAccessibility(QObject *object, int child, Event reason) Q_ASSERT(object); QAccessibleEvent ev(object, reason); + ev.setChild(child); updateAccessibility(&ev); } diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 61a3895a6b7..9770aca9e52 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -51,6 +51,7 @@ #include "qvariant.h" #include "qimagepixmapcleanuphooks_p.h" #include "qplatformintegration_qpa.h" +#include #include #include #include @@ -3303,10 +3304,10 @@ extern const uchar *qt_pow_rgb_gamma(); void qGamma_correct_back_to_linear_cs(QImage *image) { - const uchar *gamma = qt_pow_rgb_gamma(); - if (!gamma) + const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables(); + if (!tables) return; - + const uchar *gamma = tables->qt_pow_rgb_gamma; // gamma correct the pixels back to linear color space... int h = image->height(); int w = image->width(); diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp index 6d8693ffb11..5b414b8d002 100644 --- a/src/gui/image/qimagepixmapcleanuphooks.cpp +++ b/src/gui/image/qimagepixmapcleanuphooks.cpp @@ -125,8 +125,14 @@ void QImagePixmapCleanupHooks::executePlatformPixmapDestructionHooks(QPlatformPi void QImagePixmapCleanupHooks::executeImageHooks(qint64 key) { - for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks()->imageHooks.count(); ++i) - qt_image_and_pixmap_cleanup_hooks()->imageHooks[i](key); + QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks(); + // the global destructor for the pixmap and image hooks might have + // been called already if the app is "leaking" global + // pixmaps/images + if (!h) + return; + for (int i = 0; i < h->imageHooks.count(); ++i) + h->imageHooks[i](key); if (qt_image_cleanup_hook_64) qt_image_cleanup_hook_64(key); diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 06773f58b57..b0fe871741a 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -15,6 +15,7 @@ HEADERS += \ kernel/qplatformscreen_qpa.h \ kernel/qplatformscreen_qpa_p.h \ kernel/qplatforminputcontext_qpa.h \ + kernel/qplatforminputcontext_qpa_p.h \ kernel/qplatformintegrationfactory_qpa_p.h \ kernel/qplatformintegrationplugin_qpa.h \ kernel/qplatformtheme_qpa.h\ diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index 95b2b4a28e3..476d3a449b8 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -205,6 +205,13 @@ QT_BEGIN_NAMESPACE You can call QWidget::mapFromGlobal() to translate it to widget coordinates. + \note The position is queried from the windowing system. If mouse events are generated + via other means (e.g., via QWindowSystemInterface in a unit test), those fake mouse + moves will not be reflected in the returned value. + + \note On platforms where there is no windowing system or cursors are not available, the returned + position is based on the mouse move events generated via QWindowSystemInterface. + \sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen() */ @@ -218,6 +225,16 @@ QT_BEGIN_NAMESPACE You can call QWidget::mapToGlobal() to translate widget coordinates to global screen coordinates. + \note Calling this function results in changing the cursor position through the windowing + system. The windowing system will typically respond by sending mouse events to the application's + window. This means that the usage of this function should be avoided in unit tests and + everywhere where fake mouse events are being injected via QWindowSystemInterface because the + windowing system's mouse state (with regards to buttons for example) may not match the state in + the application-generated events. + + \note On platforms where there is no windowing system or cursors are not available, this + function may do nothing. + \sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal() */ diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 5c419a79dde..6a93ef4d094 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -52,6 +52,7 @@ #include "qplatformintegration_qpa.h" #include +#include #include #include #include @@ -61,13 +62,15 @@ #include #include #include +#include #include #include #include #include #include - +#include +#include #include #include "private/qwindowsysteminterface_qpa_p.h" @@ -142,6 +145,8 @@ static QBasicMutex applicationFontMutex; QFont *QGuiApplicationPrivate::app_font = 0; bool QGuiApplicationPrivate::obey_desktop_settings = true; +static qreal fontSmoothingGamma = 1.7; + extern void qRegisterGuiVariant(); extern void qInitDrawhelperAsm(); extern void qInitImageConversions(); @@ -575,13 +580,13 @@ static void init_platform(const QString &pluginArgument, const QString &platform nativeInterface->setProperty(name.constData(), value); } } + fontSmoothingGamma = QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::FontSmoothingGamma).toReal(); } static void init_plugins(const QList &pluginList) { for (int i = 0; i < pluginList.count(); ++i) { QByteArray pluginSpec = pluginList.at(i); - qDebug() << "init_plugins" << i << pluginSpec; int colonPos = pluginSpec.indexOf(':'); QObject *plugin; if (colonPos < 0) @@ -589,7 +594,6 @@ static void init_plugins(const QList &pluginList) else plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec.mid(0, colonPos)), QLatin1String(pluginSpec.mid(colonPos+1))); - qDebug() << " created" << plugin; if (plugin) QGuiApplicationPrivate::generic_plugin_list.append(plugin); } @@ -597,12 +601,10 @@ static void init_plugins(const QList &pluginList) void QGuiApplicationPrivate::createPlatformIntegration() { - Q_Q(QGuiApplication); - // Use the Qt menus by default. Platform plugins that // want to enable a native menu implementation can clear // this flag. - q->setAttribute(Qt::AA_DontUseNativeMenuBar, true); + QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true); // Load the platform integration QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH")); @@ -706,6 +708,10 @@ void QGuiApplicationPrivate::init() argc = j; } + // Load environment exported generic plugins + foreach (const QByteArray &plugin, qgetenv("QT_QPA_GENERIC_PLUGINS").split(',')) + pluginList << plugin; + if (platform_integration == 0) createPlatformIntegration(); @@ -761,6 +767,7 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate() delete platform_theme; delete platform_integration; platform_integration = 0; + delete m_gammaTables.load(); } #if 0 @@ -1168,7 +1175,7 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate QFocusEvent focusOut(QEvent::FocusOut); QCoreApplication::sendSpontaneousEvent(previous, &focusOut); QObject::disconnect(previous, SIGNAL(focusObjectChanged(QObject*)), - qApp, SIGNAL(focusObjectChanged(QObject*))); + qApp, SLOT(q_updateFocusObject(QObject*))); } else { QEvent appActivate(QEvent::ApplicationActivate); qApp->sendSpontaneousEvent(qApp, &appActivate); @@ -1178,17 +1185,18 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate QFocusEvent focusIn(QEvent::FocusIn); QCoreApplication::sendSpontaneousEvent(QGuiApplicationPrivate::focus_window, &focusIn); QObject::connect(QGuiApplicationPrivate::focus_window, SIGNAL(focusObjectChanged(QObject*)), - qApp, SIGNAL(focusObjectChanged(QObject*))); + qApp, SLOT(q_updateFocusObject(QObject*))); } else { QEvent appActivate(QEvent::ApplicationDeactivate); qApp->sendSpontaneousEvent(qApp, &appActivate); } - if (self) + if (self) { self->notifyActiveWindowChange(previous); - if (previousFocusObject != qApp->focusObject()) - emit qApp->focusObjectChanged(qApp->focusObject()); + if (previousFocusObject != qApp->focusObject()) + self->q_updateFocusObject(qApp->focusObject()); + } } void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse) @@ -2160,4 +2168,36 @@ void QGuiApplicationPrivate::notifyThemeChanged() } } +const QDrawHelperGammaTables *QGuiApplicationPrivate::gammaTables() +{ + QDrawHelperGammaTables *result = m_gammaTables.load(); + if (!result){ + QDrawHelperGammaTables *tables = new QDrawHelperGammaTables(fontSmoothingGamma); + if (!m_gammaTables.testAndSetRelease(0, tables)) + delete tables; + result = m_gammaTables.load(); + } + return result; +} + +void QGuiApplicationPrivate::q_updateFocusObject(QObject *object) +{ + Q_Q(QGuiApplication); + + bool enabled = false; + if (object) { + QInputMethodQueryEvent query(Qt::ImEnabled); + QGuiApplication::sendEvent(object, &query); + enabled = query.value(Qt::ImEnabled).toBool(); + } + + QPlatformInputContextPrivate::setInputMethodAccepted(enabled); + QPlatformInputContext *inputContext = platformIntegration()->inputContext(); + if (inputContext) + inputContext->setFocusObject(object); + emit q->focusObjectChanged(object); +} + +#include "moc_qguiapplication.cpp" + QT_END_NAMESPACE diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index cc7dea422f0..b58720db133 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -155,6 +155,8 @@ private: Q_DISABLE_COPY(QGuiApplication) Q_DECLARE_PRIVATE(QGuiApplication) + Q_PRIVATE_SLOT(d_func(), void q_updateFocusObject(QObject *object)) + #ifndef QT_NO_GESTURES friend class QGestureManager; #endif diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 6792e9382cc..352917f2dbc 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QPlatformIntegration; class QPlatformTheme; +struct QDrawHelperGammaTables; class Q_GUI_EXPORT QGuiApplicationPrivate : public QCoreApplicationPrivate { @@ -141,6 +142,8 @@ public: QPixmap getPixmapCursor(Qt::CursorShape cshape); + void q_updateFocusObject(QObject *object); + static QGuiApplicationPrivate *instance() { return self; } static QString *platform_name; @@ -200,6 +203,8 @@ public: }; QHash synthesizedMousePoints; + const QDrawHelperGammaTables *gammaTables(); + protected: virtual void notifyThemeChanged(); @@ -209,6 +214,7 @@ private: static QGuiApplicationPrivate *self; static QTouchDevice *m_fakeTouchDevice; static int m_fakeMouseSourcePointId; + QAtomicPointer m_gammaTables; }; Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k); diff --git a/src/gui/kernel/qinputmethod.cpp b/src/gui/kernel/qinputmethod.cpp index 23ab8535a0e..c443a47cacb 100644 --- a/src/gui/kernel/qinputmethod.cpp +++ b/src/gui/kernel/qinputmethod.cpp @@ -43,6 +43,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -72,7 +73,7 @@ QInputMethod::~QInputMethod() information like virtual keyboard visibility and keyboard dimensions. Qt Quick also provides access to QInputMethod in QML through \l{QmlGlobalQtObject}{Qt global object} - as \c Qt.application.inputPanel property. + as \c Qt.inputMethod property. */ /*! @@ -295,8 +296,12 @@ void QInputMethod::update(Qt::InputMethodQueries queries) { Q_D(QInputMethod); - if (queries & Qt::ImEnabled) - d->q_checkFocusObject(qApp->focusObject()); + if (queries & Qt::ImEnabled) { + QObject *focus = qApp->focusObject(); + bool enabled = d->objectAcceptsInputMethod(focus); + setInputItem(enabled ? focus : 0); + QPlatformInputContextPrivate::setInputMethodAccepted(enabled); + } QPlatformInputContext *ic = d->platformInputContext(); if (ic) @@ -361,14 +366,20 @@ void QInputMethodPrivate::q_connectFocusObject() void QInputMethodPrivate::q_checkFocusObject(QObject *object) { Q_Q(QInputMethod); + bool enabled = objectAcceptsInputMethod(object); + q->setInputItem(enabled ? object : 0); +} +bool QInputMethodPrivate::objectAcceptsInputMethod(QObject *object) +{ bool enabled = false; if (object) { QInputMethodQueryEvent query(Qt::ImEnabled); QGuiApplication::sendEvent(object, &query); enabled = query.value(Qt::ImEnabled).toBool(); } - q->setInputItem(enabled ? object : 0); + + return enabled; } QT_END_NAMESPACE diff --git a/src/gui/kernel/qinputmethod_p.h b/src/gui/kernel/qinputmethod_p.h index 8a17c859902..34a0430f10e 100644 --- a/src/gui/kernel/qinputmethod_p.h +++ b/src/gui/kernel/qinputmethod_p.h @@ -71,6 +71,7 @@ public: } void q_connectFocusObject(); void q_checkFocusObject(QObject *object); + bool objectAcceptsInputMethod(QObject *object); QTransform inputItemTransform; QWeakPointer inputItem; diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h index ca619a89b4f..96295ab5db3 100644 --- a/src/gui/kernel/qpalette.h +++ b/src/gui/kernel/qpalette.h @@ -86,12 +86,12 @@ public: enum ColorRole { WindowText, Button, Light, Midlight, Dark, Mid, Text, BrightText, ButtonText, Base, Window, Shadow, Highlight, HighlightedText, - Link, LinkVisited, // ### Qt 5: remove + Link, LinkVisited, AlternateBase, - NoRole, // ### Qt 5: value should be 0 or -1 + NoRole, ToolTipBase, ToolTipText, NColorRoles = ToolTipText + 1, - Foreground = WindowText, Background = Window // ### Qt 5: remove + Foreground = WindowText, Background = Window }; inline ColorGroup currentColorGroup() const { return static_cast(current_group); } diff --git a/src/gui/kernel/qplatforminputcontext_qpa.cpp b/src/gui/kernel/qplatforminputcontext_qpa.cpp index ee18f3ebd13..8612b4b42f4 100644 --- a/src/gui/kernel/qplatforminputcontext_qpa.cpp +++ b/src/gui/kernel/qplatforminputcontext_qpa.cpp @@ -43,6 +43,7 @@ #include #include #include "private/qkeymapper_p.h" +#include "private/qplatforminputcontext_qpa_p.h" QT_BEGIN_NAMESPACE @@ -75,6 +76,7 @@ QT_BEGIN_NAMESPACE \internal */ QPlatformInputContext::QPlatformInputContext() + : QObject(*(new QPlatformInputContextPrivate)) { } @@ -228,5 +230,29 @@ void QPlatformInputContext::emitInputDirectionChanged(Qt::LayoutDirection newDir emit qApp->inputMethod()->inputDirectionChanged(newDirection); } +/*! + This virtual method gets called to notify updated focus to \a object. + \warning Input methods must not call this function directly. + */ +void QPlatformInputContext::setFocusObject(QObject *object) +{ + Q_UNUSED(object) +} + +/*! + Returns true if current focus object supports input method events. + */ +bool QPlatformInputContext::inputMethodAccepted() const +{ + return QPlatformInputContextPrivate::s_inputMethodAccepted; +} + +bool QPlatformInputContextPrivate::s_inputMethodAccepted = false; + +void QPlatformInputContextPrivate::setInputMethodAccepted(bool accepted) +{ + QPlatformInputContextPrivate::s_inputMethodAccepted = accepted; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatforminputcontext_qpa.h b/src/gui/kernel/qplatforminputcontext_qpa.h index c7d823d662c..5e8060c6e0c 100644 --- a/src/gui/kernel/qplatforminputcontext_qpa.h +++ b/src/gui/kernel/qplatforminputcontext_qpa.h @@ -48,13 +48,13 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE - -class QWindow; -class QMouseEvent; +class QPlatformInputContextPrivate; class Q_GUI_EXPORT QPlatformInputContext : public QObject { Q_OBJECT + Q_DECLARE_PRIVATE(QPlatformInputContext) + public: QPlatformInputContext(); virtual ~QPlatformInputContext(); @@ -81,6 +81,14 @@ public: void emitLocaleChanged(); virtual Qt::LayoutDirection inputDirection() const; void emitInputDirectionChanged(Qt::LayoutDirection newDirection); + + virtual void setFocusObject(QObject *object); + bool inputMethodAccepted() const; + +private: + friend class QGuiApplication; + friend class QGuiApplicationPrivate; + friend class QInputMethod; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xlib/qxlibcursor.h b/src/gui/kernel/qplatforminputcontext_qpa_p.h similarity index 75% rename from src/plugins/platforms/xlib/qxlibcursor.h rename to src/gui/kernel/qplatforminputcontext_qpa_p.h index 0056aa95540..dc12d26ffc1 100644 --- a/src/plugins/platforms/xlib/qxlibcursor.h +++ b/src/gui/kernel/qplatforminputcontext_qpa_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -39,31 +39,29 @@ ** ****************************************************************************/ -#ifndef QTESTLITECURSOR_H -#define QTESTLITECURSOR_H +#ifndef QPLATFORMINPUTCONTEXT_P_H +#define QPLATFORMINPUTCONTEXT_P_H -#include +#include -#include "qxlibintegration.h" +QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QXlibCursor : public QPlatformCursor +class QPlatformInputContextPrivate: public QObjectPrivate { public: - QXlibCursor(QXlibScreen *screen); + QPlatformInputContextPrivate() {} + ~QPlatformInputContextPrivate() {} - void changeCursor(QCursor * cursor, QWindow * widget); -private: + static void setInputMethodAccepted(bool accepted); + static bool inputMethodAccepted(); - Cursor createCursorBitmap(QCursor * cursor); - Cursor createCursorShape(int cshape); - - QXlibScreen *testLiteScreen() const { return m_screen; } - QMap cursorMap; - QXlibScreen *m_screen; + static bool s_inputMethodAccepted; }; QT_END_NAMESPACE -#endif // QTESTLITECURSOR_H +QT_END_HEADER + +#endif diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index 6879f0517eb..5269d8fb246 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -247,6 +247,7 @@ QPlatformSharedGraphicsCache *QPlatformIntegration::createPlatformSharedGraphics */ QPaintEngine *QPlatformIntegration::createImagePaintEngine(QPaintDevice *paintDevice) const { + Q_UNUSED(paintDevice) return 0; } @@ -293,6 +294,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const return false; case PasswordMaskDelay: return 0; + case FontSmoothingGamma: + return qreal(1.7); } return 0; diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h index 68dfc218339..fe40fd3dad4 100644 --- a/src/gui/kernel/qplatformintegration_qpa.h +++ b/src/gui/kernel/qplatformintegration_qpa.h @@ -122,7 +122,8 @@ public: StartDragTime, KeyboardAutoRepeatRate, ShowIsFullScreen, - PasswordMaskDelay + PasswordMaskDelay, + FontSmoothingGamma }; virtual QVariant styleHint(StyleHint hint) const; diff --git a/src/gui/kernel/qplatformsharedgraphicscache_qpa.h b/src/gui/kernel/qplatformsharedgraphicscache_qpa.h index f8ee201d85b..8a92dbdd31d 100644 --- a/src/gui/kernel/qplatformsharedgraphicscache_qpa.h +++ b/src/gui/kernel/qplatformsharedgraphicscache_qpa.h @@ -76,17 +76,18 @@ public: const QVector &items) = 0; Q_INVOKABLE virtual void releaseItems(const QByteArray &cacheId, const QVector &itemIds) = 0; - virtual void serializeBuffer(void *bufferId, QByteArray *serializedData, int *fileDescriptor) const = 0; virtual uint textureIdForBuffer(void *bufferId) = 0; virtual void referenceBuffer(void *bufferId) = 0; virtual bool dereferenceBuffer(void *bufferId) = 0; + virtual QSize sizeOfBuffer(void *bufferId) = 0; + virtual void *eglImageForBuffer(void *bufferId) = 0; Q_SIGNALS: void itemsMissing(const QByteArray &cacheId, const QVector &itemIds); - void itemsAvailable(const QByteArray &cacheId, void *bufferId, const QSize &bufferSize, + void itemsAvailable(const QByteArray &cacheId, void *bufferId, const QVector &itemIds, const QVector &positionsInBuffer); void itemsInvalidated(const QByteArray &cacheId, const QVector &itemIds); - void itemsUpdated(const QByteArray &cacheId, void *bufferId, const QSize &bufferSize, + void itemsUpdated(const QByteArray &cacheId, void *bufferId, const QVector &itemIds, const QVector &positionsInBuffer); }; diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp index 4970f6a26b3..9384d34097d 100644 --- a/src/gui/kernel/qstylehints.cpp +++ b/src/gui/kernel/qstylehints.cpp @@ -101,4 +101,9 @@ int QStyleHints::passwordMaskDelay() const return hint(QPlatformIntegration::PasswordMaskDelay).toInt(); } +qreal QStyleHints::fontSmoothingGamma() const +{ + return hint(QPlatformIntegration::FontSmoothingGamma).toReal(); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h index ae51ebc0521..301b51868f3 100644 --- a/src/gui/kernel/qstylehints.h +++ b/src/gui/kernel/qstylehints.h @@ -63,6 +63,7 @@ public: int cursorFlashTime() const; bool showIsFullScreen() const; int passwordMaskDelay() const; + qreal fontSmoothingGamma() const; private: friend class QGuiApplication; diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 85f619db31b..d65998ce49b 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -375,6 +375,8 @@ bool QWindow::isTopLevel() const Returns whether the window is modal. A modal window prevents other windows from getting any input. + + \sa QWindow::windowModality */ bool QWindow::isModal() const { @@ -382,26 +384,37 @@ bool QWindow::isModal() const return d->modality != Qt::NonModal; } -/*! - Returns the window's modality. +/*! \property QWindow::windowModality + \brief the modality of the window - \sa setWindowModality() + A modal window prevents other windows from receiving input events. Qt + supports two types of modality: Qt::WindowModal and Qt::ApplicationModal. + + By default, this property is Qt::NonModal + + \sa Qt::WindowModality */ + Qt::WindowModality QWindow::windowModality() const { Q_D(const QWindow); return d->modality; } -/*! - Sets the window's modality to \a windowModality. -*/ -void QWindow::setWindowModality(Qt::WindowModality windowModality) +void QWindow::setWindowModality(Qt::WindowModality modality) { Q_D(QWindow); - d->modality = windowModality; + if (d->modality == modality) + return; + d->modality = modality; + emit windowModalityChanged(modality); } +/*! \fn void QWindow::windowModalityChanged(Qt::WindowModality windowModality) + + This signal is emitted when the Qwindow::windowModality property changes to \a windowModality. +*/ + /*! Sets the window's surface \a format. diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 62ddb66a75e..5cf6b413ba7 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -85,6 +85,7 @@ class Q_GUI_EXPORT QWindow : public QObject, public QSurface Q_DECLARE_PRIVATE(QWindow) Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) + Q_PROPERTY(Qt::WindowModality windowModality READ windowModality WRITE setWindowModality NOTIFY windowModalityChanged) Q_PROPERTY(int x READ x WRITE setX NOTIFY xChanged) Q_PROPERTY(int y READ y WRITE setY NOTIFY yChanged) Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) @@ -255,6 +256,7 @@ public Q_SLOTS: Q_SIGNALS: void backBufferReady(); void screenChanged(QScreen *screen); + void windowModalityChanged(Qt::WindowModality windowModality); void xChanged(int arg); void yChanged(int arg); diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 0792343ce13..d1dd246e9cb 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -75,6 +75,7 @@ SOURCES += \ SOURCES += \ painting/qpaintengine_raster.cpp \ painting/qdrawhelper.cpp \ + painting/qgammatables.cpp \ painting/qimagescale.cpp \ painting/qgrayraster.c \ painting/qpaintengine_blitter.cpp \ diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 3aea7945afc..919a19eb9b3 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -39,6 +39,18 @@ ** ****************************************************************************/ +#if defined(__OPTIMIZE__) && !defined(__INTEL_COMPILER) && defined(__GNUC__) \ + && (__GNUC__ * 100 + __GNUC_MINOR__ >= 404) +// GCC 4.4 supports #pragma GCC optimize and #pragma GCC target +# pragma GCC optimize "O3" +# if defined(__i386__) && defined(__SSE2__) && !defined(__SSE2_MATH__) +# pragma GCC target "fpmath=sse" +# endif +#endif + +#include +#include +#include #include #include #include @@ -51,6 +63,7 @@ #include #endif #include +#include #include QT_BEGIN_NAMESPACE @@ -5313,54 +5326,6 @@ inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer, map, mapWidth, mapHeight, mapStride); } - -struct QDrawHelperGammaTables -{ - QDrawHelperGammaTables(); - - uchar qt_pow_rgb_gamma[256]; - uchar qt_pow_rgb_invgamma[256]; - -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - uint qt_pow_gamma[256]; - uchar qt_pow_invgamma[2048]; -#endif -}; - -QDrawHelperGammaTables::QDrawHelperGammaTables() -{ - qreal smoothing = qreal(1.7); - - for (int i=0; i<256; ++i) { - qt_pow_rgb_gamma[i] = uchar(qRound(qPow(i / qreal(255.0), smoothing) * 255)); - qt_pow_rgb_invgamma[i] = uchar(qRound(qPow(i / qreal(255.), 1 / smoothing) * 255)); - } - -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - const qreal gray_gamma = 2.31; - for (int i=0; i<256; ++i) - qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047)); - for (int i=0; i<2048; ++i) - qt_pow_invgamma[i] = uchar(qRound(qPow(i / qreal(2047.0), 1 / gray_gamma) * 255)); -#endif -} - -Q_GLOBAL_STATIC(QDrawHelperGammaTables, qt_gamma_tables); - -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) -const uint *qt_pow_gamma() -{ - QDrawHelperGammaTables *tables = qt_gamma_tables(); - return tables ? tables->qt_pow_gamma : 0; -} -#endif - -const uchar *qt_pow_rgb_gamma() -{ - QDrawHelperGammaTables *tables = qt_gamma_tables(); - return tables ? tables->qt_pow_rgb_gamma : 0; -} - static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, int x, int y, quint32 color, const uchar *map, @@ -5473,7 +5438,7 @@ static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer, const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint32); #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - QDrawHelperGammaTables *tables = qt_gamma_tables(); + const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables(); if (!tables) return; @@ -5570,7 +5535,7 @@ static void qt_alphargbblit_quint32(QRasterBuffer *rasterBuffer, int sb = qBlue(color); int sa = qAlpha(color); - QDrawHelperGammaTables *tables = qt_gamma_tables(); + const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables(); if (!tables) return; diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 442fd8bcd7f..2e9f064951c 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -328,6 +328,18 @@ struct QSpanData void adjustSpanMethods(); }; +struct QDrawHelperGammaTables +{ + explicit QDrawHelperGammaTables(qreal smoothing); + + void refresh(qreal smoothing); + + uchar qt_pow_rgb_gamma[256]; + uchar qt_pow_rgb_invgamma[256]; + uint qt_pow_gamma[256]; + uchar qt_pow_invgamma[2048]; +}; + static inline uint qt_gradient_clamp(const QGradientData *data, int ipos) { if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) { diff --git a/src/plugins/platforms/xlib/main.cpp b/src/gui/painting/qgammatables.cpp similarity index 68% rename from src/plugins/platforms/xlib/main.cpp rename to src/gui/painting/qgammatables.cpp index 95c4d9e4d85..06dc95a103a 100644 --- a/src/plugins/platforms/xlib/main.cpp +++ b/src/gui/painting/qgammatables.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -39,36 +39,28 @@ ** ****************************************************************************/ -#include -#include "qxlibintegration.h" +#include QT_BEGIN_NAMESPACE -class QXlibIntegrationPlugin : public QPlatformIntegrationPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformIntegrationFactoryInterface" FILE "xlib.json") -public: - QStringList keys() const; - QPlatformIntegration *create(const QString&, const QStringList&); -}; -QStringList QXlibIntegrationPlugin::keys() const +QDrawHelperGammaTables::QDrawHelperGammaTables(qreal smoothing) { - QStringList list; - list << "xlib"; - return list; + const qreal gray_gamma = 2.31; + for (int i=0; i<256; ++i) + qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047)); + for (int i=0; i<2048; ++i) + qt_pow_invgamma[i] = uchar(qRound(qPow(i / qreal(2047.0), 1 / gray_gamma) * 255)); + + refresh(smoothing); } -QPlatformIntegration* QXlibIntegrationPlugin::create(const QString& system, const QStringList& paramList) +void QDrawHelperGammaTables::refresh(qreal smoothing) { - Q_UNUSED(paramList); - if (system.toLower() == "xlib") - return new QXlibIntegration; - - return 0; + for (int i=0; i<256; ++i) { + qt_pow_rgb_gamma[i] = uchar(qRound(qPow(i / qreal(255.0), smoothing) * 255)); + qt_pow_rgb_invgamma[i] = uchar(qRound(qPow(i / qreal(255.), 1 / smoothing) * 255)); + } } QT_END_NAMESPACE - -#include "main.moc" diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index b5e8bca7e08..15f344bf81b 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -737,7 +737,7 @@ void QRasterPaintEngine::updatePen(const QPen &pen) s->flags.fast_pen = pen_style > Qt::NoPen && s->penData.blend && ((pen.isCosmetic() && penWidth <= 1) - || (s->flags.tx_noshear && penWidth * s->txscale <= 1)); + || (!pen.isCosmetic() && s->flags.tx_noshear && penWidth * s->txscale <= 1)); s->flags.non_complex_pen = qpen_capStyle(s->lastPen) <= Qt::SquareCap && s->flags.tx_noshear; diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 79ed03e3930..f1310a5dca2 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -194,7 +194,7 @@ public: void clip(const QVectorPath &path, Qt::ClipOperation op); void clip(const QRect &rect, Qt::ClipOperation op); void clip(const QRegion ®ion, Qt::ClipOperation op); - inline const QClipData *clip() const; + inline const QClipData *clipData() const; void drawStaticTextItem(QStaticTextItem *textItem); virtual bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, @@ -492,7 +492,7 @@ inline const QClipData *QRasterPaintEnginePrivate::clip() const { return baseClip.data(); } -inline const QClipData *QRasterPaintEngine::clip() const { +inline const QClipData *QRasterPaintEngine::clipData() const { Q_D(const QRasterPaintEngine); if (state() && state()->clip && state()->clip->enabled) return state()->clip; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 2752fbd5739..849955100bc 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7248,6 +7248,7 @@ void QPainter::setRedirected(const QPaintDevice *device, const QPoint &offset) { Q_ASSERT(device != 0); + Q_UNUSED(device) Q_UNUSED(replacement) Q_UNUSED(offset) qWarning("QPainter::setRedirected(): ignoring call to deprecated function, use QWidget::render() instead"); diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 843551d51f3..cfa0a28fda8 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1524,6 +1524,7 @@ bool QPdfEngine::begin(QPaintDevice *pdev) d->pages.clear(); d->imageCache.clear(); + d->alphaCache.clear(); setActive(true); d->writeHeader(); diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp index 589c0f701fc..e14cfe0f82f 100644 --- a/src/gui/text/qabstracttextdocumentlayout.cpp +++ b/src/gui/text/qabstracttextdocumentlayout.cpp @@ -577,6 +577,21 @@ QString QAbstractTextDocumentLayout::anchorAt(const QPointF& pos) const if (cursorPos == -1) return QString(); + // compensate for preedit in the hit text block + QTextBlock block = document()->firstBlock(); + while (block.isValid()) { + QRectF blockBr = blockBoundingRect(block); + if (blockBr.contains(pos)) { + QTextLayout *layout = block.layout(); + int relativeCursorPos = cursorPos - block.position(); + const int preeditLength = layout ? layout->preeditAreaText().length() : 0; + if (preeditLength > 0 && relativeCursorPos > layout->preeditAreaPosition()) + cursorPos -= qMin(cursorPos - layout->preeditAreaPosition(), preeditLength); + break; + } + block = block.next(); + } + QTextDocumentPrivate *pieceTable = qobject_cast(parent())->docHandle(); QTextDocumentPrivate::FragmentIterator it = pieceTable->find(cursorPos); QTextCharFormat fmt = pieceTable->formatCollection()->charFormat(it->format); diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp index 6bd8284fa02..6af0398f006 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.cpp +++ b/src/gui/text/qplatformfontdatabase_qpa.cpp @@ -250,10 +250,10 @@ QPlatformFontDatabase::~QPlatformFontDatabase() void QPlatformFontDatabase::populateFontDatabase() { QString fontpath = fontDir(); - if(!QFile::exists(fontpath)) { - qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?", - qPrintable(fontpath)); + qWarning("QFontDatabase: Cannot find font directory '%s' - is Qt installed correctly?", + qPrintable(QDir::toNativeSeparators(fontpath))); + return; } QDir dir(fontpath); diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 9fbeef46851..5cdd563a33e 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -672,7 +672,7 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ */ void QRawFont::setPixelSize(qreal pixelSize) { - if (d->fontEngine == 0) + if (d->fontEngine == 0 || qFuzzyCompare(d->fontEngine->fontDef.pixelSize, pixelSize)) return; d.detach(); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 3d58d911698..7d366275a35 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE -static const float smallCapsFraction = 0.7; +static const float smallCapsFraction = 0.7f; namespace { // Helper class used in QTextEngine::itemize diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp index 6804dba95c6..4f699ee45fe 100644 --- a/src/gui/text/qtextimagehandler.cpp +++ b/src/gui/text/qtextimagehandler.cpp @@ -79,7 +79,7 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format) if (img.isNull()) { // try direct loading name = format.name(); // remove qrc:/ prefix again if (name.isEmpty() || !img.load(name)) - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/file-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png")); } pm = QPixmap::fromImage(img); doc->addResource(QTextDocument::ImageResource, url, pm); @@ -154,7 +154,7 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format) if (image.isNull()) { // try direct loading name = format.name(); // remove qrc:/ prefix again if (name.isEmpty() || !image.load(name)) - return QImage(QLatin1String(":/trolltech/styles/commonstyle/images/file-16.png")); + return QImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png")); } doc->addResource(QTextDocument::ImageResource, url, image); } diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 95b8f48ec55..bec574bb837 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -506,6 +506,7 @@ QString QTextLayout::preeditAreaText() const /*! Sets the additional formats supported by the text layout to \a formatList. + The formats are applied with preedit area text in place. \sa additionalFormats(), clearAdditionalFormats() */ @@ -2169,7 +2170,8 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, const QGlyphLayout &g glyphRun.setFlags(flags); glyphRun.setRawFont(font); - glyphRun.setBoundingRect(QRectF(selectionX.toReal(), minY, selectionWidth.toReal(), height)); + glyphRun.setBoundingRect(QRectF(selectionX.toReal(), minY - font.ascent(), + selectionWidth.toReal(), height)); return glyphRun; } @@ -2586,6 +2588,10 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const int pos = *cursorPos; int itm; const HB_CharAttributes *attributes = eng->attributes(); + if (!attributes) { + *cursorPos = 0; + return x.toReal(); + } while (pos < line.from + line.length && !attributes[pos].charStop) pos++; if (pos == line.from + (int)line.length) { @@ -2703,6 +2709,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const Converts the x-coordinate \a x, to the nearest matching cursor position, depending on the cursor position type, \a cpos. + Note that result cursor position includes possible preedit area text. \sa cursorToX() */ diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index 337326d3d72..1491c1efbcc 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -505,7 +505,7 @@ void QZipReaderPrivate::scanFiles() int num_dir_entries = 0; EndOfDirectory eod; while (start_of_directory == -1) { - int pos = device->size() - sizeof(EndOfDirectory) - i; + const int pos = device->size() - int(sizeof(EndOfDirectory)) - i; if (pos < 0 || i > 65535) { qWarning() << "QZip: EndOfDirectory not found"; return; diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index 1a6661440c5..26aecadcf45 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -287,17 +287,26 @@ void QDesktopServices::unsetUrlHandler(const QString &scheme) QString QDesktopServices::storageLocationImpl(StandardLocation type) { -#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) if (type == DataLocation) { - QString xdgDataHome = QLatin1String(qgetenv("XDG_DATA_HOME")); - if (xdgDataHome.isEmpty()) - xdgDataHome = QDir::homePath() + QLatin1String("/.local/share"); - xdgDataHome += QLatin1String("/data/") - + QCoreApplication::organizationName() + QLatin1Char('/') - + QCoreApplication::applicationName(); - return xdgDataHome; - } + // Preserve Qt 4 compatibility: + // * QCoreApplication::applicationName() must default to empty + // * Unix data location is under the "data/" subdirectory + extern Q_CORE_EXPORT QString qt_applicationName_noFallback(); + const QString compatAppName = qt_applicationName_noFallback(); + const QString baseDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); +#if defined(Q_OS_WIN) || defined(Q_OS_MAC) + QString result = baseDir; + if (!QCoreApplication::organizationName().isEmpty()) + result += QLatin1Char('/') + QCoreApplication::organizationName(); + if (!compatAppName.isEmpty()) + result += QLatin1Char('/') + compatAppName; + return result; +#elif defined(Q_OS_UNIX) + return baseDir + QLatin1String("/data/") + + QCoreApplication::organizationName() + QLatin1Char('/') + + compatAppName; #endif + } return QStandardPaths::writableLocation(static_cast(type)); } diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index d4931bd2075..6e33836feb7 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -733,14 +733,8 @@ void QHttpNetworkConnectionChannel::allDone() } } else if (alreadyPipelinedRequests.isEmpty() && socket->bytesAvailable() > 0) { // this is weird. we had nothing pipelined but still bytes available. better close it. - //if (socket->bytesAvailable() > 0) - // close(); - // - // FIXME - // We do not close it anymore now, but should introduce this again after having fixed - // the chunked decoder in QHttpNetworkReply to read the whitespace after the last chunk. - // (Currently this is worked around by readStatus in the QHttpNetworkReply ignoring - // leading whitespace. + close(); + QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } else if (alreadyPipelinedRequests.isEmpty()) { if (connectionCloseEnabled) diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 85463ee2106..39204163f2e 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -257,6 +257,7 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) chunkedTransferEncoding(false), connectionCloseEnabled(true), forceConnectionCloseEnabled(false), + lastChunkRead(false), currentChunkSize(0), currentChunkRead(0), connection(0), autoDecompress(false), responseData(), requestIsPrepared(false) ,pipeliningUsed(false), downstreamLimited(false) @@ -277,6 +278,7 @@ void QHttpNetworkReplyPrivate::clearHttpLayerInformation() totalProgress = 0; currentChunkSize = 0; currentChunkRead = 0; + lastChunkRead = false; connectionCloseEnabled = true; #ifndef QT_NO_COMPRESS if (autoDecompress) @@ -721,7 +723,7 @@ qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QAbstractSocket *socket, Q { qint64 bytes = 0; while (socket->bytesAvailable()) { - if (currentChunkRead >= currentChunkSize) { + if (!lastChunkRead && currentChunkRead >= currentChunkSize) { // For the first chunk and when we're done with a chunk currentChunkSize = 0; currentChunkRead = 0; @@ -744,8 +746,23 @@ qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QAbstractSocket *socket, Q break; } // if the chunk size is 0, end of the stream - if (currentChunkSize == 0) { - state = AllDoneState; + if (currentChunkSize == 0 || lastChunkRead) { + lastChunkRead = true; + // try to read the "\r\n" after the chunk + char crlf[2]; + qint64 haveRead = socket->read(crlf, 2); + if (haveRead > 0) + bytes += haveRead; + + if ((haveRead == 2 && crlf[0] == '\r' && crlf[1] == '\n') || (haveRead == 1 && crlf[0] == '\n')) + state = AllDoneState; + else if (haveRead == 1 && crlf[0] == '\r') + break; // Still waiting for the last \n + else if (haveRead > 0) { + // If we read something else then CRLF, we need to close the channel. + forceConnectionCloseEnabled = true; + state = AllDoneState; + } break; } diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 04e4569457a..97fefc6e1b8 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -217,6 +217,7 @@ public: bool chunkedTransferEncoding; bool connectionCloseEnabled; bool forceConnectionCloseEnabled; + bool lastChunkRead; qint64 currentChunkSize; qint64 currentChunkRead; QPointer connection; diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp index 42201aa9a31..4aa491db0c2 100644 --- a/src/network/access/qnetworkaccessftpbackend.cpp +++ b/src/network/access/qnetworkaccessftpbackend.cpp @@ -223,6 +223,7 @@ void QNetworkAccessFtpBackend::ftpDone() if (ftp->state() == QFtp::Connected) { // the login did not succeed QUrl newUrl = url(); + QString userInfo = newUrl.userInfo(); newUrl.setUserInfo(QString()); setUrl(newUrl); @@ -236,6 +237,10 @@ void QNetworkAccessFtpBackend::ftpDone() return; } + // Re insert the user info so that we can remove the cache entry. + newUrl.setUserInfo(userInfo); + setUrl(newUrl); + error(QNetworkReply::AuthenticationRequiredError, tr("Logging in to %1 failed: authentication required") .arg(url().host())); diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 0dbfdb2f0cf..7174acc31ef 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -606,7 +606,7 @@ static bool checkStaticArray(int &val, const QByteArray &dateString, int at, con val = j; return true; } - i += strlen(str) + 1; + i += int(strlen(str)) + 1; ++j; } } diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp index a311af76861..8e3b5ce7c0c 100644 --- a/src/network/kernel/qnetworkinterface_win.cpp +++ b/src/network/kernel/qnetworkinterface_win.cpp @@ -182,6 +182,8 @@ static QList interfaceListingWinXP() iface->flags |= QNetworkInterface::IsUp | QNetworkInterface::IsRunning; if ((ptr->Flags & IP_ADAPTER_NO_MULTICAST) == 0) iface->flags |= QNetworkInterface::CanMulticast; + if (ptr->IfType == IF_TYPE_PPP) + iface->flags |= QNetworkInterface::IsPointToPoint; iface->name = QString::fromLocal8Bit(ptr->AdapterName); iface->friendlyName = QString::fromWCharArray(ptr->FriendlyName); diff --git a/src/network/kernel/qnetworkinterface_win_p.h b/src/network/kernel/qnetworkinterface_win_p.h index 73e5c625ec0..303f4d3690f 100644 --- a/src/network/kernel/qnetworkinterface_win_p.h +++ b/src/network/kernel/qnetworkinterface_win_p.h @@ -94,6 +94,9 @@ QT_BEGIN_NAMESPACE # define MIB_IF_TYPE_LOOPBACK 24 # define MIB_IF_TYPE_SLIP 28 +// definitions from Ipifcons.h +#define IF_TYPE_PPP 23 + #endif // copied from qnativesocketengine_win.cpp struct qt_in6_addr { diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp index 4f1dece4a90..a17f5477425 100644 --- a/src/network/kernel/qnetworkproxy_win.cpp +++ b/src/network/kernel/qnetworkproxy_win.cpp @@ -113,13 +113,49 @@ typedef HINTERNET (WINAPI * PtrWinHttpOpen)(LPCWSTR, DWORD, LPCWSTR, LPCWSTR,DWO typedef BOOL (WINAPI * PtrWinHttpGetDefaultProxyConfiguration)(WINHTTP_PROXY_INFO*); typedef BOOL (WINAPI * PtrWinHttpGetIEProxyConfigForCurrentUser)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*); typedef BOOL (WINAPI * PtrWinHttpCloseHandle)(HINTERNET); +typedef SC_HANDLE (WINAPI * PtrOpenSCManager)(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess); +typedef BOOL (WINAPI * PtrEnumServicesStatusEx)(SC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, + LPDWORD lpServicesReturned, LPDWORD lpResumeHandle, LPCWSTR pszGroupName); +typedef BOOL (WINAPI * PtrCloseServiceHandle)(SC_HANDLE hSCObject); static PtrWinHttpGetProxyForUrl ptrWinHttpGetProxyForUrl = 0; static PtrWinHttpOpen ptrWinHttpOpen = 0; static PtrWinHttpGetDefaultProxyConfiguration ptrWinHttpGetDefaultProxyConfiguration = 0; static PtrWinHttpGetIEProxyConfigForCurrentUser ptrWinHttpGetIEProxyConfigForCurrentUser = 0; static PtrWinHttpCloseHandle ptrWinHttpCloseHandle = 0; +static PtrOpenSCManager ptrOpenSCManager = 0; +static PtrEnumServicesStatusEx ptrEnumServicesStatusEx = 0; +static PtrCloseServiceHandle ptrCloseServiceHandle = 0; +static bool currentProcessIsService() +{ + if (!ptrOpenSCManager || !ptrEnumServicesStatusEx|| !ptrCloseServiceHandle) + return false; + + SC_HANDLE hSCM = ptrOpenSCManager(0, 0, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT); + if (!hSCM) + return false; + + ULONG bufSize = 0; + ULONG nbServices = 0; + if (ptrEnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, 0, bufSize, &bufSize, &nbServices, 0, 0)) + return false; //error case + + LPENUM_SERVICE_STATUS_PROCESS info = reinterpret_cast(malloc(bufSize)); + bool foundService = false; + if (ptrEnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, (LPBYTE)info, bufSize, &bufSize, &nbServices, 0, 0)) { + DWORD currProcId = GetCurrentProcessId(); + for (ULONG i = 0; i < nbServices && !foundService; i++) { + if (info[i].ServiceStatusProcess.dwProcessId == currProcId) + foundService = true; + } + } + + ptrCloseServiceHandle(hSCM); + free(info); + return foundService; +} + static QStringList splitSpaceSemicolon(const QString &source) { QStringList list; @@ -364,10 +400,14 @@ void QWindowsSystemProxy::init() ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl)lib.resolve("WinHttpGetProxyForUrl"); ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration)lib.resolve("WinHttpGetDefaultProxyConfiguration"); ptrWinHttpGetIEProxyConfigForCurrentUser = (PtrWinHttpGetIEProxyConfigForCurrentUser)lib.resolve("WinHttpGetIEProxyConfigForCurrentUser"); + ptrOpenSCManager = (PtrOpenSCManager) QSystemLibrary(L"advapi32").resolve("OpenSCManagerW"); + ptrEnumServicesStatusEx = (PtrEnumServicesStatusEx) QSystemLibrary(L"advapi32").resolve("EnumServicesStatusExW"); + ptrCloseServiceHandle = (PtrCloseServiceHandle) QSystemLibrary(L"advapi32").resolve("CloseServiceHandle"); // Try to obtain the Internet Explorer configuration. WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig; - if (ptrWinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig)) { + const bool hasIEConfig = ptrWinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig); + if (hasIEConfig) { if (ieProxyConfig.lpszAutoConfigUrl) { autoConfigUrl = QString::fromWCharArray(ieProxyConfig.lpszAutoConfigUrl); GlobalFree(ieProxyConfig.lpszAutoConfigUrl); @@ -383,9 +423,13 @@ void QWindowsSystemProxy::init() proxyBypass = splitSpaceSemicolon(QString::fromWCharArray(ieProxyConfig.lpszProxyBypass)); GlobalFree(ieProxyConfig.lpszProxyBypass); } - } else { + } + + if (!hasIEConfig || + (currentProcessIsService() && proxyServerList.isEmpty() && proxyBypass.isEmpty())) { // no user configuration // attempt to get the default configuration instead + // that config will serve as default if WPAD fails WINHTTP_PROXY_INFO proxyInfo; if (ptrWinHttpGetDefaultProxyConfiguration(&proxyInfo) && proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY) { diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index af22b20b217..0c4eed8de97 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1984,7 +1984,16 @@ bool QAbstractSocket::waitForConnected(int msecs) d->_q_startConnecting(QHostInfoPrivate::fromName(d->hostName, networkSession)); } else #endif - d->_q_startConnecting(QHostInfo::fromName(d->hostName)); + { + QHostAddress temp; + if (temp.setAddress(d->hostName)) { + QHostInfo info; + info.setAddresses(QList() << temp); + d->_q_startConnecting(info); + } else { + d->_q_startConnecting(QHostInfo::fromName(d->hostName)); + } + } } if (state() == UnconnectedState) return false; // connect not im progress anymore! diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index a34b19f7efe..8fac3613c04 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -637,6 +637,19 @@ bool QNativeSocketEngine::joinMulticastGroup(const QHostAddress &groupAddress, Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::joinMulticastGroup(), false); Q_CHECK_STATE(QNativeSocketEngine::joinMulticastGroup(), QAbstractSocket::BoundState, false); Q_CHECK_TYPE(QNativeSocketEngine::joinMulticastGroup(), QAbstractSocket::UdpSocket, false); + + // if the user binds a socket to an IPv6 address (or QHostAddress::Any) and + // then attempts to join an IPv4 multicast group, this won't work on + // Windows. In order to make this cross-platform, we warn & fail on all + // platforms. + if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol && + (d->socketProtocol == QAbstractSocket::IPv6Protocol || + d->socketProtocol == QAbstractSocket::AnyIPProtocol)) { + qWarning("QAbstractSocket: cannot bind to QHostAddress::Any (or an IPv6 address) and join an IPv4 multicast group"); + qWarning("QAbstractSocket: bind to QHostAddress::AnyIPv4 instead if you want to do this"); + return false; + } + return d->nativeJoinMulticastGroup(groupAddress, iface); } diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 295d3961a85..7cd8e1bff31 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -321,7 +321,13 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt } case QNativeSocketEngine::AddressReusable: #if defined(SO_REUSEPORT) - n = SO_REUSEPORT; + // on OS X, SO_REUSEADDR isn't sufficient to allow multiple binds to the + // same port (which is useful for multicast UDP). SO_REUSEPORT is, but + // we most definitely do not want to use this for TCP. See QTBUG-6305. + if (socketType == QAbstractSocket::UdpSocket) + n = SO_REUSEPORT; + else + n = SO_REUSEADDR; #else n = SO_REUSEADDR; #endif diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp index ec751c289e4..23c1956ec5a 100644 --- a/src/network/socket/qudpsocket.cpp +++ b/src/network/socket/qudpsocket.cpp @@ -178,6 +178,10 @@ QUdpSocket::~QUdpSocket() interface chosen by the operating system. The socket must be in BoundState, otherwise an error occurs. + Note that if you are attempting to join an IPv4 group, your socket must not + be bound using IPv6 (or in dual mode, using QHostAddress::Any). You must use + QHostAddress::AnyIPv4 instead. + This function returns true if successful; otherwise it returns false and sets the socket error accordingly. diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index aa25215755b..b5374d13cd0 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -53,6 +53,9 @@ #if defined(Q_OS_UNIX) #include #endif +#ifdef Q_OS_LINUX +#include +#endif QT_BEGIN_NAMESPACE @@ -347,6 +350,23 @@ static bool libGreaterThan(const QString &lhs, const QString &rhs) return true; } +#ifdef Q_OS_LINUX +static int dlIterateCallback(struct dl_phdr_info *info, size_t size, void *data) +{ + if (size < sizeof (info->dlpi_addr) + sizeof (info->dlpi_name)) + return 1; + QSet *paths = (QSet *)data; + QString path = QString::fromLocal8Bit(info->dlpi_name); + if (!path.isEmpty()) { + QFileInfo fi(path); + path = fi.absolutePath(); + if (!path.isEmpty()) + paths->insert(path); + } + return 0; +} +#endif + static QStringList findAllLibSsl() { QStringList paths; @@ -358,6 +378,12 @@ static QStringList findAllLibSsl() .split(QLatin1Char(':'), QString::SkipEmptyParts); # endif paths << QLatin1String("/lib") << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib"); +#ifdef Q_OS_LINUX + // discover paths of already loaded libraries + QSet loadedPaths; + dl_iterate_phdr(dlIterateCallback, &loadedPaths); + paths.append(loadedPaths.toList()); +#endif QStringList foundSsls; foreach (const QString &path, paths) { diff --git a/src/platformsupport/cglconvenience/cglconvenience.pri b/src/platformsupport/cglconvenience/cglconvenience.pri index fef3b50ea32..a367e4d0536 100644 --- a/src/platformsupport/cglconvenience/cglconvenience.pri +++ b/src/platformsupport/cglconvenience/cglconvenience.pri @@ -7,5 +7,5 @@ mac { OBJECTIVE_SOURCES += \ $$PWD/cglconvenience.mm - LIBS += -framework Cocoa -framework OpenGl + LIBS += -framework Cocoa -framework OpenGL } diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index 5579b4cd26e..38fe0cce516 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -89,7 +89,6 @@ QIBusPlatformInputContext::QIBusPlatformInputContext () connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool))); } QInputMethod *p = qApp->inputMethod(); - connect(p, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); connect(p, SIGNAL(cursorRectangleChanged()), this, SLOT(cursorRectChanged())); } @@ -130,7 +129,7 @@ void QIBusPlatformInputContext::commit() if (!d->valid) return; - QObject *input = qApp->inputMethod()->inputItem(); + QObject *input = qApp->focusObject(); if (!input) { d->predit = QString(); return; @@ -159,7 +158,7 @@ void QIBusPlatformInputContext::cursorRectChanged() if(!r.isValid()) return; - QWindow *inputWindow = qApp->inputMethod()->inputWindow(); + QWindow *inputWindow = qApp->focusWindow(); if (!inputWindow) return; r.moveTopLeft(inputWindow->mapToGlobal(r.topLeft())); @@ -168,15 +167,14 @@ void QIBusPlatformInputContext::cursorRectChanged() d->context->SetCursorLocation(r.x(), r.y(), r.width(), r.height()); } -void QIBusPlatformInputContext::inputItemChanged() +void QIBusPlatformInputContext::setFocusObject(QObject *object) { if (!d->valid) return; - QObject *input = qApp->inputMethod()->inputItem(); if (debug) - qDebug() << "setFocusObject" << input; - if (input) + qDebug() << "setFocusObject" << object; + if (object) d->context->FocusIn(); else d->context->FocusOut(); @@ -184,7 +182,7 @@ void QIBusPlatformInputContext::inputItemChanged() void QIBusPlatformInputContext::commitText(const QDBusVariant &text) { - QObject *input = qApp->inputMethod()->inputItem(); + QObject *input = qApp->focusObject(); if (!input) return; @@ -206,7 +204,7 @@ void QIBusPlatformInputContext::commitText(const QDBusVariant &text) void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint cursorPos, bool visible) { - QObject *input = qApp->inputMethod()->inputItem(); + QObject *input = qApp->focusObject(); if (!input) return; @@ -254,6 +252,9 @@ QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state, if (!d->valid) return false; + if (!inputMethodAccepted()) + return false; + if (!press) return false; diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h index ca8f492c5db..1ed4262ef65 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h @@ -56,6 +56,7 @@ public: ~QIBusPlatformInputContext(); bool isValid() const; + void setFocusObject(QObject *object); void invokeAction(QInputMethod::Action a, int x); void reset(); @@ -67,7 +68,6 @@ public: public Q_SLOTS: void commitText(const QDBusVariant &text); void updatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible); - void inputItemChanged(); void cursorRectChanged(); private: diff --git a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp b/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp index dbb4e6e650f..882aae286ea 100644 --- a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp @@ -182,8 +182,6 @@ QMaliitPlatformInputContext::QMaliitPlatformInputContext() { if (debug) qDebug() << "QMaliitPlatformInputContext::QMaliitPlatformInputContext()"; - QInputMethod *im = qApp->inputMethod(); - connect(im, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); } QMaliitPlatformInputContext::~QMaliitPlatformInputContext(void) @@ -198,8 +196,7 @@ bool QMaliitPlatformInputContext::isValid() const void QMaliitPlatformInputContext::invokeAction(QInputMethod::Action action, int x) { - QObject *input = qApp->inputMethod()->inputItem(); - if (!input) + if (!inputMethodAccepted()) return; if (action == QInputMethod::Click) { @@ -220,14 +217,12 @@ void QMaliitPlatformInputContext::invokeAction(QInputMethod::Action action, int void QMaliitPlatformInputContext::reset() { - QObject *input = qApp->inputMethod()->inputItem(); - const bool hadPreedit = !d->preedit.isEmpty(); - if (hadPreedit && input) { + if (hadPreedit && inputMethodAccepted()) { // ### selection QInputMethodEvent event; event.setCommitString(d->preedit); - QGuiApplication::sendEvent(input, &event); + QGuiApplication::sendEvent(qGuiApp->focusObject(), &event); d->preedit.clear(); } @@ -238,13 +233,11 @@ void QMaliitPlatformInputContext::reset() void QMaliitPlatformInputContext::update(Qt::InputMethodQueries queries) { - QInputMethod *method = qApp->inputMethod(); - QObject *input = method->inputItem(); - if (!input) + if (!qGuiApp->focusObject()) return; QInputMethodQueryEvent query(queries); - QGuiApplication::sendEvent(input, &query); + QGuiApplication::sendEvent(qGuiApp->focusObject(), &query); if (queries & Qt::ImSurroundingText) d->imState["surroundingText"] = query.value(Qt::ImSurroundingText); @@ -254,8 +247,8 @@ void QMaliitPlatformInputContext::update(Qt::InputMethodQueries queries) d->imState["anchorPosition"] = query.value(Qt::ImAnchorPosition); if (queries & Qt::ImCursorRectangle) { QRect rect = query.value(Qt::ImCursorRectangle).toRect(); - rect = method->inputItemTransform().mapRect(rect); - QWindow *window = method->inputWindow(); + rect = qGuiApp->inputMethod()->inputItemTransform().mapRect(rect); + QWindow *window = qGuiApp->focusWindow(); if (window) d->imState["cursorRectangle"] = QRect(window->mapToGlobal(rect.topLeft()), rect.size()); } @@ -289,8 +282,7 @@ void QMaliitPlatformInputContext::activationLostEvent() void QMaliitPlatformInputContext::commitString(const QString &string, int replacementStart, int replacementLength, int /* cursorPos */) { - QObject *input = qApp->inputMethod()->inputItem(); - if (!input) + if (!inputMethodAccepted()) return; d->preedit.clear(); @@ -300,13 +292,12 @@ void QMaliitPlatformInputContext::commitString(const QString &string, int replac // ### start/cursorPos QInputMethodEvent event; event.setCommitString(string, replacementStart, replacementLength); - QCoreApplication::sendEvent(input, &event); + QCoreApplication::sendEvent(qGuiApp->focusObject(), &event); } void QMaliitPlatformInputContext::updatePreedit(const QDBusMessage &message) { - QObject *input = qApp->inputMethod()->inputItem(); - if (!input) + if (!inputMethodAccepted()) return; QList arguments = message.arguments(); @@ -375,7 +366,7 @@ void QMaliitPlatformInputContext::updatePreedit(const QDBusMessage &message) QInputMethodEvent event(d->preedit, attributes); if (replacementStart || replacementLength) event.setCommitString(QString(), replacementStart, replacementLength); - QCoreApplication::sendEvent(input, &event); + QCoreApplication::sendEvent(qGuiApp->focusObject(), &event); } void QMaliitPlatformInputContext::copy() @@ -435,12 +426,11 @@ bool QMaliitPlatformInputContext::selection(QString &selection) { selection.clear(); - QObject *input = qApp->inputMethod()->inputItem(); - if (!input) + if (!inputMethodAccepted()) return false; QInputMethodQueryEvent query(Qt::ImCurrentSelection); - QGuiApplication::sendEvent(input, &query); + QGuiApplication::sendEvent(qGuiApp->focusObject(), &query); QVariant value = query.value(Qt::ImCurrentSelection); if (!value.isValid()) return false; @@ -471,14 +461,13 @@ void QMaliitPlatformInputContext::setRedirectKeys(bool) void QMaliitPlatformInputContext::setSelection(int start, int length) { - QObject *input = qApp->inputMethod()->inputItem(); - if (!input) + if (!inputMethodAccepted()) return; QList attributes; attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, start, length, QVariant()); QInputMethodEvent event(QString(), attributes); - QGuiApplication::sendEvent(input, &event); + QGuiApplication::sendEvent(qGuiApp->focusObject(), &event); } void QMaliitPlatformInputContext::updateInputMethodArea(int x, int y, int width, int height) @@ -492,14 +481,12 @@ void QMaliitPlatformInputContext::updateServerWindowOrientation(Qt::ScreenOrient d->server->appOrientationChanged(orientationAngle(orientation)); } -void QMaliitPlatformInputContext::inputItemChanged() +void QMaliitPlatformInputContext::setFocusObject(QObject *object) { if (!d->valid) return; - QInputMethod *method = qApp->inputMethod(); - QObject *input = method->inputItem(); - QWindow *window = method->inputWindow(); + QWindow *window = qGuiApp->focusWindow(); if (window != d->window.data()) { if (d->window) disconnect(d->window.data(), SIGNAL(contentOrientationChanged(Qt::ScreenOrientation)), @@ -510,8 +497,8 @@ void QMaliitPlatformInputContext::inputItemChanged() this, SLOT(updateServerWindowOrientation(Qt::ScreenOrientation))); } - d->imState["focusState"] = input != 0; - if (input) { + d->imState["focusState"] = (object != 0); + if (inputMethodAccepted()) { if (window) d->imState["winId"] = static_cast(window->winId()); @@ -524,7 +511,7 @@ void QMaliitPlatformInputContext::inputItemChanged() } } d->sendStateUpdate(/*focusChanged*/true); - if (input && window && d->visibility == InputPanelShowRequested) + if (inputMethodAccepted() && window && d->visibility == InputPanelShowRequested) showInputPanel(); } @@ -533,8 +520,7 @@ void QMaliitPlatformInputContext::showInputPanel() if (debug) qDebug() << "showInputPanel"; - QInputMethod *method = qApp->inputMethod(); - if (!method->inputItem() || !method->inputWindow()) + if (!inputMethodAccepted()) d->visibility = InputPanelShowRequested; else { d->server->showInputMethod(); diff --git a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.h b/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.h index a17abe7cbb6..26125246195 100644 --- a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.h @@ -67,10 +67,9 @@ public: virtual void showInputPanel(); virtual void hideInputPanel(); virtual bool isInputPanelVisible() const; + void setFocusObject(QObject *object); public Q_SLOTS: - void inputItemChanged(); - void activationLostEvent(); void commitString(const QString &in0, int in1, int in2, int in3); void updatePreedit(const QDBusMessage &message); diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.mm b/src/plugins/platforms/cocoa/qcocoaclipboard.mm index f76174e0855..90e89d0198e 100644 --- a/src/plugins/platforms/cocoa/qcocoaclipboard.mm +++ b/src/plugins/platforms/cocoa/qcocoaclipboard.mm @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "QCocoaclipboard.h" +#include "qcocoaclipboard.h" #include "qmacmime.h" #include "qmacclipboard.h" diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index bd8d32b07e0..363c746f41f 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -204,19 +204,19 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor) return createCursorFromPixmap(pixmap); break; } case Qt::WaitCursor: { - QPixmap pixmap = QPixmap(QLatin1String(":/trolltech/mac/cursors/images/spincursor.png")); + QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/spincursor.png")); return createCursorFromPixmap(pixmap); break; } case Qt::SizeAllCursor: { - QPixmap pixmap = QPixmap(QLatin1String(":/trolltech/mac/cursors/images/pluscursor.png")); + QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/pluscursor.png")); return createCursorFromPixmap(pixmap); break; } case Qt::BusyCursor: { - QPixmap pixmap = QPixmap(QLatin1String(":/trolltech/mac/cursors/images/waitcursor.png")); + QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/waitcursor.png")); return createCursorFromPixmap(pixmap); break; } case Qt::ForbiddenCursor: { - QPixmap pixmap = QPixmap(QLatin1String(":/trolltech/mac/cursors/images/forbiddencursor.png")); + QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/forbiddencursor.png")); return createCursorFromPixmap(pixmap); break; } #define QT_USE_APPROXIMATE_CURSORS diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index 70e974161ee..4993937b91a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -82,7 +82,7 @@ void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader) } // Copy nib files from resources to temp. - QDir nibResource(":/trolltech/mac/qt_menu.nib/"); + QDir nibResource(":/qt-project.org/mac/qt_menu.nib/"); if (!nibResource.exists()) { qWarning("qt_mac_loadMenuNib: could not load nib from resources"); return; diff --git a/src/plugins/platforms/cocoa/qcocoaresources.qrc b/src/plugins/platforms/cocoa/qcocoaresources.qrc index de50d397c69..392300bb030 100644 --- a/src/plugins/platforms/cocoa/qcocoaresources.qrc +++ b/src/plugins/platforms/cocoa/qcocoaresources.qrc @@ -1,15 +1,15 @@ - + images/copyarrowcursor.png images/forbiddencursor.png images/spincursor.png images/waitcursor.png images/pluscursor.png - + images/leopard-unified-toolbar-on.png - + qt_menu.nib/classes.nib qt_menu.nib/info.nib qt_menu.nib/keyedobjects.nib diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 4f954897987..de588427728 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -96,8 +96,8 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) : QPlatformWindow(tlw) , m_nsWindow(0) - , m_glContext(0) , m_inConstructor(true) + , m_glContext(0) { QCocoaAutoReleasePool pool; @@ -231,9 +231,10 @@ void QCocoaWindow::propagateSizeHints() if (!window()->sizeIncrement().isNull()) [m_nsWindow setResizeIncrements : qt_mac_toNSSize(window()->sizeIncrement())]; + QRect rect = geometry(); QSize baseSize = window()->baseSize(); if (!baseSize.isNull() && baseSize.isValid()) { - [m_nsWindow setFrameSize : NSMakeSize(baseSize.width(), baseSize.height()) display : YES]; + [m_nsWindow setFrame:NSMakeRect(rect.x(), rect.y(), baseSize.width(), baseSize.height()) display:YES]; } } @@ -364,6 +365,30 @@ NSWindow * QCocoaWindow::createNSWindow() NSUInteger styleMask; NSWindow *createdWindow = 0; + NSInteger windowLevel = -1; + + if (type == Qt::Tool) { + windowLevel = NSFloatingWindowLevel; + } else if ((type & Qt::Popup) == Qt::Popup) { + // styleMask = NSBorderlessWindowMask; + windowLevel = NSPopUpMenuWindowLevel; + + // Popup should be in at least the same level as its parent. + const QWindow * const transientParent = window()->transientParent(); + const QCocoaWindow * const transientParentWindow = transientParent ? static_cast(transientParent->handle()) : 0; + if (transientParentWindow) + windowLevel = qMax([transientParentWindow->m_nsWindow level], windowLevel); + } + + // StayOnTop window should appear above Tool windows. + if (flags & Qt::WindowStaysOnTopHint) + windowLevel = NSPopUpMenuWindowLevel; + // Tooltips should appear above StayOnTop windows. + if (type == Qt::ToolTip) + windowLevel = NSScreenSaverWindowLevel; + // All other types are Normal level. + if (windowLevel == -1) + windowLevel = NSNormalWindowLevel; // Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen) if ((type & Qt::Popup) == Qt::Popup) { @@ -403,6 +428,9 @@ NSWindow * QCocoaWindow::createNSWindow() createdWindow = window; } + + [createdWindow setLevel:windowLevel]; + return createdWindow; } diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro index c12d612c983..89d56efc822 100644 --- a/src/plugins/platforms/eglfs/eglfs.pro +++ b/src/plugins/platforms/eglfs/eglfs.pro @@ -21,7 +21,16 @@ SOURCES = main.cpp \ HEADERS = qeglfsintegration.h \ qeglfswindow.h \ qeglfsbackingstore.h \ - qeglfsscreen.h + qeglfsscreen.h \ + qeglfs_hooks.h + +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +!isEmpty(EGLFS_PLATFORM_HOOKS_SOURCES) { + HEADERS += $$EGLFS_PLATFORM_HOOKS_HEADERS + SOURCES += $$EGLFS_PLATFORM_HOOKS_SOURCES + DEFINES += EGLFS_PLATFORM_HOOKS +} CONFIG += egl qpa/genericunixfontdatabase diff --git a/src/plugins/platforms/xlib/qxlibdisplay.h b/src/plugins/platforms/eglfs/qeglfs_hooks.h similarity index 79% rename from src/plugins/platforms/xlib/qxlibdisplay.h rename to src/plugins/platforms/eglfs/qeglfs_hooks.h index 900751366f1..a30af9409ff 100644 --- a/src/plugins/platforms/xlib/qxlibdisplay.h +++ b/src/plugins/platforms/eglfs/qeglfs_hooks.h @@ -39,25 +39,23 @@ ** ****************************************************************************/ -#ifndef QXLIBDISPLAY_H -#define QXLIBDISPLAY_H +#ifndef QEGLFS_HOOKS_H +#define QEGLFS_HOOKS_H -#include "qxlibintegration.h" +#include "qplatformintegration_qpa.h" +#include -class QXlibDisplay -{ -public: - QXlibDisplay(Display *display); - ~QXlibDisplay(); - QString displayName() const; +QT_BEGIN_NAMESPACE - Display *nativeDisplay() const; - - void sync() const; - void flush() const; -private: - Display *mDisplay; - QString mDisplayName; +struct QEglFSHooks { + void platformInit(); + void platformDestroy(); + EGLNativeDisplayType platformDisplay() const; + QSize screenSize() const; + EGLNativeWindowType createNativeWindow(const QSize &size); + void destroyNativeWindow(EGLNativeWindowType window); }; -#endif // QXLIBDISPLAY_H +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.h b/src/plugins/platforms/eglfs/qeglfsbackingstore.h index 1eb4d8d79a5..97ea3224204 100644 --- a/src/plugins/platforms/eglfs/qeglfsbackingstore.h +++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QEGLWINDOWSURFACE_H -#define QEGLWINDOWSURFACE_H +#ifndef QEGLFSBACKINGSTORE_H +#define QEGLFSBACKINGSTORE_H #include @@ -70,4 +70,4 @@ private: QT_END_NAMESPACE -#endif // QEGLWINDOWSURFACE_H +#endif // QEGLFSBACKINGSTORE_H diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index d180de349e3..d9214f87fec 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -43,6 +43,7 @@ #include "qeglfswindow.h" #include "qeglfsbackingstore.h" +#include "qeglfs_hooks.h" #include #include @@ -57,15 +58,20 @@ QT_BEGIN_NAMESPACE QEglFSIntegration::QEglFSIntegration() - : mFontDb(new QGenericUnixFontDatabase()) + : mFontDb(new QGenericUnixFontDatabase()), mScreen(new QEglFSScreen) { - screenAdded(new QEglFSScreen(EGL_DEFAULT_DISPLAY)); + screenAdded(mScreen); #ifdef QEGL_EXTRA_DEBUG qWarning("QEglIntegration\n"); #endif } +QEglFSIntegration::~QEglFSIntegration() +{ + delete mScreen; +} + bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index ee30d4bbf23..eea36a489d5 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef EGLINTEGRATION_H -#define EGLINTEGRATION_H +#ifndef QEGLFSINTEGRATION_H +#define QEGLFSINTEGRATION_H #include "qeglfsscreen.h" @@ -55,6 +55,7 @@ class QEglFSIntegration : public QPlatformIntegration { public: QEglFSIntegration(); + ~QEglFSIntegration(); bool hasCapability(QPlatformIntegration::Capability cap) const; @@ -70,9 +71,10 @@ public: private: QPlatformFontDatabase *mFontDb; + QPlatformScreen *mScreen; }; QT_END_NAMESPACE QT_END_HEADER -#endif +#endif // QEGLFSINTEGRATION_H diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 000bedf2939..c7e983b0fb6 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -41,6 +41,7 @@ #include "qeglfsscreen.h" #include "qeglfswindow.h" +#include "qeglfs_hooks.h" #include #include @@ -52,6 +53,13 @@ QT_BEGIN_NAMESPACE +#ifdef EGLFS_PLATFORM_HOOKS +extern QEglFSHooks platform_hooks; +static QEglFSHooks *hooks = &platform_hooks; +#else +static QEglFSHooks *hooks = 0; +#endif + // #define QEGL_EXTRA_DEBUG #ifdef QEGL_EXTRA_DEBUG @@ -104,16 +112,20 @@ public: } }; -QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) +QEglFSScreen::QEglFSScreen() : m_depth(32) , m_format(QImage::Format_Invalid) , m_platformContext(0) , m_surface(0) + , m_window(0) { #ifdef QEGL_EXTRA_DEBUG qWarning("QEglScreen %p\n", this); #endif + if (hooks) + hooks->platformInit(); + EGLint major, minor; if (!eglBindAPI(EGL_OPENGL_ES_API)) { @@ -121,7 +133,7 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) qFatal("EGL error"); } - m_dpy = eglGetDisplay(display); + m_dpy = eglGetDisplay(hooks ? hooks->platformDisplay() : EGL_DEFAULT_DISPLAY); if (m_dpy == EGL_NO_DISPLAY) { qWarning("Could not open egl display\n"); qFatal("EGL error"); @@ -146,6 +158,20 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) eglSwapInterval(m_dpy, swapInterval); } +QEglFSScreen::~QEglFSScreen() +{ + if (m_surface) + eglDestroySurface(m_dpy, m_surface); + + if (hooks) + hooks->destroyNativeWindow(m_window); + + eglTerminate(m_dpy); + + if (hooks) + hooks->platformDestroy(); +} + void QEglFSScreen::createAndSetPlatformContext() const { const_cast(this)->createAndSetPlatformContext(); } @@ -177,14 +203,16 @@ void QEglFSScreen::createAndSetPlatformContext() EGLConfig config = q_configFromGLFormat(m_dpy, platformFormat); - EGLNativeWindowType eglWindow = 0; #ifdef Q_OPENKODE if (kdInitializeNV() == KD_ENOTINITIALIZED) { qFatal("Did not manage to initialize openkode"); } KDWindow *window = kdCreateWindow(m_dpy,config,0); - kdRealizeWindow(window,&eglWindow); + kdRealizeWindow(window, &m_window); +#else + if (hooks) + m_window = hooks->createNativeWindow(hooks->screenSize()); #endif #ifdef QEGL_EXTRA_DEBUG @@ -201,7 +229,7 @@ void QEglFSScreen::createAndSetPlatformContext() qWarning("\n"); #endif - m_surface = eglCreateWindowSurface(m_dpy, config, eglWindow, NULL); + m_surface = eglCreateWindowSurface(m_dpy, config, m_window, NULL); if (m_surface == EGL_NO_SURFACE) { qWarning("Could not create the egl surface: error = 0x%x\n", eglGetError()); eglTerminate(m_dpy); diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index 18fc643b980..66e600d7c2a 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QEGLSCREEN_H -#define QEGLSCREEN_H +#ifndef QEGLFSSCREEN_H +#define QEGLFSSCREEN_H #include @@ -55,8 +55,8 @@ class QPlatformOpenGLContext; class QEglFSScreen : public QPlatformScreen //huh: FullScreenScreen ;) just to follow namespace { public: - QEglFSScreen(EGLNativeDisplayType display); - ~QEglFSScreen() {} + QEglFSScreen(); + ~QEglFSScreen(); QRect geometry() const; int depth() const; @@ -76,7 +76,8 @@ private: QPlatformOpenGLContext *m_platformContext; EGLDisplay m_dpy; EGLSurface m_surface; + EGLNativeWindowType m_window; }; QT_END_NAMESPACE -#endif // QEGLSCREEN_H +#endif // QEGLFSSCREEN_H diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index 807470bc785..1376708ad6f 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QEGLWINDOW_H -#define QEGLWINDOW_H +#ifndef QEGLFSWINDOW_H +#define QEGLFSWINDOW_H #include "qeglfsintegration.h" #include "qeglfsscreen.h" @@ -62,4 +62,4 @@ private: WId m_winid; }; QT_END_NAMESPACE -#endif // QEGLWINDOW_H +#endif // QEGLFSWINDOW_H diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 692332291c8..442390f6a60 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -12,7 +12,7 @@ mac { win32: SUBDIRS += windows -qnx-*-qcc { +qnx { SUBDIRS += qnx } diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 588464fc479..bdc8c386148 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -20,6 +20,7 @@ QT += opengl opengl-private platformsupport platformsupport-private widgets-priv #DEFINES += QQNXRASTERBACKINGSTORE_DEBUG #DEFINES += QQNXROOTWINDOW_DEBUG #DEFINES += QQNXSCREEN_DEBUG +#DEFINES += QQNXSCREENEVENT_DEBUG #DEFINES += QQNXVIRTUALKEYBOARD_DEBUG #DEFINES += QQNXWINDOW_DEBUG @@ -35,8 +36,10 @@ SOURCES = main.cpp \ qqnxrasterbackingstore.cpp \ qqnxvirtualkeyboard.cpp \ qqnxclipboard.cpp \ - qqnxrootwindow.cpp - + qqnxrootwindow.cpp \ + qqnxscreeneventhandler.cpp \ + qqnxabstractvirtualkeyboard.cpp \ + qqnxnativeinterface.cpp HEADERS = qqnxbuffer.h \ qqnxeventthread.h \ @@ -50,7 +53,10 @@ HEADERS = qqnxbuffer.h \ qqnxrasterbackingstore.h \ qqnxvirtualkeyboard.h \ qqnxclipboard.h \ - qqnxrootwindow.h + qqnxrootwindow.h \ + qqnxscreeneventhandler.h \ + qqnxabstractvirtualkeyboard.h \ + qqnxnativeinterface.h CONFIG(blackberry) { SOURCES += qqnxservices.cpp diff --git a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp new file mode 100644 index 00000000000..0ac1af6d2fc --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxabstractvirtualkeyboard.h" + +QT_BEGIN_NAMESPACE + +QQnxAbstractVirtualKeyboard::QQnxAbstractVirtualKeyboard(QObject *parent) + : QObject(parent) + , m_height(0) + , m_visible(false) + , m_locale(QLocale::system()) + , m_keyboardMode(Default) +{ +} + +void QQnxAbstractVirtualKeyboard::setKeyboardMode(KeyboardMode mode) +{ + if (mode == m_keyboardMode) + return; + + m_keyboardMode = mode; + + applyKeyboardMode(mode); +} + +void QQnxAbstractVirtualKeyboard::setHeight(int height) +{ + if (height == m_height) + return; + + const int effectiveHeight = this->height(); + + m_height = height; + + if (effectiveHeight != this->height()) + emit heightChanged(this->height()); +} + +void QQnxAbstractVirtualKeyboard::setVisible(bool visible) +{ + if (visible == m_visible) + return; + + const int effectiveHeight = height(); + + m_visible = visible; + + emit visibilityChanged(visible); + + if (effectiveHeight != height()) + emit heightChanged(height()); +} + +void QQnxAbstractVirtualKeyboard::setLocale(const QLocale &locale) +{ + if (locale == m_locale) + return; + + m_locale = locale; + + emit localeChanged(locale); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h new file mode 100644 index 00000000000..e548fa5ca27 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h @@ -0,0 +1,100 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXABSTRACTVIRTUALKEYBOARD_H +#define QQNXABSTRACTVIRTUALKEYBOARD_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QQnxAbstractVirtualKeyboard : public QObject +{ + Q_OBJECT +public: + // NOTE: Not all the following keyboard modes are currently used. + // Default - Regular Keyboard + // Url/Email - Enhanced keys for each types. + // Web - Regular keyboard with two blank keys, currently unused. + // NumPunc - Numbers & Punctionation, alternate to Symbol + // Symbol - All symbols, alternate to NumPunc, currently unused. + // Phone - Phone enhanced keyboard - currently unused as no alternate keyboard available to access a-zA-Z + // Pin - Keyboard for entering Pins (Hex values) currently unused. + // + // SPECIAL NOTE: Usage of NumPunc may have to be removed, ABC button is non-functional. + // + enum KeyboardMode { Default, Url, Email, Web, NumPunc, Symbol, Phone, Pin }; + + explicit QQnxAbstractVirtualKeyboard(QObject *parent = 0); + + virtual bool showKeyboard() = 0; + virtual bool hideKeyboard() = 0; + + int height() { return m_visible ? m_height : 0; } + bool isVisible() const { return m_visible; } + QLocale locale() const { return m_locale; } + + void setKeyboardMode(KeyboardMode mode); + KeyboardMode keyboardMode() const { return m_keyboardMode; } + +Q_SIGNALS: + void heightChanged(int height); + void visibilityChanged(bool visible); + void localeChanged(const QLocale &locale); + +protected: + virtual void applyKeyboardMode(KeyboardMode mode) = 0; + + void setHeight(int height); + void setVisible(bool visible); + void setLocale(const QLocale &locale); + +private: + int m_height; + bool m_visible; + QLocale m_locale; + KeyboardMode m_keyboardMode; +}; + +QT_END_NAMESPACE + +#endif // QQNXABSTRACTVIRTUALKEYBOARD_H diff --git a/src/plugins/platforms/qnx/qqnxclipboard.h b/src/plugins/platforms/qnx/qqnxclipboard.h index 1104885d8cc..c9ceff41f66 100644 --- a/src/plugins/platforms/qnx/qqnxclipboard.h +++ b/src/plugins/platforms/qnx/qqnxclipboard.h @@ -51,9 +51,9 @@ class QQnxClipboard : public QPlatformClipboard { public: QQnxClipboard(); - virtual ~QQnxClipboard(); - virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); - virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); + ~QQnxClipboard(); + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); private: class MimeData; diff --git a/src/plugins/platforms/qnx/qqnxeventthread.cpp b/src/plugins/platforms/qnx/qqnxeventthread.cpp index cd30da1971c..768d508add4 100644 --- a/src/plugins/platforms/qnx/qqnxeventthread.cpp +++ b/src/plugins/platforms/qnx/qqnxeventthread.cpp @@ -40,53 +40,22 @@ ****************************************************************************/ #include "qqnxeventthread.h" -#include "qqnxintegration.h" -#include "qqnxkeytranslator.h" - -#if defined(QQNX_IMF) -#include "qqnxinputcontext_imf.h" -#else -#include "qqnxinputcontext_noimf.h" -#endif - -#include -#include -#include +#include "qqnxscreeneventhandler.h" #include #include #include -#include #include -QQnxEventThread::QQnxEventThread(screen_context_t context, QPlatformScreen& screen) +QQnxEventThread::QQnxEventThread(screen_context_t context, + QQnxScreenEventHandler *screenEventHandler) : QThread(), m_screenContext(context), - m_platformScreen(screen), - m_quit(false), - m_lastButtonState(Qt::NoButton), - m_lastMouseWindow(0) + m_screenEventHandler(screenEventHandler), + m_quit(false) { - // Create a touch device - m_touchDevice = new QTouchDevice; - m_touchDevice->setType(QTouchDevice::TouchScreen); - m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition); - QWindowSystemInterface::registerTouchDevice(m_touchDevice); - - // initialize array of touch points - for (int i = 0; i < MaximumTouchPoints; i++) { - - // map array index to id - m_touchPoints[i].id = i; - - // pressure is not supported - use default - m_touchPoints[i].pressure = 1.0; - - // nothing touching - m_touchPoints[i].state = Qt::TouchPointReleased; - } } QQnxEventThread::~QQnxEventThread() @@ -95,6 +64,11 @@ QQnxEventThread::~QQnxEventThread() shutdown(); } +void QQnxEventThread::injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap) +{ + QQnxScreenEventHandler::injectKeyboardEvent(flags, sym, mod, scan, cap); +} + void QQnxEventThread::run() { screen_event_t event; @@ -102,9 +76,8 @@ void QQnxEventThread::run() // create screen event errno = 0; int result = screen_create_event(&event); - if (result) { + if (result) qFatal("QQNX: failed to create event, errno=%d", errno); - } #if defined(QQNXEVENTTHREAD_DEBUG) qDebug() << "QQNX: event loop started"; @@ -116,12 +89,26 @@ void QQnxEventThread::run() // block until screen event is available errno = 0; result = screen_get_event(m_screenContext, event, -1); - if (result) { + if (result) qFatal("QQNX: failed to get event, errno=%d", errno); - } // process received event - dispatchEvent(event); + // get the event type + errno = 0; + int qnxType; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType); + if (result) + qFatal("QQNX: failed to query event type, errno=%d", errno); + + if (qnxType == SCREEN_EVENT_USER) { + // treat all user events as shutdown requests + #if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: QNX user event"; + #endif + m_quit = true; + } else { + m_screenEventHandler->handleEvent(event, qnxType); + } } #if defined(QQNXEVENTTHREAD_DEBUG) @@ -139,26 +126,23 @@ void QQnxEventThread::shutdown() // create screen event errno = 0; int result = screen_create_event(&event); - if (result) { + if (result) qFatal("QQNX: failed to create event, errno=%d", errno); - } // set the event type as user errno = 0; int type = SCREEN_EVENT_USER; result = screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type); - if (result) { + if (result) qFatal("QQNX: failed to set event type, errno=%d", errno); - } // NOTE: ignore SCREEN_PROPERTY_USER_DATA; treat all user events as shutdown events // post event to event loop so it will wake up and die errno = 0; result = screen_send_event(m_screenContext, event, getpid()); - if (result) { + if (result) qFatal("QQNX: failed to set event type, errno=%d", errno); - } // cleanup screen_destroy_event(event); @@ -174,399 +158,3 @@ void QQnxEventThread::shutdown() qDebug() << "QQNX: event loop shutdown end"; #endif } - -void QQnxEventThread::dispatchEvent(screen_event_t event) -{ - // get the event type - errno = 0; - int qnxType; - int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType); - if (result) { - qFatal("QQNX: failed to query event type, errno=%d", errno); - } - - switch (qnxType) { - case SCREEN_EVENT_MTOUCH_TOUCH: - case SCREEN_EVENT_MTOUCH_MOVE: - case SCREEN_EVENT_MTOUCH_RELEASE: - handleTouchEvent(event, qnxType); - break; - - case SCREEN_EVENT_KEYBOARD: - handleKeyboardEvent(event); - break; - - case SCREEN_EVENT_POINTER: - handlePointerEvent(event); - break; - - case SCREEN_EVENT_CLOSE: - handleCloseEvent(event); - break; - - case SCREEN_EVENT_USER: - // treat all user events as shutdown requests -#if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: QNX user event"; -#endif - m_quit = true; - break; - - default: - // event ignored -#if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: QNX unknown event"; -#endif - break; - } -} - -void QQnxEventThread::handleKeyboardEvent(screen_event_t event) -{ - // get flags of key event - errno = 0; - int flags; - int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags); - if (result) { - qFatal("QQNX: failed to query event flags, errno=%d", errno); - } - - // get key code - errno = 0; - int sym; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym); - if (result) { - qFatal("QQNX: failed to query event sym, errno=%d", errno); - } - - int modifiers; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers); - if (result) { - qFatal("QQNX: failed to query event modifiers, errno=%d", errno); - } - - int scan; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan); - if (result) { - qFatal("QQNX: failed to query event modifiers, errno=%d", errno); - } - - int cap; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap); - if (result) { - qFatal("QQNX: failed to query event cap, errno=%d", errno); - } - - injectKeyboardEvent(flags, sym, modifiers, scan, cap); -} - -void QQnxEventThread::injectKeyboardEvent(int flags, int sym, int modifiers, int scan, int cap) -{ - Q_UNUSED(scan); - - Qt::KeyboardModifiers qtMod = Qt::NoModifier; - if (modifiers & KEYMOD_SHIFT) - qtMod |= Qt::ShiftModifier; - if (modifiers & KEYMOD_CTRL) - qtMod |= Qt::ControlModifier; - if (modifiers & KEYMOD_ALT) - qtMod |= Qt::AltModifier; - - // determine event type - QEvent::Type type = (flags & KEY_DOWN) ? QEvent::KeyPress : QEvent::KeyRelease; - - // Check if the key cap is valid - if (flags & KEY_CAP_VALID) { - Qt::Key key; - QString keyStr; - - if (cap >= 0x20 && cap <= 0x0ff) { - key = Qt::Key(std::toupper(cap)); // Qt expects the CAP to be upper case. - - if ( qtMod & Qt::ControlModifier ) { - keyStr = QChar((int)(key & 0x3f)); - } else { - if (flags & KEY_SYM_VALID) { - keyStr = QChar(sym); - } - } - } else if ((cap > 0x0ff && cap < UNICODE_PRIVATE_USE_AREA_FIRST) || cap > UNICODE_PRIVATE_USE_AREA_LAST) { - key = (Qt::Key)cap; - keyStr = QChar(sym); - } else { - if (isKeypadKey(cap)) - qtMod |= Qt::KeypadModifier; // Is this right? - key = keyTranslator(cap); - } - - QWindowSystemInterface::handleKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod, keyStr); -#if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: Qt key t=" << type << ", k=" << key << ", s=" << keyStr; -#endif - } -} - -void QQnxEventThread::handlePointerEvent(screen_event_t event) -{ - errno = 0; - - // Query the window that was clicked - screen_window_t qnxWindow; - void *handle; - int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); - if (result) { - qFatal("QQNX: failed to query event window, errno=%d", errno); - } - qnxWindow = static_cast(handle); - - // Query the button states - int buttonState = 0; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState); - if (result) { - qFatal("QQNX: failed to query event button state, errno=%d", errno); - } - - // Query the window position - int windowPos[2]; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos); - if (result) { - qFatal("QQNX: failed to query event window position, errno=%d", errno); - } - - // Query the screen position - int pos[2]; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos); - if (result) { - qFatal("QQNX: failed to query event position, errno=%d", errno); - } - - // Query the wheel delta - int wheelDelta = 0; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta); - if (result) { - qFatal("QQNX: failed to query event wheel delta, errno=%d", errno); - } - - // Map window handle to top-level QWindow - QWindow *w = QQnxIntegration::window(qnxWindow); - - // Generate enter and leave events as needed. - if (qnxWindow != m_lastMouseWindow) { - QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow); - - if (wOld) { - QWindowSystemInterface::handleLeaveEvent(wOld); -#if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: Qt leave, w=" << wOld; -#endif - } - - if (w) { - QWindowSystemInterface::handleEnterEvent(w); -#if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: Qt enter, w=" << w; -#endif - } - } - m_lastMouseWindow = qnxWindow; - - // Apply scaling to wheel delta and invert value for Qt. We'll probably want to scale - // this via a system preference at some point. But for now this is a sane value and makes - // the wheel usable. - wheelDelta *= -10; - - // convert point to local coordinates - QPoint globalPoint(pos[0], pos[1]); - QPoint localPoint(windowPos[0], windowPos[1]); - - // Convert buttons. - // Some QNX header files invert 'Right Button versus "Left Button' ('Right' == 0x01). But they also offer a 'Button Swap' bit, - // so we may receive events as shown. (If this is wrong, the fix is easy.) - // QNX Button mask is 8 buttons wide, with a maximum value of x080. - Qt::MouseButtons buttons = Qt::NoButton; - if (buttonState & 0x01) - buttons |= Qt::LeftButton; - if (buttonState & 0x02) - buttons |= Qt::MidButton; - if (buttonState & 0x04) - buttons |= Qt::RightButton; - if (buttonState & 0x08) - buttons |= Qt::ExtraButton1; // AKA 'Qt::BackButton' - if (buttonState & 0x10) - buttons |= Qt::ExtraButton2; // AKA 'Qt::ForwardButton' - if (buttonState & 0x20) - buttons |= Qt::ExtraButton3; - if (buttonState & 0x40) - buttons |= Qt::ExtraButton4; - if (buttonState & 0x80) - buttons |= Qt::ExtraButton5; - - if (w) { - // Inject mouse event into Qt only if something has changed. - if (m_lastGlobalMousePoint != globalPoint || - m_lastLocalMousePoint != localPoint || - m_lastButtonState != buttons) { - QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons); -#if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << static_cast(buttons); -#endif - } - - if (wheelDelta) { - // Screen only supports a single wheel, so we will assume Vertical orientation for - // now since that is pretty much standard. - QWindowSystemInterface::handleWheelEvent(w, localPoint, globalPoint, wheelDelta, Qt::Vertical); -#if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: Qt wheel, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), d=" << static_cast(wheelDelta); -#endif - } - } - - m_lastGlobalMousePoint = globalPoint; - m_lastLocalMousePoint = localPoint; - m_lastButtonState = buttons; -} - -void QQnxEventThread::handleTouchEvent(screen_event_t event, int qnxType) -{ - // get display coordinates of touch - errno = 0; - int pos[2]; - int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos); - if (result) { - qFatal("QQNX: failed to query event position, errno=%d", errno); - } - - // get window coordinates of touch - errno = 0; - int windowPos[2]; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos); - if (result) { - qFatal("QQNX: failed to query event window position, errno=%d", errno); - } - - // determine which finger touched - errno = 0; - int touchId; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId); - if (result) { - qFatal("QQNX: failed to query event touch id, errno=%d", errno); - } - - // determine which window was touched - errno = 0; - void *handle; - result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); - if (result) { - qFatal("QQNX: failed to query event window, errno=%d", errno); - } - screen_window_t qnxWindow = static_cast(handle); - - // check if finger is valid - if (touchId < MaximumTouchPoints) { - - // Map window handle to top-level QWindow - QWindow *w = QQnxIntegration::window(qnxWindow); - - // Generate enter and leave events as needed. - if (qnxWindow != m_lastMouseWindow) { - QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow); - - if (wOld) { - QWindowSystemInterface::handleLeaveEvent(wOld); - #if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: Qt leave, w=" << wOld; - #endif - } - - if (w) { - QWindowSystemInterface::handleEnterEvent(w); - #if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: Qt enter, w=" << w; - #endif - } - } - m_lastMouseWindow = qnxWindow; - - if (w) { - // convert primary touch to mouse event - if (touchId == 0) { - - // convert point to local coordinates - QPoint globalPoint(pos[0], pos[1]); - QPoint localPoint(windowPos[0], windowPos[1]); - - // map touch state to button state - Qt::MouseButtons buttons = (qnxType == SCREEN_EVENT_MTOUCH_RELEASE) ? Qt::NoButton : Qt::LeftButton; - - // inject event into Qt - QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons); -#if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << buttons; -#endif - } - - // get size of screen which contains window - QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w); - QSizeF screenSize = platformScreen->physicalSize(); - - // update cached position of current touch point - m_touchPoints[touchId].normalPosition = QPointF( static_cast(pos[0]) / screenSize.width(), static_cast(pos[1]) / screenSize.height() ); - m_touchPoints[touchId].area = QRectF( pos[0], pos[1], 0.0, 0.0 ); - - // determine event type and update state of current touch point - QEvent::Type type = QEvent::None; - switch (qnxType) { - case SCREEN_EVENT_MTOUCH_TOUCH: - m_touchPoints[touchId].state = Qt::TouchPointPressed; - type = QEvent::TouchBegin; - break; - case SCREEN_EVENT_MTOUCH_MOVE: - m_touchPoints[touchId].state = Qt::TouchPointMoved; - type = QEvent::TouchUpdate; - break; - case SCREEN_EVENT_MTOUCH_RELEASE: - m_touchPoints[touchId].state = Qt::TouchPointReleased; - type = QEvent::TouchEnd; - break; - } - - // build list of active touch points - QList pointList; - for (int i = 0; i < MaximumTouchPoints; i++) { - if (i == touchId) { - // current touch point is always active - pointList.append(m_touchPoints[i]); - } else if (m_touchPoints[i].state != Qt::TouchPointReleased) { - // finger is down but did not move - m_touchPoints[i].state = Qt::TouchPointStationary; - pointList.append(m_touchPoints[i]); - } - } - - // inject event into Qt - QWindowSystemInterface::handleTouchEvent(w, m_touchDevice, pointList); -#if defined(QQNXEVENTTHREAD_DEBUG) - qDebug() << "QQNX: Qt touch, w=" << w << ", p=(" << pos[0] << "," << pos[1] << "), t=" << type; -#endif - } - } -} - -void QQnxEventThread::handleCloseEvent(screen_event_t event) -{ - // Query the window that was closed - void *handle; - int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); - if (result != 0) { - qFatal("QQNX: failed to query event window, errno=%d", errno); - } - screen_window_t qnxWindow = static_cast(handle); - - // Map window handle to top-level QWindow - QWindow *w = QQnxIntegration::window(qnxWindow); - if (w != 0) { - QWindowSystemInterface::handleCloseEvent(w); - } -} - diff --git a/src/plugins/platforms/qnx/qqnxeventthread.h b/src/plugins/platforms/qnx/qqnxeventthread.h index 61831233e91..aa6186aa0d0 100644 --- a/src/plugins/platforms/qnx/qqnxeventthread.h +++ b/src/plugins/platforms/qnx/qqnxeventthread.h @@ -44,45 +44,29 @@ #include -#include -#include - #include QT_BEGIN_NAMESPACE +class QQnxScreenEventHandler; + class QQnxEventThread : public QThread { public: - QQnxEventThread(screen_context_t context, QPlatformScreen& screen); + QQnxEventThread(screen_context_t context, QQnxScreenEventHandler *screenEventHandler); virtual ~QQnxEventThread(); static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap); protected: - virtual void run(); + void run(); private: - enum { - MaximumTouchPoints = 10 - }; - void shutdown(); - void dispatchEvent(screen_event_t event); - void handleKeyboardEvent(screen_event_t event); - void handlePointerEvent(screen_event_t event); - void handleTouchEvent(screen_event_t event, int type); - void handleCloseEvent(screen_event_t event); screen_context_t m_screenContext; - QPlatformScreen& m_platformScreen; + QQnxScreenEventHandler *m_screenEventHandler; bool m_quit; - QPoint m_lastGlobalMousePoint; - QPoint m_lastLocalMousePoint; - Qt::MouseButtons m_lastButtonState; - screen_window_t m_lastMouseWindow; - QTouchDevice *m_touchDevice; - QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints]; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxglbackingstore.h b/src/plugins/platforms/qnx/qqnxglbackingstore.h index d04fe22f5db..b694079f37a 100644 --- a/src/plugins/platforms/qnx/qqnxglbackingstore.h +++ b/src/plugins/platforms/qnx/qqnxglbackingstore.h @@ -58,11 +58,11 @@ class QQnxGLPaintDevice : public QGLPaintDevice { public: QQnxGLPaintDevice(QWindow *window); - virtual ~QQnxGLPaintDevice(); + ~QQnxGLPaintDevice(); - virtual QPaintEngine *paintEngine() const; - virtual QSize size() const; - virtual QGLContext *context() const { return m_glContext; } + QPaintEngine *paintEngine() const; + QSize size() const; + QGLContext *context() const { return m_glContext; } private: QQnxWindow *m_window; @@ -73,13 +73,13 @@ class QQnxGLBackingStore : public QPlatformBackingStore { public: QQnxGLBackingStore(QWindow *window); - virtual ~QQnxGLBackingStore(); + ~QQnxGLBackingStore(); - virtual QPaintDevice *paintDevice() { return m_paintDevice; } - virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); - virtual void resize(const QSize &size, const QRegion &staticContents); - virtual void beginPaint(const QRegion ®ion); - virtual void endPaint(const QRegion ®ion); + QPaintDevice *paintDevice() { return m_paintDevice; } + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size, const QRegion &staticContents); + void beginPaint(const QRegion ®ion); + void endPaint(const QRegion ®ion); void resizeSurface(const QSize &size); diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp index d620feb7107..882b71753e2 100644 --- a/src/plugins/platforms/qnx/qqnxglcontext.cpp +++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp @@ -48,6 +48,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -103,7 +104,7 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext) // Check if all channels are don't care if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) { // Set colour channels based on depth of window's screen - QQnxScreen *screen = static_cast(QQnxScreen::screens().first()); + QQnxScreen *screen = static_cast(glContext->screen()->handle()); int depth = screen->depth(); if (depth == 32) { // SCREEN_FORMAT_RGBA8888 diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h index 36c439802a3..ee8d61ce00d 100644 --- a/src/plugins/platforms/qnx/qqnxglcontext.h +++ b/src/plugins/platforms/qnx/qqnxglcontext.h @@ -61,10 +61,10 @@ public: static void initialize(); static void shutdown(); - virtual bool makeCurrent(QPlatformSurface *surface); - virtual void doneCurrent(); - virtual void swapBuffers(QPlatformSurface *surface); - virtual QFunctionPointer getProcAddress(const QByteArray &procName); + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + void swapBuffers(QPlatformSurface *surface); + QFunctionPointer getProcAddress(const QByteArray &procName); virtual QSurfaceFormat format() const { return m_windowFormat; } diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp index 3f9d768ccc6..976249f229c 100644 --- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp +++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp @@ -41,7 +41,7 @@ #include "qqnxinputcontext_imf.h" #include "qqnxeventthread.h" -#include "qqnxvirtualkeyboard.h" +#include "qqnxabstractvirtualkeyboard.h" #include #include @@ -674,12 +674,15 @@ static bool imfAvailable() return s_imfReady; } -QQnxInputContext::QQnxInputContext(): +QT_BEGIN_NAMESPACE + +QQnxInputContext::QQnxInputContext(QQnxAbstractVirtualKeyboard &keyboard): QPlatformInputContext(), m_lastCaretPos(0), m_isComposing(false), m_inputPanelVisible(false), - m_inputPanelLocale(QLocale::c()) + m_inputPanelLocale(QLocale::c()), + m_virtualKeyboad(keyboard) { #if defined(QQNXINPUTCONTEXT_DEBUG) qDebug() << Q_FUNC_INFO; @@ -697,15 +700,10 @@ QQnxInputContext::QQnxInputContext(): // p_vkb_init_selection_service(); - QQnxVirtualKeyboard &keyboard = QQnxVirtualKeyboard::instance(); connect(&keyboard, SIGNAL(visibilityChanged(bool)), this, SLOT(keyboardVisibilityChanged(bool))); connect(&keyboard, SIGNAL(localeChanged(QLocale)), this, SLOT(keyboardLocaleChanged(QLocale))); keyboardVisibilityChanged(keyboard.isVisible()); keyboardLocaleChanged(keyboard.locale()); - - QInputMethod *inputMethod = qApp->inputMethod(); - connect(inputMethod, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); - } QQnxInputContext::~QQnxInputContext() @@ -946,8 +944,7 @@ bool QQnxInputContext::hasSession() bool QQnxInputContext::hasSelectedText() { - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!input) return false; @@ -959,13 +956,12 @@ bool QQnxInputContext::hasSelectedText() bool QQnxInputContext::dispatchRequestSoftwareInputPanel() { - QQnxVirtualKeyboard::instance().showKeyboard(); + m_virtualKeyboard.showKeyboard(); #if defined(QQNXINPUTCONTEXT_DEBUG) qDebug() << "QQNX: requesting virtual keyboard"; #endif - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) + QObject *input = qGuiApp->focusObject(); + if (!imfAvailable() || !input || !inputMethodAccepted()) return true; if (!hasSession()) @@ -986,7 +982,7 @@ bool QQnxInputContext::dispatchRequestSoftwareInputPanel() bool QQnxInputContext::dispatchCloseSoftwareInputPanel() { - QQnxVirtualKeyboard::instance().hideKeyboard(); + m_virtualKeyboard.hideKeyboard(); #if defined(QQNXINPUTCONTEXT_DEBUG) qDebug() << "QQNX: hiding virtual keyboard"; #endif @@ -1138,8 +1134,7 @@ void QQnxInputContext::endComposition() if (!m_isComposing) return; - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return; @@ -1161,8 +1156,7 @@ void QQnxInputContext::setComposingText(QString const& composingText) m_composingText = composingText; m_isComposing = true; - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return; @@ -1273,8 +1267,7 @@ int32_t QQnxInputContext::onCommitText(input_session_t *ic, spannable_string_t * if (!isSessionOkay(ic)) return 0; - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return 0; @@ -1303,8 +1296,7 @@ int32_t QQnxInputContext::onDeleteSurroundingText(input_session_t *ic, int32_t l if (!isSessionOkay(ic)) return 0; - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return 0; @@ -1347,8 +1339,7 @@ int32_t QQnxInputContext::onFinishComposingText(input_session_t *ic) if (!isSessionOkay(ic)) return 0; - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return 0; @@ -1389,8 +1380,7 @@ int32_t QQnxInputContext::onGetCursorPosition(input_session_t *ic) if (!isSessionOkay(ic)) return 0; - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return 0; @@ -1432,8 +1422,7 @@ spannable_string_t *QQnxInputContext::onGetSelectedText(input_session_t *ic, int if (!isSessionOkay(ic)) return toSpannableString(""); - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return 0; @@ -1454,8 +1443,7 @@ spannable_string_t *QQnxInputContext::onGetTextAfterCursor(input_session_t *ic, if (!isSessionOkay(ic)) return toSpannableString(""); - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return toSpannableString(""); @@ -1477,8 +1465,7 @@ spannable_string_t *QQnxInputContext::onGetTextBeforeCursor(input_session_t *ic, if (!isSessionOkay(ic)) return toSpannableString(""); - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return toSpannableString(""); @@ -1559,8 +1546,7 @@ int32_t QQnxInputContext::onSetComposingRegion(input_session_t *ic, int32_t star if (!isSessionOkay(ic)) return 0; - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return 0; @@ -1594,8 +1580,7 @@ int32_t QQnxInputContext::onSetComposingText(input_session_t *ic, spannable_stri if (!isSessionOkay(ic)) return 0; - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); + QObject *input = qGuiApp->focusObject(); if (!imfAvailable() || !input) return 0; @@ -1672,25 +1657,24 @@ void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale) } } -void QQnxInputContext::inputItemChanged() +void QQnxInputContext::setFocusObject(QObject *object) { - QInputMethod *inputMethod = qApp->inputMethod(); - QObject *inputItem = inputMethod->inputItem(); - #if defined(QQNXINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "input item=" << inputItem; + qDebug() << Q_FUNC_INFO << "input item=" << object; #endif - if (!inputItem) { + if (!inputMethodAccepted()) { if (m_inputPanelVisible) hideInputPanel(); } else { - if (qobject_cast(inputItem)) { - QQnxVirtualKeyboard::instance().setKeyboardMode(QQnxVirtualKeyboard::NumPunc); - } else { - QQnxVirtualKeyboard::instance().setKeyboardMode(QQnxVirtualKeyboard::Default); - } + if (qobject_cast(object)) + m_virtualKeyboard.setKeyboardMode(QQnxAbstractVirtualKeyboard::Phone); + else + m_virtualKeyboard.setKeyboardMode(QQnxAbstractVirtualKeyboard::Default); + if (!m_inputPanelVisible) showInputPanel(); } } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.h b/src/plugins/platforms/qnx/qqnxinputcontext_imf.h index 1fb55296a65..5f7d95bc4a6 100644 --- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.h +++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.h @@ -53,25 +53,28 @@ QT_BEGIN_NAMESPACE +class QQnxAbstractVirtualKeyboard; + class QQnxInputContext : public QPlatformInputContext { Q_OBJECT public: - QQnxInputContext(); + explicit QQnxInputContext(QQnxAbstractVirtualKeyboard &keyboard); ~QQnxInputContext(); - virtual bool isValid() const; + bool isValid() const; - virtual bool filterEvent(const QEvent *event); - virtual void reset(); - virtual void update(Qt::InputMethodQueries); + bool filterEvent(const QEvent *event); + void reset(); + void update(Qt::InputMethodQueries); bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap); - virtual void showInputPanel(); - virtual void hideInputPanel(); - virtual bool isInputPanelVisible() const; + void showInputPanel(); + void hideInputPanel(); + bool isInputPanelVisible() const; - virtual QLocale locale() const; + QLocale locale() const; + void setFocusObject(QObject *object); protected: // Filters only for IMF events. @@ -80,7 +83,6 @@ protected: private Q_SLOTS: void keyboardVisibilityChanged(bool visible); void keyboardLocaleChanged(const QLocale &locale); - void inputItemChanged(); private: // IMF Event dispatchers @@ -123,6 +125,7 @@ private: QString m_composingText; bool m_inputPanelVisible; QLocale m_inputPanelLocale; + QQnxAbstractVirtualKeyboard &m_virtualKeyboad; }; Q_DECLARE_METATYPE(extracted_text_t*) diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp index 33b6c0e6f3e..4d229fd872f 100644 --- a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp +++ b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp @@ -40,25 +40,24 @@ ****************************************************************************/ #include "qqnxinputcontext_noimf.h" -#include "qqnxvirtualkeyboard.h" +#include "qqnxabstractvirtualkeyboard.h" #include #include #include -QQnxInputContext::QQnxInputContext() : +QT_BEGIN_NAMESPACE + +QQnxInputContext::QQnxInputContext(QQnxAbstractVirtualKeyboard &keyboard) : QPlatformInputContext(), m_inputPanelVisible(false), - m_inputPanelLocale(QLocale::c()) + m_inputPanelLocale(QLocale::c()), + m_virtualKeyboard(keyboard) { - QQnxVirtualKeyboard &keyboard = QQnxVirtualKeyboard::instance(); connect(&keyboard, SIGNAL(visibilityChanged(bool)), this, SLOT(keyboardVisibilityChanged(bool))); connect(&keyboard, SIGNAL(localeChanged(QLocale)), this, SLOT(keyboardLocaleChanged(QLocale))); keyboardVisibilityChanged(keyboard.isVisible()); keyboardLocaleChanged(keyboard.locale()); - - QInputMethod *inputMethod = qApp->inputMethod(); - connect(inputMethod, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); } QQnxInputContext::~QQnxInputContext() @@ -86,7 +85,7 @@ bool QQnxInputContext::filterEvent( const QEvent *event ) return false; if (event->type() == QEvent::CloseSoftwareInputPanel) { - QQnxVirtualKeyboard::instance().hideKeyboard(); + m_virtualKeyboard.hideKeyboard(); #if defined(QQNXINPUTCONTEXT_DEBUG) qDebug() << "QQNX: hiding virtual keyboard"; #endif @@ -94,7 +93,7 @@ bool QQnxInputContext::filterEvent( const QEvent *event ) } if (event->type() == QEvent::RequestSoftwareInputPanel) { - QQnxVirtualKeyboard::instance().showKeyboard(); + m_virtualKeyboard.showKeyboard(); #if defined(QQNXINPUTCONTEXT_DEBUG) qDebug() << "QQNX: requesting virtual keyboard"; #endif @@ -120,7 +119,7 @@ void QQnxInputContext::showInputPanel() #if defined(QQNXINPUTCONTEXT_DEBUG) qDebug() << Q_FUNC_INFO; #endif - QQnxVirtualKeyboard::instance().showKeyboard(); + m_virtualKeyboard.showKeyboard(); } void QQnxInputContext::hideInputPanel() @@ -128,7 +127,7 @@ void QQnxInputContext::hideInputPanel() #if defined(QQNXINPUTCONTEXT_DEBUG) qDebug() << Q_FUNC_INFO; #endif - QQnxVirtualKeyboard::instance().hideKeyboard(); + m_virtualKeyboard.hideKeyboard(); } bool QQnxInputContext::isInputPanelVisible() const @@ -163,25 +162,24 @@ void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale) } } -void QQnxInputContext::inputItemChanged() +void QQnxInputContext::setFocusObject(QObject *object) { - QInputMethod *inputMethod = qApp->inputMethod(); - QObject *inputItem = inputMethod->inputItem(); - #if defined(QQNXINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "input item=" << inputItem; + qDebug() << Q_FUNC_INFO << "input item=" << object; #endif - if (!inputItem) { + if (!inputMethodAccepted()) { if (m_inputPanelVisible) hideInputPanel(); } else { - if (qobject_cast(inputItem)) { - QQnxVirtualKeyboard::instance().setKeyboardMode(QQnxVirtualKeyboard::NumPunc); - } else { - QQnxVirtualKeyboard::instance().setKeyboardMode(QQnxVirtualKeyboard::Default); - } + if (qobject_cast(object)) + m_virtualKeyboard.setKeyboardMode(QQnxAbstractVirtualKeyboard::Phone); + else + m_virtualKeyboard.setKeyboardMode(QQnxAbstractVirtualKeyboard::Default); + if (!m_inputPanelVisible) showInputPanel(); } } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.h b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.h index 33a4631d161..d73c5136b58 100644 --- a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.h +++ b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.h @@ -48,35 +48,38 @@ QT_BEGIN_NAMESPACE +class QQnxAbstractVirtualKeyboard; + class QQnxInputContext : public QPlatformInputContext { Q_OBJECT public: - explicit QQnxInputContext(); + explicit QQnxInputContext(QQnxAbstractVirtualKeyboard &keyboard); ~QQnxInputContext(); - virtual bool isValid() const; + bool isValid() const; void reset(); - virtual bool filterEvent( const QEvent *event ); + bool filterEvent( const QEvent *event ); bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap); - virtual void showInputPanel(); - virtual void hideInputPanel(); - virtual bool isInputPanelVisible() const; + void showInputPanel(); + void hideInputPanel(); + bool isInputPanelVisible() const; - virtual QLocale locale() const; + QLocale locale() const; + void setFocusObject(QObject *object); private Q_SLOTS: void keyboardVisibilityChanged(bool visible); void keyboardLocaleChanged(const QLocale &locale); - void inputItemChanged(); private: bool hasPhysicalKeyboard(); bool m_inputPanelVisible; QLocale m_inputPanelLocale; + QQnxAbstractVirtualKeyboard &m_virtualKeyboard; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 5ef34f3aea8..f12073e367c 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -43,9 +43,11 @@ #include "qqnxeventthread.h" #include "qqnxglbackingstore.h" #include "qqnxglcontext.h" +#include "qqnxnativeinterface.h" #include "qqnxnavigatoreventhandler.h" #include "qqnxrasterbackingstore.h" #include "qqnxscreen.h" +#include "qqnxscreeneventhandler.h" #include "qqnxwindow.h" #include "qqnxvirtualkeyboard.h" #include "qqnxclipboard.h" @@ -79,11 +81,14 @@ QQnxIntegration::QQnxIntegration() : QPlatformIntegration() , m_eventThread(0) , m_navigatorEventHandler(0) + , m_virtualKeyboard(0) , m_inputContext(0) , m_fontDatabase(new QGenericUnixFontDatabase()) , m_paintUsingOpenGL(false) , m_eventDispatcher(createUnixEventDispatcher()) + , m_nativeInterface(new QQnxNativeInterface()) , m_services(0) + , m_screenEventHandler(new QQnxScreenEventHandler()) #ifndef QT_NO_CLIPBOARD , m_clipboard(0) #endif @@ -98,34 +103,36 @@ QQnxIntegration::QQnxIntegration() qFatal("QQnx: failed to connect to composition manager, errno=%d", errno); } + // Create/start navigator event handler + m_navigatorEventHandler = new QQnxNavigatorEventHandler; + + // delay invocation of start() to the time the event loop is up and running + // needed to have the QThread internals of the main thread properly initialized + QMetaObject::invokeMethod(m_navigatorEventHandler, "start", Qt::QueuedConnection); + // Create displays for all possible screens (which may not be attached) - QQnxScreen::createDisplays(m_screenContext); - Q_FOREACH (QPlatformScreen *screen, QQnxScreen::screens()) { - screenAdded(screen); - } + createDisplays(); // Initialize global OpenGL resources QQnxGLContext::initialize(); // Create/start event thread - m_eventThread = new QQnxEventThread(m_screenContext, *QQnxScreen::primaryDisplay()); + m_eventThread = new QQnxEventThread(m_screenContext, m_screenEventHandler); m_eventThread->start(); - // Create/start navigator event handler - // Not on BlackBerry, it has specialised event dispatcher which also handles navigator events -#ifndef Q_OS_BLACKBERRY - m_navigatorEventHandler = new QQnxNavigatorEventHandler(*QQnxScreen::primaryDisplay()); + // Create/start the keyboard class. + m_virtualKeyboard = new QQnxVirtualKeyboard(); // delay invocation of start() to the time the event loop is up and running // needed to have the QThread internals of the main thread properly initialized - QMetaObject::invokeMethod(m_navigatorEventHandler, "start", Qt::QueuedConnection); -#endif + QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection); - // Create/start the keyboard class. - QQnxVirtualKeyboard::instance(); + // TODO check if we need to do this for all screens or only the primary one + QObject::connect(m_virtualKeyboard, SIGNAL(heightChanged(int)), + primaryDisplay(), SLOT(keyboardHeightChanged(int))); // Set up the input context - m_inputContext = new QQnxInputContext; + m_inputContext = new QQnxInputContext(*m_virtualKeyboard); // Create services handling class #ifdef Q_OS_BLACKBERRY @@ -138,8 +145,15 @@ QQnxIntegration::~QQnxIntegration() #if defined(QQNXINTEGRATION_DEBUG) qDebug() << "QQnx: platform plugin shutdown begin"; #endif + + + delete m_nativeInterface; + + // Destroy input context + delete m_inputContext; + // Destroy the keyboard class. - QQnxVirtualKeyboard::destroy(); + delete m_virtualKeyboard; #ifndef QT_NO_CLIPBOARD // Delete the clipboard @@ -152,8 +166,10 @@ QQnxIntegration::~QQnxIntegration() // Stop/destroy navigator thread delete m_navigatorEventHandler; + delete m_screenEventHandler; + // Destroy all displays - QQnxScreen::destroyDisplays(); + destroyDisplays(); // Close connection to QNX composition manager screen_destroy_context(m_screenContext); @@ -191,7 +207,6 @@ QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const #if defined(QQNXINTEGRATION_DEBUG) qDebug() << Q_FUNC_INFO; #endif - // New windows are created on the primary display. return new QQnxWindow(window, m_screenContext); } @@ -232,20 +247,12 @@ void QQnxIntegration::moveToScreen(QWindow *window, int screen) QQnxWindow *platformWindow = static_cast(window->handle()); // lookup platform screen by index - QQnxScreen *platformScreen = static_cast(QQnxScreen::screens().at(screen)); + QQnxScreen *platformScreen = m_screens.at(screen); // move the platform window to the platform screen platformWindow->setScreen(platformScreen); } -QList QQnxIntegration::screens() const -{ -#if defined(QQNXINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - return QQnxScreen::screens(); -} - QAbstractEventDispatcher *QQnxIntegration::guiThreadEventDispatcher() const { #if defined(QQNXINTEGRATION_DEBUG) @@ -254,6 +261,11 @@ QAbstractEventDispatcher *QQnxIntegration::guiThreadEventDispatcher() const return m_eventDispatcher; } +QPlatformNativeInterface *QQnxIntegration::nativeInterface() const +{ + return m_nativeInterface; +} + #ifndef QT_NO_CLIPBOARD QPlatformClipboard *QQnxIntegration::clipboard() const { @@ -313,4 +325,56 @@ void QQnxIntegration::removeWindow(screen_window_t qnxWindow) ms_windowMapper.remove(qnxWindow); } +void QQnxIntegration::createDisplays() +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // Query number of displays + errno = 0; + int displayCount; + int result = screen_get_context_property_iv(m_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount); + if (result != 0) { + qFatal("QQnxIntegration: failed to query display count, errno=%d", errno); + } + + // Get all displays + errno = 0; + screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount); + result = screen_get_context_property_pv(m_screenContext, SCREEN_PROPERTY_DISPLAYS, (void **)displays); + if (result != 0) { + qFatal("QQnxIntegration: failed to query displays, errno=%d", errno); + } + + for (int i=0; i screens() const; - virtual void moveToScreen(QWindow *window, int screen); + void moveToScreen(QWindow *window, int screen); - virtual QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *guiThreadEventDispatcher() const; - virtual QPlatformFontDatabase *fontDatabase() const { return m_fontDatabase; } + QPlatformFontDatabase *fontDatabase() const { return m_fontDatabase; } + + QPlatformNativeInterface *nativeInterface() const; #ifndef QT_NO_CLIPBOARD - virtual QPlatformClipboard *clipboard() const; + QPlatformClipboard *clipboard() const; #endif - virtual QVariant styleHint(StyleHint hint) const; + QVariant styleHint(StyleHint hint) const; bool paintUsingOpenGL() const { return m_paintUsingOpenGL; } - virtual QPlatformServices *services() const; + QPlatformServices *services() const; static QWindow *window(screen_window_t qnxWindow); private: + void createDisplays(); + void destroyDisplays(); + QQnxScreen *primaryDisplay() const; + static void addWindow(screen_window_t qnxWindow, QWindow *window); static void removeWindow(screen_window_t qnxWindow); screen_context_t m_screenContext; QQnxEventThread *m_eventThread; QQnxNavigatorEventHandler *m_navigatorEventHandler; + QQnxAbstractVirtualKeyboard *m_virtualKeyboard; QQnxInputContext *m_inputContext; QPlatformFontDatabase *m_fontDatabase; bool m_paintUsingOpenGL; QAbstractEventDispatcher *m_eventDispatcher; + QQnxNativeInterface *m_nativeInterface; QQnxServices *m_services; + QList m_screens; + QQnxScreenEventHandler *m_screenEventHandler; #ifndef QT_NO_CLIPBOARD mutable QQnxClipboard* m_clipboard; #endif diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp new file mode 100644 index 00000000000..45e555488d4 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxnativeinterface.h" + +#include "qqnxscreen.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +void *QQnxNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window) +{ + if (resource == "windowGroup" && window && window->screen()) { + const QQnxScreen * const screen = static_cast(window->screen()->handle()); + if (screen) { + // We can't just call data() instead of constData() here, since that would detach + // and the lifetime of the char * would not be long enough. Therefore the const_cast. + return const_cast(screen->rootWindow()->groupName().constData()); + } + } + + return 0; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.h b/src/plugins/platforms/qnx/qqnxnativeinterface.h new file mode 100644 index 00000000000..ec896d40fae --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.h @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXNATIVEINTERFACE_H +#define QQNXNATIVEINTERFACE_H + +#include + +QT_BEGIN_NAMESPACE + +class QQnxNativeInterface : public QPlatformNativeInterface +{ +public: + void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); +}; + +QT_END_NAMESPACE + +#endif // QQNXNATIVEINTERFACE_H diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp index 4db86cb5cf2..9527a57ca37 100644 --- a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qqnxnavigatoreventhandler.h" -#include "qqnxscreen.h" #include #include @@ -61,8 +60,8 @@ static const char *navigatorControlPath = "/pps/services/navigator/control"; static const int ppsBufferSize = 4096; -QQnxNavigatorEventHandler::QQnxNavigatorEventHandler(QQnxScreen& primaryScreen) - : m_primaryScreen(primaryScreen), +QQnxNavigatorEventHandler::QQnxNavigatorEventHandler(QObject *parent) + : QObject(parent), m_fd(-1), m_readNotifier(0) { @@ -202,8 +201,7 @@ void QQnxNavigatorEventHandler::handleMessage(const QByteArray &msg, const QByte #if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG) qDebug() << "PPS: orientation, o=" << dat; #endif - m_primaryScreen.setRotation( dat.toInt() ); - QWindowSystemInterface::handleScreenGeometryChange(0, m_primaryScreen.geometry()); + Q_EMIT rotationChanged(dat.toInt()); replyPPS(msg, id, ""); } else if (msg == "SWIPE_DOWN") { diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h index 2e0bd1fa14b..8084eba1d9c 100644 --- a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h +++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h @@ -46,15 +46,17 @@ QT_BEGIN_NAMESPACE -class QQnxScreen; class QSocketNotifier; class QQnxNavigatorEventHandler : public QObject { Q_OBJECT public: - QQnxNavigatorEventHandler(QQnxScreen &primaryScreen); - virtual ~QQnxNavigatorEventHandler(); + explicit QQnxNavigatorEventHandler(QObject *parent = 0); + ~QQnxNavigatorEventHandler(); + +Q_SIGNALS: + void rotationChanged(int angle); public Q_SLOTS: void start(); @@ -67,7 +69,6 @@ private: void replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat); void handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id); - QQnxScreen &m_primaryScreen; int m_fd; QSocketNotifier *m_readNotifier; }; diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.h b/src/plugins/platforms/qnx/qqnxrasterbackingstore.h index fec51a19b90..7a7f211e9a4 100644 --- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.h +++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.h @@ -54,14 +54,14 @@ class QQnxRasterBackingStore : public QPlatformBackingStore { public: QQnxRasterBackingStore(QWindow *window); - virtual ~QQnxRasterBackingStore(); + ~QQnxRasterBackingStore(); - virtual QPaintDevice *paintDevice(); - virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); - virtual void resize(const QSize &size, const QRegion &staticContents); - virtual bool scroll(const QRegion &area, int dx, int dy); - virtual void beginPaint(const QRegion ®ion); - virtual void endPaint(const QRegion ®ion); + QPaintDevice *paintDevice(); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size, const QRegion &staticContents); + bool scroll(const QRegion &area, int dx, int dy); + void beginPaint(const QRegion ®ion); + void endPaint(const QRegion ®ion); private: class ScrollOp { diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index cd77c3088a4..27c1357a871 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -40,25 +40,25 @@ ****************************************************************************/ #include "qqnxscreen.h" -#include "qqnxvirtualkeyboard.h" #include "qqnxwindow.h" -#include -#include +#include +#ifdef QQNXSCREEN_DEBUG +# include +#endif +#include #include QT_BEGIN_NAMESPACE -QList QQnxScreen::ms_screens; -QList QQnxScreen::ms_childWindows; - QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display, bool primaryScreen) : m_screenContext(screenContext), m_display(display), m_rootWindow(), m_primaryScreen(primaryScreen), m_posted(false), + m_keyboardHeight(0), m_platformContext(0) { #if defined(QQNXSCREEN_DEBUG) @@ -114,52 +114,7 @@ QQnxScreen::~QQnxScreen() #endif } -/* static */ -void QQnxScreen::createDisplays(screen_context_t context) -{ -#if defined(QQNXSCREEN_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // Query number of displays - errno = 0; - int displayCount; - int result = screen_get_context_property_iv(context, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount); - if (result != 0) { - qFatal("QQnxScreen: failed to query display count, errno=%d", errno); - } - - // Get all displays - errno = 0; - screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount); - result = screen_get_context_property_pv(context, SCREEN_PROPERTY_DISPLAYS, (void **)displays); - if (result != 0) { - qFatal("QQnxScreen: failed to query displays, errno=%d", errno); - } - - for (int i=0; ifindWindow(windowHandle); + if (result) + return result; + } + + return 0; +} + void QQnxScreen::addWindow(QQnxWindow *window) { #if defined(QQNXSCREEN_DEBUG) qDebug() << Q_FUNC_INFO << "window =" << window; #endif - if (ms_childWindows.contains(window)) + if (m_childWindows.contains(window)) return; - ms_childWindows.push_back(window); - QQnxScreen::updateHierarchy(); + m_childWindows.push_back(window); + updateHierarchy(); } void QQnxScreen::removeWindow(QQnxWindow *window) @@ -253,8 +229,9 @@ void QQnxScreen::removeWindow(QQnxWindow *window) qDebug() << Q_FUNC_INFO << "window =" << window; #endif - ms_childWindows.removeAll(window); - QQnxScreen::updateHierarchy(); + const int numWindowsRemoved = m_childWindows.removeAll(window); + if (numWindowsRemoved > 0) + updateHierarchy(); } void QQnxScreen::raiseWindow(QQnxWindow *window) @@ -264,8 +241,8 @@ void QQnxScreen::raiseWindow(QQnxWindow *window) #endif removeWindow(window); - ms_childWindows.push_back(window); - QQnxScreen::updateHierarchy(); + m_childWindows.push_back(window); + updateHierarchy(); } void QQnxScreen::lowerWindow(QQnxWindow *window) @@ -275,8 +252,8 @@ void QQnxScreen::lowerWindow(QQnxWindow *window) #endif removeWindow(window); - ms_childWindows.push_front(window); - QQnxScreen::updateHierarchy(); + m_childWindows.push_front(window); + updateHierarchy(); } void QQnxScreen::updateHierarchy() @@ -285,15 +262,24 @@ void QQnxScreen::updateHierarchy() qDebug() << Q_FUNC_INFO; #endif - QList::iterator it; + QList::const_iterator it; int topZorder = 1; // root window is z-order 0, all "top" level windows are "above" it - for (it = ms_childWindows.begin(); it != ms_childWindows.end(); it++) + for (it = m_childWindows.constBegin(); it != m_childWindows.constEnd(); ++it) (*it)->updateZorder(topZorder); + topZorder++; + Q_FOREACH (screen_window_t overlay, m_overlays) { + // Do nothing when this fails. This can happen if we have stale windows in mOverlays, + // which in turn can happen because a window was removed but we didn't get a notification + // yet. + screen_set_window_property_iv(overlay, SCREEN_PROPERTY_ZORDER, &topZorder); + topZorder++; + } + // After a hierarchy update, we need to force a flush on all screens. // Right now, all screens share a context. - screen_flush_context( primaryDisplay()->m_screenContext, 0 ); + screen_flush_context( m_screenContext, 0 ); } void QQnxScreen::onWindowPost(QQnxWindow *window) @@ -312,4 +298,54 @@ void QQnxScreen::onWindowPost(QQnxWindow *window) } } +void QQnxScreen::keyboardHeightChanged(int height) +{ + if (height == m_keyboardHeight) + return; + + m_keyboardHeight = height; + + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), availableGeometry()); +} + +void QQnxScreen::addOverlayWindow(screen_window_t window) +{ + m_overlays.append(window); + updateHierarchy(); +} + +void QQnxScreen::removeOverlayWindow(screen_window_t window) +{ + const int numOverlaysRemoved = m_overlays.removeAll(window); + if (numOverlaysRemoved > 0) + updateHierarchy(); +} + +void QQnxScreen::newWindowCreated(void *window) +{ + Q_ASSERT(thread() == QThread::currentThread()); + const screen_window_t windowHandle = reinterpret_cast(window); + screen_display_t display = NULL; + if (screen_get_window_property_pv(windowHandle, SCREEN_PROPERTY_DISPLAY, (void**)&display) != 0) { + qWarning("QQnx: Failed to get screen for window, errno=%d", errno); + return; + } + + if (display == nativeDisplay()) { + // A window was created on this screen. If we don't know about this window yet, it means + // it was not created by Qt, but by some foreign library like the multimedia renderer, which + // creates an overlay window when playing a video. + // Treat all foreign windows as overlays here. + if (!findWindow(windowHandle)) + addOverlayWindow(windowHandle); + } +} + +void QQnxScreen::windowClosed(void *window) +{ + Q_ASSERT(thread() == QThread::currentThread()); + const screen_window_t windowHandle = reinterpret_cast(window); + removeOverlayWindow(windowHandle); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h index 5749a66f5d6..272cdd6261b 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.h +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -46,7 +46,7 @@ #include "qqnxrootwindow.h" -#include +#include #include #include @@ -55,65 +55,70 @@ QT_BEGIN_NAMESPACE class QQnxWindow; -class QQnxScreen : public QPlatformScreen +class QQnxScreen : public QObject, public QPlatformScreen { + Q_OBJECT public: - static QList screens() { return ms_screens; } - static void createDisplays(screen_context_t context); - static void destroyDisplays(); - static QQnxScreen *primaryDisplay() { return static_cast(ms_screens.at(0)); } - static int defaultDepth(); + QQnxScreen(screen_context_t context, screen_display_t display, bool primaryScreen); + ~QQnxScreen(); - virtual QRect geometry() const { return m_currentGeometry; } - virtual QRect availableGeometry() const; - virtual int depth() const { return defaultDepth(); } - virtual QImage::Format format() const { return (depth() == 32) ? QImage::Format_RGB32 : QImage::Format_RGB16; } - virtual QSizeF physicalSize() const { return m_currentPhysicalSize; } + QRect geometry() const { return m_currentGeometry; } + QRect availableGeometry() const; + int depth() const; + QImage::Format format() const { return (depth() == 32) ? QImage::Format_RGB32 : QImage::Format_RGB16; } + QSizeF physicalSize() const { return m_currentPhysicalSize; } bool isPrimaryScreen() const { return m_primaryScreen; } int rotation() const { return m_currentRotation; } - void setRotation(int rotation); int nativeFormat() const { return (depth() == 32) ? SCREEN_FORMAT_RGBA8888 : SCREEN_FORMAT_RGB565; } screen_display_t nativeDisplay() const { return m_display; } screen_context_t nativeContext() const { return m_screenContext; } const char *windowGroupName() const { return m_rootWindow->groupName().constData(); } + QQnxWindow *findWindow(screen_window_t windowHandle); + /* Window hierarchy management */ - static void addWindow(QQnxWindow *child); - static void removeWindow(QQnxWindow *child); - static void raiseWindow(QQnxWindow *window); - static void lowerWindow(QQnxWindow *window); - static void updateHierarchy(); + void addWindow(QQnxWindow *child); + void removeWindow(QQnxWindow *child); + void raiseWindow(QQnxWindow *window); + void lowerWindow(QQnxWindow *window); + void updateHierarchy(); void onWindowPost(QQnxWindow *window); QSharedPointer rootWindow() const { return m_rootWindow; } -private: - QQnxScreen(screen_context_t context, screen_display_t display, bool primaryScreen); - virtual ~QQnxScreen(); +public Q_SLOTS: + void setRotation(int rotation); + void newWindowCreated(void *window); + void windowClosed(void *window); - static bool orthogonal(int rotation1, int rotation2); +private Q_SLOTS: + void keyboardHeightChanged(int height); + +private: + void addOverlayWindow(screen_window_t window); + void removeOverlayWindow(screen_window_t window); screen_context_t m_screenContext; screen_display_t m_display; QSharedPointer m_rootWindow; bool m_primaryScreen; bool m_posted; - bool m_usingOpenGL; int m_initialRotation; int m_currentRotation; + int m_keyboardHeight; QSize m_initialPhysicalSize; QSize m_currentPhysicalSize; QRect m_initialGeometry; QRect m_currentGeometry; QPlatformOpenGLContext *m_platformContext; - static QList ms_screens; - static QList ms_childWindows; + QList m_childWindows; + QList m_overlays; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp new file mode 100644 index 00000000000..9640c65bcb3 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -0,0 +1,487 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxscreeneventhandler.h" +#include "qqnxintegration.h" +#include "qqnxkeytranslator.h" + +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +QQnxScreenEventHandler::QQnxScreenEventHandler() + : m_lastButtonState(Qt::NoButton) + , m_lastMouseWindow(0) + , m_touchDevice(0) +{ + // Create a touch device + m_touchDevice = new QTouchDevice; + m_touchDevice->setType(QTouchDevice::TouchScreen); + m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition); + QWindowSystemInterface::registerTouchDevice(m_touchDevice); + + // initialize array of touch points + for (int i = 0; i < MaximumTouchPoints; i++) { + + // map array index to id + m_touchPoints[i].id = i; + + // pressure is not supported - use default + m_touchPoints[i].pressure = 1.0; + + // nothing touching + m_touchPoints[i].state = Qt::TouchPointReleased; + } +} + +bool QQnxScreenEventHandler::handleEvent(screen_event_t event) +{ + // get the event type + errno = 0; + int qnxType; + int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType); + if (result) { + qFatal("QQNX: failed to query event type, errno=%d", errno); + } + + return handleEvent(event, qnxType); +} + +bool QQnxScreenEventHandler::handleEvent(screen_event_t event, int qnxType) +{ + switch (qnxType) { + case SCREEN_EVENT_MTOUCH_TOUCH: + case SCREEN_EVENT_MTOUCH_MOVE: + case SCREEN_EVENT_MTOUCH_RELEASE: + handleTouchEvent(event, qnxType); + break; + + case SCREEN_EVENT_KEYBOARD: + handleKeyboardEvent(event); + break; + + case SCREEN_EVENT_POINTER: + handlePointerEvent(event); + break; + + case SCREEN_EVENT_CREATE: + handleCreateEvent(event); + break; + + case SCREEN_EVENT_CLOSE: + handleCloseEvent(event); + break; + + default: + // event ignored +#if defined(QQNXSCREENEVENT_DEBUG) + qDebug() << "QQNX: QNX unknown event"; +#endif + return false; + } + + return true; +} + +void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifiers, int scan, int cap) +{ + Q_UNUSED(scan); + + Qt::KeyboardModifiers qtMod = Qt::NoModifier; + if (modifiers & KEYMOD_SHIFT) + qtMod |= Qt::ShiftModifier; + if (modifiers & KEYMOD_CTRL) + qtMod |= Qt::ControlModifier; + if (modifiers & KEYMOD_ALT) + qtMod |= Qt::AltModifier; + + // determine event type + QEvent::Type type = (flags & KEY_DOWN) ? QEvent::KeyPress : QEvent::KeyRelease; + + // Check if the key cap is valid + if (flags & KEY_CAP_VALID) { + Qt::Key key; + QString keyStr; + + if (cap >= 0x20 && cap <= 0x0ff) { + key = Qt::Key(std::toupper(cap)); // Qt expects the CAP to be upper case. + + if ( qtMod & Qt::ControlModifier ) { + keyStr = QChar((int)(key & 0x3f)); + } else { + if (flags & KEY_SYM_VALID) { + keyStr = QChar(sym); + } + } + } else if ((cap > 0x0ff && cap < UNICODE_PRIVATE_USE_AREA_FIRST) || cap > UNICODE_PRIVATE_USE_AREA_LAST) { + key = (Qt::Key)cap; + keyStr = QChar(sym); + } else { + if (isKeypadKey(cap)) + qtMod |= Qt::KeypadModifier; // Is this right? + key = keyTranslator(cap); + } + + QWindowSystemInterface::handleExtendedKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod, + scan, sym, modifiers, keyStr); +#if defined(QQNXSCREENEVENT_DEBUG) + qDebug() << "QQNX: Qt key t=" << type << ", k=" << key << ", s=" << keyStr; +#endif + } +} + +void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event) +{ + // get flags of key event + errno = 0; + int flags; + int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags); + if (result) { + qFatal("QQNX: failed to query event flags, errno=%d", errno); + } + + // get key code + errno = 0; + int sym; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym); + if (result) { + qFatal("QQNX: failed to query event sym, errno=%d", errno); + } + + int modifiers; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers); + if (result) { + qFatal("QQNX: failed to query event modifiers, errno=%d", errno); + } + + int scan; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan); + if (result) { + qFatal("QQNX: failed to query event modifiers, errno=%d", errno); + } + + int cap; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap); + if (result) { + qFatal("QQNX: failed to query event cap, errno=%d", errno); + } + + injectKeyboardEvent(flags, sym, modifiers, scan, cap); +} + +void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event) +{ + errno = 0; + + // Query the window that was clicked + screen_window_t qnxWindow; + void *handle; + int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); + if (result) { + qFatal("QQNX: failed to query event window, errno=%d", errno); + } + qnxWindow = static_cast(handle); + + // Query the button states + int buttonState = 0; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState); + if (result) { + qFatal("QQNX: failed to query event button state, errno=%d", errno); + } + + // Query the window position + int windowPos[2]; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos); + if (result) { + qFatal("QQNX: failed to query event window position, errno=%d", errno); + } + + // Query the screen position + int pos[2]; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos); + if (result) { + qFatal("QQNX: failed to query event position, errno=%d", errno); + } + + // Query the wheel delta + int wheelDelta = 0; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta); + if (result) { + qFatal("QQNX: failed to query event wheel delta, errno=%d", errno); + } + + // Map window handle to top-level QWindow + QWindow *w = QQnxIntegration::window(qnxWindow); + + // Generate enter and leave events as needed. + if (qnxWindow != m_lastMouseWindow) { + QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow); + + if (wOld) { + QWindowSystemInterface::handleLeaveEvent(wOld); +#if defined(QQNXSCREENEVENT_DEBUG) + qDebug() << "QQNX: Qt leave, w=" << wOld; +#endif + } + + if (w) { + QWindowSystemInterface::handleEnterEvent(w); +#if defined(QQNXSCREENEVENT_DEBUG) + qDebug() << "QQNX: Qt enter, w=" << w; +#endif + } + } + m_lastMouseWindow = qnxWindow; + + // Apply scaling to wheel delta and invert value for Qt. We'll probably want to scale + // this via a system preference at some point. But for now this is a sane value and makes + // the wheel usable. + wheelDelta *= -10; + + // convert point to local coordinates + QPoint globalPoint(pos[0], pos[1]); + QPoint localPoint(windowPos[0], windowPos[1]); + + // Convert buttons. + // Some QNX header files invert 'Right Button versus "Left Button' ('Right' == 0x01). But they also offer a 'Button Swap' bit, + // so we may receive events as shown. (If this is wrong, the fix is easy.) + // QNX Button mask is 8 buttons wide, with a maximum value of x080. + Qt::MouseButtons buttons = Qt::NoButton; + if (buttonState & 0x01) + buttons |= Qt::LeftButton; + if (buttonState & 0x02) + buttons |= Qt::MidButton; + if (buttonState & 0x04) + buttons |= Qt::RightButton; + if (buttonState & 0x08) + buttons |= Qt::ExtraButton1; // AKA 'Qt::BackButton' + if (buttonState & 0x10) + buttons |= Qt::ExtraButton2; // AKA 'Qt::ForwardButton' + if (buttonState & 0x20) + buttons |= Qt::ExtraButton3; + if (buttonState & 0x40) + buttons |= Qt::ExtraButton4; + if (buttonState & 0x80) + buttons |= Qt::ExtraButton5; + + if (w) { + // Inject mouse event into Qt only if something has changed. + if (m_lastGlobalMousePoint != globalPoint || + m_lastLocalMousePoint != localPoint || + m_lastButtonState != buttons) { + QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons); +#if defined(QQNXSCREENEVENT_DEBUG) + qDebug() << "QQNX: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << static_cast(buttons); +#endif + } + + if (wheelDelta) { + // Screen only supports a single wheel, so we will assume Vertical orientation for + // now since that is pretty much standard. + QWindowSystemInterface::handleWheelEvent(w, localPoint, globalPoint, wheelDelta, Qt::Vertical); +#if defined(QQNXSCREENEVENT_DEBUG) + qDebug() << "QQNX: Qt wheel, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), d=" << static_cast(wheelDelta); +#endif + } + } + + m_lastGlobalMousePoint = globalPoint; + m_lastLocalMousePoint = localPoint; + m_lastButtonState = buttons; +} + +void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType) +{ + // get display coordinates of touch + errno = 0; + int pos[2]; + int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos); + if (result) { + qFatal("QQNX: failed to query event position, errno=%d", errno); + } + + // get window coordinates of touch + errno = 0; + int windowPos[2]; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos); + if (result) { + qFatal("QQNX: failed to query event window position, errno=%d", errno); + } + + // determine which finger touched + errno = 0; + int touchId; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId); + if (result) { + qFatal("QQNX: failed to query event touch id, errno=%d", errno); + } + + // determine which window was touched + errno = 0; + void *handle; + result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); + if (result) { + qFatal("QQNX: failed to query event window, errno=%d", errno); + } + screen_window_t qnxWindow = static_cast(handle); + + // check if finger is valid + if (touchId < MaximumTouchPoints) { + + // Map window handle to top-level QWindow + QWindow *w = QQnxIntegration::window(qnxWindow); + + // Generate enter and leave events as needed. + if (qnxWindow != m_lastMouseWindow) { + QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow); + + if (wOld) { + QWindowSystemInterface::handleLeaveEvent(wOld); + #if defined(QQNXSCREENEVENT_DEBUG) + qDebug() << "QQNX: Qt leave, w=" << wOld; + #endif + } + + if (w) { + QWindowSystemInterface::handleEnterEvent(w); + #if defined(QQNXSCREENEVENT_DEBUG) + qDebug() << "QQNX: Qt enter, w=" << w; + #endif + } + } + m_lastMouseWindow = qnxWindow; + + if (w) { + // convert primary touch to mouse event + if (touchId == 0) { + + // convert point to local coordinates + QPoint globalPoint(pos[0], pos[1]); + QPoint localPoint(windowPos[0], windowPos[1]); + + // map touch state to button state + Qt::MouseButtons buttons = (qnxType == SCREEN_EVENT_MTOUCH_RELEASE) ? Qt::NoButton : Qt::LeftButton; + + // inject event into Qt + QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons); +#if defined(QQNXSCREENEVENT_DEBUG) + qDebug() << "QQNX: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << buttons; +#endif + } + + // get size of screen which contains window + QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w); + QSizeF screenSize = platformScreen->physicalSize(); + + // update cached position of current touch point + m_touchPoints[touchId].normalPosition = QPointF( static_cast(pos[0]) / screenSize.width(), static_cast(pos[1]) / screenSize.height() ); + m_touchPoints[touchId].area = QRectF( pos[0], pos[1], 0.0, 0.0 ); + + // determine event type and update state of current touch point + QEvent::Type type = QEvent::None; + switch (qnxType) { + case SCREEN_EVENT_MTOUCH_TOUCH: + m_touchPoints[touchId].state = Qt::TouchPointPressed; + type = QEvent::TouchBegin; + break; + case SCREEN_EVENT_MTOUCH_MOVE: + m_touchPoints[touchId].state = Qt::TouchPointMoved; + type = QEvent::TouchUpdate; + break; + case SCREEN_EVENT_MTOUCH_RELEASE: + m_touchPoints[touchId].state = Qt::TouchPointReleased; + type = QEvent::TouchEnd; + break; + } + + // build list of active touch points + QList pointList; + for (int i = 0; i < MaximumTouchPoints; i++) { + if (i == touchId) { + // current touch point is always active + pointList.append(m_touchPoints[i]); + } else if (m_touchPoints[i].state != Qt::TouchPointReleased) { + // finger is down but did not move + m_touchPoints[i].state = Qt::TouchPointStationary; + pointList.append(m_touchPoints[i]); + } + } + + // inject event into Qt + QWindowSystemInterface::handleTouchEvent(w, m_touchDevice, pointList); +#if defined(QQNXSCREENEVENT_DEBUG) + qDebug() << "QQNX: Qt touch, w=" << w << ", p=(" << pos[0] << "," << pos[1] << "), t=" << type; +#endif + } + } +} + +void QQnxScreenEventHandler::handleCloseEvent(screen_event_t event) +{ + screen_window_t window = 0; + if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) + qFatal("QQnx: failed to query window property, errno=%d", errno); + + Q_EMIT windowClosed(window); + + // Map window handle to top-level QWindow + QWindow *w = QQnxIntegration::window(window); + if (w != 0) { + QWindowSystemInterface::handleCloseEvent(w); + } +} + +void QQnxScreenEventHandler::handleCreateEvent(screen_event_t event) +{ + screen_window_t window = 0; + if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) + qFatal("QQnx: failed to query window property, errno=%d", errno); + + Q_EMIT newWindowCreated(window); +} + +#include "moc_qqnxscreeneventhandler.cpp" + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/xlib/qxlibbackingstore.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h similarity index 58% rename from src/plugins/platforms/xlib/qxlibbackingstore.h rename to src/plugins/platforms/qnx/qqnxscreeneventhandler.h index 7414905a762..06cc7a0b329 100644 --- a/src/plugins/platforms/xlib/qxlibbackingstore.h +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h @@ -1,6 +1,6 @@ -/**************************************************************************** +/*************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2011 - 2012 Research In Motion ** Contact: http://www.qt-project.org/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -39,49 +39,50 @@ ** ****************************************************************************/ -#ifndef QWINDOWSURFACE_TESTLITE_H -#define QWINDOWSURFACE_TESTLITE_H +#ifndef QQNXSCREENEVENTHANDLER_H +#define QQNXSCREENEVENTHANDLER_H -#include -#include +#include + +#include QT_BEGIN_NAMESPACE -class QXlibWindow; -class QXlibIntegration; -class QXlibScreen; -class QXlibShmImageInfo; - -class QXlibBackingStore : public QPlatformBackingStore +class QQnxScreenEventHandler : public QObject { + Q_OBJECT public: - QXlibBackingStore (QWindow *window); - ~QXlibBackingStore(); + QQnxScreenEventHandler(); - QPaintDevice *paintDevice(); - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + bool handleEvent(screen_event_t event); + bool handleEvent(screen_event_t event, int qnxType); - void resize(const QSize &size, const QRegion &staticContents); + static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap); - void beginPaint(const QRegion ®ion); - void endPaint(); +Q_SIGNALS: + void newWindowCreated(void *window); + void windowClosed(void *window); private: - bool painted; - void resizeBuffer(QSize); - QSize bufferSize() const; + void handleKeyboardEvent(screen_event_t event); + void handlePointerEvent(screen_event_t event); + void handleTouchEvent(screen_event_t event, int qnxType); + void handleCloseEvent(screen_event_t event); + void handleCreateEvent(screen_event_t event); +private: + enum { + MaximumTouchPoints = 10 + }; - void resizeShmImage(int width, int height); - - QImage shm_img; - QXlibShmImageInfo *image_info; - - QXlibWindow *xw; - + QPoint m_lastGlobalMousePoint; + QPoint m_lastLocalMousePoint; + Qt::MouseButtons m_lastButtonState; + screen_window_t m_lastMouseWindow; + QTouchDevice *m_touchDevice; + QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints]; }; - QT_END_NAMESPACE -#endif +#endif // QQNXSCREENEVENTHANDLER_H diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp index 20c89d3e320..916c6dfa62b 100644 --- a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp +++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp @@ -42,9 +42,6 @@ #include "qqnxvirtualkeyboard.h" #include "qqnxscreen.h" -#include -#include - #include #include #include @@ -59,11 +56,11 @@ #include #include +QT_BEGIN_NAMESPACE + const char *QQnxVirtualKeyboard::ms_PPSPath = "/pps/services/input/control?wait"; const size_t QQnxVirtualKeyboard::ms_bufferSize = 2048; -static QQnxVirtualKeyboard *s_instance = 0; - // Huge hack for keyboard shadow (see QNX PR 88400). Should be removed ASAP. #define KEYBOARD_SHADOW_HEIGHT 8 @@ -71,11 +68,7 @@ QQnxVirtualKeyboard::QQnxVirtualKeyboard() : m_encoder(0), m_decoder(0), m_buffer(0), - m_height(0), m_fd(-1), - m_keyboardMode(Default), - m_visible(false), - m_locale(QLatin1String("en_US")), m_readNotifier(0) { } @@ -85,20 +78,6 @@ QQnxVirtualKeyboard::~QQnxVirtualKeyboard() close(); } -/* static */ -QQnxVirtualKeyboard& QQnxVirtualKeyboard::instance() -{ - if (!s_instance) { - s_instance = new QQnxVirtualKeyboard(); - - // delay invocation of start() to the time the event loop is up and running - // needed to have the QThread internals of the main thread properly initialized - QMetaObject::invokeMethod(s_instance, "start", Qt::QueuedConnection); - } - - return *s_instance; -} - void QQnxVirtualKeyboard::start() { #ifdef QQNXVIRTUALKEYBOARD_DEBUG @@ -108,13 +87,9 @@ void QQnxVirtualKeyboard::start() return; } -/* static */ -void QQnxVirtualKeyboard::destroy() +void QQnxVirtualKeyboard::applyKeyboardMode(KeyboardMode mode) { - if (s_instance) { - delete s_instance; - s_instance = 0; - } + applyKeyboardModeOptions(mode); } void QQnxVirtualKeyboard::close() @@ -194,12 +169,6 @@ bool QQnxVirtualKeyboard::queryPPSInfo() return true; } -void QQnxVirtualKeyboard::notifyClientActiveStateChange(bool active) -{ - if (!active) - hideKeyboard(); -} - void QQnxVirtualKeyboard::ppsDataReady() { ssize_t nread = qt_safe_read(m_fd, m_buffer, ms_bufferSize - 1); @@ -234,17 +203,9 @@ void QQnxVirtualKeyboard::ppsDataReady() if (pps_decoder_get_string(m_decoder, "msg", &value) == PPS_DECODER_OK) { if (strcmp(value, "show") == 0) { - const bool oldVisible = m_visible; - m_visible = true; - handleKeyboardStateChangeMessage(true); - if (oldVisible != m_visible) - emit visibilityChanged(m_visible); + setVisible(true); } else if (strcmp(value, "hide") == 0) { - const bool oldVisible = m_visible; - m_visible = false; - handleKeyboardStateChangeMessage(false); - if (oldVisible != m_visible) - emit visibilityChanged(m_visible); + setVisible(false); } else if (strcmp(value, "info") == 0) handleKeyboardInfoMessage(); else if (strcmp(value, "connect") == 0) { } @@ -290,49 +251,16 @@ void QQnxVirtualKeyboard::handleKeyboardInfoMessage() // HUGE hack, should be removed ASAP. newHeight -= KEYBOARD_SHADOW_HEIGHT; // We want to ignore the 8 pixel shadow above the keyboard. (PR 88400) - if (newHeight != m_height) { - m_height = newHeight; - updateAvailableScreenGeometry(); - } + setHeight(newHeight); const QLocale locale = QLocale(languageId + QLatin1Char('_') + countryId); - if (locale != m_locale) { - m_locale = locale; - emit localeChanged(locale); - } + setLocale(locale); #ifdef QQNXVIRTUALKEYBOARD_DEBUG qDebug() << "QQNX: handleKeyboardInfoMessage size=" << m_height << "locale=" << m_locale; #endif } -void QQnxVirtualKeyboard::handleKeyboardStateChangeMessage(bool visible) -{ - -#ifdef QQNXVIRTUALKEYBOARD_DEBUG - qDebug() << "QQNX: handleKeyboardStateChangeMessage " << visible; -#endif - updateAvailableScreenGeometry(); - - if (visible) - showKeyboard(); - else - hideKeyboard(); -} - -void QQnxVirtualKeyboard::updateAvailableScreenGeometry() -{ -#ifdef QQNXVIRTUALKEYBOARD_DEBUG - qDebug() << "QQNX: updateAvailableScreenGeometry: keyboard visible=" << m_visible << ", keyboard height=" << m_height; -#endif - - // TODO: What screen index should be used? I assume primaryScreen here because it works, and - // we do it for handleScreenGeometryChange elsewhere but since we have support - // for more than one screen, that's not going to always work. - QQnxScreen *platformScreen = QQnxScreen::primaryDisplay(); - QWindowSystemInterface::handleScreenAvailableGeometryChange(platformScreen->screen(), platformScreen->availableGeometry()); -} - bool QQnxVirtualKeyboard::showKeyboard() { #ifdef QQNXVIRTUALKEYBOARD_DEBUG @@ -345,7 +273,10 @@ bool QQnxVirtualKeyboard::showKeyboard() // NOTE: This must be done everytime the keyboard is shown even if there is no change because // hiding the keyboard wipes the setting. - applyKeyboardModeOptions(); + applyKeyboardModeOptions(keyboardMode()); + + if (isVisible()) + return true; pps_encoder_reset(m_encoder); @@ -396,12 +327,7 @@ bool QQnxVirtualKeyboard::hideKeyboard() return true; } -void QQnxVirtualKeyboard::setKeyboardMode(KeyboardMode mode) -{ - m_keyboardMode = mode; -} - -void QQnxVirtualKeyboard::applyKeyboardModeOptions() +void QQnxVirtualKeyboard::applyKeyboardModeOptions(KeyboardMode mode) { // Try to connect. if (m_fd == -1 && !connect()) @@ -411,7 +337,7 @@ void QQnxVirtualKeyboard::applyKeyboardModeOptions() pps_encoder_add_string(m_encoder, "msg", "options"); pps_encoder_start_object(m_encoder, "dat"); - switch (m_keyboardMode) { + switch (mode) { case Url: addUrlModeOptions(); break; @@ -495,3 +421,5 @@ void QQnxVirtualKeyboard::addSymbolModeOptions() pps_encoder_add_string(m_encoder, "enter", "enter.default"); pps_encoder_add_string(m_encoder, "type", "symbol"); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h index 73a296fb9f3..b01a4df9637 100644 --- a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h +++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h @@ -42,72 +42,42 @@ #ifndef VIRTUALKEYBOARD_H_ #define VIRTUALKEYBOARD_H_ -#include -#include -#include -#include +#include "qqnxabstractvirtualkeyboard.h" -#include -#include -#include #include -class QSocketNotifier; - QT_BEGIN_NAMESPACE +class QSocketNotifier; + /* Shamelessly copied from the browser - this should be rewritten once we have a proper PPS wrapper class */ -class QQnxVirtualKeyboard : public QObject +class QQnxVirtualKeyboard : public QQnxAbstractVirtualKeyboard { Q_OBJECT public: - // NOTE: Not all the following keyboard modes are currently used. - // Default - Regular Keyboard - // Url/Email - Enhanced keys for each types. - // Web - Regular keyboard with two blank keys, currently unused. - // NumPunc - Numbers & Punctionation, alternate to Symbol - // Symbol - All symbols, alternate to NumPunc, currently unused. - // Phone - Phone enhanced keyboard - currently unused as no alternate keyboard available to access a-zA-Z - // Pin - Keyboard for entering Pins (Hex values) currently unused. - // - // SPECIAL NOTE: Usage of NumPunc may have to be removed, ABC button is non-functional. - // - enum KeyboardMode { Default, Url, Email, Web, NumPunc, Symbol, Phone, Pin }; - - static QQnxVirtualKeyboard& instance(); - static void destroy(); + QQnxVirtualKeyboard(); + ~QQnxVirtualKeyboard(); bool showKeyboard(); bool hideKeyboard(); - int height() { return m_visible ? m_height : 0; } - void setKeyboardMode(KeyboardMode); - void notifyClientActiveStateChange(bool); - bool isVisible() const { return m_visible; } - QLocale locale() const { return m_locale; } public Q_SLOTS: void start(); -Q_SIGNALS: - void localeChanged(const QLocale &locale); - void visibilityChanged(bool visible); +protected: + void applyKeyboardMode(KeyboardMode mode); private Q_SLOTS: void ppsDataReady(); private: - QQnxVirtualKeyboard(); - virtual ~QQnxVirtualKeyboard(); - // Will be called internally if needed. bool connect(); void close(); bool queryPPSInfo(); void handleKeyboardInfoMessage(); - void handleKeyboardStateChangeMessage(bool visible); - void updateAvailableScreenGeometry(); - void applyKeyboardModeOptions(); + void applyKeyboardModeOptions(KeyboardMode mode); void addDefaultModeOptions(); void addUrlModeOptions(); void addEmailModeOptions(); @@ -120,11 +90,7 @@ private: pps_encoder_t *m_encoder; pps_decoder_t *m_decoder; char *m_buffer; - int m_height; int m_fd; - KeyboardMode m_keyboardMode; - bool m_visible; - QLocale m_locale; QSocketNotifier *m_readNotifier; // Path to keyboardManager in PPS. diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index cf45d062bd5..2b41631d068 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -121,11 +121,7 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context) qFatal("QQnxWindow: failed to set window swap interval, errno=%d", errno); } - // Assign the window to the primary display (this is the default specified by screen). - setScreen(QQnxScreen::primaryDisplay()); - - // Add the window to the root of the hierarchy - QQnxScreen::addWindow(this); + setScreen(static_cast(window->screen()->handle())); // Add window to plugin's window mapper QQnxIntegration::addWindow(m_window, window); @@ -141,7 +137,7 @@ QQnxWindow::~QQnxWindow() // Remove from parent's Hierarchy. removeFromParent(); - QQnxScreen::updateHierarchy(); + m_screen->updateHierarchy(); // We shouldn't allow this case unless QT allows it. Does it? Or should we send the // handleCloseEvent on all children when this window is deleted? @@ -196,12 +192,12 @@ void QQnxWindow::setGeometry(const QRect &rect) QList::iterator it; for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) { - (*it)->offset(offset); + (*it)->setOffset(offset); } } } -void QQnxWindow::offset(const QPoint &offset) +void QQnxWindow::setOffset(const QPoint &offset) { #if defined(QQNXWINDOW_DEBUG) qDebug() << Q_FUNC_INFO << "window =" << window(); @@ -225,7 +221,7 @@ void QQnxWindow::offset(const QPoint &offset) QList::iterator it; for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) { - (*it)->offset(offset); + (*it)->setOffset(offset); } } @@ -416,6 +412,9 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen) if (m_screen == platformScreen) return; + if (m_screen) + m_screen->removeWindow(this); + platformScreen->addWindow(this); m_screen = platformScreen; // Move window to proper screen/display @@ -441,7 +440,7 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen) (*it)->setScreen(platformScreen); } - QQnxScreen::updateHierarchy(); + m_screen->updateHierarchy(); } void QQnxWindow::removeFromParent() @@ -456,7 +455,7 @@ void QQnxWindow::removeFromParent() else qFatal("QQnxWindow: Window Hierarchy broken; window has parent, but parent hasn't got child."); } else { - QQnxScreen::removeWindow(this); + m_screen->removeWindow(this); } } @@ -484,10 +483,10 @@ void QQnxWindow::setParent(const QPlatformWindow *window) m_parentWindow->m_childWindows.push_back(this); } else { - QQnxScreen::addWindow(this); + m_screen->addWindow(this); } - QQnxScreen::updateHierarchy(); + m_screen->updateHierarchy(); } void QQnxWindow::raise() @@ -501,10 +500,10 @@ void QQnxWindow::raise() removeFromParent(); oldParent->m_childWindows.push_back(this); } else { - QQnxScreen::raiseWindow(this); + m_screen->raiseWindow(this); } - QQnxScreen::updateHierarchy(); + m_screen->updateHierarchy(); } void QQnxWindow::lower() @@ -518,10 +517,10 @@ void QQnxWindow::lower() removeFromParent(); oldParent->m_childWindows.push_front(this); } else { - QQnxScreen::lowerWindow(this); + m_screen->lowerWindow(this); } - QQnxScreen::updateHierarchy(); + m_screen->updateHierarchy(); } void QQnxWindow::requestActivateWindow() @@ -553,6 +552,20 @@ void QQnxWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext) m_platformOpenGLContext = platformOpenGLContext; } +QQnxWindow *QQnxWindow::findWindow(screen_window_t windowHandle) +{ + if (m_window == windowHandle) + return this; + + Q_FOREACH (QQnxWindow *window, m_childWindows) { + QQnxWindow * const result = window->findWindow(windowHandle); + if (result) + return result; + } + + return 0; +} + void QQnxWindow::updateZorder(int &topZorder) { errno = 0; diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h index 9c03af7594c..63e71c0bf8d 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -69,11 +69,11 @@ public: QQnxWindow(QWindow *window, screen_context_t context); virtual ~QQnxWindow(); - virtual void setGeometry(const QRect &rect); - virtual void setVisible(bool visible); - virtual void setOpacity(qreal level); + void setGeometry(const QRect &rect); + void setVisible(bool visible); + void setOpacity(qreal level); - virtual WId winId() const { return (WId)m_window; } + WId winId() const { return (WId)m_window; } screen_window_t nativeHandle() const { return m_window; } void setBufferSize(const QSize &size); @@ -86,10 +86,10 @@ public: void setScreen(QQnxScreen *platformScreen); - virtual void setParent(const QPlatformWindow *window); - virtual void raise(); - virtual void lower(); - virtual void requestActivateWindow(); + void setParent(const QPlatformWindow *window); + void raise(); + void lower(); + void requestActivateWindow(); void gainedFocus(); @@ -99,9 +99,11 @@ public: void setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext); QQnxGLContext *platformOpenGLContext() const { return m_platformOpenGLContext; } + QQnxWindow *findWindow(screen_window_t windowHandle); + private: void removeFromParent(); - void offset(const QPoint &offset); + void setOffset(const QPoint &setOffset); void updateVisibility(bool parentVisible); void updateZorder(int &topZorder); diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index c3d5c543cfc..be680e7d486 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -169,7 +169,9 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryInterface(REFIID id, LPVOI { HRESULT hr = QWindowsMsaaAccessible::QueryInterface(id, iface); if (!SUCCEEDED(hr)) { - if (id == IID_IAccessible2) { + if (id == IID_IServiceProvider) { + *iface = (IServiceProvider*)this; + } else if (id == IID_IAccessible2) { *iface = (IAccessible2*)this; } else if (id == IID_IAccessibleAction) { if (accessible->actionInterface()) diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index bd928399c85..0672a86dd90 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -232,9 +232,6 @@ QWindow *QWindowsAccessibility::windowHelper(const QAccessibleInterface *iface) */ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc) { -#ifdef Q_CC_MINGW - return 0; -#else if (!acc) return 0; #ifdef Q_CC_MINGW @@ -245,7 +242,6 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc) IAccessible *iacc = 0; wacc->QueryInterface(IID_IAccessible, (void**)&iacc); return iacc; -#endif } /*! diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index e0be731b532..c1c25dd6863 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -51,6 +51,7 @@ #include #include +#include #include @@ -68,8 +69,10 @@ QT_BEGIN_NAMESPACE */ QWindowsFontEngineData::QWindowsFontEngineData() + : clearTypeEnabled(false) + , fontSmoothingGamma(QWindowsFontDatabase::fontSmoothingGamma()) #if !defined(QT_NO_DIRECTWRITE) - : directWriteFactory(0) + , directWriteFactory(0) , directWriteGdiInterop(0) #endif { @@ -78,17 +81,6 @@ QWindowsFontEngineData::QWindowsFontEngineData() if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0)) clearTypeEnabled = (result == FE_FONTSMOOTHINGCLEARTYPE); - int winSmooth; - if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) { - fontSmoothingGamma = winSmooth / qreal(1000.0); - } else { - fontSmoothingGamma = 1.0; - } - - // Safeguard ourselves against corrupt registry values... - if (fontSmoothingGamma > 5 || fontSmoothingGamma < 1) - fontSmoothingGamma = qreal(1.4); - const qreal gray_gamma = 2.31; for (int i=0; i<256; ++i) pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047)); @@ -110,6 +102,19 @@ QWindowsFontEngineData::~QWindowsFontEngineData() #endif } +qreal QWindowsFontDatabase::fontSmoothingGamma() +{ + int winSmooth; + qreal result = 1; + if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) + result = qreal(winSmooth) / qreal(1000.0); + + // Safeguard ourselves against corrupt registry values... + if (result > 5 || result < 1) + result = qreal(1.4); + return result; +} + #if !defined(QT_NO_DIRECTWRITE) static inline bool initDirectWrite(QWindowsFontEngineData *d) { @@ -614,14 +619,14 @@ static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, void QWindowsFontDatabase::populateFontDatabase() { - if (m_families.isEmpty()) { - QPlatformFontDatabase::populateFontDatabase(); - populate(); // Called multiple times. - // Work around EnumFontFamiliesEx() not listing the system font, see below. - const QString sysFontFamily = QGuiApplication::font().family(); - if (!m_families.contains(sysFontFamily)) - populate(sysFontFamily); - } + m_families.clear(); + removeApplicationFonts(); + QPlatformFontDatabase::populateFontDatabase(); + populate(); // Called multiple times. + // Work around EnumFontFamiliesEx() not listing the system font, see below. + const QString sysFontFamily = QGuiApplication::font().family(); + if (!m_families.contains(sysFontFamily)) + populate(sysFontFamily); } /*! @@ -665,6 +670,7 @@ QWindowsFontDatabase::QWindowsFontDatabase() : QWindowsFontDatabase::~QWindowsFontDatabase() { + removeApplicationFonts(); } QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, @@ -698,11 +704,160 @@ QStringList QWindowsFontDatabase::fallbacksForFamily(const QString family, const return result; } +static QList getTrueTypeFontOffsets(const uchar *fontData) +{ + QList offsets; + const quint32 headerTag = *reinterpret_cast(fontData); + if (headerTag != MAKE_TAG('t', 't', 'c', 'f')) { + if (headerTag != MAKE_TAG(0, 1, 0, 0) + && headerTag != MAKE_TAG('O', 'T', 'T', 'O') + && headerTag != MAKE_TAG('t', 'r', 'u', 'e') + && headerTag != MAKE_TAG('t', 'y', 'p', '1')) + return offsets; + offsets << 0; + return offsets; + } + const quint32 numFonts = qFromBigEndian(fontData + 8); + for (uint i = 0; i < numFonts; ++i) { + offsets << qFromBigEndian(fontData + 12 + i * 4); + } + return offsets; +} + +static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag, const uchar **table, quint32 *length) +{ + const quint16 numTables = qFromBigEndian(data + 4); + for (uint i = 0; i < numTables; ++i) { + const quint32 offset = 12 + 16 * i; + if (*reinterpret_cast(data + offset) == tag) { + *table = fileBegin + qFromBigEndian(data + offset + 8); + *length = qFromBigEndian(data + offset + 12); + return; + } + } + *table = 0; + *length = 0; + return; +} + +static void getFamiliesAndSignatures(const QByteArray &fontData, + QStringList *families, + QVector *signatures) +{ + const uchar *data = reinterpret_cast(fontData.constData()); + + QList offsets = getTrueTypeFontOffsets(data); + if (offsets.isEmpty()) + return; + + for (int i = 0; i < offsets.count(); ++i) { + const uchar *font = data + offsets.at(i); + const uchar *table; + quint32 length; + getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length); + if (!table) + continue; + QString name = getEnglishName(table, length); + if (name.isEmpty()) + continue; + + families->append(name); + + if (signatures) { + FONTSIGNATURE signature; + getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length); + if (table && length >= 86) { + // Offsets taken from OS/2 table in the TrueType spec + signature.fsUsb[0] = qFromBigEndian(table + 42); + signature.fsUsb[1] = qFromBigEndian(table + 46); + signature.fsUsb[2] = qFromBigEndian(table + 50); + signature.fsUsb[3] = qFromBigEndian(table + 54); + + signature.fsCsb[0] = qFromBigEndian(table + 78); + signature.fsCsb[1] = qFromBigEndian(table + 82); + } else { + memset(&signature, 0, sizeof(signature)); + } + signatures->append(signature); + } + } +} + QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) { - const QStringList result = QPlatformFontDatabase::addApplicationFont(fontData, fileName); - Q_UNIMPLEMENTED(); - return result; + WinApplicationFont font; + font.fileName = fileName; + QVector signatures; + QStringList families; + + if (!fontData.isEmpty()) { + getFamiliesAndSignatures(fontData, &families, &signatures); + if (families.isEmpty()) + return families; + + DWORD dummy = 0; + font.handle = AddFontMemResourceEx((void *)fontData.constData(), fontData.size(), 0, + &dummy); + if (font.handle == 0) + return QStringList(); + + // Memory fonts won't show up in enumeration, so do add them the hard way. + for (int j = 0; j < families.count(); ++j) { + const QString familyName = families.at(j); + HDC hdc = GetDC(0); + LOGFONT lf; + memset(&lf, 0, sizeof(LOGFONT)); + memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE, familyName.size())); + lf.lfCharSet = DEFAULT_CHARSET; + HFONT hfont = CreateFontIndirect(&lf); + HGDIOBJ oldobj = SelectObject(hdc, hfont); + + TEXTMETRIC textMetrics; + GetTextMetrics(hdc, &textMetrics); + + addFontToDatabase(familyName, QString(), &textMetrics, &signatures.at(j), + TRUETYPE_FONTTYPE); + + SelectObject(hdc, oldobj); + DeleteObject(hfont); + ReleaseDC(0, hdc); + } + } else { + QFile f(fileName); + if (!f.open(QIODevice::ReadOnly)) + return families; + QByteArray data = f.readAll(); + f.close(); + + getFamiliesAndSignatures(data, &families, 0); + if (families.isEmpty()) + return families; + + if (AddFontResourceExW((wchar_t*)fileName.utf16(), FR_PRIVATE, 0) == 0) + return QStringList(); + + font.handle = 0; + + // Fonts based on files are added via populate, as they will show up in font enumeration. + for (int j = 0; j < families.count(); ++j) + populate(families.at(j)); + } + + m_applicationFonts << font; + + return families; +} + +void QWindowsFontDatabase::removeApplicationFonts() +{ + foreach (const WinApplicationFont &font, m_applicationFonts) { + if (font.handle) { + RemoveFontMemResourceEx(font.handle); + } else { + RemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0); + } + } + m_applicationFonts.clear(); } void QWindowsFontDatabase::releaseHandle(void *handle) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h index f8f2a1eb851..2fa615253eb 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h @@ -96,10 +96,20 @@ public: static HFONT systemFont(); static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0); + static qreal fontSmoothingGamma(); + private: void populate(const QString &family = QString()); + void removeApplicationFonts(); QSharedPointer m_fontEngineData; QSet m_families; + + struct WinApplicationFont { + HANDLE handle; + QString fileName; + }; + + QList m_applicationFonts; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index f90a880cd3b..e84f0c76301 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -195,9 +195,11 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, const QStringList allKeys = fontRegistry.allKeys(); allFonts.reserve(allKeys.size()); const QString trueType = QStringLiteral("(TrueType)"); + const QRegExp sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+")); foreach (const QString &key, allKeys) { QString realKey = key; realKey.remove(trueType); + realKey.remove(sizeListMatch); QStringList fonts; const QStringList fontNames = realKey.trimmed().split(QLatin1Char('&')); foreach (const QString &fontName, fontNames) @@ -273,14 +275,13 @@ static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, void QWindowsFontDatabaseFT::populateFontDatabase() { - if (m_families.isEmpty()) { - QPlatformFontDatabase::populateFontDatabase(); - populate(); // Called multiple times. - // Work around EnumFontFamiliesEx() not listing the system font, see below. - const QString sysFontFamily = QGuiApplication::font().family(); - if (!m_families.contains(sysFontFamily)) - populate(sysFontFamily); - } + m_families.clear(); + QPlatformFontDatabase::populateFontDatabase(); + populate(); // Called multiple times. + // Work around EnumFontFamiliesEx() not listing the system font, see below. + const QString sysFontFamily = QGuiApplication::font().family(); + if (!m_families.contains(sysFontFamily)) + populate(sysFontFamily); } /*! @@ -426,14 +427,6 @@ QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString family, con << script << result << m_families; return result; } - -QStringList QWindowsFontDatabaseFT::addApplicationFont(const QByteArray &fontData, const QString &fileName) -{ - const QStringList result = QPlatformFontDatabase::addApplicationFont(fontData, fileName); - Q_UNIMPLEMENTED(); - return result; -} - QString QWindowsFontDatabaseFT::fontDir() const { const QString result = QLatin1String(qgetenv("windir")) + QLatin1String("/Fonts");//QPlatformFontDatabase::fontDir(); diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h index 24810c92028..bb55b682514 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h @@ -56,7 +56,6 @@ public: QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const; - QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); virtual QString fontDir() const; virtual QFont defaultFont() const; diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index ae5053210e8..03a76258f4b 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -184,7 +184,7 @@ void QWindowsInputContext::reset() QPlatformInputContext::reset(); if (!m_compositionContext.hwnd) return; - QObject *fo = qApp->inputMethod()->inputItem(); + QObject *fo = qApp->focusObject(); if (QWindowsContext::verboseInputMethods) qDebug() << __FUNCTION__<< fo; if (!fo) @@ -329,11 +329,11 @@ static inline QTextFormat standardFormat(StandardFormat format) bool QWindowsInputContext::startComposition(HWND hwnd) { - const QObject *fo = qApp->inputMethod()->inputItem(); + const QObject *fo = qApp->focusObject(); if (!fo) return false; // This should always match the object. - QWindow *window = qApp->inputMethod()->inputWindow(); + QWindow *window = qApp->focusWindow(); if (!window) return false; if (QWindowsContext::verboseInputMethods) @@ -397,7 +397,7 @@ static inline QList bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn) { - QObject *fo = qApp->inputMethod()->inputItem(); + QObject *fo = qApp->focusObject(); const int lParam = int(lParamIn); if (QWindowsContext::verboseInputMethods) qDebug() << '>' << __FUNCTION__ << fo << debugComposition(lParam) @@ -459,7 +459,7 @@ bool QWindowsInputContext::endComposition(HWND hwnd) // against that. if (m_endCompositionRecursionGuard || m_compositionContext.hwnd != hwnd) return false; - QObject *fo = qApp->inputMethod()->inputItem(); + QObject *fo = qApp->focusObject(); if (!fo) return false; @@ -537,7 +537,7 @@ bool QWindowsInputContext::handleIME_Request(WPARAM wParam, int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv) { - QObject *fo = qApp->inputMethod()->inputItem(); + QObject *fo = qApp->focusObject(); if (!fo) return false; diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index ee58a19ca9d..47d6a2f11a1 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -283,10 +283,11 @@ QPlatformFontDatabase *QWindowsIntegration::fontDatabase() const { if (!d->m_fontDatabase) { #ifndef QT_NO_FREETYPE - if (d->m_nativeInterface.property("fontengine").toString() == QLatin1String("native")) - d->m_fontDatabase = new QWindowsFontDatabase(); - else + const QVariant argument = d->m_nativeInterface.property("fontengine"); + if (argument.isValid() && argument.toString() == QLatin1String("freetype")) d->m_fontDatabase = new QWindowsFontDatabaseFT(); + else + d->m_fontDatabase = new QWindowsFontDatabase(); #else d->m_fontDatabase = new QWindowsFontDatabase(); #endif @@ -317,6 +318,8 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co case QPlatformIntegration::KeyboardInputInterval: case QPlatformIntegration::ShowIsFullScreen: break; // Not implemented + case QPlatformIntegration::FontSmoothingGamma: + return QVariant(QWindowsFontDatabase::fontSmoothingGamma()); } return QPlatformIntegration::styleHint(hint); } diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index f3a9d91d000..000311a807a 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -68,12 +68,27 @@ static inline QTextStream& operator<<(QTextStream &str, const QColor &c) return str; } +static inline void paletteRoleToString(const QPalette &palette, + const QPalette::ColorRole role, + QTextStream &str) +{ + str << "Role: "; + str.setFieldWidth(2); + str.setPadChar(QLatin1Char('0')); + str << role; + str.setFieldWidth(0); + str << " Active: " << palette.color(QPalette::Active, role) + << " Disabled: " << palette.color(QPalette::Disabled, role) + << " Inactive: " << palette.color(QPalette::Inactive, role) + << '\n'; +} + static inline QString paletteToString(const QPalette &palette) { QString result; QTextStream str(&result); - str << "text=" << palette.color(QPalette::WindowText) - << " background=" << palette.color(QPalette::Window); + for (int r = 0; r < QPalette::NColorRoles; ++r) + paletteRoleToString(palette, static_cast(r), str); return result; } @@ -105,9 +120,26 @@ static inline QColor getSysColor(int index) return qColorToCOLORREF(GetSysColor(index)); } +// from QStyle::standardPalette +static inline QPalette standardPalette() +{ + QColor backgroundColor(0xd4, 0xd0, 0xc8); // win 2000 grey + QColor lightColor(backgroundColor.lighter()); + QColor darkColor(backgroundColor.darker()); + const QBrush darkBrush(darkColor); + QColor midColor(Qt::gray); + QPalette palette(Qt::black, backgroundColor, lightColor, darkColor, + midColor, Qt::black, Qt::white); + palette.setBrush(QPalette::Disabled, QPalette::WindowText, darkBrush); + palette.setBrush(QPalette::Disabled, QPalette::Text, darkBrush); + palette.setBrush(QPalette::Disabled, QPalette::ButtonText, darkBrush); + palette.setBrush(QPalette::Disabled, QPalette::Base, QBrush(backgroundColor)); + return palette; +} + static inline QPalette systemPalette() { - QPalette result; + QPalette result = standardPalette(); result.setColor(QPalette::WindowText, getSysColor(COLOR_WINDOWTEXT)); result.setColor(QPalette::Button, getSysColor(COLOR_BTNFACE)); result.setColor(QPalette::Light, getSysColor(COLOR_BTNHIGHLIGHT)); @@ -183,7 +215,7 @@ static inline QPalette toolTipPalette(const QPalette &systemPalette) static inline QPalette menuPalette(const QPalette &systemPalette) { QPalette result(systemPalette); - const QColor menuColor(getSysColor(COLOR_INFOBK)); + const QColor menuColor(getSysColor(COLOR_MENU)); const QColor menuTextColor(getSysColor(COLOR_MENUTEXT)); const QColor disabled(getSysColor(COLOR_GRAYTEXT)); const bool isFlat = booleanSystemParametersInfo(SPI_GETFLATMENU, false); diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp index 12979bfb686..6a1209e6cf5 100644 --- a/src/plugins/platforms/xcb/qxcbimage.cpp +++ b/src/plugins/platforms/xcb/qxcbimage.cpp @@ -84,20 +84,15 @@ QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap const xcb_visualtype_t *visual) { xcb_connection_t *conn = connection->xcb_connection(); - xcb_generic_error_t *error = 0; xcb_get_image_cookie_t get_image_cookie = - xcb_get_image(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap, + xcb_get_image_unchecked(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap, 0, 0, width, height, 0xffffffff); xcb_get_image_reply_t *image_reply = - xcb_get_image_reply(conn, get_image_cookie, &error); + xcb_get_image_reply(conn, get_image_cookie, NULL); if (!image_reply) { - if (error) { - connection->handleXcbError(error); - free(error); - } return QPixmap(); } diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index c5e124ab450..ef98f82e977 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1073,14 +1073,6 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod int count = chars.count(); QString string = translateKeySym(sym, state, qtcode, modifiers, chars, count); - if (inputContext) { - QKeyEvent event(type, qtcode, modifiers, string); - event.setTimestamp(time); - bool retval = inputContext->filterEvent(&event); - if (retval) - return; - } - bool isAutoRepeat = false; if (type == QEvent::KeyPress) { @@ -1099,13 +1091,28 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod m_autorepeat_code = isAutoRepeat ? code : 0; } - QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers, - code, 0, state, string.left(count), isAutoRepeat); + bool filtered = false; + if (inputContext) { + QKeyEvent event(type, qtcode, modifiers, string, isAutoRepeat); + event.setTimestamp(time); + filtered = inputContext->filterEvent(&event); + } + + if (!filtered) + QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers, + code, 0, state, string.left(count), isAutoRepeat); if (isAutoRepeat && type == QEvent::KeyRelease) { // since we removed it from the event queue using checkEvent we need to send the key press here - QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers, - code, 0, state, string.left(count), isAutoRepeat); + filtered = false; + if (inputContext) { + QKeyEvent event(QEvent::KeyPress, qtcode, modifiers, string, isAutoRepeat); + event.setTimestamp(time); + filtered = inputContext->filterEvent(&event); + } + if (!filtered) + QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers, + code, 0, state, string.left(count), isAutoRepeat); } } diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index a076dd4282d..ae5e4cce348 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -76,13 +76,11 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num xcb_change_window_attributes(xcb_connection(), screen->root, mask, values); - xcb_generic_error_t *error; - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), - xcb_get_property(xcb_connection(), false, screen->root, + xcb_get_property_unchecked(xcb_connection(), false, screen->root, atom(QXcbAtom::_NET_SUPPORTING_WM_CHECK), - XCB_ATOM_WINDOW, 0, 1024), &error); + XCB_ATOM_WINDOW, 0, 1024), NULL); if (reply && reply->format == 32 && reply->type == XCB_ATOM_WINDOW) { xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply)); @@ -90,24 +88,18 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num if (windowManager != XCB_WINDOW_NONE) { xcb_get_property_reply_t *windowManagerReply = xcb_get_property_reply(xcb_connection(), - xcb_get_property(xcb_connection(), false, windowManager, + xcb_get_property_unchecked(xcb_connection(), false, windowManager, atom(QXcbAtom::_NET_WM_NAME), - atom(QXcbAtom::UTF8_STRING), 0, 1024), &error); + atom(QXcbAtom::UTF8_STRING), 0, 1024), NULL); if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) { m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply), xcb_get_property_value_length(windowManagerReply)); #ifdef Q_XCB_DEBUG qDebug("Running window manager: %s", qPrintable(m_windowManagerName)); #endif - } else if (error) { - connection->handleXcbError(error); - free(error); } free(windowManagerReply); } - } else if (error) { - connection->handleXcbError(error); - free(error); } free(reply); @@ -171,23 +163,17 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const int x = p.x(); int y = p.y(); - xcb_generic_error_t *error; - xcb_window_t parent = root; xcb_window_t child = root; do { xcb_translate_coordinates_cookie_t translate_cookie = - xcb_translate_coordinates(xcb_connection(), parent, child, x, y); + xcb_translate_coordinates_unchecked(xcb_connection(), parent, child, x, y); xcb_translate_coordinates_reply_t *translate_reply = - xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, &error); + xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, NULL); if (!translate_reply) { - if (error) { - connection()->handleXcbError(error); - free(error); - } return 0; } @@ -252,17 +238,12 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) if (width == 0 || height == 0) return QPixmap(); - xcb_get_geometry_cookie_t geometry_cookie = xcb_get_geometry(xcb_connection(), window); + xcb_get_geometry_cookie_t geometry_cookie = xcb_get_geometry_unchecked(xcb_connection(), window); - xcb_generic_error_t *error; xcb_get_geometry_reply_t *reply = - xcb_get_geometry_reply(xcb_connection(), geometry_cookie, &error); + xcb_get_geometry_reply(xcb_connection(), geometry_cookie, NULL); if (!reply) { - if (error) { - connection()->handleXcbError(error); - free(error); - } return QPixmap(); } @@ -274,15 +255,11 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) // TODO: handle multiple screens QXcbScreen *screen = const_cast(this); xcb_window_t root = screen->root(); - geometry_cookie = xcb_get_geometry(xcb_connection(), root); + geometry_cookie = xcb_get_geometry_unchecked(xcb_connection(), root); xcb_get_geometry_reply_t *root_reply = - xcb_get_geometry_reply(xcb_connection(), geometry_cookie, &error); + xcb_get_geometry_reply(xcb_connection(), geometry_cookie, NULL); if (!root_reply) { - if (error) { - connection()->handleXcbError(error); - free(error); - } free(reply); return QPixmap(); } @@ -294,16 +271,12 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) // map x and y to the root window xcb_translate_coordinates_cookie_t translate_cookie = - xcb_translate_coordinates(xcb_connection(), window, root, x, y); + xcb_translate_coordinates_unchecked(xcb_connection(), window, root, x, y); xcb_translate_coordinates_reply_t *translate_reply = - xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, &error); + xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, NULL); if (!translate_reply) { - if (error) { - connection()->handleXcbError(error); - free(error); - } free(reply); free(root_reply); return QPixmap(); @@ -323,13 +296,9 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) } xcb_get_window_attributes_reply_t *attributes_reply = - xcb_get_window_attributes_reply(xcb_connection(), xcb_get_window_attributes(xcb_connection(), window), &error); + xcb_get_window_attributes_reply(xcb_connection(), xcb_get_window_attributes_unchecked(xcb_connection(), window), NULL); if (!attributes_reply) { - if (error) { - connection()->handleXcbError(error); - free(error); - } free(reply); return QPixmap(); } @@ -338,11 +307,7 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) free(attributes_reply); xcb_pixmap_t pixmap = xcb_generate_id(xcb_connection()); - error = xcb_request_check(xcb_connection(), xcb_create_pixmap_checked(xcb_connection(), reply->depth, pixmap, window, width, height)); - if (error) { - connection()->handleXcbError(error); - free(error); - } + xcb_create_pixmap(xcb_connection(), reply->depth, pixmap, window, width, height); uint32_t gc_value_mask = XCB_GC_SUBWINDOW_MODE; uint32_t gc_value_list[] = { XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS }; @@ -350,11 +315,7 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) xcb_gcontext_t gc = xcb_generate_id(xcb_connection()); xcb_create_gc(xcb_connection(), gc, pixmap, gc_value_mask, gc_value_list); - error = xcb_request_check(xcb_connection(), xcb_copy_area_checked(xcb_connection(), window, pixmap, gc, x, y, 0, 0, width, height)); - if (error) { - connection()->handleXcbError(error); - free(error); - } + xcb_copy_area(xcb_connection(), window, pixmap, gc, x, y, 0, 0, width, height); QPixmap result = qt_xcb_pixmapFromXPixmap(connection(), pixmap, width, height, reply->depth, visual); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 458ba8f07fa..f328c2f2f8b 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -66,6 +66,7 @@ #ifdef XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS #define xcb_get_wm_hints_reply xcb_icccm_get_wm_hints_reply #define xcb_get_wm_hints xcb_icccm_get_wm_hints +#define xcb_get_wm_hints_unchecked xcb_icccm_get_wm_hints_unchecked #define xcb_set_wm_hints xcb_icccm_set_wm_hints #define xcb_set_wm_normal_hints xcb_icccm_set_wm_normal_hints #define xcb_size_hints_set_base_size xcb_icccm_size_hints_set_base_size @@ -422,10 +423,9 @@ QMargins QXcbWindow::frameMargins() const connection()->wmSupport()->virtualRoots(); while (!foundRoot) { - xcb_query_tree_cookie_t cookie = xcb_query_tree(xcb_connection(), parent); + xcb_query_tree_cookie_t cookie = xcb_query_tree_unchecked(xcb_connection(), parent); - xcb_generic_error_t *error; - xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, &error); + xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, NULL); if (reply) { if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1) { foundRoot = true; @@ -436,11 +436,6 @@ QMargins QXcbWindow::frameMargins() const free(reply); } else { - if (error) { - connection()->handleXcbError(error); - free(error); - } - m_dirtyFrameMargins = false; m_frameMargins = QMargins(); return m_frameMargins; @@ -449,25 +444,22 @@ QMargins QXcbWindow::frameMargins() const QPoint offset; - xcb_generic_error_t *error; xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply( xcb_connection(), xcb_translate_coordinates(xcb_connection(), window, parent, 0, 0), - &error); + NULL); if (reply) { offset = QPoint(reply->dst_x, reply->dst_y); free(reply); - } else if (error) { - free(error); } xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply( xcb_connection(), xcb_get_geometry(xcb_connection(), parent), - &error); + NULL); if (geom) { // -- @@ -487,8 +479,6 @@ QMargins QXcbWindow::frameMargins() const m_frameMargins = QMargins(left, top, right, bottom); free(geom); - } else if (error) { - free(error); } m_dirtyFrameMargins = false; @@ -508,17 +498,10 @@ void QXcbWindow::setVisible(bool visible) void QXcbWindow::show() { if (window()->isTopLevel()) { - xcb_get_property_cookie_t cookie = xcb_get_wm_hints(xcb_connection(), m_window); - - xcb_generic_error_t *error; + xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); xcb_wm_hints_t hints; - xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, &error); - - if (error) { - connection()->handleXcbError(error); - free(error); - } + xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, NULL); if (window()->windowState() & Qt::WindowMinimized) xcb_wm_hints_set_iconic(&hints); @@ -618,20 +601,15 @@ static QtMotifWmHints getMotifWmHints(QXcbConnection *c, xcb_window_t window) QtMotifWmHints hints; xcb_get_property_cookie_t get_cookie = - xcb_get_property(c->xcb_connection(), 0, window, c->atom(QXcbAtom::_MOTIF_WM_HINTS), + xcb_get_property_unchecked(c->xcb_connection(), 0, window, c->atom(QXcbAtom::_MOTIF_WM_HINTS), c->atom(QXcbAtom::_MOTIF_WM_HINTS), 0, 20); - xcb_generic_error_t *error; - xcb_get_property_reply_t *reply = - xcb_get_property_reply(c->xcb_connection(), get_cookie, &error); + xcb_get_property_reply(c->xcb_connection(), get_cookie, NULL); if (reply && reply->format == 32 && reply->type == c->atom(QXcbAtom::_MOTIF_WM_HINTS)) { hints = *((QtMotifWmHints *)xcb_get_property_value(reply)); - } else if (error) { - c->handleXcbError(error); - free(error); - + } else { hints.flags = 0L; hints.functions = MWM_FUNC_ALL; hints.decorations = MWM_DECOR_ALL; @@ -685,13 +663,11 @@ QVector QXcbWindow::getNetWmState() QVector result; xcb_get_property_cookie_t get_cookie = - xcb_get_property(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE), + xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE), XCB_ATOM_ATOM, 0, 1024); - xcb_generic_error_t *error; - xcb_get_property_reply_t *reply = - xcb_get_property_reply(xcb_connection(), get_cookie, &error); + xcb_get_property_reply(xcb_connection(), get_cookie, NULL); if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) { result.resize(reply->length); @@ -704,9 +680,6 @@ QVector QXcbWindow::getNetWmState() #endif free(reply); - } else if (error) { - connection()->handleXcbError(error); - free(error); } else { #ifdef NET_WM_STATE_DEBUG printf("getting net wm state (%x), empty\n", m_window); @@ -1086,16 +1059,10 @@ void QXcbWindow::setTransparentForMouseEvents(bool transparent) void QXcbWindow::updateDoesNotAcceptFocus(bool doesNotAcceptFocus) { - xcb_get_property_cookie_t cookie = xcb_get_wm_hints(xcb_connection(), m_window); - - xcb_generic_error_t *error; + xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); xcb_wm_hints_t hints; - xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, &error); - - if (error) { - connection()->handleXcbError(error); - free(error); + if (!xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, NULL)) { return; } @@ -1316,14 +1283,11 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * // Do not trust the position, query it instead. xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcb_window(), m_screen->root(), 0, 0); - xcb_generic_error_t *error; - xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, &error); + xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); if (reply) { pos.setX(reply->dst_x); pos.setY(reply->dst_y); free(reply); - } else if (error) { - free(error); } } @@ -1515,19 +1479,14 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev xcb_get_property(xcb_connection(), 0, m_window, atom(QXcbAtom::WM_STATE), XCB_ATOM_ANY, 0, 1024); - xcb_generic_error_t *error; - xcb_get_property_reply_t *reply = - xcb_get_property_reply(xcb_connection(), get_cookie, &error); + xcb_get_property_reply(xcb_connection(), get_cookie, NULL); xcb_atom_t wm_state = XCB_WM_STATE_WITHDRAWN; if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) { if (reply->length != 0) wm_state = ((long *)xcb_get_property_value(reply))[0]; free(reply); - } else if (error) { - connection()->handleXcbError(error); - free(error); } QVector netWmState = getNetWmState(); @@ -1593,11 +1552,9 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab) xcb_grab_keyboard_cookie_t cookie = xcb_grab_keyboard(xcb_connection(), false, m_window, XCB_TIME_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); - xcb_generic_error_t *err; - xcb_grab_keyboard_reply_t *reply = xcb_grab_keyboard_reply(xcb_connection(), cookie, &err); - bool result = !(err || !reply || reply->status != XCB_GRAB_STATUS_SUCCESS); + xcb_grab_keyboard_reply_t *reply = xcb_grab_keyboard_reply(xcb_connection(), cookie, NULL); + bool result = !(!reply || reply->status != XCB_GRAB_STATUS_SUCCESS); free(reply); - free(err); return result; } @@ -1614,11 +1571,9 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab) XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_WINDOW_NONE, XCB_CURSOR_NONE, XCB_TIME_CURRENT_TIME); - xcb_generic_error_t *err; - xcb_grab_pointer_reply_t *reply = xcb_grab_pointer_reply(xcb_connection(), cookie, &err); - bool result = !(err || !reply || reply->status != XCB_GRAB_STATUS_SUCCESS); + xcb_grab_pointer_reply_t *reply = xcb_grab_pointer_reply(xcb_connection(), cookie, NULL); + bool result = !(!reply || reply->status != XCB_GRAB_STATUS_SUCCESS); free(reply); - free(err); return result; } diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp index c9f4ca69dd9..e164c7ae2da 100644 --- a/src/plugins/platforms/xcb/qxcbwmsupport.cpp +++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp @@ -68,10 +68,9 @@ void QXcbWMSupport::updateNetWMAtoms() int offset = 0; int remaining = 0; do { - xcb_generic_error_t *error = 0; xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_SUPPORTED), XCB_ATOM_ATOM, offset, 1024); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, &error); - if (!reply || error) + xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, NULL); + if (!reply) break; remaining = 0; @@ -103,10 +102,9 @@ void QXcbWMSupport::updateVirtualRoots() int offset = 0; int remaining = 0; do { - xcb_generic_error_t *error = 0; xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_VIRTUAL_ROOTS), XCB_ATOM_ATOM, offset, 1024); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, &error); - if (!reply || error) + xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, NULL); + if (!reply) break; remaining = 0; diff --git a/src/plugins/platforms/xlib/qglxintegration.cpp b/src/plugins/platforms/xlib/qglxintegration.cpp deleted file mode 100644 index b2d44cf0840..00000000000 --- a/src/plugins/platforms/xlib/qglxintegration.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include "qxlibwindow.h" -#include "qxlibscreen.h" -#include "qxlibdisplay.h" - -#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2) -#include -#include -#include -#include "private/qglxconvenience_p.h" - -#include "qglxintegration.h" - -#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) -#include -#endif - -QT_BEGIN_NAMESPACE - -QGLXContext::QGLXContext(QXlibScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share) - : QPlatformOpenGLContext() - , m_screen(screen) - , m_context(0) - , m_windowFormat(format) -{ - GLXContext shareGlxContext = 0; - if (share) - shareGlxContext = static_cast(share)->glxContext(); - - Display *xDisplay = screen->display()->nativeDisplay(); - - GLXFBConfig config = qglx_findConfig(xDisplay,screen->xScreenNumber(),format); - if (config) { - m_context = glXCreateNewContext(xDisplay,config,GLX_RGBA_TYPE,shareGlxContext,TRUE); - m_windowFormat = qglx_surfaceFormatFromGLXFBConfig(xDisplay,config,m_context); - } else { - XVisualInfo *visualInfo = qglx_findVisualInfo(xDisplay, screen->xScreenNumber(), &m_windowFormat); - if (!visualInfo) - qFatal("Could not initialize GLX"); - m_context = glXCreateContext(xDisplay, visualInfo, shareGlxContext, true); - XFree(visualInfo); - } - -#ifdef MYX11_DEBUG - qDebug() << "QGLXGLContext::create context" << m_context; -#endif -} - -QGLXContext::~QGLXContext() -{ - if (m_context) { - qDebug("Destroying GLX context 0x%p", m_context); - glXDestroyContext(m_screen->display()->nativeDisplay(), m_context); - } -} - -QSurfaceFormat QGLXContext::format() const -{ - return m_windowFormat; -} - -bool QGLXContext::makeCurrent(QPlatformSurface *surface) -{ - Q_UNUSED(surface); - - GLXDrawable glxDrawable = static_cast(surface)->winId(); -#ifdef MYX11_DEBUG - qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", glxDrawable, m_context); -#endif - return glXMakeCurrent(m_screen->display()->nativeDisplay(), glxDrawable, m_context); -} - -void QGLXContext::doneCurrent() -{ - glXMakeCurrent(m_screen->display()->nativeDisplay(), 0, 0); -} - -void QGLXContext::swapBuffers(QPlatformSurface *surface) -{ - Q_UNUSED(surface); - - GLXDrawable glxDrawable = static_cast(surface)->winId(); - glXSwapBuffers(m_screen->display()->nativeDisplay(), glxDrawable); -} - -void (*QGLXContext::getProcAddress(const QByteArray& procName))() -{ - typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *); - static qt_glXGetProcAddressARB glXGetProcAddressARB = 0; - static bool resolved = false; - - if (resolved && !glXGetProcAddressARB) - return 0; - if (!glXGetProcAddressARB) { - QList glxExt = QByteArray(glXGetClientString(m_screen->display()->nativeDisplay(), GLX_EXTENSIONS)).split(' '); - if (glxExt.contains("GLX_ARB_get_proc_address")) { -#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) - void *handle = dlopen(NULL, RTLD_LAZY); - if (handle) { - glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB"); - dlclose(handle); - } - if (!glXGetProcAddressARB) -#endif - { - extern const QString qt_gl_library_name(); -// QLibrary lib(qt_gl_library_name()); - QLibrary lib(QLatin1String("GL")); - glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB"); - } - } - resolved = true; - } - if (!glXGetProcAddressARB) - return 0; - return (void (*)())glXGetProcAddressARB(reinterpret_cast(procName.constData())); -} - -QSurfaceFormat QGLXContext::surfaceFormat() const -{ - return m_windowFormat; -} - -QT_END_NAMESPACE - -#endif //!defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2) diff --git a/src/plugins/platforms/xlib/qxlibbackingstore.cpp b/src/plugins/platforms/xlib/qxlibbackingstore.cpp deleted file mode 100644 index 53f052c4caf..00000000000 --- a/src/plugins/platforms/xlib/qxlibbackingstore.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qxlibbackingstore.h" -#include "qxlibintegration.h" - -#include -#include - -#include "qxlibwindow.h" -#include "qxlibscreen.h" -#include "qxlibdisplay.h" - -#include "qpainter.h" - -# include -# include -# include - -QT_BEGIN_NAMESPACE - -struct QXlibShmImageInfo { - QXlibShmImageInfo(Display *xdisplay) : image(0), display(xdisplay) {} - ~QXlibShmImageInfo() { destroy(); } - - void destroy(); - - XShmSegmentInfo shminfo; - XImage *image; - Display *display; -}; - - -#ifndef DONT_USE_MIT_SHM -void QXlibShmImageInfo::destroy() -{ - XShmDetach (display, &shminfo); - XDestroyImage (image); - shmdt (shminfo.shmaddr); - shmctl (shminfo.shmid, IPC_RMID, 0); -} -#endif - -void QXlibBackingStore::resizeShmImage(int width, int height) -{ - QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(window()); - QXlibWindow *win = static_cast(window()->handle()); - - QImage::Format format = win->depth() == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32; - -#ifdef DONT_USE_MIT_SHM - shm_img = QImage(width, height, format); -#else - - if (image_info) - image_info->destroy(); - else - image_info = new QXlibShmImageInfo(screen->display()->nativeDisplay()); - - XImage *image = XShmCreateImage (screen->display()->nativeDisplay(), win->visual(), win->depth(), ZPixmap, 0, - &image_info->shminfo, width, height); - - - image_info->shminfo.shmid = shmget (IPC_PRIVATE, - image->bytes_per_line * image->height, IPC_CREAT|0777); - - image_info->shminfo.shmaddr = image->data = (char*)shmat (image_info->shminfo.shmid, 0, 0); - image_info->shminfo.readOnly = False; - - image_info->image = image; - - Status shm_attach_status = XShmAttach(screen->display()->nativeDisplay(), &image_info->shminfo); - - Q_ASSERT(shm_attach_status == True); - - shm_img = QImage((uchar*) image->data, image->width, image->height, image->bytes_per_line, format); -#endif - painted = false; -} - - -void QXlibBackingStore::resizeBuffer(QSize s) -{ - if (shm_img.size() != s) - resizeShmImage(s.width(), s.height()); -} - -QSize QXlibBackingStore::bufferSize() const -{ - return shm_img.size(); -} - -QXlibBackingStore::QXlibBackingStore(QWindow *window) - : QPlatformBackingStore(window), - painted(false), image_info(0) -{ - xw = static_cast(window->handle()); -// qDebug() << "QTestLiteWindowSurface::QTestLiteWindowSurface:" << xw->window; -} - -QXlibBackingStore::~QXlibBackingStore() -{ - delete image_info; -} - -QPaintDevice *QXlibBackingStore::paintDevice() -{ - return &shm_img; -} - - -void QXlibBackingStore::flush(QWindow *w, const QRegion ®ion, const QPoint &offset) -{ - Q_UNUSED(region); - Q_UNUSED(offset); - - if (!painted) - return; - - QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(w); - GC gc = xw->graphicsContext(); - Window window = xw->xWindow(); -#ifdef DONT_USE_MIT_SHM - // just convert the image every time... - if (!shm_img.isNull()) { - QXlibWindow *win = static_cast(w->handle()); - - QImage image = shm_img; - //img.convertToFormat( - XImage *xi = XCreateImage(screen->display()->nativeDisplay(), win->visual(), win->depth(), ZPixmap, - 0, (char *) image.scanLine(0), image.width(), image.height(), - 32, image.bytesPerLine()); - - int x = 0; - int y = 0; - - /*int r =*/ XPutImage(screen->display()->nativeDisplay(), window, gc, xi, 0, 0, x, y, image.width(), image.height()); - - xi->data = 0; // QImage owns these bits - XDestroyImage(xi); - } -#else - // Use MIT_SHM - if (image_info && image_info->image) { - //qDebug() << "Here we go" << image_info->image->width << image_info->image->height; - int x = 0; - int y = 0; - - // We could set send_event to true, and then use the ShmCompletion to synchronize, - // but let's do like Qt/11 and just use XSync - XShmPutImage (screen->display()->nativeDisplay(), window, gc, image_info->image, 0, 0, - x, y, image_info->image->width, image_info->image->height, - /*send_event*/ False); - - screen->display()->sync(); - } -#endif -} - -void QXlibBackingStore::resize(const QSize &size, const QRegion &) -{ - resizeBuffer(size); -} - - -void QXlibBackingStore::beginPaint(const QRegion ®ion) -{ - Q_UNUSED(region); - - if (shm_img.hasAlphaChannel()) { - QPainter p(&shm_img); - p.setCompositionMode(QPainter::CompositionMode_Source); - const QVector rects = region.rects(); - const QColor blank = Qt::transparent; - for (QVector::const_iterator it = rects.begin(); it != rects.end(); ++it) { - p.fillRect(*it, blank); - } - } -} - -void QXlibBackingStore::endPaint() -{ - painted = true; //there is content in the buffer -} -QT_END_NAMESPACE diff --git a/src/plugins/platforms/xlib/qxlibclipboard.cpp b/src/plugins/platforms/xlib/qxlibclipboard.cpp deleted file mode 100644 index 69a0f207779..00000000000 --- a/src/plugins/platforms/xlib/qxlibclipboard.cpp +++ /dev/null @@ -1,676 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "qxlibclipboard.h" - -#include "qxlibscreen.h" -#include "qxlibmime.h" -#include "qxlibdisplay.h" - -#include - -class QXlibClipboardMime : public QXlibMime -{ - Q_OBJECT -public: - QXlibClipboardMime(QClipboard::Mode mode, QXlibClipboard *clipboard) - : QXlibMime() - , m_clipboard(clipboard) - { - switch (mode) { - case QClipboard::Selection: - modeAtom = XA_PRIMARY; - break; - - case QClipboard::Clipboard: - modeAtom = QXlibStatic::atom(QXlibStatic::CLIPBOARD); - break; - - default: - qWarning("QTestLiteMime: Internal error: Unsupported clipboard mode"); - break; - } - } - -protected: - QStringList formats_sys() const - { - if (empty()) - return QStringList(); - - if (!formatList.count()) { - QXlibClipboardMime *that = const_cast(this); - // get the list of targets from the current clipboard owner - we do this - // once so that multiple calls to this function don't require multiple - // server round trips... - that->format_atoms = m_clipboard->getDataInFormat(modeAtom,QXlibStatic::atom(QXlibStatic::TARGETS)); - - if (format_atoms.size() > 0) { - Atom *targets = (Atom *) format_atoms.data(); - int size = format_atoms.size() / sizeof(Atom); - - for (int i = 0; i < size; ++i) { - if (targets[i] == 0) - continue; - - QStringList formatsForAtom = mimeFormatsForAtom(m_clipboard->screen()->display()->nativeDisplay(),targets[i]); - for (int j = 0; j < formatsForAtom.size(); ++j) { - if (!formatList.contains(formatsForAtom.at(j))) - that->formatList.append(formatsForAtom.at(j)); - } - } - } - } - - return formatList; - } - - bool hasFormat_sys(const QString &format) const - { - QStringList list = formats(); - return list.contains(format); - } - - QVariant retrieveData_sys(const QString &fmt, QVariant::Type requestedType) const - { - if (fmt.isEmpty() || empty()) - return QByteArray(); - - (void)formats(); // trigger update of format list - - QList atoms; - Atom *targets = (Atom *) format_atoms.data(); - int size = format_atoms.size() / sizeof(Atom); - for (int i = 0; i < size; ++i) - atoms.append(targets[i]); - - QByteArray encoding; - Atom fmtatom = mimeAtomForFormat(m_clipboard->screen()->display()->nativeDisplay(),fmt, requestedType, atoms, &encoding); - - if (fmtatom == 0) - return QVariant(); - - return mimeConvertToFormat(m_clipboard->screen()->display()->nativeDisplay(),fmtatom, m_clipboard->getDataInFormat(modeAtom,fmtatom), fmt, requestedType, encoding); - } -private: - bool empty() const - { - Window win = XGetSelectionOwner(m_clipboard->screen()->display()->nativeDisplay(), modeAtom); - - return win == XNone; - } - - - Atom modeAtom; - QXlibClipboard *m_clipboard; - QStringList formatList; - QByteArray format_atoms; -}; - -const int QXlibClipboard::clipboard_timeout = 5000; - -QXlibClipboard::QXlibClipboard(QXlibScreen *screen) - : QPlatformClipboard() - , m_screen(screen) - , m_xClipboard(0) - , m_clientClipboard(0) - , m_xSelection(0) - , m_clientSelection(0) - , m_requestor(XNone) - , m_owner(XNone) -{ -} - -QMimeData * QXlibClipboard::mimeData(QClipboard::Mode mode) -{ - if (mode == QClipboard::Clipboard) { - if (!m_xClipboard) { - m_xClipboard = new QXlibClipboardMime(mode, this); - } - Window clipboardOwner = XGetSelectionOwner(screen()->display()->nativeDisplay(),QXlibStatic::atom(QXlibStatic::CLIPBOARD)); - if (clipboardOwner == owner()) { - return m_clientClipboard; - } else { - return m_xClipboard; - } - } else if (mode == QClipboard::Selection) { - if (!m_xSelection) { - m_xSelection = new QXlibClipboardMime(mode, this); - } - Window clipboardOwner = XGetSelectionOwner(screen()->display()->nativeDisplay(),XA_PRIMARY); - if (clipboardOwner == owner()) { - return m_clientSelection; - } else { - return m_xSelection; - } - } - return 0; -} - -void QXlibClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) -{ - Atom modeAtom; - QMimeData **d; - switch (mode) { - case QClipboard::Selection: - modeAtom = XA_PRIMARY; - d = &m_clientSelection; - break; - - case QClipboard::Clipboard: - modeAtom = QXlibStatic::atom(QXlibStatic::CLIPBOARD); - d = &m_clientClipboard; - break; - - default: - qWarning("QClipboard::setMimeData: unsupported mode '%d'", mode); - return; - } - - Window newOwner; - - if (! data) { // no data, clear clipboard contents - newOwner = XNone; - } else { - newOwner = owner(); - - *d = data; - } - - XSetSelectionOwner(m_screen->display()->nativeDisplay(), modeAtom, newOwner, CurrentTime); - - if (XGetSelectionOwner(m_screen->display()->nativeDisplay(), modeAtom) != newOwner) { - qWarning("QClipboard::setData: Cannot set X11 selection owner"); - } - - emitChanged(mode); -} - -bool QXlibClipboard::supportsMode(QClipboard::Mode mode) const -{ - if (mode == QClipboard::Clipboard || mode == QClipboard::Selection) - return true; - return false; -} - - -QXlibScreen * QXlibClipboard::screen() const -{ - return m_screen; -} - -Window QXlibClipboard::requestor() const -{ - if (!m_requestor) { - int x = 0, y = 0, w = 3, h = 3; - QXlibClipboard *that = const_cast(this); - Window window = XCreateSimpleWindow(m_screen->display()->nativeDisplay(), m_screen->rootWindow(), - x, y, w, h, 0 /*border_width*/, - m_screen->blackPixel(), m_screen->whitePixel()); - that->setRequestor(window); - } - return m_requestor; -} - -void QXlibClipboard::setRequestor(Window window) -{ - if (m_requestor != XNone) { - XDestroyWindow(m_screen->display()->nativeDisplay(),m_requestor); - } - m_requestor = window; -} - -Window QXlibClipboard::owner() const -{ - if (!m_owner) { - int x = 0, y = 0, w = 3, h = 3; - QXlibClipboard *that = const_cast(this); - Window window = XCreateSimpleWindow(m_screen->display()->nativeDisplay(), m_screen->rootWindow(), - x, y, w, h, 0 /*border_width*/, - m_screen->blackPixel(), m_screen->whitePixel()); - that->setOwner(window); - } - return m_owner; -} - -void QXlibClipboard::setOwner(Window window) -{ - if (m_owner != XNone){ - XDestroyWindow(m_screen->display()->nativeDisplay(),m_owner); - } - m_owner = window; -} - -Atom QXlibClipboard::sendTargetsSelection(QMimeData *d, Window window, Atom property) -{ - QVector types; - QStringList formats = QInternalMimeData::formatsHelper(d); - for (int i = 0; i < formats.size(); ++i) { - QList atoms = QXlibMime::mimeAtomsForFormat(screen()->display()->nativeDisplay(),formats.at(i)); - for (int j = 0; j < atoms.size(); ++j) { - if (!types.contains(atoms.at(j))) - types.append(atoms.at(j)); - } - } - types.append(QXlibStatic::atom(QXlibStatic::TARGETS)); - types.append(QXlibStatic::atom(QXlibStatic::MULTIPLE)); - types.append(QXlibStatic::atom(QXlibStatic::TIMESTAMP)); - types.append(QXlibStatic::atom(QXlibStatic::SAVE_TARGETS)); - - XChangeProperty(screen()->display()->nativeDisplay(), window, property, XA_ATOM, 32, - PropModeReplace, (uchar *) types.data(), types.size()); - return property; -} - -Atom QXlibClipboard::sendSelection(QMimeData *d, Atom target, Window window, Atom property) -{ - Atom atomFormat = target; - int dataFormat = 0; - QByteArray data; - - QString fmt = QXlibMime::mimeAtomToString(screen()->display()->nativeDisplay(), target); - if (fmt.isEmpty()) { // Not a MIME type we have - qDebug() << "QClipboard: send_selection(): converting to type '%s' is not supported" << fmt.data(); - return XNone; - } - qDebug() << "QClipboard: send_selection(): converting to type '%s'" << fmt.data(); - - if (QXlibMime::mimeDataForAtom(screen()->display()->nativeDisplay(),target, d, &data, &atomFormat, &dataFormat)) { - - // don't allow INCR transfers when using MULTIPLE or to - // Motif clients (since Motif doesn't support INCR) - static Atom motif_clip_temporary = QXlibStatic::atom(QXlibStatic::CLIP_TEMPORARY); - bool allow_incr = property != motif_clip_temporary; - - // X_ChangeProperty protocol request is 24 bytes - const int increment = (XMaxRequestSize(screen()->display()->nativeDisplay()) * 4) - 24; - if (data.size() > increment && allow_incr) { - long bytes = data.size(); - XChangeProperty(screen()->display()->nativeDisplay(), window, property, - QXlibStatic::atom(QXlibStatic::INCR), 32, PropModeReplace, (uchar *) &bytes, 1); - -// (void)new QClipboardINCRTransaction(window, property, atomFormat, dataFormat, data, increment); - qDebug() << "not implemented INCRT just YET!"; - return property; - } - - // make sure we can perform the XChangeProperty in a single request - if (data.size() > increment) - return XNone; // ### perhaps use several XChangeProperty calls w/ PropModeAppend? - int dataSize = data.size() / (dataFormat / 8); - // use a single request to transfer data - XChangeProperty(screen()->display()->nativeDisplay(), window, property, atomFormat, - dataFormat, PropModeReplace, (uchar *) data.data(), - dataSize); - } - return property; -} - -void QXlibClipboard::handleSelectionRequest(XEvent *xevent) -{ - XSelectionRequestEvent *req = &xevent->xselectionrequest; - - if (requestor() && req->requestor == requestor()) { - qDebug() << "This should be caught before"; - return; - } - - XEvent event; - event.xselection.type = SelectionNotify; - event.xselection.display = req->display; - event.xselection.requestor = req->requestor; - event.xselection.selection = req->selection; - event.xselection.target = req->target; - event.xselection.property = XNone; - event.xselection.time = req->time; - - QMimeData *d; - if (req->selection == XA_PRIMARY) { - d = m_clientSelection; - } else if (req->selection == QXlibStatic::atom(QXlibStatic::CLIPBOARD)) { - d = m_clientClipboard; - } else { - qWarning("QClipboard: Unknown selection '%lx'", req->selection); - XSendEvent(screen()->display()->nativeDisplay(), req->requestor, False, NoEventMask, &event); - return; - } - - if (!d) { - qWarning("QClipboard: Cannot transfer data, no data available"); - XSendEvent(screen()->display()->nativeDisplay(), req->requestor, False, NoEventMask, &event); - return; - } - - Atom xa_targets = QXlibStatic::atom(QXlibStatic::TARGETS); - Atom xa_multiple = QXlibStatic::atom(QXlibStatic::MULTIPLE); - Atom xa_timestamp = QXlibStatic::atom(QXlibStatic::TIMESTAMP); - - struct AtomPair { Atom target; Atom property; } *multi = 0; - Atom multi_type = XNone; - int multi_format = 0; - int nmulti = 0; - int imulti = -1; - bool multi_writeback = false; - - if (req->target == xa_multiple) { - QByteArray multi_data; - if (req->property == XNone - || !clipboardReadProperty(req->requestor, req->property, false, &multi_data, - 0, &multi_type, &multi_format) - || multi_format != 32) { - // MULTIPLE property not formatted correctly - XSendEvent(screen()->display()->nativeDisplay(), req->requestor, False, NoEventMask, &event); - return; - } - nmulti = multi_data.size()/sizeof(*multi); - multi = new AtomPair[nmulti]; - memcpy(multi,multi_data.data(),multi_data.size()); - imulti = 0; - } - - for (; imulti < nmulti; ++imulti) { - Atom target; - Atom property; - - if (multi) { - target = multi[imulti].target; - property = multi[imulti].property; - } else { - target = req->target; - property = req->property; - if (property == XNone) // obsolete client - property = target; - } - - Atom ret = XNone; - if (target == XNone || property == XNone) { - ; - } else if (target == xa_timestamp) { -// if (d->timestamp != CurrentTime) { -// XChangeProperty(screen()->display()->nativeDisplay(), req->requestor, property, XA_INTEGER, 32, -// PropModeReplace, CurrentTime, 1); -// ret = property; -// } else { -// qWarning("QClipboard: Invalid data timestamp"); -// } - } else if (target == xa_targets) { - ret = sendTargetsSelection(d, req->requestor, property); - } else { - ret = sendSelection(d, target, req->requestor, property); - } - - if (nmulti > 0) { - if (ret == XNone) { - multi[imulti].property = XNone; - multi_writeback = true; - } - } else { - event.xselection.property = ret; - break; - } - } - - if (nmulti > 0) { - if (multi_writeback) { - // according to ICCCM 2.6.2 says to put None back - // into the original property on the requestor window - XChangeProperty(screen()->display()->nativeDisplay(), req->requestor, req->property, multi_type, 32, - PropModeReplace, (uchar *) multi, nmulti * 2); - } - - delete [] multi; - event.xselection.property = req->property; - } - - // send selection notify to requestor - XSendEvent(screen()->display()->nativeDisplay(), req->requestor, False, NoEventMask, &event); -} - -static inline int maxSelectionIncr(Display *dpy) -{ return XMaxRequestSize(dpy) > 65536 ? 65536*4 : XMaxRequestSize(dpy)*4 - 100; } - -bool QXlibClipboard::clipboardReadProperty(Window win, Atom property, bool deleteProperty, QByteArray *buffer, int *size, Atom *type, int *format) const -{ - int maxsize = maxSelectionIncr(screen()->display()->nativeDisplay()); - ulong bytes_left; // bytes_after - ulong length; // nitems - uchar *data; - Atom dummy_type; - int dummy_format; - int r; - - if (!type) // allow null args - type = &dummy_type; - if (!format) - format = &dummy_format; - - // Don't read anything, just get the size of the property data - r = XGetWindowProperty(screen()->display()->nativeDisplay(), win, property, 0, 0, False, - AnyPropertyType, type, format, - &length, &bytes_left, &data); - if (r != Success || (type && *type == XNone)) { - buffer->resize(0); - return false; - } - XFree((char*)data); - - int offset = 0, buffer_offset = 0, format_inc = 1, proplen = bytes_left; - - switch (*format) { - case 8: - default: - format_inc = sizeof(char) / 1; - break; - - case 16: - format_inc = sizeof(short) / 2; - proplen *= sizeof(short) / 2; - break; - - case 32: - format_inc = sizeof(long) / 4; - proplen *= sizeof(long) / 4; - break; - } - - int newSize = proplen; - buffer->resize(newSize); - - bool ok = (buffer->size() == newSize); - - if (ok && newSize) { - // could allocate buffer - - while (bytes_left) { - // more to read... - - r = XGetWindowProperty(screen()->display()->nativeDisplay(), win, property, offset, maxsize/4, - False, AnyPropertyType, type, format, - &length, &bytes_left, &data); - if (r != Success || (type && *type == XNone)) - break; - - offset += length / (32 / *format); - length *= format_inc * (*format) / 8; - - // Here we check if we get a buffer overflow and tries to - // recover -- this shouldn't normally happen, but it doesn't - // hurt to be defensive - if ((int)(buffer_offset + length) > buffer->size()) { - length = buffer->size() - buffer_offset; - - // escape loop - bytes_left = 0; - } - - memcpy(buffer->data() + buffer_offset, data, length); - buffer_offset += length; - - XFree((char*)data); - } - - if (*format == 8 && *type == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) { - // convert COMPOUND_TEXT to a multibyte string - XTextProperty textprop; - textprop.encoding = *type; - textprop.format = *format; - textprop.nitems = buffer_offset; - textprop.value = (unsigned char *) buffer->data(); - - char **list_ret = 0; - int count; - if (XmbTextPropertyToTextList(screen()->display()->nativeDisplay(), &textprop, &list_ret, - &count) == Success && count && list_ret) { - offset = buffer_offset = strlen(list_ret[0]); - buffer->resize(offset); - memcpy(buffer->data(), list_ret[0], offset); - } - if (list_ret) XFreeStringList(list_ret); - } - } - - // correct size, not 0-term. - if (size) - *size = buffer_offset; - - if (deleteProperty) - XDeleteProperty(screen()->display()->nativeDisplay(), win, property); - - screen()->display()->flush(); - - return ok; -} - -QByteArray QXlibClipboard::clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm) -{ - XEvent event; - - QByteArray buf; - QByteArray tmp_buf; - bool alloc_error = false; - int length; - int offset = 0; - - if (nbytes > 0) { - // Reserve buffer + zero-terminator (for text data) - // We want to complete the INCR transfer even if we cannot - // allocate more memory - buf.resize(nbytes+1); - alloc_error = buf.size() != nbytes+1; - } - - for (;;) { - screen()->display()->flush(); - if (!screen()->waitForClipboardEvent(win,PropertyNotify,&event,clipboard_timeout)) - break; - if (event.xproperty.atom != property || - event.xproperty.state != PropertyNewValue) - continue; - if (clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0)) { - if (length == 0) { // no more data, we're done - if (nullterm) { - buf.resize(offset+1); - buf[offset] = '\0'; - } else { - buf.resize(offset); - } - return buf; - } else if (!alloc_error) { - if (offset+length > (int)buf.size()) { - buf.resize(offset+length+65535); - if (buf.size() != offset+length+65535) { - alloc_error = true; - length = buf.size() - offset; - } - } - memcpy(buf.data()+offset, tmp_buf.constData(), length); - tmp_buf.resize(0); - offset += length; - } - } else { - break; - } - } - - // timed out ... create a new requestor window, otherwise the requestor - // could consider next request to be still part of this timed out request - setRequestor(0); - - return QByteArray(); -} - -QByteArray QXlibClipboard::getDataInFormat(Atom modeAtom, Atom fmtatom) -{ - QByteArray buf; - - Window win = requestor(); - - XSelectInput(screen()->display()->nativeDisplay(), win, NoEventMask); // don't listen for any events - - XDeleteProperty(screen()->display()->nativeDisplay(), win, QXlibStatic::atom(QXlibStatic::_QT_SELECTION)); - XConvertSelection(screen()->display()->nativeDisplay(), modeAtom, fmtatom, QXlibStatic::atom(QXlibStatic::_QT_SELECTION), win, CurrentTime); - screen()->display()->sync(); - - XEvent xevent; - if (!screen()->waitForClipboardEvent(win,SelectionNotify,&xevent,clipboard_timeout) || - xevent.xselection.property == XNone) { - return buf; - } - - Atom type; - XSelectInput(screen()->display()->nativeDisplay(), win, PropertyChangeMask); - - if (clipboardReadProperty(win, QXlibStatic::atom(QXlibStatic::_QT_SELECTION), true, &buf, 0, &type, 0)) { - if (type == QXlibStatic::atom(QXlibStatic::INCR)) { - int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0; - buf = clipboardReadIncrementalProperty(win, QXlibStatic::atom(QXlibStatic::_QT_SELECTION), nbytes, false); - } - } - - XSelectInput(screen()->display()->nativeDisplay(), win, NoEventMask); - - - return buf; -} - -#include "qxlibclipboard.moc" diff --git a/src/plugins/platforms/xlib/qxlibclipboard.h b/src/plugins/platforms/xlib/qxlibclipboard.h deleted file mode 100644 index 43c12298ae6..00000000000 --- a/src/plugins/platforms/xlib/qxlibclipboard.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTESTLITECLIPBOARD_H -#define QTESTLITECLIPBOARD_H - -#include -#include "qxlibstatic.h" - -class QXlibScreen; -class QXlibClipboard : public QPlatformClipboard -{ -public: - QXlibClipboard(QXlibScreen *screen); - - QMimeData *mimeData(QClipboard::Mode mode); - void setMimeData(QMimeData *data, QClipboard::Mode mode); - - bool supportsMode(QClipboard::Mode mode) const; - - QXlibScreen *screen() const; - - Window requestor() const; - void setRequestor(Window window); - - Window owner() const; - - void handleSelectionRequest(XEvent *event); - - bool clipboardReadProperty(Window win, Atom property, bool deleteProperty, QByteArray *buffer, int *size, Atom *type, int *format) const; - QByteArray clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm); - - QByteArray getDataInFormat(Atom modeAtom, Atom fmtatom); - -private: - void setOwner(Window window); - - Atom sendTargetsSelection(QMimeData *d, Window window, Atom property); - Atom sendSelection(QMimeData *d, Atom target, Window window, Atom property); - - QXlibScreen *m_screen; - - QMimeData *m_xClipboard; - QMimeData *m_clientClipboard; - - QMimeData *m_xSelection; - QMimeData *m_clientSelection; - - Window m_requestor; - Window m_owner; - - static const int clipboard_timeout; - -}; - -#endif // QTESTLITECLIPBOARD_H diff --git a/src/plugins/platforms/xlib/qxlibcursor.cpp b/src/plugins/platforms/xlib/qxlibcursor.cpp deleted file mode 100644 index a714f823716..00000000000 --- a/src/plugins/platforms/xlib/qxlibcursor.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qxlibcursor.h" - -#include "qxlibintegration.h" -#include "qxlibscreen.h" -#include "qxlibwindow.h" -#include "qxlibdisplay.h" - -#include - -#include - -QT_BEGIN_NAMESPACE - -QXlibCursor::QXlibCursor(QXlibScreen *screen) : m_screen(screen) -{ -} - -void QXlibCursor::changeCursor(QCursor *cursor, QWindow *window) -{ - QXlibWindow *w = 0; - if (window) { - w = static_cast(window->handle()); - } else { - // No X11 cursor control when there is no widget under the cursor - return; - } - - if (!w) - return; - - int id = cursor->handle(); - - Cursor c; - if (!cursorMap.contains(id)) { - if (cursor->shape() == Qt::BitmapCursor) - c = createCursorBitmap(cursor); - else - c = createCursorShape(cursor->shape()); - if (!c) { - return; - } - cursorMap.insert(id, c); - } else { - c = cursorMap.value(id); - } - - w->setCursor(c); -} - -Cursor QXlibCursor::createCursorBitmap(QCursor * cursor) -{ - XColor bg, fg; - bg.red = 255 << 8; - bg.green = 255 << 8; - bg.blue = 255 << 8; - fg.red = 0; - fg.green = 0; - fg.blue = 0; - QPoint spot = cursor->hotSpot(); - Window rootwin = testLiteScreen()->rootWindow(); - - QImage mapImage = cursor->bitmap()->toImage().convertToFormat(QImage::Format_MonoLSB); - QImage maskImage = cursor->mask()->toImage().convertToFormat(QImage::Format_MonoLSB); - - int width = cursor->bitmap()->width(); - int height = cursor->bitmap()->height(); - int bytesPerLine = mapImage.bytesPerLine(); - int destLineSize = width / 8; - if (width % 8) - destLineSize++; - - const uchar * map = mapImage.bits(); - const uchar * mask = maskImage.bits(); - - char * mapBits = new char[height * destLineSize]; - char * maskBits = new char[height * destLineSize]; - for (int i = 0; i < height; i++) { - memcpy(mapBits + (destLineSize * i),map + (bytesPerLine * i), destLineSize); - memcpy(maskBits + (destLineSize * i),mask + (bytesPerLine * i), destLineSize); - } - - Pixmap cp = XCreateBitmapFromData(testLiteScreen()->display()->nativeDisplay(), rootwin, mapBits, width, height); - Pixmap mp = XCreateBitmapFromData(testLiteScreen()->display()->nativeDisplay(), rootwin, maskBits, width, height); - Cursor c = XCreatePixmapCursor(testLiteScreen()->display()->nativeDisplay(), cp, mp, &fg, &bg, spot.x(), spot.y()); - XFreePixmap(testLiteScreen()->display()->nativeDisplay(), cp); - XFreePixmap(testLiteScreen()->display()->nativeDisplay(), mp); - delete[] mapBits; - delete[] maskBits; - - return c; -} - -Cursor QXlibCursor::createCursorShape(int cshape) -{ - Cursor cursor = 0; - - if (cshape < 0 || cshape > Qt::LastCursor) - return 0; - - switch (cshape) { - case Qt::ArrowCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_left_ptr); - break; - case Qt::UpArrowCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_center_ptr); - break; - case Qt::CrossCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_crosshair); - break; - case Qt::WaitCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_watch); - break; - case Qt::IBeamCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_xterm); - break; - case Qt::SizeAllCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_fleur); - break; - case Qt::PointingHandCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_hand2); - break; - case Qt::SizeBDiagCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_top_right_corner); - break; - case Qt::SizeFDiagCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_bottom_right_corner); - break; - case Qt::SizeVerCursor: - case Qt::SplitVCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_sb_v_double_arrow); - break; - case Qt::SizeHorCursor: - case Qt::SplitHCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_sb_h_double_arrow); - break; - case Qt::WhatsThisCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_question_arrow); - break; - case Qt::ForbiddenCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_circle); - break; - case Qt::BusyCursor: - cursor = XCreateFontCursor(testLiteScreen()->display()->nativeDisplay(), XC_watch); - break; - - default: //default cursor for all the rest - break; - } - return cursor; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/xlib/qxlibintegration.cpp b/src/plugins/platforms/xlib/qxlibintegration.cpp deleted file mode 100644 index 65d4d231c8b..00000000000 --- a/src/plugins/platforms/xlib/qxlibintegration.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "qxlibintegration.h" -#include "qxlibbackingstore.h" -#include -#include -#include -#include - -#include "qxlibwindow.h" -#include -#include -#include "qxlibscreen.h" -#include "qxlibclipboard.h" -#include "qxlibdisplay.h" -#include "qxlibnativeinterface.h" -#include "qglxintegration.h" - -QT_BEGIN_NAMESPACE - -QXlibIntegration::QXlibIntegration() - : mFontDb(new QGenericUnixFontDatabase()) - , mClipboard(0) - , mNativeInterface(new QXlibNativeInterface) -{ - mEventDispatcher = createUnixEventDispatcher(); - QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); - - XInitThreads(); - - mPrimaryScreen = new QXlibScreen(mNativeInterface); - mScreens.append(mPrimaryScreen); - screenAdded(mPrimaryScreen); -} - -bool QXlibIntegration::hasCapability(QPlatformIntegration::Capability) const -{ - return true; -} - -QPlatformBackingStore *QXlibIntegration::createPlatformBackingStore(QWindow *window) const -{ - return new QXlibBackingStore(window); -} - -QPlatformOpenGLContext *QXlibIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const -{ - QXlibScreen *screen = static_cast(context->screen()->handle()); - - return new QGLXContext(screen, context->format(), context->shareHandle()); -} - - -QPlatformWindow *QXlibIntegration::createPlatformWindow(QWindow *window) const -{ - return new QXlibWindow(window); -} - -QAbstractEventDispatcher *QXlibIntegration::guiThreadEventDispatcher() const -{ - return mEventDispatcher; -} - -QPlatformFontDatabase *QXlibIntegration::fontDatabase() const -{ - return mFontDb; -} - -QPlatformClipboard * QXlibIntegration::clipboard() const -{ - //Use lazy init since clipboard needs QTestliteScreen - if (!mClipboard) { - QXlibIntegration *that = const_cast(this); - that->mClipboard = new QXlibClipboard(mPrimaryScreen); - } - return mClipboard; -} - -QPlatformNativeInterface * QXlibIntegration::nativeInterface() const -{ - return mNativeInterface; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/xlib/qxlibintegration.h b/src/plugins/platforms/xlib/qxlibintegration.h deleted file mode 100644 index 76c3f13ff65..00000000000 --- a/src/plugins/platforms/xlib/qxlibintegration.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSYSTEM_TESTLITE_H -#define QGRAPHICSSYSTEM_TESTLITE_H - -//make sure textstream is included before any X11 headers -#include - -#include -#include -#include - -#include "qxlibstatic.h" - -QT_BEGIN_NAMESPACE - -class QXlibScreen; -class QXlibNativeInterface; - -class QXlibIntegration : public QPlatformIntegration -{ -public: - QXlibIntegration(); - - bool hasCapability(Capability cap) const; - - QPlatformWindow *createPlatformWindow(QWindow *window) const; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; - - QAbstractEventDispatcher *guiThreadEventDispatcher() const; - - QPixmap grabWindow(WId window, int x, int y, int width, int height) const; - - QList screens() const { return mScreens; } - - QPlatformFontDatabase *fontDatabase() const; - QPlatformClipboard *clipboard() const; - - QPlatformNativeInterface *nativeInterface() const; - -private: - QXlibScreen *mPrimaryScreen; - QList mScreens; - QPlatformFontDatabase *mFontDb; - QPlatformClipboard *mClipboard; - QXlibNativeInterface *mNativeInterface; - QAbstractEventDispatcher *mEventDispatcher; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.cpp b/src/plugins/platforms/xlib/qxlibkeyboard.cpp deleted file mode 100644 index 1ebf22b7baa..00000000000 --- a/src/plugins/platforms/xlib/qxlibkeyboard.cpp +++ /dev/null @@ -1,975 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qxlibkeyboard.h" - -#include "qxlibscreen.h" -#include "qxlibdisplay.h" - -#include - -#include - -#if defined(QT_LINUXBASE) -# include -#endif - -#ifndef XK_ISO_Left_Tab -#define XK_ISO_Left_Tab 0xFE20 -#endif - -#ifndef XK_dead_hook -#define XK_dead_hook 0xFE61 -#endif - -#ifndef XK_dead_horn -#define XK_dead_horn 0xFE62 -#endif - -#ifndef XK_Codeinput -#define XK_Codeinput 0xFF37 -#endif - -#ifndef XK_Kanji_Bangou -#define XK_Kanji_Bangou 0xFF37 /* same as codeinput */ -#endif - -// Fix old X libraries -#ifndef XK_KP_Home -#define XK_KP_Home 0xFF95 -#endif -#ifndef XK_KP_Left -#define XK_KP_Left 0xFF96 -#endif -#ifndef XK_KP_Up -#define XK_KP_Up 0xFF97 -#endif -#ifndef XK_KP_Right -#define XK_KP_Right 0xFF98 -#endif -#ifndef XK_KP_Down -#define XK_KP_Down 0xFF99 -#endif -#ifndef XK_KP_Prior -#define XK_KP_Prior 0xFF9A -#endif -#ifndef XK_KP_Next -#define XK_KP_Next 0xFF9B -#endif -#ifndef XK_KP_End -#define XK_KP_End 0xFF9C -#endif -#ifndef XK_KP_Insert -#define XK_KP_Insert 0xFF9E -#endif -#ifndef XK_KP_Delete -#define XK_KP_Delete 0xFF9F -#endif - -// the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special -// multimedia keys. They are included here as not every system has them. -#define XF86XK_MonBrightnessUp 0x1008FF02 -#define XF86XK_MonBrightnessDown 0x1008FF03 -#define XF86XK_KbdLightOnOff 0x1008FF04 -#define XF86XK_KbdBrightnessUp 0x1008FF05 -#define XF86XK_KbdBrightnessDown 0x1008FF06 -#define XF86XK_Standby 0x1008FF10 -#define XF86XK_AudioLowerVolume 0x1008FF11 -#define XF86XK_AudioMute 0x1008FF12 -#define XF86XK_AudioRaiseVolume 0x1008FF13 -#define XF86XK_AudioPlay 0x1008FF14 -#define XF86XK_AudioStop 0x1008FF15 -#define XF86XK_AudioPrev 0x1008FF16 -#define XF86XK_AudioNext 0x1008FF17 -#define XF86XK_HomePage 0x1008FF18 -#define XF86XK_Mail 0x1008FF19 -#define XF86XK_Start 0x1008FF1A -#define XF86XK_Search 0x1008FF1B -#define XF86XK_AudioRecord 0x1008FF1C -#define XF86XK_Calculator 0x1008FF1D -#define XF86XK_Memo 0x1008FF1E -#define XF86XK_ToDoList 0x1008FF1F -#define XF86XK_Calendar 0x1008FF20 -#define XF86XK_PowerDown 0x1008FF21 -#define XF86XK_ContrastAdjust 0x1008FF22 -#define XF86XK_Back 0x1008FF26 -#define XF86XK_Forward 0x1008FF27 -#define XF86XK_Stop 0x1008FF28 -#define XF86XK_Refresh 0x1008FF29 -#define XF86XK_PowerOff 0x1008FF2A -#define XF86XK_WakeUp 0x1008FF2B -#define XF86XK_Eject 0x1008FF2C -#define XF86XK_ScreenSaver 0x1008FF2D -#define XF86XK_WWW 0x1008FF2E -#define XF86XK_Sleep 0x1008FF2F -#define XF86XK_Favorites 0x1008FF30 -#define XF86XK_AudioPause 0x1008FF31 -#define XF86XK_AudioMedia 0x1008FF32 -#define XF86XK_MyComputer 0x1008FF33 -#define XF86XK_LightBulb 0x1008FF35 -#define XF86XK_Shop 0x1008FF36 -#define XF86XK_History 0x1008FF37 -#define XF86XK_OpenURL 0x1008FF38 -#define XF86XK_AddFavorite 0x1008FF39 -#define XF86XK_HotLinks 0x1008FF3A -#define XF86XK_BrightnessAdjust 0x1008FF3B -#define XF86XK_Finance 0x1008FF3C -#define XF86XK_Community 0x1008FF3D -#define XF86XK_AudioRewind 0x1008FF3E -#define XF86XK_BackForward 0x1008FF3F -#define XF86XK_Launch0 0x1008FF40 -#define XF86XK_Launch1 0x1008FF41 -#define XF86XK_Launch2 0x1008FF42 -#define XF86XK_Launch3 0x1008FF43 -#define XF86XK_Launch4 0x1008FF44 -#define XF86XK_Launch5 0x1008FF45 -#define XF86XK_Launch6 0x1008FF46 -#define XF86XK_Launch7 0x1008FF47 -#define XF86XK_Launch8 0x1008FF48 -#define XF86XK_Launch9 0x1008FF49 -#define XF86XK_LaunchA 0x1008FF4A -#define XF86XK_LaunchB 0x1008FF4B -#define XF86XK_LaunchC 0x1008FF4C -#define XF86XK_LaunchD 0x1008FF4D -#define XF86XK_LaunchE 0x1008FF4E -#define XF86XK_LaunchF 0x1008FF4F -#define XF86XK_ApplicationLeft 0x1008FF50 -#define XF86XK_ApplicationRight 0x1008FF51 -#define XF86XK_Book 0x1008FF52 -#define XF86XK_CD 0x1008FF53 -#define XF86XK_Calculater 0x1008FF54 -#define XF86XK_Clear 0x1008FF55 -#define XF86XK_ClearGrab 0x1008FE21 -#define XF86XK_Close 0x1008FF56 -#define XF86XK_Copy 0x1008FF57 -#define XF86XK_Cut 0x1008FF58 -#define XF86XK_Display 0x1008FF59 -#define XF86XK_DOS 0x1008FF5A -#define XF86XK_Documents 0x1008FF5B -#define XF86XK_Excel 0x1008FF5C -#define XF86XK_Explorer 0x1008FF5D -#define XF86XK_Game 0x1008FF5E -#define XF86XK_Go 0x1008FF5F -#define XF86XK_iTouch 0x1008FF60 -#define XF86XK_LogOff 0x1008FF61 -#define XF86XK_Market 0x1008FF62 -#define XF86XK_Meeting 0x1008FF63 -#define XF86XK_MenuKB 0x1008FF65 -#define XF86XK_MenuPB 0x1008FF66 -#define XF86XK_MySites 0x1008FF67 -#define XF86XK_News 0x1008FF69 -#define XF86XK_OfficeHome 0x1008FF6A -#define XF86XK_Option 0x1008FF6C -#define XF86XK_Paste 0x1008FF6D -#define XF86XK_Phone 0x1008FF6E -#define XF86XK_Reply 0x1008FF72 -#define XF86XK_Reload 0x1008FF73 -#define XF86XK_RotateWindows 0x1008FF74 -#define XF86XK_RotationPB 0x1008FF75 -#define XF86XK_RotationKB 0x1008FF76 -#define XF86XK_Save 0x1008FF77 -#define XF86XK_Send 0x1008FF7B -#define XF86XK_Spell 0x1008FF7C -#define XF86XK_SplitScreen 0x1008FF7D -#define XF86XK_Support 0x1008FF7E -#define XF86XK_TaskPane 0x1008FF7F -#define XF86XK_Terminal 0x1008FF80 -#define XF86XK_Tools 0x1008FF81 -#define XF86XK_Travel 0x1008FF82 -#define XF86XK_Video 0x1008FF87 -#define XF86XK_Word 0x1008FF89 -#define XF86XK_Xfer 0x1008FF8A -#define XF86XK_ZoomIn 0x1008FF8B -#define XF86XK_ZoomOut 0x1008FF8C -#define XF86XK_Away 0x1008FF8D -#define XF86XK_Messenger 0x1008FF8E -#define XF86XK_WebCam 0x1008FF8F -#define XF86XK_MailForward 0x1008FF90 -#define XF86XK_Pictures 0x1008FF91 -#define XF86XK_Music 0x1008FF92 -#define XF86XK_Battery 0x1008FF93 -#define XF86XK_Bluetooth 0x1008FF94 -#define XF86XK_WLAN 0x1008FF95 -#define XF86XK_UWB 0x1008FF96 -#define XF86XK_AudioForward 0x1008FF97 -#define XF86XK_AudioRepeat 0x1008FF98 -#define XF86XK_AudioRandomPlay 0x1008FF99 -#define XF86XK_Subtitle 0x1008FF9A -#define XF86XK_AudioCycleTrack 0x1008FF9B -#define XF86XK_Time 0x1008FF9F -#define XF86XK_Select 0x1008FFA0 -#define XF86XK_View 0x1008FFA1 -#define XF86XK_TopMenu 0x1008FFA2 -#define XF86XK_Suspend 0x1008FFA7 -#define XF86XK_Hibernate 0x1008FFA8 -#define XF86XK_TouchpadToggle 0x1008FFA9 -#define XF86XK_TouchpadOn 0x1008FFB0 -#define XF86XK_TouchpadOff 0x1008FFB1 - - -// end of XF86keysyms.h - -// keyboard mapping table -static const unsigned int KeyTbl[] = { - - // misc keys - - XK_Escape, Qt::Key_Escape, - XK_Tab, Qt::Key_Tab, - XK_ISO_Left_Tab, Qt::Key_Backtab, - XK_BackSpace, Qt::Key_Backspace, - XK_Return, Qt::Key_Return, - XK_Insert, Qt::Key_Insert, - XK_Delete, Qt::Key_Delete, - XK_Clear, Qt::Key_Delete, - XK_Pause, Qt::Key_Pause, - XK_Print, Qt::Key_Print, - 0x1005FF60, Qt::Key_SysReq, // hardcoded Sun SysReq - 0x1007ff00, Qt::Key_SysReq, // hardcoded X386 SysReq - - // cursor movement - - XK_Home, Qt::Key_Home, - XK_End, Qt::Key_End, - XK_Left, Qt::Key_Left, - XK_Up, Qt::Key_Up, - XK_Right, Qt::Key_Right, - XK_Down, Qt::Key_Down, - XK_Prior, Qt::Key_PageUp, - XK_Next, Qt::Key_PageDown, - - // modifiers - - XK_Shift_L, Qt::Key_Shift, - XK_Shift_R, Qt::Key_Shift, - XK_Shift_Lock, Qt::Key_Shift, - XK_Control_L, Qt::Key_Control, - XK_Control_R, Qt::Key_Control, - XK_Meta_L, Qt::Key_Meta, - XK_Meta_R, Qt::Key_Meta, - XK_Alt_L, Qt::Key_Alt, - XK_Alt_R, Qt::Key_Alt, - XK_Caps_Lock, Qt::Key_CapsLock, - XK_Num_Lock, Qt::Key_NumLock, - XK_Scroll_Lock, Qt::Key_ScrollLock, - XK_Super_L, Qt::Key_Super_L, - XK_Super_R, Qt::Key_Super_R, - XK_Menu, Qt::Key_Menu, - XK_Hyper_L, Qt::Key_Hyper_L, - XK_Hyper_R, Qt::Key_Hyper_R, - XK_Help, Qt::Key_Help, - 0x1000FF74, Qt::Key_Backtab, // hardcoded HP backtab - 0x1005FF10, Qt::Key_F11, // hardcoded Sun F36 (labeled F11) - 0x1005FF11, Qt::Key_F12, // hardcoded Sun F37 (labeled F12) - - // numeric and function keypad keys - - XK_KP_Space, Qt::Key_Space, - XK_KP_Tab, Qt::Key_Tab, - XK_KP_Enter, Qt::Key_Enter, - //XK_KP_F1, Qt::Key_F1, - //XK_KP_F2, Qt::Key_F2, - //XK_KP_F3, Qt::Key_F3, - //XK_KP_F4, Qt::Key_F4, - XK_KP_Home, Qt::Key_Home, - XK_KP_Left, Qt::Key_Left, - XK_KP_Up, Qt::Key_Up, - XK_KP_Right, Qt::Key_Right, - XK_KP_Down, Qt::Key_Down, - XK_KP_Prior, Qt::Key_PageUp, - XK_KP_Next, Qt::Key_PageDown, - XK_KP_End, Qt::Key_End, - XK_KP_Begin, Qt::Key_Clear, - XK_KP_Insert, Qt::Key_Insert, - XK_KP_Delete, Qt::Key_Delete, - XK_KP_Equal, Qt::Key_Equal, - XK_KP_Multiply, Qt::Key_Asterisk, - XK_KP_Add, Qt::Key_Plus, - XK_KP_Separator, Qt::Key_Comma, - XK_KP_Subtract, Qt::Key_Minus, - XK_KP_Decimal, Qt::Key_Period, - XK_KP_Divide, Qt::Key_Slash, - - // International input method support keys - - // International & multi-key character composition - XK_ISO_Level3_Shift, Qt::Key_AltGr, - XK_Multi_key, Qt::Key_Multi_key, - XK_Codeinput, Qt::Key_Codeinput, - XK_SingleCandidate, Qt::Key_SingleCandidate, - XK_MultipleCandidate, Qt::Key_MultipleCandidate, - XK_PreviousCandidate, Qt::Key_PreviousCandidate, - - // Misc Functions - XK_Mode_switch, Qt::Key_Mode_switch, - XK_script_switch, Qt::Key_Mode_switch, - - // Japanese keyboard support - XK_Kanji, Qt::Key_Kanji, - XK_Muhenkan, Qt::Key_Muhenkan, - //XK_Henkan_Mode, Qt::Key_Henkan_Mode, - XK_Henkan_Mode, Qt::Key_Henkan, - XK_Henkan, Qt::Key_Henkan, - XK_Romaji, Qt::Key_Romaji, - XK_Hiragana, Qt::Key_Hiragana, - XK_Katakana, Qt::Key_Katakana, - XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana, - XK_Zenkaku, Qt::Key_Zenkaku, - XK_Hankaku, Qt::Key_Hankaku, - XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku, - XK_Touroku, Qt::Key_Touroku, - XK_Massyo, Qt::Key_Massyo, - XK_Kana_Lock, Qt::Key_Kana_Lock, - XK_Kana_Shift, Qt::Key_Kana_Shift, - XK_Eisu_Shift, Qt::Key_Eisu_Shift, - XK_Eisu_toggle, Qt::Key_Eisu_toggle, - //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou, - //XK_Zen_Koho, Qt::Key_Zen_Koho, - //XK_Mae_Koho, Qt::Key_Mae_Koho, - XK_Kanji_Bangou, Qt::Key_Codeinput, - XK_Zen_Koho, Qt::Key_MultipleCandidate, - XK_Mae_Koho, Qt::Key_PreviousCandidate, - -#ifdef XK_KOREAN - // Korean keyboard support - XK_Hangul, Qt::Key_Hangul, - XK_Hangul_Start, Qt::Key_Hangul_Start, - XK_Hangul_End, Qt::Key_Hangul_End, - XK_Hangul_Hanja, Qt::Key_Hangul_Hanja, - XK_Hangul_Jamo, Qt::Key_Hangul_Jamo, - XK_Hangul_Romaja, Qt::Key_Hangul_Romaja, - //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput, - XK_Hangul_Codeinput, Qt::Key_Codeinput, - XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja, - XK_Hangul_Banja, Qt::Key_Hangul_Banja, - XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja, - XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja, - //XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate, - //XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate, - //XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate, - XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate, - XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate, - XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate, - XK_Hangul_Special, Qt::Key_Hangul_Special, - //XK_Hangul_switch, Qt::Key_Hangul_switch, - XK_Hangul_switch, Qt::Key_Mode_switch, -#endif // XK_KOREAN - - // dead keys - XK_dead_grave, Qt::Key_Dead_Grave, - XK_dead_acute, Qt::Key_Dead_Acute, - XK_dead_circumflex, Qt::Key_Dead_Circumflex, - XK_dead_tilde, Qt::Key_Dead_Tilde, - XK_dead_macron, Qt::Key_Dead_Macron, - XK_dead_breve, Qt::Key_Dead_Breve, - XK_dead_abovedot, Qt::Key_Dead_Abovedot, - XK_dead_diaeresis, Qt::Key_Dead_Diaeresis, - XK_dead_abovering, Qt::Key_Dead_Abovering, - XK_dead_doubleacute, Qt::Key_Dead_Doubleacute, - XK_dead_caron, Qt::Key_Dead_Caron, - XK_dead_cedilla, Qt::Key_Dead_Cedilla, - XK_dead_ogonek, Qt::Key_Dead_Ogonek, - XK_dead_iota, Qt::Key_Dead_Iota, - XK_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound, - XK_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound, - XK_dead_belowdot, Qt::Key_Dead_Belowdot, - XK_dead_hook, Qt::Key_Dead_Hook, - XK_dead_horn, Qt::Key_Dead_Horn, - - // Special keys from X.org - This include multimedia keys, - // wireless/bluetooth/uwb keys, special launcher keys, etc. - XF86XK_Back, Qt::Key_Back, - XF86XK_Forward, Qt::Key_Forward, - XF86XK_Stop, Qt::Key_Stop, - XF86XK_Refresh, Qt::Key_Refresh, - XF86XK_Favorites, Qt::Key_Favorites, - XF86XK_AudioMedia, Qt::Key_LaunchMedia, - XF86XK_OpenURL, Qt::Key_OpenUrl, - XF86XK_HomePage, Qt::Key_HomePage, - XF86XK_Search, Qt::Key_Search, - XF86XK_AudioLowerVolume, Qt::Key_VolumeDown, - XF86XK_AudioMute, Qt::Key_VolumeMute, - XF86XK_AudioRaiseVolume, Qt::Key_VolumeUp, - XF86XK_AudioPlay, Qt::Key_MediaPlay, - XF86XK_AudioStop, Qt::Key_MediaStop, - XF86XK_AudioPrev, Qt::Key_MediaPrevious, - XF86XK_AudioNext, Qt::Key_MediaNext, - XF86XK_AudioRecord, Qt::Key_MediaRecord, - XF86XK_Mail, Qt::Key_LaunchMail, - XF86XK_MyComputer, Qt::Key_Launch0, // ### Qt 5: remap properly - XF86XK_Calculator, Qt::Key_Launch1, - XF86XK_Memo, Qt::Key_Memo, - XF86XK_ToDoList, Qt::Key_ToDoList, - XF86XK_Calendar, Qt::Key_Calendar, - XF86XK_PowerDown, Qt::Key_PowerDown, - XF86XK_ContrastAdjust, Qt::Key_ContrastAdjust, - XF86XK_Standby, Qt::Key_Standby, - XF86XK_MonBrightnessUp, Qt::Key_MonBrightnessUp, - XF86XK_MonBrightnessDown, Qt::Key_MonBrightnessDown, - XF86XK_KbdLightOnOff, Qt::Key_KeyboardLightOnOff, - XF86XK_KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp, - XF86XK_KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown, - XF86XK_PowerOff, Qt::Key_PowerOff, - XF86XK_WakeUp, Qt::Key_WakeUp, - XF86XK_Eject, Qt::Key_Eject, - XF86XK_ScreenSaver, Qt::Key_ScreenSaver, - XF86XK_WWW, Qt::Key_WWW, - XF86XK_Sleep, Qt::Key_Sleep, - XF86XK_LightBulb, Qt::Key_LightBulb, - XF86XK_Shop, Qt::Key_Shop, - XF86XK_History, Qt::Key_History, - XF86XK_AddFavorite, Qt::Key_AddFavorite, - XF86XK_HotLinks, Qt::Key_HotLinks, - XF86XK_BrightnessAdjust, Qt::Key_BrightnessAdjust, - XF86XK_Finance, Qt::Key_Finance, - XF86XK_Community, Qt::Key_Community, - XF86XK_AudioRewind, Qt::Key_AudioRewind, - XF86XK_BackForward, Qt::Key_BackForward, - XF86XK_ApplicationLeft, Qt::Key_ApplicationLeft, - XF86XK_ApplicationRight, Qt::Key_ApplicationRight, - XF86XK_Book, Qt::Key_Book, - XF86XK_CD, Qt::Key_CD, - XF86XK_Calculater, Qt::Key_Calculator, - XF86XK_Clear, Qt::Key_Clear, - XF86XK_ClearGrab, Qt::Key_ClearGrab, - XF86XK_Close, Qt::Key_Close, - XF86XK_Copy, Qt::Key_Copy, - XF86XK_Cut, Qt::Key_Cut, - XF86XK_Display, Qt::Key_Display, - XF86XK_DOS, Qt::Key_DOS, - XF86XK_Documents, Qt::Key_Documents, - XF86XK_Excel, Qt::Key_Excel, - XF86XK_Explorer, Qt::Key_Explorer, - XF86XK_Game, Qt::Key_Game, - XF86XK_Go, Qt::Key_Go, - XF86XK_iTouch, Qt::Key_iTouch, - XF86XK_LogOff, Qt::Key_LogOff, - XF86XK_Market, Qt::Key_Market, - XF86XK_Meeting, Qt::Key_Meeting, - XF86XK_MenuKB, Qt::Key_MenuKB, - XF86XK_MenuPB, Qt::Key_MenuPB, - XF86XK_MySites, Qt::Key_MySites, - XF86XK_News, Qt::Key_News, - XF86XK_OfficeHome, Qt::Key_OfficeHome, - XF86XK_Option, Qt::Key_Option, - XF86XK_Paste, Qt::Key_Paste, - XF86XK_Phone, Qt::Key_Phone, - XF86XK_Reply, Qt::Key_Reply, - XF86XK_Reload, Qt::Key_Reload, - XF86XK_RotateWindows, Qt::Key_RotateWindows, - XF86XK_RotationPB, Qt::Key_RotationPB, - XF86XK_RotationKB, Qt::Key_RotationKB, - XF86XK_Save, Qt::Key_Save, - XF86XK_Send, Qt::Key_Send, - XF86XK_Spell, Qt::Key_Spell, - XF86XK_SplitScreen, Qt::Key_SplitScreen, - XF86XK_Support, Qt::Key_Support, - XF86XK_TaskPane, Qt::Key_TaskPane, - XF86XK_Terminal, Qt::Key_Terminal, - XF86XK_Tools, Qt::Key_Tools, - XF86XK_Travel, Qt::Key_Travel, - XF86XK_Video, Qt::Key_Video, - XF86XK_Word, Qt::Key_Word, - XF86XK_Xfer, Qt::Key_Xfer, - XF86XK_ZoomIn, Qt::Key_ZoomIn, - XF86XK_ZoomOut, Qt::Key_ZoomOut, - XF86XK_Away, Qt::Key_Away, - XF86XK_Messenger, Qt::Key_Messenger, - XF86XK_WebCam, Qt::Key_WebCam, - XF86XK_MailForward, Qt::Key_MailForward, - XF86XK_Pictures, Qt::Key_Pictures, - XF86XK_Music, Qt::Key_Music, - XF86XK_Battery, Qt::Key_Battery, - XF86XK_Bluetooth, Qt::Key_Bluetooth, - XF86XK_WLAN, Qt::Key_WLAN, - XF86XK_UWB, Qt::Key_UWB, - XF86XK_AudioForward, Qt::Key_AudioForward, - XF86XK_AudioRepeat, Qt::Key_AudioRepeat, - XF86XK_AudioRandomPlay, Qt::Key_AudioRandomPlay, - XF86XK_Subtitle, Qt::Key_Subtitle, - XF86XK_AudioCycleTrack, Qt::Key_AudioCycleTrack, - XF86XK_Time, Qt::Key_Time, - XF86XK_Select, Qt::Key_Select, - XF86XK_View, Qt::Key_View, - XF86XK_TopMenu, Qt::Key_TopMenu, - XF86XK_Bluetooth, Qt::Key_Bluetooth, - XF86XK_Suspend, Qt::Key_Suspend, - XF86XK_Hibernate, Qt::Key_Hibernate, - XF86XK_TouchpadToggle, Qt::Key_TouchpadToggle, - XF86XK_TouchpadOn, Qt::Key_TouchpadOn, - XF86XK_TouchpadOff, Qt::Key_TouchpadOff, - XF86XK_Launch0, Qt::Key_Launch2, // ### Qt 5: remap properly - XF86XK_Launch1, Qt::Key_Launch3, - XF86XK_Launch2, Qt::Key_Launch4, - XF86XK_Launch3, Qt::Key_Launch5, - XF86XK_Launch4, Qt::Key_Launch6, - XF86XK_Launch5, Qt::Key_Launch7, - XF86XK_Launch6, Qt::Key_Launch8, - XF86XK_Launch7, Qt::Key_Launch9, - XF86XK_Launch8, Qt::Key_LaunchA, - XF86XK_Launch9, Qt::Key_LaunchB, - XF86XK_LaunchA, Qt::Key_LaunchC, - XF86XK_LaunchB, Qt::Key_LaunchD, - XF86XK_LaunchC, Qt::Key_LaunchE, - XF86XK_LaunchD, Qt::Key_LaunchF, - XF86XK_LaunchE, Qt::Key_LaunchG, - XF86XK_LaunchF, Qt::Key_LaunchH, - - 0, 0 -}; - -static const unsigned short katakanaKeysymsToUnicode[] = { - 0x0000, 0x3002, 0x300C, 0x300D, 0x3001, 0x30FB, 0x30F2, 0x30A1, - 0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3, - 0x30FC, 0x30A2, 0x30A4, 0x30A6, 0x30A8, 0x30AA, 0x30AB, 0x30AD, - 0x30AF, 0x30B1, 0x30B3, 0x30B5, 0x30B7, 0x30B9, 0x30BB, 0x30BD, - 0x30BF, 0x30C1, 0x30C4, 0x30C6, 0x30C8, 0x30CA, 0x30CB, 0x30CC, - 0x30CD, 0x30CE, 0x30CF, 0x30D2, 0x30D5, 0x30D8, 0x30DB, 0x30DE, - 0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E4, 0x30E6, 0x30E8, 0x30E9, - 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EF, 0x30F3, 0x309B, 0x309C -}; - -static const unsigned short cyrillicKeysymsToUnicode[] = { - 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, - 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0000, 0x045e, 0x045f, - 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, - 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0000, 0x040e, 0x040f, - 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, - 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, - 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, - 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, - 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, - 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, - 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, - 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a -}; - -static const unsigned short greekKeysymsToUnicode[] = { - 0x0000, 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, - 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, - 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, - 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, - 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7, - 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, - 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, - 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, - 0x03c8, 0x03c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static const unsigned short technicalKeysymsToUnicode[] = { - 0x0000, 0x23B7, 0x250C, 0x2500, 0x2320, 0x2321, 0x2502, 0x23A1, - 0x23A3, 0x23A4, 0x23A6, 0x239B, 0x239D, 0x239E, 0x23A0, 0x23A8, - 0x23AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222B, - 0x2234, 0x221D, 0x221E, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, - 0x223C, 0x2243, 0x0000, 0x0000, 0x0000, 0x21D4, 0x21D2, 0x2261, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221A, 0x0000, - 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222A, 0x2227, 0x2228, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, - 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193, 0x0000 -}; - -static const unsigned short specialKeysymsToUnicode[] = { - 0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x0000, 0x0000, - 0x2424, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA, - 0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C, - 0x2502, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static const unsigned short publishingKeysymsToUnicode[] = { - 0x0000, 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, - 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, - 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, - 0x2105, 0x0000, 0x0000, 0x2012, 0x2329, 0x0000, 0x232a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, - 0x0000, 0x2122, 0x2613, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25af, - 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033, - 0x0000, 0x271d, 0x0000, 0x25ac, 0x25c0, 0x25b6, 0x25cf, 0x25ae, - 0x25e6, 0x25ab, 0x25ad, 0x25b3, 0x25bd, 0x2606, 0x2022, 0x25aa, - 0x25b2, 0x25bc, 0x261c, 0x261e, 0x2663, 0x2666, 0x2665, 0x0000, - 0x2720, 0x2020, 0x2021, 0x2713, 0x2717, 0x266f, 0x266d, 0x2642, - 0x2640, 0x260e, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e, 0x0000 -}; - -static const unsigned short aplKeysymsToUnicode[] = { - 0x0000, 0x0000, 0x0000, 0x003c, 0x0000, 0x0000, 0x003e, 0x0000, - 0x2228, 0x2227, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x00af, 0x0000, 0x22a5, 0x2229, 0x230a, 0x0000, 0x005f, 0x0000, - 0x0000, 0x0000, 0x2218, 0x0000, 0x2395, 0x0000, 0x22a4, 0x25cb, - 0x0000, 0x0000, 0x0000, 0x2308, 0x0000, 0x0000, 0x222a, 0x0000, - 0x2283, 0x0000, 0x2282, 0x0000, 0x22a2, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x22a3, 0x0000, 0x0000, 0x0000 -}; - -static const unsigned short koreanKeysymsToUnicode[] = { - 0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, - 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, - 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147, - 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, - 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, - 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, - 0x3160, 0x3161, 0x3162, 0x3163, 0x11a8, 0x11a9, 0x11aa, 0x11ab, - 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, - 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, - 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x316d, - 0x3171, 0x3178, 0x317f, 0x3181, 0x3184, 0x3186, 0x318d, 0x318e, - 0x11eb, 0x11f0, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9 -}; - -static QChar keysymToUnicode(unsigned char byte3, unsigned char byte4) -{ - switch (byte3) { - case 0x04: - // katakana - if (byte4 > 0xa0 && byte4 < 0xe0) - return QChar(katakanaKeysymsToUnicode[byte4 - 0xa0]); - else if (byte4 == 0x7e) - return QChar(0x203e); // Overline - break; - case 0x06: - // russian, use lookup table - if (byte4 > 0xa0) - return QChar(cyrillicKeysymsToUnicode[byte4 - 0xa0]); - break; - case 0x07: - // greek - if (byte4 > 0xa0) - return QChar(greekKeysymsToUnicode[byte4 - 0xa0]); - break; - case 0x08: - // technical - if (byte4 > 0xa0) - return QChar(technicalKeysymsToUnicode[byte4 - 0xa0]); - break; - case 0x09: - // special - if (byte4 >= 0xe0) - return QChar(specialKeysymsToUnicode[byte4 - 0xe0]); - break; - case 0x0a: - // publishing - if (byte4 > 0xa0) - return QChar(publishingKeysymsToUnicode[byte4 - 0xa0]); - break; - case 0x0b: - // APL - if (byte4 > 0xa0) - return QChar(aplKeysymsToUnicode[byte4 - 0xa0]); - break; - case 0x0e: - // Korean - if (byte4 > 0xa0) - return QChar(koreanKeysymsToUnicode[byte4 - 0xa0]); - break; - default: - break; - } - return QChar(0x0); -} - -Qt::KeyboardModifiers QXlibKeyboard::translateModifiers(int s) -{ - Qt::KeyboardModifiers ret = 0; - if (s & ShiftMask) - ret |= Qt::ShiftModifier; - if (s & ControlMask) - ret |= Qt::ControlModifier; - if (s & m_alt_mask) - ret |= Qt::AltModifier; - if (s & m_meta_mask) - ret |= Qt::MetaModifier; -// if (s & m_mode_switch_mask) //doesn't seem to work correctly -// ret |= Qt::GroupSwitchModifier; - return ret; -} - -void QXlibKeyboard::setMask(KeySym sym, uint mask) -{ - if (m_alt_mask == 0 - && m_meta_mask != mask - && m_super_mask != mask - && m_hyper_mask != mask - && (sym == XK_Alt_L || sym == XK_Alt_R)) { - m_alt_mask = mask; - } - if (m_meta_mask == 0 - && m_alt_mask != mask - && m_super_mask != mask - && m_hyper_mask != mask - && (sym == XK_Meta_L || sym == XK_Meta_R)) { - m_meta_mask = mask; - } - if (m_super_mask == 0 - && m_alt_mask != mask - && m_meta_mask != mask - && m_hyper_mask != mask - && (sym == XK_Super_L || sym == XK_Super_R)) { - m_super_mask = mask; - } - if (m_hyper_mask == 0 - && m_alt_mask != mask - && m_meta_mask != mask - && m_super_mask != mask - && (sym == XK_Hyper_L || sym == XK_Hyper_R)) { - m_hyper_mask = mask; - } - if (m_mode_switch_mask == 0 - && m_alt_mask != mask - && m_meta_mask != mask - && m_super_mask != mask - && m_hyper_mask != mask - && sym == XK_Mode_switch) { - m_mode_switch_mask = mask; - } - if (m_num_lock_mask == 0 - && sym == XK_Num_Lock) { - m_num_lock_mask = mask; - } -} - -int QXlibKeyboard::translateKeySym(uint key) const -{ - int code = -1; - int i = 0; // any other keys - while (KeyTbl[i]) { - if (key == KeyTbl[i]) { - code = (int)KeyTbl[i+1]; - break; - } - i += 2; - } - if (m_meta_mask) { - // translate Super/Hyper keys to Meta if we're using them as the MetaModifier - if (m_meta_mask == m_super_mask && (code == Qt::Key_Super_L || code == Qt::Key_Super_R)) { - code = Qt::Key_Meta; - } else if (m_meta_mask == m_hyper_mask && (code == Qt::Key_Hyper_L || code == Qt::Key_Hyper_R)) { - code = Qt::Key_Meta; - } - } - return code; -} - -QString QXlibKeyboard::translateKeySym(KeySym keysym, uint xmodifiers, - int &code, Qt::KeyboardModifiers &modifiers, - QByteArray &chars, int &count) -{ - // all keysyms smaller than 0xff00 are actally keys that can be mapped to unicode chars - - QTextCodec *mapper = QTextCodec::codecForLocale(); - QChar converted; - - if (/*count == 0 &&*/ keysym < 0xff00) { - unsigned char byte3 = (unsigned char)(keysym >> 8); - int mib = -1; - switch(byte3) { - case 0: // Latin 1 - case 1: // Latin 2 - case 2: //latin 3 - case 3: // latin4 - mib = byte3 + 4; break; - case 5: // arabic - mib = 82; break; - case 12: // Hebrew - mib = 85; break; - case 13: // Thai - mib = 2259; break; - case 4: // kana - case 6: // cyrillic - case 7: // greek - case 8: // technical, no mapping here at the moment - case 9: // Special - case 10: // Publishing - case 11: // APL - case 14: // Korean, no mapping - mib = -1; // manual conversion - mapper= 0; -#if !defined(QT_NO_XIM) - converted = keysymToUnicode(byte3, keysym & 0xff); -#endif - case 0x20: - // currency symbols - if (keysym >= 0x20a0 && keysym <= 0x20ac) { - mib = -1; // manual conversion - mapper = 0; - converted = (uint)keysym; - } - break; - default: - break; - } - if (mib != -1) { - mapper = QTextCodec::codecForMib(mib); - if (chars.isEmpty()) - chars.resize(1); - chars[0] = (unsigned char) (keysym & 0xff); // get only the fourth bit for conversion later - count = 1; - } - } else if (keysym >= 0x1000000 && keysym <= 0x100ffff) { - converted = (ushort) (keysym - 0x1000000); - mapper = 0; - } - if (count < (int)chars.size()-1) - chars[count] = '\0'; - - QString text; - if (!mapper && converted.unicode() != 0x0) { - text = converted; - } else if (!chars.isEmpty()) { - // convert chars (8bit) to text (unicode). - if (mapper) - text = mapper->toUnicode(chars.data(), count, 0); - if (text.isEmpty()) { - // no mapper, or codec couldn't convert to unicode (this - // can happen when running in the C locale or with no LANG - // set). try converting from latin-1 - text = QString::fromLatin1(chars); - } - } - - modifiers = translateModifiers(xmodifiers); - - // Commentary in X11/keysymdef says that X codes match ASCII, so it - // is safe to use the locale functions to process X codes in ISO8859-1. - // - // This is mainly for compatibility - applications should not use the - // Qt keycodes between 128 and 255, but should rather use the - // QKeyEvent::text(). - // - if (keysym < 128 || (keysym < 256 && (!mapper || mapper->mibEnum()==4))) { - // upper-case key, if known - code = isprint((int)keysym) ? toupper((int)keysym) : 0; - } else if (keysym >= XK_F1 && keysym <= XK_F35) { - // function keys - code = Qt::Key_F1 + ((int)keysym - XK_F1); - } else if (keysym >= XK_KP_Space && keysym <= XK_KP_9) { - if (keysym >= XK_KP_0) { - // numeric keypad keys - code = Qt::Key_0 + ((int)keysym - XK_KP_0); - } else { - code = translateKeySym(keysym); - } - modifiers |= Qt::KeypadModifier; - } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f && text.unicode()->unicode() != 0x7f && !(keysym >= XK_dead_grave && keysym <= XK_dead_horn)) { - code = text.unicode()->toUpper().unicode(); - } else { - // any other keys - code = translateKeySym(keysym); - - if (code == Qt::Key_Tab && (modifiers & Qt::ShiftModifier)) { - // map shift+tab to shift+backtab, QShortcutMap knows about it - // and will handle it. - code = Qt::Key_Backtab; - text = QString(); - } - } - - return text; -} - -QXlibKeyboard::QXlibKeyboard(QXlibScreen *screen) - : m_screen(screen) - , m_alt_mask(0) - , m_super_mask(0) - , m_hyper_mask(0) - , m_meta_mask(0) -{ - changeLayout(); -} - -void QXlibKeyboard::changeLayout() -{ - XkbDescPtr xkbDesc = XkbGetMap(m_screen->display()->nativeDisplay(), XkbAllClientInfoMask, XkbUseCoreKbd); - for (int i = xkbDesc->min_key_code; i < xkbDesc->max_key_code; ++i) { - const uint mask = xkbDesc->map->modmap ? xkbDesc->map->modmap[i] : 0; - if (mask == 0) { - // key is not bound to a modifier - continue; - } - - for (int j = 0; j < XkbKeyGroupsWidth(xkbDesc, i); ++j) { - KeySym keySym = XkbKeySym(xkbDesc, i, j); - if (keySym == NoSymbol) - continue; - setMask(keySym, mask); - } - } - XkbFreeKeyboard(xkbDesc, XkbAllComponentsMask, true); - -} - -static Qt::KeyboardModifiers modifierFromKeyCode(int qtcode) -{ - switch (qtcode) { - case Qt::Key_Control: - return Qt::ControlModifier; - case Qt::Key_Alt: - return Qt::AltModifier; - case Qt::Key_Shift: - return Qt::ShiftModifier; - case Qt::Key_Meta: - return Qt::MetaModifier; - default: - return Qt::NoModifier; - } -} - -void QXlibKeyboard::handleKeyEvent(QWindow *widget, QEvent::Type type, XKeyEvent *ev) -{ - int qtcode = 0; - Qt::KeyboardModifiers modifiers = translateModifiers(ev->state); - QByteArray chars; - chars.resize(513); - int count = 0; - KeySym keySym; - count = XLookupString(ev,chars.data(),chars.size(),&keySym,0); - QString text = translateKeySym(keySym,ev->state,qtcode,modifiers,chars,count); - QWindowSystemInterface::handleExtendedKeyEvent(widget,ev->time,type,qtcode,modifiers,ev->keycode,0,ev->state,text.left(count)); -} diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.h b/src/plugins/platforms/xlib/qxlibkeyboard.h deleted file mode 100644 index 97f8aafa860..00000000000 --- a/src/plugins/platforms/xlib/qxlibkeyboard.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTESTLITEKEYBOARD_H -#define QTESTLITEKEYBOARD_H - -#include "qxlibintegration.h" - -class QXlibKeyboard -{ -public: - QXlibKeyboard(QXlibScreen *screen); - - void changeLayout(); - - void handleKeyEvent(QWindow *widget, QEvent::Type type, XKeyEvent *ev); - - Qt::KeyboardModifiers translateModifiers(int s); - -private: - - void setMask(KeySym sym, uint mask); - int translateKeySym(uint key) const; - QString translateKeySym(KeySym keysym, uint xmodifiers, - int &code, Qt::KeyboardModifiers &modifiers, - QByteArray &chars, int &count); - - QXlibScreen *m_screen; - - uint m_alt_mask; - uint m_super_mask; - uint m_hyper_mask; - uint m_meta_mask; - uint m_mode_switch_mask; - uint m_num_lock_mask; -}; - -#endif // QTESTLITEKEYBOARD_H diff --git a/src/plugins/platforms/xlib/qxlibmime.cpp b/src/plugins/platforms/xlib/qxlibmime.cpp deleted file mode 100644 index ca3a24192a2..00000000000 --- a/src/plugins/platforms/xlib/qxlibmime.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qxlibmime.h" - -#include "qxlibstatic.h" -#include "qxlibscreen.h" - -#include -#include -#include - -QXlibMime::QXlibMime() - : QInternalMimeData() -{ } - -QXlibMime::~QXlibMime() -{} - - - - - -QString QXlibMime::mimeAtomToString(Display *display, Atom a) -{ - if (!a) return 0; - - if (a == XA_STRING || a == QXlibStatic::atom(QXlibStatic::UTF8_STRING)) { - return "text/plain"; // some Xdnd clients are dumb - } - char *atom = XGetAtomName(display, a); - QString result = QString::fromLatin1(atom); - XFree(atom); - return result; -} - -Atom QXlibMime::mimeStringToAtom(Display *display, const QString &mimeType) -{ - if (mimeType.isEmpty()) - return 0; - return XInternAtom(display, mimeType.toLatin1().constData(), False); -} - -QStringList QXlibMime::mimeFormatsForAtom(Display *display, Atom a) -{ - QStringList formats; - if (a) { - QString atomName = mimeAtomToString(display, a); - formats.append(atomName); - - // special cases for string type - if (a == QXlibStatic::atom(QXlibStatic::UTF8_STRING) - || a == XA_STRING - || a == QXlibStatic::atom(QXlibStatic::TEXT) - || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) - formats.append(QLatin1String("text/plain")); - - // special cases for uris - if (atomName == QLatin1String("text/x-moz-url")) - formats.append(QLatin1String("text/uri-list")); - - // special case for images - if (a == XA_PIXMAP) - formats.append(QLatin1String("image/ppm")); - } - return formats; -} - -bool QXlibMime::mimeDataForAtom(Display *display, Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat) -{ - bool ret = false; - *atomFormat = a; - *dataFormat = 8; - QString atomName = mimeAtomToString(display, a); - if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) { - *data = QInternalMimeData::renderDataHelper(atomName, mimeData); - if (atomName == QLatin1String("application/x-color")) - *dataFormat = 16; - ret = true; - } else { - if ((a == QXlibStatic::atom(QXlibStatic::UTF8_STRING) - || a == XA_STRING - || a == QXlibStatic::atom(QXlibStatic::TEXT) - || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) - && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) { - if (a == QXlibStatic::atom(QXlibStatic::UTF8_STRING)){ - *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData); - ret = true; - } else if (a == XA_STRING) { - *data = QString::fromUtf8(QInternalMimeData::renderDataHelper( - QLatin1String("text/plain"), mimeData)).toLocal8Bit(); - ret = true; - } else if (a == QXlibStatic::atom(QXlibStatic::TEXT) - || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) { - // the ICCCM states that TEXT and COMPOUND_TEXT are in the - // encoding of choice, so we choose the encoding of the locale - QByteArray strData = QString::fromUtf8(QInternalMimeData::renderDataHelper( - QLatin1String("text/plain"), mimeData)).toLocal8Bit(); - char *list[] = { strData.data(), NULL }; - - XICCEncodingStyle style = (a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) - ? XCompoundTextStyle : XStdICCTextStyle; - XTextProperty textprop; - if (list[0] != NULL - && XmbTextListToTextProperty(display, list, 1, style, - &textprop) == Success) { - *atomFormat = textprop.encoding; - *dataFormat = textprop.format; - *data = QByteArray((const char *) textprop.value, textprop.nitems * textprop.format / 8); - ret = true; - - XFree(textprop.value); - } - } - } else if (atomName == QLatin1String("text/x-moz-url") && - QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) { - QByteArray uri = QInternalMimeData::renderDataHelper( - QLatin1String("text/uri-list"), mimeData).split('\n').first(); - QString mozUri = QString::fromLatin1(uri, uri.size()); - mozUri += QLatin1Char('\n'); - *data = QByteArray(reinterpret_cast(mozUri.utf16()), mozUri.length() * 2); - ret = true; - } else if ((a == XA_PIXMAP || a == XA_BITMAP) && mimeData->hasImage()) { - ret = true; - } - } - return ret && data != 0; -} - -QList QXlibMime::mimeAtomsForFormat(Display *display, const QString &format) -{ - QList atoms; - atoms.append(mimeStringToAtom(display, format)); - - // special cases for strings - if (format == QLatin1String("text/plain")) { - atoms.append(QXlibStatic::atom(QXlibStatic::UTF8_STRING)); - atoms.append(XA_STRING); - atoms.append(QXlibStatic::atom(QXlibStatic::TEXT)); - atoms.append(QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)); - } - - // special cases for uris - if (format == QLatin1String("text/uri-list")) { - atoms.append(mimeStringToAtom(display,QLatin1String("text/x-moz-url"))); - } - - //special cases for images - if (format == QLatin1String("image/ppm")) - atoms.append(XA_PIXMAP); - if (format == QLatin1String("image/pbm")) - atoms.append(XA_BITMAP); - - return atoms; -} - -QVariant QXlibMime::mimeConvertToFormat(Display *display, Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding) -{ - QString atomName = mimeAtomToString(display,a); - if (atomName == format) - return data; - - if (!encoding.isEmpty() - && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) { - - if (requestedType == QVariant::String) { - QTextCodec *codec = QTextCodec::codecForName(encoding); - if (codec) - return codec->toUnicode(data); - } - - return data; - } - - // special cases for string types - if (format == QLatin1String("text/plain")) { - if (a == QXlibStatic::atom(QXlibStatic::UTF8_STRING)) - return QString::fromUtf8(data); - if (a == XA_STRING) - return QString::fromLatin1(data); - if (a == QXlibStatic::atom(QXlibStatic::TEXT) - || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) - // #### might be wrong for COMPUND_TEXT - return QString::fromLocal8Bit(data, data.size()); - } - - // special case for uri types - if (format == QLatin1String("text/uri-list")) { - if (atomName == QLatin1String("text/x-moz-url")) { - // we expect this as utf16 - // the first part is a url that should only contain ascci char - // so it should be safe to check that the second char is 0 - // to verify that it is utf16 - if (data.size() > 1 && data.at(1) == 0) - return QString::fromRawData((const QChar *)data.constData(), - data.size() / 2).split(QLatin1Char('\n')).first().toLatin1(); - } - } - - // special cas for images - if (format == QLatin1String("image/ppm")) { - if (a == XA_PIXMAP && data.size() == sizeof(Pixmap)) { - Pixmap xpm = *((Pixmap*)data.data()); - if (!xpm) - return QByteArray(); - Window root; - int x; - int y; - uint width; - uint height; - uint border_width; - uint depth; - - XGetGeometry(display, xpm, &root, &x, &y, &width, &height, &border_width, &depth); - XImage *ximg = XGetImage(display,xpm,x,y,width,height,AllPlanes,depth==1 ? XYPixmap : ZPixmap); - QImage qimg = QXlibStatic::qimageFromXImage(ximg); - XDestroyImage(ximg); - - QImageWriter imageWriter; - imageWriter.setFormat("PPMRAW"); - QBuffer buf; - buf.open(QIODevice::WriteOnly); - imageWriter.setDevice(&buf); - imageWriter.write(qimg); - return buf.buffer(); - } - } - return QVariant(); -} - -Atom QXlibMime::mimeAtomForFormat(Display *display, const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *requestedEncoding) -{ - requestedEncoding->clear(); - - // find matches for string types - if (format == QLatin1String("text/plain")) { - if (atoms.contains(QXlibStatic::atom(QXlibStatic::UTF8_STRING))) - return QXlibStatic::atom(QXlibStatic::UTF8_STRING); - if (atoms.contains(QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT))) - return QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT); - if (atoms.contains(QXlibStatic::atom(QXlibStatic::TEXT))) - return QXlibStatic::atom(QXlibStatic::TEXT); - if (atoms.contains(XA_STRING)) - return XA_STRING; - } - - // find matches for uri types - if (format == QLatin1String("text/uri-list")) { - Atom a = mimeStringToAtom(display,format); - if (a && atoms.contains(a)) - return a; - a = mimeStringToAtom(display,QLatin1String("text/x-moz-url")); - if (a && atoms.contains(a)) - return a; - } - - // find match for image - if (format == QLatin1String("image/ppm")) { - if (atoms.contains(XA_PIXMAP)) - return XA_PIXMAP; - } - - // for string/text requests try to use a format with a well-defined charset - // first to avoid encoding problems - if (requestedType == QVariant::String - && format.startsWith(QLatin1String("text/")) - && !format.contains(QLatin1String("charset="))) { - - QString formatWithCharset = format; - formatWithCharset.append(QLatin1String(";charset=utf-8")); - - Atom a = mimeStringToAtom(display,formatWithCharset); - if (a && atoms.contains(a)) { - *requestedEncoding = "utf-8"; - return a; - } - } - - Atom a = mimeStringToAtom(display,format); - if (a && atoms.contains(a)) - return a; - - return 0; -} diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.cpp b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp deleted file mode 100644 index 0519a365cff..00000000000 --- a/src/plugins/platforms/xlib/qxlibnativeinterface.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qguiapplication_p.h> -#include "qxlibnativeinterface.h" - -#include "qxlibdisplay.h" -#include "qscreen.h" - -class QXlibResourceMap : public QMap<QByteArray, QXlibNativeInterface::ResourceType> -{ -public: - QXlibResourceMap() - :QMap<QByteArray, QXlibNativeInterface::ResourceType>() - { - insert("display",QXlibNativeInterface::Display); - insert("egldisplay",QXlibNativeInterface::EglDisplay); - insert("connection",QXlibNativeInterface::Connection); - insert("screen",QXlibNativeInterface::Screen); - insert("graphicsdevice",QXlibNativeInterface::GraphicsDevice); - insert("eglcontext",QXlibNativeInterface::EglContext); - } -}; - -Q_GLOBAL_STATIC(QXlibResourceMap, qXlibResourceMap) - - -void * QXlibNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) -{ - QByteArray lowerCaseResource = resourceString.toLower(); - ResourceType resource = qXlibResourceMap()->value(lowerCaseResource); - void *result = 0; - switch(resource) { - case Display: - result = displayForWindow(window); - break; - case EglDisplay: - result = eglDisplayForWindow(window); - break; - case Connection: - result = connectionForWindow(window); - break; - case Screen: - result = reinterpret_cast<void *>(qPlatformScreenForWindow(window)->xScreenNumber()); - break; - case GraphicsDevice: - result = graphicsDeviceForWindow(window); - break; - case EglContext: - result = eglContextForWindow(window); - break; - default: - result = 0; - } - return result; -} -QPlatformNativeInterface::EventFilter QXlibNativeInterface::setEventFilter(const QByteArray &eventType, QPlatformNativeInterface::EventFilter filter) -{ - EventFilter oldFilter = m_eventFilters.value(eventType); - m_eventFilters.insert(eventType, filter); - return oldFilter; -} - -QPlatformNativeInterface::EventFilter QXlibNativeInterface::eventFilterForEventType(const QByteArray& eventType) const -{ - return m_eventFilters.value(eventType); -} - -void * QXlibNativeInterface::displayForWindow(QWindow *window) -{ - return qPlatformScreenForWindow(window)->display()->nativeDisplay(); -} - -void * QXlibNativeInterface::eglDisplayForWindow(QWindow *window) -{ - Q_UNUSED(window); - return 0; -} - -void * QXlibNativeInterface::screenForWindow(QWindow *window) -{ - Q_UNUSED(window); - return 0; -} - -void * QXlibNativeInterface::graphicsDeviceForWindow(QWindow *window) -{ - Q_UNUSED(window); - return 0; -} - -void * QXlibNativeInterface::eglContextForWindow(QWindow *window) -{ - Q_UNUSED(window); - return 0; -} - -QXlibScreen * QXlibNativeInterface::qPlatformScreenForWindow(QWindow *window) -{ - QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen(); - return static_cast<QXlibScreen *>(screen->handle()); -} diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.h b/src/plugins/platforms/xlib/qxlibnativeinterface.h deleted file mode 100644 index 9ec4ab51c81..00000000000 --- a/src/plugins/platforms/xlib/qxlibnativeinterface.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QXLIBNATIVEINTERFACE_H -#define QXLIBNATIVEINTERFACE_H - -#include "qxlibscreen.h" - -#include <QtGui/QPlatformNativeInterface> - -class QXlibNativeInterface : public QPlatformNativeInterface -{ -public: - enum ResourceType { - Display, - EglDisplay, - Connection, - Screen, - GraphicsDevice, - EglContext - }; - - void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window); - - EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter); - EventFilter eventFilterForEventType(const QByteArray& eventType) const; - - void *displayForWindow(QWindow *window); - void *eglDisplayForWindow(QWindow *window); - void *connectionForWindow(QWindow *window); - void *screenForWindow(QWindow *window); - void *graphicsDeviceForWindow(QWindow *window); - void *eglContextForWindow(QWindow *window); - -private: - QHash<QByteArray, EventFilter> m_eventFilters; - static QXlibScreen *qPlatformScreenForWindow(QWindow *window); -}; - - -#endif // QXLIBNATIVEINTERFACE_H diff --git a/src/plugins/platforms/xlib/qxlibscreen.cpp b/src/plugins/platforms/xlib/qxlibscreen.cpp deleted file mode 100644 index 62c80b6ad41..00000000000 --- a/src/plugins/platforms/xlib/qxlibscreen.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qguiapplication_p.h> -#include "qxlibscreen.h" - -#include <X11/extensions/Xfixes.h> - -#include "qxlibcursor.h" -#include "qxlibwindow.h" -#include "qxlibkeyboard.h" -#include "qxlibstatic.h" -#include "qxlibclipboard.h" -#include "qxlibdisplay.h" -#include "qxlibnativeinterface.h" - -#include <QtCore/QDebug> -#include <QtCore/QSocketNotifier> -#include <QtCore/QElapsedTimer> - -#include <QtGui/QScreen> - -QT_BEGIN_NAMESPACE - -static int (*original_x_errhandler)(Display *dpy, XErrorEvent *); -static bool seen_badwindow; - -static int qt_x_errhandler(Display *dpy, XErrorEvent *err) -{ - -qDebug() << "qt_x_errhandler" << err->error_code; - - switch (err->error_code) { - case BadAtom: -#if 0 - if (err->request_code == 20 /* X_GetProperty */ - && (err->resourceid == XA_RESOURCE_MANAGER - || err->resourceid == XA_RGB_DEFAULT_MAP - || err->resourceid == ATOM(_NET_SUPPORTED) - || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK) - || err->resourceid == ATOM(KDE_FULL_SESSION) - || err->resourceid == ATOM(KWIN_RUNNING) - || err->resourceid == ATOM(XdndProxy) - || err->resourceid == ATOM(XdndAware)) - - - ) { - // Perhaps we're running under SECURITY reduction? :/ - return 0; - } -#endif - qDebug() << "BadAtom"; - break; - - case BadWindow: - if (err->request_code == 2 /* X_ChangeWindowAttributes */ - || err->request_code == 38 /* X_QueryPointer */) { - for (int i = 0; i < ScreenCount(dpy); ++i) { - if (err->resourceid == RootWindow(dpy, i)) { - // Perhaps we're running under SECURITY reduction? :/ - return 0; - } - } - } - seen_badwindow = true; - if (err->request_code == 25 /* X_SendEvent */) { - for (int i = 0; i < ScreenCount(dpy); ++i) { - if (err->resourceid == RootWindow(dpy, i)) { - // Perhaps we're running under SECURITY reduction? :/ - return 0; - } - } -#if 0 - if (X11->xdndHandleBadwindow()) { - qDebug("xdndHandleBadwindow returned true"); - return 0; - } -#endif - } -#if 0 - if (X11->ignore_badwindow) - return 0; -#endif - break; - - case BadMatch: - if (err->request_code == 42 /* X_SetInputFocus */) - return 0; - break; - - default: -#if 0 //!defined(QT_NO_XINPUT) - if (err->request_code == X11->xinput_major - && err->error_code == (X11->xinput_errorbase + XI_BadDevice) - && err->minor_code == 3 /* X_OpenDevice */) { - return 0; - } -#endif - break; - } - - char errstr[256]; - XGetErrorText( dpy, err->error_code, errstr, 256 ); - char buffer[256]; - char request_str[256]; - qsnprintf(buffer, 256, "%d", err->request_code); - XGetErrorDatabaseText(dpy, "XRequest", buffer, "", request_str, 256); - if (err->request_code < 128) { - // X error for a normal protocol request - qWarning( "X Error: %s %d\n" - " Major opcode: %d (%s)\n" - " Resource id: 0x%lx", - errstr, err->error_code, - err->request_code, - request_str, - err->resourceid ); - } else { - // X error for an extension request - const char *extensionName = 0; -#if 0 - if (err->request_code == X11->xrender_major) - extensionName = "RENDER"; - else if (err->request_code == X11->xrandr_major) - extensionName = "RANDR"; - else if (err->request_code == X11->xinput_major) - extensionName = "XInputExtension"; - else if (err->request_code == X11->mitshm_major) - extensionName = "MIT-SHM"; -#endif - char minor_str[256]; - if (extensionName) { - qsnprintf(buffer, 256, "%s.%d", extensionName, err->minor_code); - XGetErrorDatabaseText(dpy, "XRequest", buffer, "", minor_str, 256); - } else { - extensionName = "Uknown extension"; - qsnprintf(minor_str, 256, "Unknown request"); - } - qWarning( "X Error: %s %d\n" - " Extension: %d (%s)\n" - " Minor opcode: %d (%s)\n" - " Resource id: 0x%lx", - errstr, err->error_code, - err->request_code, - extensionName, - err->minor_code, - minor_str, - err->resourceid ); - } - - // ### we really should distinguish between severe, non-severe and - // ### application specific errors - - return 0; -} - -QXlibScreen::QXlibScreen(QXlibNativeInterface *nativeInterface) - : mNativeInterface(nativeInterface) - , mFormat(QImage::Format_RGB32) -#if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2) - , mEGLDisplay(0) -#endif -{ - char *display_name = getenv("DISPLAY"); - Display *display = XOpenDisplay(display_name); - mDisplay = new QXlibDisplay(display); - - -#ifndef DONT_USE_MIT_SHM - int MIT_SHM_extension_supported = XShmQueryExtension (mDisplay->nativeDisplay()); - Q_ASSERT(MIT_SHM_extension_supported == True); -#endif - original_x_errhandler = XSetErrorHandler(qt_x_errhandler); - - if (qgetenv("DO_X_SYNCHRONIZE").toInt()) - XSynchronize(mDisplay->nativeDisplay(), true); - - mScreen = DefaultScreen(mDisplay->nativeDisplay()); - XSelectInput(mDisplay->nativeDisplay(),rootWindow(), KeymapStateMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask); - int width = DisplayWidth(mDisplay->nativeDisplay(), mScreen); - int height = DisplayHeight(mDisplay->nativeDisplay(), mScreen); - mGeometry = QRect(0,0,width,height); - - int physicalWidth = DisplayWidthMM(mDisplay->nativeDisplay(), mScreen); - int physicalHeight = DisplayHeightMM(mDisplay->nativeDisplay(), mScreen); - mPhysicalSize = QSizeF(physicalWidth, physicalHeight); - - int xSocketNumber = XConnectionNumber(mDisplay->nativeDisplay()); - - mDepth = DefaultDepth(mDisplay->nativeDisplay(),mScreen); -#ifdef MYX11_DEBUG - qDebug() << "X socket:"<< xSocketNumber; -#endif - QSocketNotifier *sock = new QSocketNotifier(xSocketNumber, QSocketNotifier::Read, this); - connect(sock, SIGNAL(activated(int)), this, SLOT(eventDispatcher())); - - mCursor = new QXlibCursor(this); - mKeyboard = new QXlibKeyboard(this); -} - -QXlibScreen::~QXlibScreen() -{ - delete mCursor; - delete mDisplay; -} - -QPlatformCursor *QXlibScreen::cursor() const -{ - return mCursor; -} - -Window QXlibScreen::rootWindow() -{ - return RootWindow(mDisplay->nativeDisplay(), mScreen); -} - -unsigned long QXlibScreen::blackPixel() -{ - return BlackPixel(mDisplay->nativeDisplay(), mScreen); -} - -unsigned long QXlibScreen::whitePixel() -{ - return WhitePixel(mDisplay->nativeDisplay(), mScreen); -} - -#ifdef KeyPress -#undef KeyPress -#endif -#ifdef KeyRelease -#undef KeyRelease -#endif - -bool QXlibScreen::handleEvent(XEvent *xe) -{ - if (QPlatformNativeInterface::EventFilter filter = mNativeInterface->eventFilterForEventType(QByteArrayLiteral("XEvent"))) { - if (filter(xe, 0)) - return true; - } - - int quit = false; - QXlibWindow *platformWindow = QXlibWindow::platformWindowForXWindow(xe->xany.window); - if (!platformWindow) - return false; - - Atom wmProtocolsAtom = QXlibStatic::atom(QXlibStatic::WM_PROTOCOLS); - Atom wmDeleteWindowAtom = QXlibStatic::atom(QXlibStatic::WM_DELETE_WINDOW); - switch (xe->type) { - - case ClientMessage: - if (xe->xclient.format == 32 && xe->xclient.message_type == wmProtocolsAtom) { - Atom a = xe->xclient.data.l[0]; - if (a == wmDeleteWindowAtom) - platformWindow->handleCloseEvent(); - } - break; - - case Expose: - // ### -// if (xe->xexpose.count == 0) -// platformWindow->paintEvent(); - break; - case ConfigureNotify: - platformWindow->resizeEvent(&xe->xconfigure); - break; - - case ButtonPress: - platformWindow->mousePressEvent(&xe->xbutton); - break; - - case ButtonRelease: - platformWindow->handleMouseEvent(QEvent::MouseButtonRelease, &xe->xbutton); - break; - - case MotionNotify: - platformWindow->handleMouseEvent(QEvent::MouseMove, &xe->xbutton); - break; - - case XKeyPress: - mKeyboard->handleKeyEvent(platformWindow->window(), QEvent::KeyPress, &xe->xkey); - break; - - case XKeyRelease: - mKeyboard->handleKeyEvent(platformWindow->window(), QEvent::KeyRelease, &xe->xkey); - break; - - case EnterNotify: - platformWindow->handleEnterEvent(); - break; - - case LeaveNotify: - platformWindow->handleLeaveEvent(); - break; - - case XFocusIn: - platformWindow->handleFocusInEvent(); - break; - - case XFocusOut: - platformWindow->handleFocusOutEvent(); - break; - - case PropertyNotify: - break; - - case SelectionClear: - qDebug() << "Selection Clear!!!"; - break; - case SelectionRequest: - handleSelectionRequest(xe); - break; - case SelectionNotify: - qDebug() << "Selection Notify!!!!"; - - break; - - - default: -#ifdef MYX11_DEBUG - qDebug() << hex << xe->xany.window << "Other X event" << xe->type; -#endif - break; - } - - return quit; -} - -static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer) -{ - Atom clipboard = QXlibStatic::atom(QXlibStatic::CLIPBOARD); - return ((e->type == SelectionRequest && (e->xselectionrequest.selection == XA_PRIMARY - || e->xselectionrequest.selection == clipboard)) - || (e->type == SelectionClear && (e->xselectionclear.selection == XA_PRIMARY - || e->xselectionclear.selection == clipboard))); -} - -bool QXlibScreen::waitForClipboardEvent(Window win, int type, XEvent *event, int timeout) -{ - QElapsedTimer timer; - timer.start(); - do { - if (XCheckTypedWindowEvent(mDisplay->nativeDisplay(),win,type,event)) - return true; - - // process other clipboard events, since someone is probably requesting data from us - XEvent e; - if (XCheckIfEvent(mDisplay->nativeDisplay(), &e, checkForClipboardEvents, 0)) - handleEvent(&e); - - mDisplay->flush(); - - // sleep 50 ms, so we don't use up CPU cycles all the time. - struct timeval usleep_tv; - usleep_tv.tv_sec = 0; - usleep_tv.tv_usec = 50000; - select(0, 0, 0, 0, &usleep_tv); - } while (timer.elapsed() < timeout); - return false; -} - -void QXlibScreen::eventDispatcher() -{ - ulong marker = XNextRequest(mDisplay->nativeDisplay()); - // int i = 0; - while (XPending(mDisplay->nativeDisplay())) { - XEvent event; - XNextEvent(mDisplay->nativeDisplay(), &event); - /* done = */ - handleEvent(&event); - - if (event.xany.serial >= marker) { - #ifdef MYX11_DEBUG - qDebug() << "potential livelock averted"; - #endif - #if 0 - if (XEventsQueued(mDisplay->nativeDisplay(), QueuedAfterFlush)) { - qDebug() << " with events queued"; - QTimer::singleShot(0, this, SLOT(eventDispatcher())); - } - #endif - break; - } - } -} - -QImage QXlibScreen::grabWindow(Window window, int x, int y, int w, int h) -{ - if (w == 0 || h ==0) - return QImage(); - - //WinId 0 means the desktop widget - if (!window) - window = rootWindow(); - - XWindowAttributes window_attr; - if (!XGetWindowAttributes(mDisplay->nativeDisplay(), window, &window_attr)) - return QImage(); - - if (w < 0) - w = window_attr.width - x; - if (h < 0) - h = window_attr.height - y; - - // Ideally, we should also limit ourselves to the screen area, but the Qt docs say - // that it's "unsafe" to go outside the screen, so we can ignore that problem. - - //We're definitely not optimizing for speed... - XImage *xi = XGetImage(mDisplay->nativeDisplay(), window, x, y, w, h, AllPlanes, ZPixmap); - - if (!xi) - return QImage(); - - //taking a copy to make sure we have ownership -- not fast - QImage result = QImage( (uchar*) xi->data, xi->width, xi->height, xi->bytes_per_line, QImage::Format_RGB32 ).copy(); - - XDestroyImage(xi); - - return result; -} - -QXlibScreen * QXlibScreen::testLiteScreenForWidget(QWindow *widget) -{ - return static_cast<QXlibScreen *>(widget->screen()->handle()); -} - -QXlibDisplay * QXlibScreen::display() const -{ - return mDisplay; -} - -int QXlibScreen::xScreenNumber() const -{ - return mScreen; -} - -Visual * QXlibScreen::defaultVisual() const -{ - return DefaultVisual(display()->nativeDisplay(), xScreenNumber()); -} - -QXlibKeyboard * QXlibScreen::keyboard() const -{ - return mKeyboard; -} - -void QXlibScreen::handleSelectionRequest(XEvent *event) -{ - QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration(); - QXlibClipboard *clipboard = static_cast<QXlibClipboard *>(integration->clipboard()); - clipboard->handleSelectionRequest(event); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/xlib/qxlibscreen.h b/src/plugins/platforms/xlib/qxlibscreen.h deleted file mode 100644 index 5bb6cc7735c..00000000000 --- a/src/plugins/platforms/xlib/qxlibscreen.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTESTLITESCREEN_H -#define QTESTLITESCREEN_H - -#include <QtGui/QPlatformScreen> -#include "qxlibintegration.h" - -QT_BEGIN_NAMESPACE - -class QXlibCursor; -class QXlibKeyboard; -class QXlibDisplay; - -class QXlibScreen : public QObject, public QPlatformScreen -{ - Q_OBJECT -public: - QXlibScreen(QXlibNativeInterface *nativeInterface); - - ~QXlibScreen(); - - QRect geometry() const { return mGeometry; } - int depth() const { return mDepth; } - QImage::Format format() const { return mFormat; } - QSizeF physicalSize() const { return mPhysicalSize; } - QPlatformCursor *cursor() const; - - Window rootWindow(); - unsigned long blackPixel(); - unsigned long whitePixel(); - - bool handleEvent(XEvent *xe); - bool waitForClipboardEvent(Window win, int type, XEvent *event, int timeout); - - QImage grabWindow(Window window, int x, int y, int w, int h); - - static QXlibScreen *testLiteScreenForWidget(QWindow *widget); - - QXlibDisplay *display() const; - int xScreenNumber() const; - - Visual *defaultVisual() const; - - QXlibKeyboard *keyboard() const; - -#if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2) - void *eglDisplay() const { return mEGLDisplay; } - void setEglDisplay(void *display) { mEGLDisplay = display; } -#endif - -public slots: - void eventDispatcher(); - -private: - - void handleSelectionRequest(XEvent *event); - QXlibNativeInterface *mNativeInterface; - QRect mGeometry; - QSizeF mPhysicalSize; - int mDepth; - QImage::Format mFormat; - QXlibCursor *mCursor; - QXlibKeyboard *mKeyboard; - - QXlibDisplay * mDisplay; -#if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2) - void *mEGLDisplay; -#endif - int mScreen; -}; - -QT_END_NAMESPACE - -#endif // QTESTLITESCREEN_H diff --git a/src/plugins/platforms/xlib/qxlibstatic.cpp b/src/plugins/platforms/xlib/qxlibstatic.cpp deleted file mode 100644 index 9cf938ece7c..00000000000 --- a/src/plugins/platforms/xlib/qxlibstatic.cpp +++ /dev/null @@ -1,509 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qguiapplication_p.h> -#include "qxlibstatic.h" -#include "qxlibscreen.h" -#include "qxlibdisplay.h" - -#include <qplatformdefs.h> -#include <QtGui/qscreen.h> - -#include <QtCore/QBuffer> -#include <QtCore/QLibrary> - -#include <QDebug> - -static const char * x11_atomnames = { - // window-manager <-> client protocols - "WM_PROTOCOLS\0" - "WM_DELETE_WINDOW\0" - "WM_TAKE_FOCUS\0" - "_NET_WM_PING\0" - "_NET_WM_CONTEXT_HELP\0" - "_NET_WM_SYNC_REQUEST\0" - "_NET_WM_SYNC_REQUEST_COUNTER\0" - - // ICCCM window state - "WM_STATE\0" - "WM_CHANGE_STATE\0" - - // Session management - "WM_CLIENT_LEADER\0" - "WM_WINDOW_ROLE\0" - "SM_CLIENT_ID\0" - - // Clipboard - "CLIPBOARD\0" - "INCR\0" - "TARGETS\0" - "MULTIPLE\0" - "TIMESTAMP\0" - "SAVE_TARGETS\0" - "CLIP_TEMPORARY\0" - "_QT_SELECTION\0" - "_QT_CLIPBOARD_SENTINEL\0" - "_QT_SELECTION_SENTINEL\0" - "CLIPBOARD_MANAGER\0" - - "RESOURCE_MANAGER\0" - - "_XSETROOT_ID\0" - - "_QT_SCROLL_DONE\0" - "_QT_INPUT_ENCODING\0" - - "_MOTIF_WM_HINTS\0" - - "DTWM_IS_RUNNING\0" - "ENLIGHTENMENT_DESKTOP\0" - "_DT_SAVE_MODE\0" - "_SGI_DESKS_MANAGER\0" - - // EWMH (aka NETWM) - "_NET_SUPPORTED\0" - "_NET_VIRTUAL_ROOTS\0" - "_NET_WORKAREA\0" - - "_NET_MOVERESIZE_WINDOW\0" - "_NET_WM_MOVERESIZE\0" - - "_NET_WM_NAME\0" - "_NET_WM_ICON_NAME\0" - "_NET_WM_ICON\0" - - "_NET_WM_PID\0" - - "_NET_WM_WINDOW_OPACITY\0" - - "_NET_WM_STATE\0" - "_NET_WM_STATE_ABOVE\0" - "_NET_WM_STATE_BELOW\0" - "_NET_WM_STATE_FULLSCREEN\0" - "_NET_WM_STATE_MAXIMIZED_HORZ\0" - "_NET_WM_STATE_MAXIMIZED_VERT\0" - "_NET_WM_STATE_MODAL\0" - "_NET_WM_STATE_STAYS_ON_TOP\0" - "_NET_WM_STATE_DEMANDS_ATTENTION\0" - - "_NET_WM_USER_TIME\0" - "_NET_WM_USER_TIME_WINDOW\0" - "_NET_WM_FULL_PLACEMENT\0" - - "_NET_WM_WINDOW_TYPE\0" - "_NET_WM_WINDOW_TYPE_DESKTOP\0" - "_NET_WM_WINDOW_TYPE_DOCK\0" - "_NET_WM_WINDOW_TYPE_TOOLBAR\0" - "_NET_WM_WINDOW_TYPE_MENU\0" - "_NET_WM_WINDOW_TYPE_UTILITY\0" - "_NET_WM_WINDOW_TYPE_SPLASH\0" - "_NET_WM_WINDOW_TYPE_DIALOG\0" - "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0" - "_NET_WM_WINDOW_TYPE_POPUP_MENU\0" - "_NET_WM_WINDOW_TYPE_TOOLTIP\0" - "_NET_WM_WINDOW_TYPE_NOTIFICATION\0" - "_NET_WM_WINDOW_TYPE_COMBO\0" - "_NET_WM_WINDOW_TYPE_DND\0" - "_NET_WM_WINDOW_TYPE_NORMAL\0" - "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0" - - "_KDE_NET_WM_FRAME_STRUT\0" - - "_NET_STARTUP_INFO\0" - "_NET_STARTUP_INFO_BEGIN\0" - - "_NET_SUPPORTING_WM_CHECK\0" - - "_NET_WM_CM_S0\0" - - "_NET_SYSTEM_TRAY_VISUAL\0" - - "_NET_ACTIVE_WINDOW\0" - - // Property formats - "COMPOUND_TEXT\0" - "TEXT\0" - "UTF8_STRING\0" - - // xdnd - "XdndEnter\0" - "XdndPosition\0" - "XdndStatus\0" - "XdndLeave\0" - "XdndDrop\0" - "XdndFinished\0" - "XdndTypeList\0" - "XdndActionList\0" - - "XdndSelection\0" - - "XdndAware\0" - "XdndProxy\0" - - "XdndActionCopy\0" - "XdndActionLink\0" - "XdndActionMove\0" - "XdndActionPrivate\0" - - // Motif DND - "_MOTIF_DRAG_AND_DROP_MESSAGE\0" - "_MOTIF_DRAG_INITIATOR_INFO\0" - "_MOTIF_DRAG_RECEIVER_INFO\0" - "_MOTIF_DRAG_WINDOW\0" - "_MOTIF_DRAG_TARGETS\0" - - "XmTRANSFER_SUCCESS\0" - "XmTRANSFER_FAILURE\0" - - // Xkb - "_XKB_RULES_NAMES\0" - - // XEMBED - "_XEMBED\0" - "_XEMBED_INFO\0" - - // Wacom old. (before version 0.10) - "Wacom Stylus\0" - "Wacom Cursor\0" - "Wacom Eraser\0" - - // Tablet - "STYLUS\0" - "ERASER\0" -}; - -/*! - \internal - Try to resolve a \a symbol from \a library with the version specified - by \a vernum. - - Note that, in the case of the Xfixes library, \a vernum is not the same as - \c XFIXES_MAJOR - it is a part of soname and may differ from the Xfixes - version. -*/ -static QFunctionPointer qt_load_library_runtime(const char *library, int vernum, - int highestVernum, const char *symbol) -{ - QList<int> versions; - // we try to load in the following order: - // explicit version -> the default one -> (from the highest (highestVernum) to the lowest (vernum) ) - if (vernum != -1) - versions << vernum; - versions << -1; - if (vernum != -1) { - for(int i = highestVernum; i > vernum; --i) - versions << i; - } - Q_FOREACH(int version, versions) { - QLatin1String libName(library); - QLibrary xfixesLib(libName, version); - QFunctionPointer ptr = xfixesLib.resolve(symbol); - if (ptr) - return ptr; - } - return 0; -} - -# define XFIXES_LOAD_RUNTIME(vernum, symbol, symbol_type) \ - (symbol_type)qt_load_library_runtime("libXfixes", vernum, 4, #symbol); -# define XFIXES_LOAD_V1(symbol) \ - XFIXES_LOAD_RUNTIME(1, symbol, Ptr##symbol) -# define XFIXES_LOAD_V2(symbol) \ - XFIXES_LOAD_RUNTIME(2, symbol, Ptr##symbol) - - -class QTestLiteStaticInfoPrivate -{ -public: - QTestLiteStaticInfoPrivate() - : use_xfixes(false) - , xfixes_major(0) - , xfixes_eventbase(0) - , xfixes_errorbase(0) - { - QXlibScreen *screen = static_cast<QXlibScreen *> (QGuiApplication::primaryScreen()->handle()); - Q_ASSERT(screen); - - initializeAllAtoms(screen); - initializeSupportedAtoms(screen); - - resolveXFixes(screen); - } - - bool isSupportedByWM(Atom atom) - { - if (!m_supportedAtoms) - return false; - - bool supported = false; - int i = 0; - while (m_supportedAtoms[i] != 0) { - if (m_supportedAtoms[i++] == atom) { - supported = true; - break; - } - } - - return supported; - } - - Atom atom(QXlibStatic::X11Atom atom) - { - return m_allAtoms[atom]; - } - - bool useXFixes() const { return use_xfixes; } - - int xFixesEventBase() const {return xfixes_eventbase; } - - PtrXFixesSelectSelectionInput xFixesSelectSelectionInput() const - { - return ptrXFixesSelectSelectionInput; - } - - QImage qimageFromXImage(XImage *xi) - { - QImage::Format format = QImage::Format_ARGB32_Premultiplied; - if (xi->depth == 24) - format = QImage::Format_RGB32; - else if (xi->depth == 16) - format = QImage::Format_RGB16; - - QImage image = QImage((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format).copy(); - - // we may have to swap the byte order - if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst) - || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst)) - { - for (int i=0; i < image.height(); i++) { - if (xi->depth == 16) { - ushort *p = (ushort*)image.scanLine(i); - ushort *end = p + image.width(); - while (p < end) { - *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff); - p++; - } - } else { - uint *p = (uint*)image.scanLine(i); - uint *end = p + image.width(); - while (p < end) { - *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000) - | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff); - p++; - } - } - } - } - - // fix-up alpha channel - if (format == QImage::Format_RGB32) { - QRgb *p = (QRgb *)image.bits(); - for (int y = 0; y < xi->height; ++y) { - for (int x = 0; x < xi->width; ++x) - p[x] |= 0xff000000; - p += xi->bytes_per_line / 4; - } - } - - return image; - } - - -private: - - void initializeAllAtoms(QXlibScreen *screen) { - const char *names[QXlibStatic::NAtoms]; - const char *ptr = x11_atomnames; - - int i = 0; - while (*ptr) { - names[i++] = ptr; - while (*ptr) - ++ptr; - ++ptr; - } - - Q_ASSERT(i == QXlibStatic::NPredefinedAtoms); - - QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_"); - settings_atom_name += XDisplayName(qPrintable(screen->display()->displayName())); - names[i++] = settings_atom_name; - - Q_ASSERT(i == QXlibStatic::NAtoms); - #if 0//defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 6) - XInternAtoms(screen->display(), (char **)names, i, False, m_allAtoms); - #else - for (i = 0; i < QXlibStatic::NAtoms; ++i) - m_allAtoms[i] = XInternAtom(screen->display()->nativeDisplay(), (char *)names[i], False); - #endif - } - - void initializeSupportedAtoms(QXlibScreen *screen) - { - Atom type; - int format; - long offset = 0; - unsigned long nitems, after; - unsigned char *data = 0; - - int e = XGetWindowProperty(screen->display()->nativeDisplay(), screen->rootWindow(), - this->atom(QXlibStatic::_NET_SUPPORTED), 0, 0, - False, XA_ATOM, &type, &format, &nitems, &after, &data); - if (data) - XFree(data); - - if (e == Success && type == XA_ATOM && format == 32) { - QBuffer ts; - ts.open(QIODevice::WriteOnly); - - while (after > 0) { - XGetWindowProperty(screen->display()->nativeDisplay(), screen->rootWindow(), - this->atom(QXlibStatic::_NET_SUPPORTED), offset, 1024, - False, XA_ATOM, &type, &format, &nitems, &after, &data); - - if (type == XA_ATOM && format == 32) { - ts.write(reinterpret_cast<char *>(data), nitems * sizeof(long)); - offset += nitems; - } else - after = 0; - if (data) - XFree(data); - } - - // compute nitems - QByteArray buffer(ts.buffer()); - nitems = buffer.size() / sizeof(Atom); - m_supportedAtoms = new Atom[nitems + 1]; - Atom *a = (Atom *) buffer.data(); - uint i; - for (i = 0; i < nitems; i++) - m_supportedAtoms[i] = a[i]; - m_supportedAtoms[nitems] = 0; - - } - } - - void resolveXFixes(QXlibScreen *screen) - { -#ifndef QT_NO_XFIXES - // See if Xfixes is supported on the connected display - if (XQueryExtension(screen->display()->nativeDisplay(), "XFIXES", &xfixes_major, - &xfixes_eventbase, &xfixes_errorbase)) { - ptrXFixesQueryExtension = XFIXES_LOAD_V1(XFixesQueryExtension); - ptrXFixesQueryVersion = XFIXES_LOAD_V1(XFixesQueryVersion); - ptrXFixesSetCursorName = XFIXES_LOAD_V2(XFixesSetCursorName); - ptrXFixesSelectSelectionInput = XFIXES_LOAD_V2(XFixesSelectSelectionInput); - - if(ptrXFixesQueryExtension && ptrXFixesQueryVersion - && ptrXFixesQueryExtension(screen->display()->nativeDisplay(), &xfixes_eventbase, - &xfixes_errorbase)) { - // Xfixes is supported. - // Note: the XFixes protocol version is negotiated using QueryVersion. - // We supply the highest version we support, the X server replies with - // the highest version it supports, but no higher than the version we - // asked for. The version sent back is the protocol version the X server - // will use to talk us. If this call is removed, the behavior of the - // X server when it receives an XFixes request is undefined. - int major = 3; - int minor = 0; - ptrXFixesQueryVersion(screen->display()->nativeDisplay(), &major, &minor); - use_xfixes = (major >= 1); - xfixes_major = major; - } - } -#endif // QT_NO_XFIXES - - } - - Atom *m_supportedAtoms; - Atom m_allAtoms[QXlibStatic::NAtoms]; - -#ifndef QT_NO_XFIXES - PtrXFixesQueryExtension ptrXFixesQueryExtension; - PtrXFixesQueryVersion ptrXFixesQueryVersion; - PtrXFixesSetCursorName ptrXFixesSetCursorName; - PtrXFixesSelectSelectionInput ptrXFixesSelectSelectionInput; -#endif - - bool use_xfixes; - int xfixes_major; - int xfixes_eventbase; - int xfixes_errorbase; - -}; -Q_GLOBAL_STATIC(QTestLiteStaticInfoPrivate, qTestLiteStaticInfoPrivate); - - -Atom QXlibStatic::atom(QXlibStatic::X11Atom atom) -{ - return qTestLiteStaticInfoPrivate()->atom(atom); -} - -bool QXlibStatic::isSupportedByWM(Atom atom) -{ - return qTestLiteStaticInfoPrivate()->isSupportedByWM(atom); -} - -bool QXlibStatic::useXFixes() -{ - return qTestLiteStaticInfoPrivate()->useXFixes(); -} - -int QXlibStatic::xFixesEventBase() -{ - return qTestLiteStaticInfoPrivate()->xFixesEventBase(); -} - -#ifndef QT_NO_XFIXES -PtrXFixesSelectSelectionInput QXlibStatic::xFixesSelectSelectionInput() -{ - qDebug() << qTestLiteStaticInfoPrivate()->useXFixes(); - if (!qTestLiteStaticInfoPrivate()->useXFixes()) - return 0; - - return qTestLiteStaticInfoPrivate()->xFixesSelectSelectionInput(); -} - -QImage QXlibStatic::qimageFromXImage(XImage *xi) -{ - return qTestLiteStaticInfoPrivate()->qimageFromXImage(xi); -} -#endif //QT_NO_XFIXES diff --git a/src/plugins/platforms/xlib/qxlibstatic.h b/src/plugins/platforms/xlib/qxlibstatic.h deleted file mode 100644 index 6fcf505220e..00000000000 --- a/src/plugins/platforms/xlib/qxlibstatic.h +++ /dev/null @@ -1,417 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTESTLITESTATICINFO_H -#define QTESTLITESTATICINFO_H - -#include <QtCore/QTextStream> -#include <QtCore/QDataStream> -#include <QtCore/QMetaType> -#include <QtCore/QVariant> -// qcoreapplication_p.h includes qsettings.h which undefines Status -// therefore it is included here before the X stuff. -#include <QtCore/private/qcoreapplication_p.h> - -#if defined(_XLIB_H_) // crude hack, but... -#error "cannot include <X11/Xlib.h> before this file" -#endif -#define XRegisterIMInstantiateCallback qt_XRegisterIMInstantiateCallback -#define XUnregisterIMInstantiateCallback qt_XUnregisterIMInstantiateCallback -#define XSetIMValues qt_XSetIMValues -#include <X11/Xlib.h> -#undef XRegisterIMInstantiateCallback -#undef XUnregisterIMInstantiateCallback -#undef XSetIMValues - -#include <X11/Xutil.h> -#include <X11/Xos.h> -#ifdef index -# undef index -#endif -#ifdef rindex -# undef rindex -#endif -#ifdef Q_OS_VXWORS -# ifdef open -# undef open -# endif -# ifdef getpid -# undef getpid -# endif -#endif // Q_OS_VXWORKS -#include <X11/Xatom.h> - -//#define QT_NO_SHAPE -#ifdef QT_NO_SHAPE -# define XShapeCombineRegion(a,b,c,d,e,f,g) -# define XShapeCombineMask(a,b,c,d,e,f,g) -#else -# include <X11/extensions/shape.h> -#endif // QT_NO_SHAPE - - -#if !defined (QT_NO_TABLET) -# include <X11/extensions/XInput.h> -#if defined (Q_OS_IRIX) -# include <X11/extensions/SGIMisc.h> -# include <wacom.h> -#endif -#endif // QT_NO_TABLET - - -// #define QT_NO_XINERAMA -#ifndef QT_NO_XINERAMA -// XFree86 does not C++ify Xinerama (at least up to XFree86 4.0.3). -extern "C" { -# include <X11/extensions/Xinerama.h> -} -#endif // QT_NO_XINERAMA - -// #define QT_NO_XRANDR -#ifndef QT_NO_XRANDR -# include <X11/extensions/Xrandr.h> -#endif // QT_NO_XRANDR - -// #define QT_NO_XRENDER -#ifndef QT_NO_XRENDER -# include <X11/extensions/Xrender.h> -#endif // QT_NO_XRENDER - -#ifndef QT_NO_XSYNC -extern "C" { -# include "X11/extensions/sync.h" -} -#endif - -// #define QT_NO_XKB -#ifndef QT_NO_XKB -# include <X11/XKBlib.h> -#endif // QT_NO_XKB - - -#if !defined(XlibSpecificationRelease) -# define X11R4 -typedef char *XPointer; -#else -# undef X11R4 -#endif - -#ifndef QT_NO_XFIXES -#include <X11/extensions/Xfixes.h> -typedef Bool (*PtrXFixesQueryExtension)(Display *, int *, int *); -typedef Status (*PtrXFixesQueryVersion)(Display *, int *, int *); -typedef void (*PtrXFixesSetCursorName)(Display *dpy, Cursor cursor, const char *name); -typedef void (*PtrXFixesSelectSelectionInput)(Display *dpy, Window win, Atom selection, unsigned long eventMask); -#endif // QT_NO_XFIXES - -#ifndef QT_NO_XCURSOR -#include <X11/Xcursor/Xcursor.h> -typedef Cursor (*PtrXcursorLibraryLoadCursor)(Display *, const char *); -#endif // QT_NO_XCURSOR - -#ifndef QT_NO_XINERAMA -typedef Bool (*PtrXineramaQueryExtension)(Display *dpy, int *event_base, int *error_base); -typedef Bool (*PtrXineramaIsActive)(Display *dpy); -typedef XineramaScreenInfo *(*PtrXineramaQueryScreens)(Display *dpy, int *number); -#endif // QT_NO_XINERAMA - -#ifndef QT_NO_XRANDR -typedef void (*PtrXRRSelectInput)(Display *, Window, int); -typedef int (*PtrXRRUpdateConfiguration)(XEvent *); -typedef int (*PtrXRRRootToScreen)(Display *, Window); -typedef Bool (*PtrXRRQueryExtension)(Display *, int *, int *); -#endif // QT_NO_XRANDR - -#ifndef QT_NO_XINPUT -typedef int (*PtrXCloseDevice)(Display *, XDevice *); -typedef XDeviceInfo* (*PtrXListInputDevices)(Display *, int *); -typedef XDevice* (*PtrXOpenDevice)(Display *, XID); -typedef void (*PtrXFreeDeviceList)(XDeviceInfo *); -typedef int (*PtrXSelectExtensionEvent)(Display *, Window, XEventClass *, int); -#endif // QT_NO_XINPUT - -/* - * Solaris patch 108652-47 and higher fixes crases in - * XRegisterIMInstantiateCallback, but the function doesn't seem to - * work. - * - * Instead, we disabled R6 input, and open the input method - * immediately at application start. - */ - -//######### XFree86 has wrong declarations for XRegisterIMInstantiateCallback -//######### and XUnregisterIMInstantiateCallback in at least version 3.3.2. -//######### Many old X11R6 header files lack XSetIMValues. -//######### Therefore, we have to declare these functions ourselves. - -extern "C" Bool XRegisterIMInstantiateCallback( - Display*, - struct _XrmHashBucketRec*, - char*, - char*, - XIMProc, //XFree86 has XIDProc, which has to be wrong - XPointer -); - -extern "C" Bool XUnregisterIMInstantiateCallback( - Display*, - struct _XrmHashBucketRec*, - char*, - char*, - XIMProc, //XFree86 has XIDProc, which has to be wrong - XPointer -); - -#ifndef X11R4 -# include <X11/Xlocale.h> -#endif // X11R4 - - -#ifndef QT_NO_MITSHM -# include <X11/extensions/XShm.h> -#endif // QT_NO_MITSHM - -// rename a couple of X defines to get rid of name clashes -// resolve the conflict between X11's FocusIn and QEvent::FocusIn -enum { - XFocusOut = FocusOut, - XFocusIn = FocusIn, - XKeyPress = KeyPress, - XKeyRelease = KeyRelease, - XNone = None, - XRevertToParent = RevertToParent, - XGrayScale = GrayScale, - XCursorShape = CursorShape -}; -#undef FocusOut -#undef FocusIn -#undef KeyPress -#undef KeyRelease -#undef None -#undef RevertToParent -#undef GrayScale -#undef CursorShape - -#ifdef FontChange -#undef FontChange -#endif - - -class QXlibStatic -{ -public: - enum X11Atom { - // window-manager <-> client protocols - WM_PROTOCOLS, - WM_DELETE_WINDOW, - WM_TAKE_FOCUS, - _NET_WM_PING, - _NET_WM_CONTEXT_HELP, - _NET_WM_SYNC_REQUEST, - _NET_WM_SYNC_REQUEST_COUNTER, - - // ICCCM window state - WM_STATE, - WM_CHANGE_STATE, - - // Session management - WM_CLIENT_LEADER, - WM_WINDOW_ROLE, - SM_CLIENT_ID, - - // Clipboard - CLIPBOARD, - INCR, - TARGETS, - MULTIPLE, - TIMESTAMP, - SAVE_TARGETS, - CLIP_TEMPORARY, - _QT_SELECTION, - _QT_CLIPBOARD_SENTINEL, - _QT_SELECTION_SENTINEL, - CLIPBOARD_MANAGER, - - RESOURCE_MANAGER, - - _XSETROOT_ID, - - _QT_SCROLL_DONE, - _QT_INPUT_ENCODING, - - _MOTIF_WM_HINTS, - - DTWM_IS_RUNNING, - ENLIGHTENMENT_DESKTOP, - _DT_SAVE_MODE, - _SGI_DESKS_MANAGER, - - // EWMH (aka NETWM) - _NET_SUPPORTED, - _NET_VIRTUAL_ROOTS, - _NET_WORKAREA, - - _NET_MOVERESIZE_WINDOW, - _NET_WM_MOVERESIZE, - - _NET_WM_NAME, - _NET_WM_ICON_NAME, - _NET_WM_ICON, - - _NET_WM_PID, - - _NET_WM_WINDOW_OPACITY, - - _NET_WM_STATE, - _NET_WM_STATE_ABOVE, - _NET_WM_STATE_BELOW, - _NET_WM_STATE_FULLSCREEN, - _NET_WM_STATE_MAXIMIZED_HORZ, - _NET_WM_STATE_MAXIMIZED_VERT, - _NET_WM_STATE_MODAL, - _NET_WM_STATE_STAYS_ON_TOP, - _NET_WM_STATE_DEMANDS_ATTENTION, - - _NET_WM_USER_TIME, - _NET_WM_USER_TIME_WINDOW, - _NET_WM_FULL_PLACEMENT, - - _NET_WM_WINDOW_TYPE, - _NET_WM_WINDOW_TYPE_DESKTOP, - _NET_WM_WINDOW_TYPE_DOCK, - _NET_WM_WINDOW_TYPE_TOOLBAR, - _NET_WM_WINDOW_TYPE_MENU, - _NET_WM_WINDOW_TYPE_UTILITY, - _NET_WM_WINDOW_TYPE_SPLASH, - _NET_WM_WINDOW_TYPE_DIALOG, - _NET_WM_WINDOW_TYPE_DROPDOWN_MENU, - _NET_WM_WINDOW_TYPE_POPUP_MENU, - _NET_WM_WINDOW_TYPE_TOOLTIP, - _NET_WM_WINDOW_TYPE_NOTIFICATION, - _NET_WM_WINDOW_TYPE_COMBO, - _NET_WM_WINDOW_TYPE_DND, - _NET_WM_WINDOW_TYPE_NORMAL, - _KDE_NET_WM_WINDOW_TYPE_OVERRIDE, - - _KDE_NET_WM_FRAME_STRUT, - - _NET_STARTUP_INFO, - _NET_STARTUP_INFO_BEGIN, - - _NET_SUPPORTING_WM_CHECK, - - _NET_WM_CM_S0, - - _NET_SYSTEM_TRAY_VISUAL, - - _NET_ACTIVE_WINDOW, - - // Property formats - COMPOUND_TEXT, - TEXT, - UTF8_STRING, - - // Xdnd - XdndEnter, - XdndPosition, - XdndStatus, - XdndLeave, - XdndDrop, - XdndFinished, - XdndTypelist, - XdndActionList, - - XdndSelection, - - XdndAware, - XdndProxy, - - XdndActionCopy, - XdndActionLink, - XdndActionMove, - XdndActionPrivate, - - // Motif DND - _MOTIF_DRAG_AND_DROP_MESSAGE, - _MOTIF_DRAG_INITIATOR_INFO, - _MOTIF_DRAG_RECEIVER_INFO, - _MOTIF_DRAG_WINDOW, - _MOTIF_DRAG_TARGETS, - - XmTRANSFER_SUCCESS, - XmTRANSFER_FAILURE, - - // Xkb - _XKB_RULES_NAMES, - - // XEMBED - _XEMBED, - _XEMBED_INFO, - - XWacomStylus, - XWacomCursor, - XWacomEraser, - - XTabletStylus, - XTabletEraser, - - NPredefinedAtoms, - - _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms, - NAtoms - }; - - static Atom atom(X11Atom atom); - static bool isSupportedByWM(Atom atom); - - static bool useXFixes(); - static int xFixesEventBase(); - - #ifndef QT_NO_XFIXES - static PtrXFixesSelectSelectionInput xFixesSelectSelectionInput(); - #endif //QT_NO_XFIXES - - static QImage qimageFromXImage(XImage *xi); - - -}; - -#endif // QTESTLITESTATICINFO_H diff --git a/src/plugins/platforms/xlib/qxlibwindow.cpp b/src/plugins/platforms/xlib/qxlibwindow.cpp deleted file mode 100644 index 00403aed645..00000000000 --- a/src/plugins/platforms/xlib/qxlibwindow.cpp +++ /dev/null @@ -1,739 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtGui/private/qguiapplication_p.h> -#include "qxlibwindow.h" - -#include "qxlibintegration.h" -#include "qxlibscreen.h" -#include "qxlibkeyboard.h" -#include "qxlibstatic.h" -#include "qxlibdisplay.h" - -#if !defined(QT_NO_OPENGL) -#if !defined(QT_OPENGL_ES_2) -#include "qglxintegration.h" -#include "private/qglxconvenience_p.h" -#else -#include "../eglconvenience/qeglconvenience.h" -#include "../eglconvenience/qeglplatformcontext.h" -#include "../eglconvenience/qxlibeglintegration.h" -#endif //QT_OPENGL_ES_2 -#endif //QT_NO_OPENGL - - -#include <QtGui/QWindowSystemInterface> -#include <QSocketNotifier> -#include <QGuiApplication> -#include <QStyleHints> -#include <QDebug> - -//#define MYX11_DEBUG - -QT_BEGIN_NAMESPACE - -QHash<Window, QXlibWindow *> QXlibWindow::windowMap; - - -QXlibWindow::QXlibWindow(QWindow *window) - : QPlatformWindow(window) - , mGLContext(0) - , mScreen(QXlibScreen::testLiteScreenForWidget(window)) -{ - int x = window->x(); - int y = window->y(); - int w = window->width(); - int h = window->height(); - - mSurfaceFormat = window->requestedFormat(); - -#if !defined(QT_NO_OPENGL) - if(window->surfaceType() == QWindow::OpenGLSurface) { -#if !defined(QT_OPENGL_ES_2) - XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber(), &mSurfaceFormat); - if (!visualInfo) - qFatal("Could not initialize GLX"); -#else - QPlatformWindowFormat windowFormat = correctColorBuffers(window->platformWindowFormat()); - - EGLDisplay eglDisplay = mScreen->eglDisplay(); - EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,windowFormat); - VisualID id = QXlibEglIntegration::getCompatibleVisualId(mScreen->display()->nativeDisplay(), eglDisplay, eglConfig); - - XVisualInfo visualInfoTemplate; - memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); - visualInfoTemplate.visualid = id; - - XVisualInfo *visualInfo; - int matchingCount = 0; - visualInfo = XGetVisualInfo(mScreen->display()->nativeDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount); - if (!visualInfo) - qFatal("Could not initialize EGL"); -#endif //!defined(QT_OPENGL_ES_2) - mDepth = visualInfo->depth; - mFormat = (mDepth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; - mVisual = visualInfo->visual; - Colormap cmap = XCreateColormap(mScreen->display()->nativeDisplay(), mScreen->rootWindow(), visualInfo->visual, AllocNone); - - XSetWindowAttributes a; - a.background_pixel = WhitePixel(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber()); - a.border_pixel = BlackPixel(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber()); - a.colormap = cmap; - x_window = XCreateWindow(mScreen->display()->nativeDisplay(), mScreen->rootWindow(),x, y, w, h, - 0, visualInfo->depth, InputOutput, visualInfo->visual, - CWBackPixel|CWBorderPixel|CWColormap, &a); - XFree(visualInfo); - } else -#endif //!defined(QT_NO_OPENGL) - { - mDepth = mScreen->depth(); - mFormat = (mDepth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; - mVisual = mScreen->defaultVisual(); - - x_window = XCreateSimpleWindow(mScreen->display()->nativeDisplay(), mScreen->rootWindow(), - x, y, w, h, 0 /*border_width*/, - mScreen->blackPixel(), mScreen->whitePixel()); - } - -#ifdef MYX11_DEBUG - qDebug() << "QTestLiteWindow::QTestLiteWindow creating" << hex << x_window << window; -#endif - - XSetWindowBackgroundPixmap(mScreen->display()->nativeDisplay(), x_window, XNone); - - XSelectInput(mScreen->display()->nativeDisplay(), x_window, - ExposureMask | KeyPressMask | KeyReleaseMask | - EnterWindowMask | LeaveWindowMask | FocusChangeMask | - PointerMotionMask | ButtonPressMask | ButtonReleaseMask | - ButtonMotionMask | PropertyChangeMask | - StructureNotifyMask); - - gc = createGC(); - - Atom protocols[5]; - int n = 0; - protocols[n++] = QXlibStatic::atom(QXlibStatic::WM_DELETE_WINDOW); // support del window protocol - protocols[n++] = QXlibStatic::atom(QXlibStatic::WM_TAKE_FOCUS); // support take focus window protocol -// protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_PING); // support _NET_WM_PING protocol -#ifndef QT_NO_XSYNC - protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_SYNC_REQUEST); // support _NET_WM_SYNC_REQUEST protocol -#endif // QT_NO_XSYNC - if (window->windowFlags() & Qt::WindowContextHelpButtonHint) - protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_CONTEXT_HELP); - XSetWMProtocols(mScreen->display()->nativeDisplay(), x_window, protocols, n); - - windowMap.insert(x_window, this); -} - - - -QXlibWindow::~QXlibWindow() -{ -#ifdef MYX11_DEBUG - qDebug() << "~QTestLiteWindow" << hex << x_window; -#endif - - windowMap.remove(x_window); - - delete mGLContext; - XFreeGC(mScreen->display()->nativeDisplay(), gc); - XDestroyWindow(mScreen->display()->nativeDisplay(), x_window); -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Mouse event stuff -static Qt::MouseButtons translateMouseButtons(int s) -{ - Qt::MouseButtons ret = 0; - if (s & Button1Mask) - ret |= Qt::LeftButton; - if (s & Button2Mask) - ret |= Qt::MidButton; - if (s & Button3Mask) - ret |= Qt::RightButton; - return ret; -} - - - -void QXlibWindow::handleMouseEvent(QEvent::Type type, XButtonEvent *e) -{ - static QPoint mousePoint; - - Qt::MouseButton button = Qt::NoButton; - Qt::MouseButtons buttons = translateMouseButtons(e->state); - Qt::KeyboardModifiers modifiers = mScreen->keyboard()->translateModifiers(e->state); - if (type != QEvent::MouseMove) { - switch (e->button) { - case Button1: button = Qt::LeftButton; break; - case Button2: button = Qt::MidButton; break; - case Button3: button = Qt::RightButton; break; - case Button4: - case Button5: - case 6: - case 7: { - //mouse wheel - if (type == QEvent::MouseButtonPress) { - //logic borrowed from qapplication_x11.cpp - int delta = 120 * ((e->button == Button4 || e->button == 6) ? 1 : -1); - bool hor = (((e->button == Button4 || e->button == Button5) - && (modifiers & Qt::AltModifier)) - || (e->button == 6 || e->button == 7)); - QWindowSystemInterface::handleWheelEvent(window(), e->time, - QPoint(e->x, e->y), - QPoint(e->x_root, e->y_root), - delta, hor ? Qt::Horizontal : Qt::Vertical); - } - return; - } - case 8: button = Qt::BackButton; break; // Also known as Qt::ExtraButton1 - case 9: button = Qt::ForwardButton; break; // Also known as Qt::ExtraButton2 - case 10: button = Qt::ExtraButton3; break; - case 11: button = Qt::ExtraButton4; break; - case 12: button = Qt::ExtraButton5; break; - case 13: button = Qt::ExtraButton6; break; - case 14: button = Qt::ExtraButton7; break; - case 15: button = Qt::ExtraButton8; break; - case 16: button = Qt::ExtraButton9; break; - case 17: button = Qt::ExtraButton10; break; - case 18: button = Qt::ExtraButton11; break; - case 19: button = Qt::ExtraButton12; break; - case 20: button = Qt::ExtraButton13; break; - case 21: button = Qt::ExtraButton14; break; - case 22: button = Qt::ExtraButton15; break; - case 23: button = Qt::ExtraButton16; break; - case 24: button = Qt::ExtraButton17; break; - case 25: button = Qt::ExtraButton18; break; - case 26: button = Qt::ExtraButton19; break; - case 27: button = Qt::ExtraButton20; break; - case 28: button = Qt::ExtraButton21; break; - case 29: button = Qt::ExtraButton22; break; - case 30: button = Qt::ExtraButton23; break; - case 31: button = Qt::ExtraButton24; break; - default: break; - } - } - - buttons ^= button; // X event uses state *before*, Qt uses state *after* - - QWindowSystemInterface::handleMouseEvent(window(), e->time, QPoint(e->x, e->y), - QPoint(e->x_root, e->y_root), - buttons); - - mousePoint = QPoint(e->x_root, e->y_root); -} - -void QXlibWindow::handleCloseEvent() -{ - QWindowSystemInterface::handleCloseEvent(window()); -} - - -void QXlibWindow::handleEnterEvent() -{ - QWindowSystemInterface::handleEnterEvent(window()); -} - -void QXlibWindow::handleLeaveEvent() -{ - QWindowSystemInterface::handleLeaveEvent(window()); -} - -void QXlibWindow::handleFocusInEvent() -{ - QWindowSystemInterface::handleWindowActivated(window()); -} - -void QXlibWindow::handleFocusOutEvent() -{ - QWindowSystemInterface::handleWindowActivated(0); -} - - - -void QXlibWindow::setGeometry(const QRect &rect) -{ - XMoveResizeWindow(mScreen->display()->nativeDisplay(), x_window, rect.x(), rect.y(), rect.width(), rect.height()); - QPlatformWindow::setGeometry(rect); -} - - -Qt::WindowFlags QXlibWindow::windowFlags() const -{ - return mWindowFlags; -} - -WId QXlibWindow::winId() const -{ - return x_window; -} - -void QXlibWindow::setParent(const QPlatformWindow *parent) -{ - QPoint topLeft = geometry().topLeft(); - WId parentWinId = parent ? parent->winId() : mScreen->rootWindow(); - XReparentWindow(mScreen->display()->nativeDisplay(),x_window,parentWinId,topLeft.x(),topLeft.y()); -} - -void QXlibWindow::raise() -{ - XRaiseWindow(mScreen->display()->nativeDisplay(), x_window); -} - -void QXlibWindow::lower() -{ - XLowerWindow(mScreen->display()->nativeDisplay(), x_window); -} - -void QXlibWindow::setWindowTitle(const QString &title) -{ - QByteArray ba = title.toLatin1(); //We're not making a general solution here... - XTextProperty windowName; - windowName.value = (unsigned char *)ba.constData(); - windowName.encoding = XA_STRING; - windowName.format = 8; - windowName.nitems = ba.length(); - - XSetWMName(mScreen->display()->nativeDisplay(), x_window, &windowName); -} - -GC QXlibWindow::createGC() -{ - GC gc; - - gc = XCreateGC(mScreen->display()->nativeDisplay(), x_window, 0, 0); - if (gc < 0) { - qWarning("QTestLiteWindow::createGC() could not create GC"); - } - return gc; -} - -void QXlibWindow::requestActivateWindow() -{ - XSetInputFocus(mScreen->display()->nativeDisplay(), x_window, XRevertToParent, CurrentTime); -} - -void QXlibWindow::resizeEvent(XConfigureEvent *e) -{ - int xpos = geometry().x(); - int ypos = geometry().y(); - if ((e->width != geometry().width() || e->height != geometry().height()) && e->x == 0 && e->y == 0) { - //qDebug() << "resize with bogus pos" << e->x << e->y << e->width << e->height << "window"<< hex << window; - } else { - //qDebug() << "geometry change" << e->x << e->y << e->width << e->height << "window"<< hex << window; - xpos = e->x; - ypos = e->y; - } -#ifdef MYX11_DEBUG - qDebug() << hex << x_window << dec << "ConfigureNotify" << e->x << e->y << e->width << e->height << - "geometry" << xpos << ypos << e->width << e->height; -#endif - - QRect newRect(xpos, ypos, e->width, e->height); - QWindowSystemInterface::handleGeometryChange(window(), newRect); -} - -void QXlibWindow::mousePressEvent(XButtonEvent *e) -{ - static long prevTime = 0; - static Window prevWindow; - static int prevX = -999; - static int prevY = -999; - - QEvent::Type type = QEvent::MouseButtonPress; - - const int doubleClickInterval = qApp->styleHints()->mouseDoubleClickInterval(); - if (e->window == prevWindow && long(e->time) - prevTime < doubleClickInterval - && qAbs(e->x - prevX) < 5 && qAbs(e->y - prevY) < 5) { - type = QEvent::MouseButtonDblClick; - prevTime = e->time - doubleClickInterval; //no double click next time - } else { - prevTime = e->time; - } - prevWindow = e->window; - prevX = e->x; - prevY = e->y; - - handleMouseEvent(type, e); -} - -QXlibMWMHints QXlibWindow::getMWMHints() const -{ - QXlibMWMHints mwmhints; - - Atom type; - int format; - ulong nitems, bytesLeft; - uchar *data = 0; - Atom atomForMotifWmHints = QXlibStatic::atom(QXlibStatic::_MOTIF_WM_HINTS); - if ((XGetWindowProperty(mScreen->display()->nativeDisplay(), x_window, atomForMotifWmHints, 0, 5, false, - atomForMotifWmHints, &type, &format, &nitems, &bytesLeft, - &data) == Success) - && (type == atomForMotifWmHints - && format == 32 - && nitems >= 5)) { - mwmhints = *(reinterpret_cast<QXlibMWMHints *>(data)); - } else { - mwmhints.flags = 0L; - mwmhints.functions = MWM_FUNC_ALL; - mwmhints.decorations = MWM_DECOR_ALL; - mwmhints.input_mode = 0L; - mwmhints.status = 0L; - } - - if (data) - XFree(data); - - return mwmhints; -} - -void QXlibWindow::setMWMHints(const QXlibMWMHints &mwmhints) -{ - Atom atomForMotifWmHints = QXlibStatic::atom(QXlibStatic::_MOTIF_WM_HINTS); - if (mwmhints.flags != 0l) { - XChangeProperty(mScreen->display()->nativeDisplay(), x_window, - atomForMotifWmHints, atomForMotifWmHints, 32, - PropModeReplace, (unsigned char *) &mwmhints, 5); - } else { - XDeleteProperty(mScreen->display()->nativeDisplay(), x_window, atomForMotifWmHints); - } -} - -// Returns true if we should set WM_TRANSIENT_FOR on \a w -static inline bool isTransient(const QWindow *w) -{ - return (w->windowType() == Qt::Dialog - || w->windowType() == Qt::Sheet - || w->windowType() == Qt::Tool - || w->windowType() == Qt::SplashScreen - || w->windowType() == Qt::ToolTip - || w->windowType() == Qt::Drawer - || w->windowType() == Qt::Popup); -} - -QVector<Atom> QXlibWindow::getNetWmState() const -{ - QVector<Atom> returnValue; - - // Don't read anything, just get the size of the property data - Atom actualType; - int actualFormat; - ulong propertyLength; - ulong bytesLeft; - uchar *propertyData = 0; - if (XGetWindowProperty(mScreen->display()->nativeDisplay(), x_window, QXlibStatic::atom(QXlibStatic::_NET_WM_STATE), 0, 0, - False, XA_ATOM, &actualType, &actualFormat, - &propertyLength, &bytesLeft, &propertyData) == Success - && actualType == XA_ATOM && actualFormat == 32) { - returnValue.resize(bytesLeft / 4); - XFree((char*) propertyData); - - // fetch all data - if (XGetWindowProperty(mScreen->display()->nativeDisplay(), x_window, QXlibStatic::atom(QXlibStatic::_NET_WM_STATE), 0, - returnValue.size(), False, XA_ATOM, &actualType, &actualFormat, - &propertyLength, &bytesLeft, &propertyData) != Success) { - returnValue.clear(); - } else if (propertyLength != (ulong)returnValue.size()) { - returnValue.resize(propertyLength); - } - - // put it into netWmState - if (!returnValue.isEmpty()) { - memcpy(returnValue.data(), propertyData, returnValue.size() * sizeof(Atom)); - } - XFree((char*) propertyData); - } - - return returnValue; -} - -Qt::WindowFlags QXlibWindow::setWindowFlags(Qt::WindowFlags flags) -{ -// Q_ASSERT(flags & Qt::Window); - mWindowFlags = flags; - -#ifdef MYX11_DEBUG - qDebug() << "QTestLiteWindow::setWindowFlags" << hex << x_window << "flags" << flags; -#endif - Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask)); - - if (type == Qt::ToolTip) - flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint; - if (type == Qt::Popup) - flags |= Qt::X11BypassWindowManagerHint; - - bool topLevel = (flags & Qt::Window); - bool popup = (type == Qt::Popup); - bool dialog = (type == Qt::Dialog - || type == Qt::Sheet); - bool desktop = (type == Qt::Desktop); - bool tool = (type == Qt::Tool || type == Qt::SplashScreen - || type == Qt::ToolTip || type == Qt::Drawer); - - Q_UNUSED(topLevel); - Q_UNUSED(dialog); - Q_UNUSED(desktop); - - bool tooltip = (type == Qt::ToolTip); - - XSetWindowAttributes wsa; - - QXlibMWMHints mwmhints; - mwmhints.flags = 0L; - mwmhints.functions = 0L; - mwmhints.decorations = 0; - mwmhints.input_mode = 0L; - mwmhints.status = 0L; - - - ulong wsa_mask = 0; - if (type != Qt::SplashScreen) { // && customize) { - mwmhints.flags |= MWM_HINTS_DECORATIONS; - - bool customize = flags & Qt::CustomizeWindowHint; - if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) { - mwmhints.decorations |= MWM_DECOR_BORDER; - mwmhints.decorations |= MWM_DECOR_RESIZEH; - - if (flags & Qt::WindowTitleHint) - mwmhints.decorations |= MWM_DECOR_TITLE; - - if (flags & Qt::WindowSystemMenuHint) - mwmhints.decorations |= MWM_DECOR_MENU; - - if (flags & Qt::WindowMinimizeButtonHint) { - mwmhints.decorations |= MWM_DECOR_MINIMIZE; - mwmhints.functions |= MWM_FUNC_MINIMIZE; - } - - if (flags & Qt::WindowMaximizeButtonHint) { - mwmhints.decorations |= MWM_DECOR_MAXIMIZE; - mwmhints.functions |= MWM_FUNC_MAXIMIZE; - } - - if (flags & Qt::WindowCloseButtonHint) - mwmhints.functions |= MWM_FUNC_CLOSE; - } - } else { - // if type == Qt::SplashScreen - mwmhints.decorations = MWM_DECOR_ALL; - } - - if (tool) { - wsa.save_under = True; - wsa_mask |= CWSaveUnder; - } - - if (flags & Qt::X11BypassWindowManagerHint) { - wsa.override_redirect = True; - wsa_mask |= CWOverrideRedirect; - } -#if 0 - if (wsa_mask && initializeWindow) { - Q_ASSERT(id); - XChangeWindowAttributes(dpy, id, wsa_mask, &wsa); - } -#endif - if (mwmhints.functions != 0) { - mwmhints.flags |= MWM_HINTS_FUNCTIONS; - mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE; - } else { - mwmhints.functions = MWM_FUNC_ALL; - } - - if (!(flags & Qt::FramelessWindowHint) - && flags & Qt::CustomizeWindowHint - && flags & Qt::WindowTitleHint - && !(flags & - (Qt::WindowMinimizeButtonHint - | Qt::WindowMaximizeButtonHint - | Qt::WindowCloseButtonHint))) { - // a special case - only the titlebar without any button - mwmhints.flags = MWM_HINTS_FUNCTIONS; - mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE; - mwmhints.decorations = 0; - } - - if (window()->windowModality() == Qt::WindowModal) { - mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL; - } else if (window()->windowModality() == Qt::ApplicationModal) { - mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL; - } - - setMWMHints(mwmhints); - - QVector<Atom> netWmState = getNetWmState(); - - if (flags & Qt::WindowStaysOnTopHint) { - if (flags & Qt::WindowStaysOnBottomHint) - qWarning() << "QWindow: Incompatible window flags: the window can't be on top and on bottom at the same time"; - if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_ABOVE))) - netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_ABOVE)); - if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_STAYS_ON_TOP))) - netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_STAYS_ON_TOP)); - } else if (flags & Qt::WindowStaysOnBottomHint) { - if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_BELOW))) - netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_BELOW)); - } - if (window()->windowState() & Qt::WindowFullScreen) { - if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_FULLSCREEN))) - netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_FULLSCREEN)); - } - if (window()->windowState() & Qt::WindowMaximized) { - if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_HORZ))) - netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_HORZ)); - if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_VERT))) - netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_VERT)); - } - if (window()->windowModality() != Qt::NonModal) { - if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MODAL))) - netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MODAL)); - } - - if (!netWmState.isEmpty()) { - XChangeProperty(mScreen->display()->nativeDisplay(), x_window, - QXlibStatic::atom(QXlibStatic::_NET_WM_STATE), XA_ATOM, 32, PropModeReplace, - (unsigned char *) netWmState.data(), netWmState.size()); - } else { - XDeleteProperty(mScreen->display()->nativeDisplay(), x_window, QXlibStatic::atom(QXlibStatic::_NET_WM_STATE)); - } - -//##### only if initializeWindow??? - - if (popup || tooltip) { // popup widget -#ifdef MYX11_DEBUG - qDebug() << "Doing XChangeWindowAttributes for popup" << wsa.override_redirect; -#endif - // set EWMH window types - // setNetWmWindowTypes(); - - wsa.override_redirect = True; - wsa.save_under = True; - XChangeWindowAttributes(mScreen->display()->nativeDisplay(), x_window, CWOverrideRedirect | CWSaveUnder, - &wsa); - } else { -#ifdef MYX11_DEBUG - qDebug() << "Doing XChangeWindowAttributes for non-popup"; -#endif - } - - return flags; -} - -Qt::WindowState QXlibWindow::setWindowState(Qt::WindowState state) -{ - // #### - return state; -} - -void QXlibWindow::setVisible(bool visible) -{ -#ifdef MYX11_DEBUG - qDebug() << "QTestLiteWindow::setVisible" << visible << hex << x_window; -#endif - if (isTransient(window())) { - Window parentXWindow = x_window; - QWindow *parent = window()->parent(); - if (parent && parent->handle()) { - QXlibWindow *xlibParent = static_cast<QXlibWindow *>(parent->handle()); - parentXWindow = xlibParent->x_window; - } - XSetTransientForHint(mScreen->display()->nativeDisplay(),x_window,parentXWindow); - } - - if (visible) { - qDebug() << ">>> mapping"; - //ensure that the window is viewed in correct position. - doSizeHints(); - XMapWindow(mScreen->display()->nativeDisplay(), x_window); - } else { - XUnmapWindow(mScreen->display()->nativeDisplay(), x_window); - } -} - -void QXlibWindow::setCursor(const Cursor &cursor) -{ - XDefineCursor(mScreen->display()->nativeDisplay(), x_window, cursor); - mScreen->display()->flush(); -} - -QSurfaceFormat QXlibWindow::format() const -{ - return mSurfaceFormat; -} - - -Window QXlibWindow::xWindow() const -{ - return x_window; -} - -GC QXlibWindow::graphicsContext() const -{ - return gc; -} - -void QXlibWindow::doSizeHints() -{ -// Q_ASSERT(window()->testAttribute(Qt::WA_WState_Created)); - XSizeHints s; - s.flags = 0; - QRect g = geometry(); - s.x = g.x(); - s.y = g.y(); - s.width = g.width(); - s.height = g.height(); - s.flags |= USPosition; - s.flags |= PPosition; - s.flags |= USSize; - s.flags |= PSize; - s.flags |= PWinGravity; - s.win_gravity = QGuiApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity; - XSetWMNormalHints(mScreen->display()->nativeDisplay(), x_window, &s); -} - - -QXlibWindow *QXlibWindow::platformWindowForXWindow(Window window) -{ - return windowMap.value(window); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/xlib/qxlibwindow.h b/src/plugins/platforms/xlib/qxlibwindow.h deleted file mode 100644 index 6b9e2d63bde..00000000000 --- a/src/plugins/platforms/xlib/qxlibwindow.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTESTLITEWINDOW_H -#define QTESTLITEWINDOW_H - -#include "qxlibintegration.h" - -#include <QPlatformWindow> -#include <QEvent> - -#include <QObject> -#include <QImage> -#include <QHash> - -struct QXlibMWMHints { - ulong flags, functions, decorations; - long input_mode; - ulong status; -}; - -enum { - MWM_HINTS_FUNCTIONS = (1L << 0), - - MWM_FUNC_ALL = (1L << 0), - MWM_FUNC_RESIZE = (1L << 1), - MWM_FUNC_MOVE = (1L << 2), - MWM_FUNC_MINIMIZE = (1L << 3), - MWM_FUNC_MAXIMIZE = (1L << 4), - MWM_FUNC_CLOSE = (1L << 5), - - MWM_HINTS_DECORATIONS = (1L << 1), - - MWM_DECOR_ALL = (1L << 0), - MWM_DECOR_BORDER = (1L << 1), - MWM_DECOR_RESIZEH = (1L << 2), - MWM_DECOR_TITLE = (1L << 3), - MWM_DECOR_MENU = (1L << 4), - MWM_DECOR_MINIMIZE = (1L << 5), - MWM_DECOR_MAXIMIZE = (1L << 6), - - MWM_HINTS_INPUT_MODE = (1L << 2), - - MWM_INPUT_MODELESS = 0L, - MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L, - MWM_INPUT_FULL_APPLICATION_MODAL = 3L -}; - -class QXlibWindow : public QPlatformWindow -{ -public: - QXlibWindow(QWindow *window); - ~QXlibWindow(); - - - void mousePressEvent(XButtonEvent*); - void handleMouseEvent(QEvent::Type, XButtonEvent *ev); - - void handleCloseEvent(); - void handleEnterEvent(); - void handleLeaveEvent(); - void handleFocusInEvent(); - void handleFocusOutEvent(); - - void resizeEvent(XConfigureEvent *configure_event); - - void requestActivateWindow(); - - void setGeometry(const QRect &rect); - - Qt::WindowFlags setWindowFlags(Qt::WindowFlags type); - Qt::WindowFlags windowFlags() const; - Qt::WindowState setWindowState(Qt::WindowState state); - - void setVisible(bool visible); - WId winId() const; - void setParent(const QPlatformWindow *parent); - void raise(); - void lower(); - void setWindowTitle(const QString &title); - - void setCursor(const Cursor &cursor); - - Window xWindow() const; - GC graphicsContext() const; - - QSurfaceFormat format() const; - Visual* visual() const { return mVisual; } - int depth() const { return mDepth; } - - static QXlibWindow *platformWindowForXWindow(Window window); - -protected: - QVector<Atom> getNetWmState() const; - void setMWMHints(const QXlibMWMHints &mwmhints); - QXlibMWMHints getMWMHints() const; - - void doSizeHints(); - -private: - Window x_window; - GC gc; - - uint mDepth; - QImage::Format mFormat; - Visual* mVisual; - - QSurfaceFormat mSurfaceFormat; - - GC createGC(); - - QPlatformOpenGLContext *mGLContext; - QXlibScreen *mScreen; - Qt::WindowFlags mWindowFlags; - - static QHash<Window, QXlibWindow *> windowMap; -}; - -#endif diff --git a/src/plugins/platforms/xlib/xlib.json b/src/plugins/platforms/xlib/xlib.json deleted file mode 100644 index 524be2fc6d8..00000000000 --- a/src/plugins/platforms/xlib/xlib.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": [ "xlib" ] -} diff --git a/src/plugins/platforms/xlib/xlib.pro b/src/plugins/platforms/xlib/xlib.pro deleted file mode 100644 index a4e006f837e..00000000000 --- a/src/plugins/platforms/xlib/xlib.pro +++ /dev/null @@ -1,59 +0,0 @@ -TARGET = qxlib - -load(qt_plugin) -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms - -QT += core-private gui-private platformsupport-private - -SOURCES = \ - main.cpp \ - qxlibintegration.cpp \ - qxlibbackingstore.cpp \ - qxlibwindow.cpp \ - qxlibcursor.cpp \ - qxlibscreen.cpp \ - qxlibkeyboard.cpp \ - qxlibclipboard.cpp \ - qxlibmime.cpp \ - qxlibstatic.cpp \ - qxlibdisplay.cpp \ - qxlibnativeinterface.cpp - -HEADERS = \ - qxlibintegration.h \ - qxlibbackingstore.h \ - qxlibwindow.h \ - qxlibcursor.h \ - qxlibscreen.h \ - qxlibkeyboard.h \ - qxlibclipboard.h \ - qxlibmime.h \ - qxlibstatic.h \ - qxlibdisplay.h \ - qxlibnativeinterface.h - -OTHER_FILES += xlib.json - -LIBS += -lX11 -lXext - -mac { - LIBS += -L/usr/X11/lib -lz -framework Carbon -} - -CONFIG += qpa/genericunixfontdatabase - -contains(QT_CONFIG, opengl) { - !contains(QT_CONFIG, opengles2) { -# load(qpa/glx/convenience) - HEADERS += qglxintegration.h - SOURCES += qglxintegration.cpp - } else { # There is no easy way to detect if we'r suppose to use glx or not -# load(qpa/egl/context) -# load(qpa/egl/convenience) -# load(qpa/egl/xlibintegration) - LIBS += -lEGL - } -} - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target diff --git a/src/printsupport/dialogs/qpagesetupdialog_mac.mm b/src/printsupport/dialogs/qpagesetupdialog_mac.mm index 6e4469e3877..e387a586070 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_mac.mm +++ b/src/printsupport/dialogs/qpagesetupdialog_mac.mm @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#ifndef QT_NO_PRINTDIALOG + #include <Cocoa/Cocoa.h> #include "qpagesetupdialog.h" @@ -47,8 +49,6 @@ #include <QtGui/qplatformnativeinterface_qpa.h> #include <QtPrintSupport/qprintengine.h> -#ifndef QT_NO_PRINTDIALOG - QT_USE_NAMESPACE @class QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate); @@ -155,11 +155,15 @@ void QPageSetupDialogPrivate::closeCocoaPageLayout() QPageSetupDialog::QPageSetupDialog(QPrinter *printer, QWidget *parent) : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), printer, parent) -{ } +{ + setAttribute(Qt::WA_DontShowOnScreen); +} QPageSetupDialog::QPageSetupDialog(QWidget *parent) : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), 0, parent) -{ } +{ + setAttribute(Qt::WA_DontShowOnScreen); +} void QPageSetupDialog::setVisible(bool visible) { @@ -172,6 +176,8 @@ void QPageSetupDialog::setVisible(bool visible) if (!visible == !isCurrentlyVisible) return; + QDialog::setVisible(visible); + if (visible) { d->openCocoaPageLayout(parentWidget() ? Qt::WindowModal : Qt::ApplicationModal); @@ -191,10 +197,15 @@ int QPageSetupDialog::exec() if (d->printer->outputFormat() != QPrinter::NativeFormat) return Rejected; + QDialog::setVisible(true); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; d->openCocoaPageLayout(Qt::ApplicationModal); d->closeCocoaPageLayout(); [pool release]; + + QDialog::setVisible(false); + return result(); } diff --git a/src/printsupport/dialogs/qpagesetupdialog_win.cpp b/src/printsupport/dialogs/qpagesetupdialog_win.cpp index beaea96dd9c..9d7387edbac 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_win.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_win.cpp @@ -58,11 +58,13 @@ class QPageSetupDialogPrivate : public QAbstractPageSetupDialogPrivate QPageSetupDialog::QPageSetupDialog(QPrinter *printer, QWidget *parent) : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), printer, parent) { + setAttribute(Qt::WA_DontShowOnScreen); } QPageSetupDialog::QPageSetupDialog(QWidget *parent) : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), 0, parent) { + setAttribute(Qt::WA_DontShowOnScreen); } int QPageSetupDialog::exec() @@ -124,7 +126,9 @@ int QPageSetupDialog::exec() psd.rtMargin.right = marginRect.width() / multiplier;; psd.rtMargin.bottom = marginRect.height() / multiplier;; + QDialog::setVisible(true); bool result = PageSetupDlg(&psd); + QDialog::setVisible(false); if (result) { ep->readDevnames(psd.hDevNames); ep->readDevmode(psd.hDevMode); diff --git a/src/printsupport/dialogs/qprintdialog.qrc b/src/printsupport/dialogs/qprintdialog.qrc index f54eb6b5eea..5a579baa558 100644 --- a/src/printsupport/dialogs/qprintdialog.qrc +++ b/src/printsupport/dialogs/qprintdialog.qrc @@ -1,5 +1,5 @@ <!DOCTYPE RCC><RCC version="1.0"> -<qresource prefix="/trolltech/dialogs/qprintpreviewdialog"> +<qresource prefix="/qt-project.org/dialogs/qprintpreviewdialog"> <file>images/fit-page-24.png</file> <file>images/fit-page-32.png</file> <file>images/fit-width-24.png</file> @@ -31,7 +31,7 @@ <file>images/zoom-out-24.png</file> <file>images/zoom-out-32.png</file> </qresource> -<qresource prefix="/trolltech/dialogs/qprintdialog"> +<qresource prefix="/qt-project.org/dialogs/qprintdialog"> <file>images/status-color.png</file> <file>images/status-gray-scale.png</file> </qresource> diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm index ecd1ef60cd1..8ea3c9a11dd 100644 --- a/src/printsupport/dialogs/qprintdialog_mac.mm +++ b/src/printsupport/dialogs/qprintdialog_mac.mm @@ -243,6 +243,7 @@ QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent) Q_D(QPrintDialog); if (!warnIfNotNative(d->printer)) return; + setAttribute(Qt::WA_DontShowOnScreen); } QPrintDialog::QPrintDialog(QWidget *parent) @@ -251,6 +252,7 @@ QPrintDialog::QPrintDialog(QWidget *parent) Q_D(QPrintDialog); if (!warnIfNotNative(d->printer)) return; + setAttribute(Qt::WA_DontShowOnScreen); } QPrintDialog::~QPrintDialog() @@ -263,10 +265,15 @@ int QPrintDialog::exec() if (!warnIfNotNative(d->printer)) return QDialog::Rejected; + QDialog::setVisible(true); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; d->openCocoaPrintPanel(Qt::ApplicationModal); d->closeCocoaPrintPanel(); [pool release]; + + QDialog::setVisible(false); + return result(); } @@ -286,6 +293,8 @@ void QPrintDialog::setVisible(bool visible) if (d->printer->outputFormat() != QPrinter::NativeFormat) return; + QDialog::setVisible(visible); + if (visible) { d->openCocoaPrintPanel(parentWidget() ? Qt::WindowModal : Qt::ApplicationModal); diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 5c5ca77a726..75c9664d1d4 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -178,7 +178,6 @@ private: const ppd_file_t* cupsPPD; #endif }; -#endif #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) class QOptionTreeItem @@ -386,9 +385,9 @@ void QPrintDialogPrivate::init() bottom = new QWidget(q); options.setupUi(bottom); options.color->setIconSize(QSize(32, 32)); - options.color->setIcon(QIcon(QLatin1String(":/trolltech/dialogs/qprintdialog/images/status-color.png"))); + options.color->setIcon(QIcon(QLatin1String(":/qt-project.org/dialogs/qprintdialog/images/status-color.png"))); options.grayscale->setIconSize(QSize(32, 32)); - options.grayscale->setIcon(QIcon(QLatin1String(":/trolltech/dialogs/qprintdialog/images/status-gray-scale.png"))); + options.grayscale->setIcon(QIcon(QLatin1String(":/qt-project.org/dialogs/qprintdialog/images/status-gray-scale.png"))); top->d->setOptionsPane(this); buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, q); @@ -1245,7 +1244,8 @@ void QPPDOptionsEditor::cbChanged(int) */ } -#endif +#endif // !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) +#endif // defined (Q_OS_UNIX) QT_END_NAMESPACE diff --git a/src/printsupport/dialogs/qprintdialog_win.cpp b/src/printsupport/dialogs/qprintdialog_win.cpp index cc36e5eb8e8..5474643de90 100644 --- a/src/printsupport/dialogs/qprintdialog_win.cpp +++ b/src/printsupport/dialogs/qprintdialog_win.cpp @@ -193,6 +193,7 @@ QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent) if (!warnIfNotNative(d->printer)) return; d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func(); + setAttribute(Qt::WA_DontShowOnScreen); } QPrintDialog::QPrintDialog(QWidget *parent) @@ -202,6 +203,7 @@ QPrintDialog::QPrintDialog(QWidget *parent) if (!warnIfNotNative(d->printer)) return; d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func(); + setAttribute(Qt::WA_DontShowOnScreen); } QPrintDialog::~QPrintDialog() @@ -230,10 +232,7 @@ int QPrintDialogPrivate::openWindowsPrintDialogModally() if (parent == 0) parent = q; - QWidget modal_widget; - modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true); - modal_widget.setParent(parent, Qt::Window); - QApplicationPrivate::enterModal(&modal_widget); + q->QDialog::setVisible(true); HGLOBAL *tempDevNames = ep->createDevNames(); @@ -274,7 +273,7 @@ int QPrintDialogPrivate::openWindowsPrintDialogModally() } } while (!done); - QApplicationPrivate::leaveModal(&modal_widget); + q->QDialog::setVisible(false); // qt_win_eatMouseMove(); diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp index ce2362b4fe1..6864b24bac4 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.cpp +++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp @@ -341,7 +341,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer) static inline void qt_setupActionIcon(QAction *action, const QLatin1String &name) { - QLatin1String imagePrefix(":/trolltech/dialogs/qprintpreviewdialog/images/"); + QLatin1String imagePrefix(":/qt-project.org/dialogs/qprintpreviewdialog/images/"); QIcon icon; icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24)); icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32)); diff --git a/src/printsupport/dialogs/qprintpreviewdialog.h b/src/printsupport/dialogs/qprintpreviewdialog.h index 28277f93d70..18d0fcee1d4 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.h +++ b/src/printsupport/dialogs/qprintpreviewdialog.h @@ -93,8 +93,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_pageSetup()) Q_PRIVATE_SLOT(d_func(), void _q_previewChanged()) Q_PRIVATE_SLOT(d_func(), void _q_zoomFactorChanged()) - - void *dummy; // ### Qt 5 - remove me }; diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index d713639dcc8..66825508497 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -364,17 +364,6 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke \sa QAbstractPrintDialog::PrintRange */ -/*! - \enum QPrinter::PrinterOption - \compat - - Use QAbstractPrintDialog::PrintDialogOption instead. - - \value PrintToFile - \value PrintSelection - \value PrintPageRange -*/ - /*! \enum QPrinter::PaperSize \since 4.4 @@ -513,22 +502,6 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke \sa setPrintRange(), printRange() */ -/* - \enum QPrinter::PrinterOption - - This enum describes various printer options that appear in the - printer setup dialog. It is used to enable and disable these - options in the setup dialog. - - \value PrintToFile Describes if print to file should be enabled. - \value PrintSelection Describes if printing selections should be enabled. - \value PrintPageRange Describes if printing page ranges (from, to) should - be enabled - \value PrintCurrentPage if Print Current Page option should be enabled - - \sa setOptionEnabled(), isOptionEnabled() -*/ - /*! Creates a new printer object with the given \a mode. */ diff --git a/src/printsupport/widgets/qprintpreviewwidget.h b/src/printsupport/widgets/qprintpreviewwidget.h index 56a4d5bbc13..d8f2aee8150 100644 --- a/src/printsupport/widgets/qprintpreviewwidget.h +++ b/src/printsupport/widgets/qprintpreviewwidget.h @@ -110,7 +110,6 @@ Q_SIGNALS: void previewChanged(); private: - void *dummy; // ### remove in Qt 5.0 Q_PRIVATE_SLOT(d_func(), void _q_fit()) Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentPage()) }; diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp index 0da7f05cbf4..6f47903de75 100644 --- a/src/sql/drivers/ibase/qsql_ibase.cpp +++ b/src/sql/drivers/ibase/qsql_ibase.cpp @@ -1847,7 +1847,7 @@ void QIBaseDriver::qHandleEventNotification(void *updatedResultBuffer) if (eBuffer->subscriptionState == QIBaseEventBuffer::Subscribed) { emit notification(i.key()); - emit notification(i.key(), QSqlDriver::UnknownSource); + emit notification(i.key(), QSqlDriver::UnknownSource, QVariant()); } else if (eBuffer->subscriptionState == QIBaseEventBuffer::Starting) eBuffer->subscriptionState = QIBaseEventBuffer::Subscribed; diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index edeb5d15424..78893119967 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -123,14 +123,21 @@ inline void qPQfreemem(void *buffer) class QPSQLDriverPrivate { public: - QPSQLDriverPrivate() : connection(0), isUtf8(false), pro(QPSQLDriver::Version6), sn(0) {} + QPSQLDriverPrivate(QPSQLDriver *qq) : q(qq), connection(0), isUtf8(false), pro(QPSQLDriver::Version6), sn(0), pendingNotifyCheck(false) {} + QPSQLDriver *q; PGconn *connection; bool isUtf8; QPSQLDriver::Protocol pro; QSocketNotifier *sn; QStringList seid; + mutable bool pendingNotifyCheck; void appendTables(QStringList &tl, QSqlQuery &t, QChar type); + PGresult * exec(const char * stmt) const; + PGresult * exec(const QString & stmt) const; + QPSQLDriver::Protocol getPSQLVersion(); + bool setEncodingUtf8(); + void setDatestyle(); }; void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type) @@ -157,6 +164,21 @@ void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type) } } +PGresult * QPSQLDriverPrivate::exec(const char * stmt) const +{ + PGresult *result = PQexec(connection, stmt); + if (seid.size() && !pendingNotifyCheck) { + pendingNotifyCheck = true; + QMetaObject::invokeMethod(q, "_q_handleNotification", Qt::QueuedConnection, Q_ARG(int,0)); + } + return result; +} + +PGresult * QPSQLDriverPrivate::exec(const QString & stmt) const +{ + return exec(isUtf8 ? stmt.toUtf8().constData() : stmt.toLocal8Bit().constData()); +} + class QPSQLResultPrivate { public: @@ -251,9 +273,7 @@ static QVariant::Type qDecodePSQLType(int t) static void qDeallocatePreparedStmt(QPSQLResultPrivate *d) { const QString stmt = QLatin1String("DEALLOCATE ") + d->preparedStmtId; - PGresult *result = PQexec(d->driver->connection, - d->driver->isUtf8 ? stmt.toUtf8().constData() - : stmt.toLocal8Bit().constData()); + PGresult *result = d->driver->exec(stmt); if (PQresultStatus(result) != PGRES_COMMAND_OK) qWarning("Unable to free statement: %s", PQerrorMessage(d->driver->connection)); @@ -431,9 +451,7 @@ bool QPSQLResult::reset (const QString& query) return false; if (!driver()->isOpen() || driver()->isOpenError()) return false; - d->result = PQexec(d->driver->connection, - d->driver->isUtf8 ? query.toUtf8().constData() - : query.toLocal8Bit().constData()); + d->result = d->driver->exec(query); return d->processResults(); } @@ -564,9 +582,7 @@ bool QPSQLResult::prepare(const QString &query) const QString stmtId = qMakePreparedStmtId(); const QString stmt = QString::fromLatin1("PREPARE %1 AS ").arg(stmtId).append(qReplacePlaceholderMarkers(query)); - PGresult *result = PQexec(d->driver->connection, - d->driver->isUtf8 ? stmt.toUtf8().constData() - : stmt.toLocal8Bit().constData()); + PGresult *result = d->driver->exec(stmt); if (PQresultStatus(result) != PGRES_COMMAND_OK) { setLastError(qMakeError(QCoreApplication::translate("QPSQLResult", @@ -595,26 +611,24 @@ bool QPSQLResult::exec() else stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId).arg(params); - d->result = PQexec(d->driver->connection, - d->driver->isUtf8 ? stmt.toUtf8().constData() - : stmt.toLocal8Bit().constData()); + d->result = d->driver->exec(stmt); return d->processResults(); } /////////////////////////////////////////////////////////////////// -static bool setEncodingUtf8(PGconn* connection) +bool QPSQLDriverPrivate::setEncodingUtf8() { - PGresult* result = PQexec(connection, "SET CLIENT_ENCODING TO 'UNICODE'"); + PGresult* result = exec("SET CLIENT_ENCODING TO 'UNICODE'"); int status = PQresultStatus(result); PQclear(result); return status == PGRES_COMMAND_OK; } -static void setDatestyle(PGconn* connection) +void QPSQLDriverPrivate::setDatestyle() { - PGresult* result = PQexec(connection, "SET DATESTYLE TO 'ISO'"); + PGresult* result = exec("SET DATESTYLE TO 'ISO'"); int status = PQresultStatus(result); if (status != PGRES_COMMAND_OK) qWarning("%s", PQerrorMessage(connection)); @@ -665,10 +679,10 @@ static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin) return QPSQLDriver::VersionUnknown; } -static QPSQLDriver::Protocol getPSQLVersion(PGconn* connection) +QPSQLDriver::Protocol QPSQLDriverPrivate::getPSQLVersion() { QPSQLDriver::Protocol serverVersion = QPSQLDriver::Version6; - PGresult* result = PQexec(connection, "select version()"); + PGresult* result = exec("select version()"); int status = PQresultStatus(result); if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) { QString val = QString::fromAscii(PQgetvalue(result, 0, 0)); @@ -691,7 +705,7 @@ static QPSQLDriver::Protocol getPSQLVersion(PGconn* connection) //Client version before QPSQLDriver::Version9 only supports escape mode for bytea type, //but bytea format is set to hex by default in PSQL 9 and above. So need to force the //server use the old escape mode when connects to the new server with old client library. - result = PQexec(connection, "SET bytea_output=escape; "); + result = exec("SET bytea_output=escape; "); status = PQresultStatus(result); } else if (serverVersion == QPSQLDriver::VersionUnknown) { serverVersion = clientVersion; @@ -726,7 +740,7 @@ QPSQLDriver::QPSQLDriver(PGconn *conn, QObject *parent) init(); d->connection = conn; if (conn) { - d->pro = getPSQLVersion(d->connection); + d->pro = d->getPSQLVersion(); setOpen(true); setOpenError(false); } @@ -734,7 +748,7 @@ QPSQLDriver::QPSQLDriver(PGconn *conn, QObject *parent) void QPSQLDriver::init() { - d = new QPSQLDriverPrivate(); + d = new QPSQLDriverPrivate(this); } QPSQLDriver::~QPSQLDriver() @@ -826,9 +840,9 @@ bool QPSQLDriver::open(const QString & db, return false; } - d->pro = getPSQLVersion(d->connection); - d->isUtf8 = setEncodingUtf8(d->connection); - setDatestyle(d->connection); + d->pro = d->getPSQLVersion(); + d->isUtf8 = d->setEncodingUtf8(); + d->setDatestyle(); setOpen(true); setOpenError(false); @@ -865,7 +879,7 @@ bool QPSQLDriver::beginTransaction() qWarning("QPSQLDriver::beginTransaction: Database not open"); return false; } - PGresult* res = PQexec(d->connection, "BEGIN"); + PGresult* res = d->exec("BEGIN"); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { PQclear(res); setLastError(qMakeError(tr("Could not begin transaction"), @@ -882,7 +896,7 @@ bool QPSQLDriver::commitTransaction() qWarning("QPSQLDriver::commitTransaction: Database not open"); return false; } - PGresult* res = PQexec(d->connection, "COMMIT"); + PGresult* res = d->exec("COMMIT"); bool transaction_failed = false; @@ -915,7 +929,7 @@ bool QPSQLDriver::rollbackTransaction() qWarning("QPSQLDriver::rollbackTransaction: Database not open"); return false; } - PGresult* res = PQexec(d->connection, "ROLLBACK"); + PGresult* res = d->exec("ROLLBACK"); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { setLastError(qMakeError(tr("Could not rollback transaction"), QSqlError::TransactionError, d)); @@ -1298,11 +1312,11 @@ bool QPSQLDriver::subscribeToNotification(const QString &name) int socket = PQsocket(d->connection); if (socket) { + // Add the name to the list of subscriptions here so that QSQLDriverPrivate::exec knows + // to check for notifications immediately after executing the LISTEN + d->seid << name; QString query = QLatin1String("LISTEN ") + escapeIdentifier(name, QSqlDriver::TableName); - if (PQresultStatus(PQexec(d->connection, - d->isUtf8 ? query.toUtf8().constData() - : query.toLocal8Bit().constData()) - ) != PGRES_COMMAND_OK) { + if (PQresultStatus(d->exec(query)) != PGRES_COMMAND_OK) { setLastError(qMakeError(tr("Unable to subscribe"), QSqlError::StatementError, d)); return false; } @@ -1311,9 +1325,11 @@ bool QPSQLDriver::subscribeToNotification(const QString &name) d->sn = new QSocketNotifier(socket, QSocketNotifier::Read); connect(d->sn, SIGNAL(activated(int)), this, SLOT(_q_handleNotification(int))); } + } else { + qWarning("QPSQLDriver::subscribeToNotificationImplementation: PQsocket didn't return a valid socket to listen on"); + return false; } - d->seid << name; return true; } @@ -1331,10 +1347,7 @@ bool QPSQLDriver::unsubscribeFromNotification(const QString &name) } QString query = QLatin1String("UNLISTEN ") + escapeIdentifier(name, QSqlDriver::TableName); - if (PQresultStatus(PQexec(d->connection, - d->isUtf8 ? query.toUtf8().constData() - : query.toLocal8Bit().constData()) - ) != PGRES_COMMAND_OK) { + if (PQresultStatus(d->exec(query)) != PGRES_COMMAND_OK) { setLastError(qMakeError(tr("Unable to unsubscribe"), QSqlError::StatementError, d)); return false; } @@ -1357,17 +1370,21 @@ QStringList QPSQLDriver::subscribedToNotifications() const void QPSQLDriver::_q_handleNotification(int) { + d->pendingNotifyCheck = false; PQconsumeInput(d->connection); PGnotify *notify = 0; while((notify = PQnotifies(d->connection)) != 0) { QString name(QLatin1String(notify->relname)); if (d->seid.contains(name)) { + QString payload; +#if defined PG_VERSION_NUM && PG_VERSION_NUM-0 >= 70400 + if (notify->extra) + payload = d->isUtf8 ? QString::fromUtf8(notify->extra) : QString::fromAscii(notify->extra); +#endif emit notification(name); - if (notify->be_pid == PQbackendPID(d->connection)) - emit notification(name, QSqlDriver::SelfSource); - else - emit notification(name, QSqlDriver::OtherSource); + QSqlDriver::NotificationSource source = (notify->be_pid == PQbackendPID(d->connection)) ? QSqlDriver::SelfSource : QSqlDriver::OtherSource; + emit notification(name, source, payload); } else qWarning("QPSQLDriver: received notification for '%s' which isn't subscribed to.", diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index deb29f80593..168500e5a87 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -92,6 +92,9 @@ static QVariant::Type qGetColumnType(const QString &tpName) return QVariant::Double; if (typeName == QLatin1String("blob")) return QVariant::ByteArray; + if (typeName == QLatin1String("boolean") + || typeName == QLatin1String("bool")) + return QVariant::Bool; return QVariant::String; } @@ -413,6 +416,7 @@ bool QSQLiteResult::exec() ba->size(), SQLITE_STATIC); break; } case QVariant::Int: + case QVariant::Bool: res = sqlite3_bind_int(d->stmt, i + 1, value.toInt()); break; case QVariant::Double: diff --git a/src/sql/kernel/qsql.qdoc b/src/sql/kernel/qsql.qdoc index 0762fa977e2..394c255b356 100644 --- a/src/sql/kernel/qsql.qdoc +++ b/src/sql/kernel/qsql.qdoc @@ -38,30 +38,6 @@ \sa {QtSql Module} */ -/*! - \enum QSql::Confirm - \compat - - This enum type describes edit confirmations. - - \value Yes - \value No - \value Cancel -*/ - -/*! - \enum QSql::Op - \compat - - This enum type describes edit operations. - - \value None - \value Insert - \value Update - \value Delete -*/ - - /*! \enum QSql::Location diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp index 28847325d96..f48673f28fb 100644 --- a/src/sql/kernel/qsqldriver.cpp +++ b/src/sql/kernel/qsqldriver.cpp @@ -133,10 +133,11 @@ QSqlDriver::~QSqlDriver() /*! \since 5.0 - \fn QSqlDriver::notification(const QString &name, NotificationSource source) + \fn QSqlDriver::notification(const QString &name, NotificationSource source, const QString & payload) This signal is emitted when the database posts an event notification - that the driver subscribes to. \a name identifies the event notification, \a source indicates the signal source. + that the driver subscribes to. \a name identifies the event notification, \a source indicates the signal source, + \a payload holds the extra data optionally delivered with the notification. \sa subscribeToNotification() */ diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h index ff19d660dae..b3c83fc678e 100644 --- a/src/sql/kernel/qsqldriver.h +++ b/src/sql/kernel/qsqldriver.h @@ -122,7 +122,7 @@ public: Q_SIGNALS: void notification(const QString &name); - void notification(const QString &name, NotificationSource source); + void notification(const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload); protected: virtual void setOpen(bool o); diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 16df1b8b067..f9dbae306b1 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -114,16 +114,18 @@ public: QString executedQuery; QHash<int, QSql::ParamType> types; QVector<QVariant> values; - typedef QHash<QString, int> IndexMap; + typedef QHash<QString, QList<int> > IndexMap; IndexMap indexes; typedef QVector<QHolder> QHolderVector; QHolderVector holders; }; +static QString qFieldSerial(int); + QString QSqlResultPrivate::holderAt(int index) const { - return indexes.key(index); + return holders.size() > index ? holders.at(index).holderName : qFieldSerial(index); } // return a unique id for bound names @@ -159,6 +161,8 @@ QString QSqlResultPrivate::positionalToNamedBinding() for (int i = 0; i < n; ++i) { QChar ch = sql.at(i); if (ch == QLatin1Char('?') && !inQuote) { + // Update the holder position since we are changing the holder name lengths + holders[count].holderPos = result.size(); result += qFieldSerial(count++); } else { if (ch == QLatin1Char('\'')) @@ -188,7 +192,9 @@ QString QSqlResultPrivate::namedToPositionalBinding() int pos = i + 2; while (pos < n && qIsAlnum(sql.at(pos))) ++pos; - indexes[sql.mid(i, pos - i)] = count++; + QString holder(sql.mid(i, pos - i)); + indexes[holder].append(count++); + holders.append(QHolder(holder, i)); result += QLatin1Char('?'); i = pos; } else { @@ -199,6 +205,7 @@ QString QSqlResultPrivate::namedToPositionalBinding() } } result.squeeze(); + values.resize(holders.size()); return result; } @@ -610,27 +617,32 @@ bool QSqlResult::savePrepare(const QString& query) */ bool QSqlResult::prepare(const QString& query) { - int n = query.size(); + if (d->holders.isEmpty()) { + int n = query.size(); - bool inQuote = false; - int i = 0; + bool inQuote = false; + int i = 0; - while (i < n) { - QChar ch = query.at(i); - if (ch == QLatin1Char(':') && !inQuote - && (i == 0 || query.at(i - 1) != QLatin1Char(':')) - && (i + 1 < n && qIsAlnum(query.at(i + 1)))) { - int pos = i + 2; - while (pos < n && qIsAlnum(query.at(pos))) - ++pos; + while (i < n) { + QChar ch = query.at(i); + if (ch == QLatin1Char(':') && !inQuote + && (i == 0 || query.at(i - 1) != QLatin1Char(':')) + && (i + 1 < n && qIsAlnum(query.at(i + 1)))) { + int pos = i + 2; + while (pos < n && qIsAlnum(query.at(pos))) + ++pos; - d->holders.append(QHolder(query.mid(i, pos - i), i)); - i = pos; - } else { - if (ch == QLatin1Char('\'')) - inQuote = !inQuote; - ++i; + QString holder(query.mid(i, pos - i)); + d->indexes[holder].append(d->holders.size()); + d->holders.append(QHolder(holder, i)); + i = pos; + } else { + if (ch == QLatin1Char('\'')) + inQuote = !inQuote; + ++i; + } } + d->values.resize(d->holders.size()); } d->sql = query; return true; // fake prepares should always succeed @@ -653,7 +665,7 @@ bool QSqlResult::exec() QString holder; for (i = d->holders.count() - 1; i >= 0; --i) { holder = d->holders.at(i).holderName; - val = d->values.value(d->indexes.value(holder)); + val = d->values.value(d->indexes.value(holder).value(0,-1)); QSqlField f(QLatin1String(""), val.type()); f.setValue(val); query = query.replace(d->holders.at(i).holderPos, @@ -697,7 +709,7 @@ bool QSqlResult::exec() void QSqlResult::bindValue(int index, const QVariant& val, QSql::ParamType paramType) { d->binds = PositionalBinding; - d->indexes[qFieldSerial(index)] = index; + d->indexes[qFieldSerial(index)].append(index); if (d->values.count() <= index) d->values.resize(index + 1); d->values[index] = val; @@ -727,19 +739,14 @@ void QSqlResult::bindValue(const QString& placeholder, const QVariant& val, d->binds = NamedBinding; // if the index has already been set when doing emulated named // bindings - don't reset it - int idx = d->indexes.value(placeholder, -1); - if (idx >= 0) { + QList<int> indexes = d->indexes.value(placeholder); + foreach (int idx, indexes) { if (d->values.count() <= idx) d->values.resize(idx + 1); d->values[idx] = val; - } else { - d->values.append(val); - idx = d->values.count() - 1; - d->indexes[placeholder] = idx; + if (paramType != QSql::In || !d->types.isEmpty()) + d->types[idx] = paramType; } - - if (paramType != QSql::In || !d->types.isEmpty()) - d->types[idx] = paramType; } /*! @@ -776,8 +783,8 @@ QVariant QSqlResult::boundValue(int index) const */ QVariant QSqlResult::boundValue(const QString& placeholder) const { - int idx = d->indexes.value(placeholder, -1); - return d->values.value(idx); + QList<int> indexes = d->indexes.value(placeholder); + return d->values.value(indexes.value(0,-1)); } /*! @@ -798,7 +805,7 @@ QSql::ParamType QSqlResult::bindValueType(int index) const */ QSql::ParamType QSqlResult::bindValueType(const QString& placeholder) const { - return d->types.value(d->indexes.value(placeholder, -1), QSql::In); + return d->types.value(d->indexes.value(placeholder).value(0,-1), QSql::In); } /*! diff --git a/src/sql/models/qsqlquerymodel.cpp b/src/sql/models/qsqlquerymodel.cpp index 341804f1ae8..fefb87dcf56 100644 --- a/src/sql/models/qsqlquerymodel.cpp +++ b/src/sql/models/qsqlquerymodel.cpp @@ -591,7 +591,8 @@ QModelIndex QSqlQueryModel::indexInQuery(const QModelIndex &item) const { Q_D(const QSqlQueryModel); if (item.column() < 0 || item.column() >= d->rec.count() - || !d->rec.isGenerated(item.column())) + || !d->rec.isGenerated(item.column()) + || item.column() >= d->colOffsets.size()) return QModelIndex(); return createIndex(item.row(), item.column() - d->colOffsets[item.column()], item.internalPointer()); diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp index 0387e5691f3..a3d45576aea 100644 --- a/src/sql/models/qsqlrelationaltablemodel.cpp +++ b/src/sql/models/qsqlrelationaltablemodel.cpp @@ -379,16 +379,21 @@ void QSqlRelationalTableModelPrivate::clearCache() keys will not be exposed through the model. The user or the database is responsible for keeping referential integrity. \li If a relation's display column name is also used as a column - name in the main table, or if it is used as display column + name in the relational table, or if it is used as display column name in more than one relation it will be aliased. The alias is - is the relation's table name and display column name joined - by an underscore (e.g. tablename_columnname). All occurrences - of the duplicate display column name are aliased when + the relation's table name, display column name and a unique id + joined by an underscore (e.g. tablename_columnname_id). + QSqlRecord::fieldName() will return the aliased column name. + All occurrences of the duplicate display column name are aliased when duplication is detected, but no aliasing is done to the column names in the main table. The aliasing doesn't affect QSqlRelation, so QSqlRelation::displayColumn() will return the - original display column name, but QSqlRecord::fieldName() will - return aliases. + original display column name. + \li The reference table name is aliased. The alias is the word "relTblAl" + and the relationed column index joined by an underscore + (e.g. relTblAl_2). The alias can be used to filter the table + (For example, setFilter("relTblAl_2='Oslo' OR + relTblAl_3='USA'")). \li When using setData() the role should always be Qt::EditRole, and when using data() the role should always be Qt::DisplayRole. \endlist diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 20d2be36e12..f7198978ddf 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -97,6 +97,7 @@ void QSqlTableModelPrivate::initRecordAndPrimaryIndex() { rec = db.record(tableName); primaryIndex = db.primaryIndex(tableName); + initColOffsets(rec.count()); } void QSqlTableModelPrivate::clear() @@ -332,7 +333,6 @@ void QSqlTableModel::setTable(const QString &tableName) clear(); d->tableName = tableName; d->initRecordAndPrimaryIndex(); - d->initColOffsets(d->rec.count()); if (d->rec.count() == 0) d->error = QSqlError(QLatin1String("Unable to find table ") + d->tableName, QString(), diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h index 441cfa1f651..47a74d73897 100644 --- a/src/testlib/qtestmouse.h +++ b/src/testlib/qtestmouse.h @@ -127,7 +127,8 @@ namespace QTest break; case MouseMove: QWindowSystemInterface::handleMouseEvent(window,pos,window->mapToGlobal(pos),lastButton,stateKey); - //QCursor::setPos(window->mapToGlobal(pos)); + // No QCursor::setPos() call here. That could potentially result in mouse events sent by the windowing system + // which is highly undesired here. Tests must avoid relying on QCursor. break; default: QTEST_ASSERT(false); diff --git a/src/tools/qdoc/atom.cpp b/src/tools/qdoc/atom.cpp index 777240c8312..8743efa6c45 100644 --- a/src/tools/qdoc/atom.cpp +++ b/src/tools/qdoc/atom.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include <qregexp.h> +#include <QRegExp> #include "atom.h" #include "location.h" #include <stdio.h> @@ -55,6 +55,7 @@ QLatin1String Atom::SPAN_ ("span"); QLatin1String Atom::SUBSCRIPT_ ("subscript"); QLatin1String Atom::SUPERSCRIPT_ ("superscript"); QLatin1String Atom::TELETYPE_ ("teletype"); +QLatin1String Atom::UICONTROL_ ("uicontrol"); QLatin1String Atom::UNDERLINE_ ("underline"); QLatin1String Atom::BULLET_ ("bullet"); @@ -196,6 +197,7 @@ static const struct { { "FormattingRight", Atom::FormattingRight }, { "GeneratedList", Atom::GeneratedList }, { "GuidLink", Atom::GuidLink}, + { "hr", Atom::HR}, { "Image", Atom::Image }, { "ImageText", Atom::ImageText }, { "ImportantLeft", Atom::ImportantLeft }, diff --git a/src/tools/qdoc/atom.h b/src/tools/qdoc/atom.h index 584e8fcd08c..7c3b5a0efb7 100644 --- a/src/tools/qdoc/atom.h +++ b/src/tools/qdoc/atom.h @@ -84,6 +84,7 @@ public: FormattingRight, GeneratedList, GuidLink, + HR, Image, ImageText, ImportantLeft, @@ -195,6 +196,7 @@ public: static QLatin1String SUBSCRIPT_; static QLatin1String SUPERSCRIPT_; static QLatin1String TELETYPE_; + static QLatin1String UICONTROL_; static QLatin1String UNDERLINE_; static QLatin1String BULLET_; @@ -221,6 +223,7 @@ private: #define ATOM_FORMATTING_SUBSCRIPT "subscript" #define ATOM_FORMATTING_SUPERSCRIPT "superscript" #define ATOM_FORMATTING_TELETYPE "teletype" +#define ATOM_FORMATTING_UICONTROL "uicontrol" #define ATOM_FORMATTING_UNDERLINE "underline" #define ATOM_LIST_BULLET "bullet" diff --git a/src/tools/qdoc/codemarker.cpp b/src/tools/qdoc/codemarker.cpp index 9f22a287d20..fe0b366350a 100644 --- a/src/tools/qdoc/codemarker.cpp +++ b/src/tools/qdoc/codemarker.cpp @@ -649,7 +649,6 @@ QStringList CodeMarker::macRefsForNode(Node *node) } case Node::Namespace: case Node::Fake: - case Node::Target: default: return QStringList(); } diff --git a/src/tools/qdoc/config.cpp b/src/tools/qdoc/config.cpp index f97b6ca93f0..8b356d15363 100644 --- a/src/tools/qdoc/config.cpp +++ b/src/tools/qdoc/config.cpp @@ -148,6 +148,7 @@ QStringList MetaStack::getExpanded(const Location& location) } QT_STATIC_CONST_IMPL QString Config::dot = QLatin1String("."); +bool Config::generateExamples = true; QString Config::overrideOutputDir; QSet<QString> Config::overrideOutputFormats; QMap<QString, QString> Config::extractedDirs; diff --git a/src/tools/qdoc/config.h b/src/tools/qdoc/config.h index 6a89684e795..f36389eb32c 100644 --- a/src/tools/qdoc/config.h +++ b/src/tools/qdoc/config.h @@ -110,6 +110,7 @@ public: QT_STATIC_CONST QString dot; + static bool generateExamples; static QString overrideOutputDir; static QSet<QString> overrideOutputFormats; diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp index 3e7d190fe43..aea8ed2119d 100644 --- a/src/tools/qdoc/cppcodemarker.cpp +++ b/src/tools/qdoc/cppcodemarker.cpp @@ -826,61 +826,38 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, return sections; } +/*! + Search the \a tree for a node named \a target + */ const Node *CppCodeMarker::resolveTarget(const QString& target, const Tree* tree, const Node* relative, const Node* self) { + const Node* node = 0; if (target.endsWith("()")) { - const FunctionNode *func; QString funcName = target; funcName.chop(2); - QStringList path = funcName.split("::"); - if ((func = tree->findFunctionNode(path, - relative, - Tree::SearchBaseClasses)) - && func->metaness() != FunctionNode::MacroWithoutParams) - return func; + const FunctionNode* fn = tree->findFunctionNode(path, relative, Tree::SearchBaseClasses); + if (fn) { + /* + Why is this case not accepted? + */ + if (fn->metaness() != FunctionNode::MacroWithoutParams) + node = fn; + } } else if (target.contains(QLatin1Char('#'))) { - // ### this doesn't belong here; get rid of TargetNode hack - int hashAt = target.indexOf(QLatin1Char('#')); - QString link = target.left(hashAt); - QString ref = target.mid(hashAt + 1); - const Node *node; - if (link.isEmpty()) { - node = relative; - } - else { - QStringList path(link); - node = tree->findNode(path, tree->root(), Tree::SearchBaseClasses); - } - if (node && node->isInnerNode()) { - const Atom *atom = node->doc().body().firstAtom(); - while (atom) { - if (atom->type() == Atom::Target && atom->string() == ref) { - Node *parentNode = const_cast<Node *>(node); - return new TargetNode(static_cast<InnerNode*>(parentNode), - ref); - } - atom = atom->next(); - } - } + // This error message is never printed; I think we can remove the case. + qDebug() << "qdoc: target case not handled:" << target; } else { QStringList path = target.split("::"); - const Node *node; - int flags = Tree::SearchBaseClasses | - Tree::SearchEnumValues | - Tree::NonFunction; - if ((node = tree->findNode(path, - relative, - flags, - self))) - return node; + int flags = Tree::SearchBaseClasses | Tree::SearchEnumValues | Tree::NonFunction; + node = tree->findNode(path, relative, flags, self); } - return 0; + return node; } static const char * const typeTable[] = { diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index 86e57a0372c..b08c6f901c9 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -79,7 +79,6 @@ QT_BEGIN_NAMESPACE #define COMMAND_PROPERTY Doc::alias("property") #define COMMAND_REIMP Doc::alias("reimp") #define COMMAND_RELATES Doc::alias("relates") -#define COMMAND_SERVICE Doc::alias("service") #define COMMAND_STARTPAGE Doc::alias("startpage") #define COMMAND_TYPEDEF Doc::alias("typedef") #define COMMAND_VARIABLE Doc::alias("variable") @@ -119,7 +118,7 @@ QStringList CppCodeParser::exampleDirs; This is used for fuzzy matching only, which in turn is only used for Qt Jambi. */ -static QString cleanType(const QString &type, const Tree *tree) +static QString cleanType(const QString &type, Tree* tree) { QString result = type; result.replace("qlonglong", "long long"); @@ -145,14 +144,13 @@ static QString cleanType(const QString &type, const Tree *tree) while ((pos = result.indexOf(regExp, pos)) != -1) { // we assume that the path for the associated enum // is the same as for the flag typedef - QStringList path = regExp.cap(2).split("::", - QString::SkipEmptyParts); - const EnumNode *enume = static_cast<const EnumNode *>( - tree->findNode(QStringList(path) << regExp.cap(3), - Node::Enum)); - if (enume && enume->flagsType()) - result.replace(pos, regExp.matchedLength(), - (QStringList(path) << enume->flagsType()->name()).join("::")); + QStringList path = regExp.cap(2).split("::", QString::SkipEmptyParts); + QStringList tmpPath = QStringList(path) << regExp.cap(3); + EnumNode* en = tree->findEnumNode(tmpPath); + if (en && en->flagsType()) { + tmpPath = QStringList(path) << en->flagsType()->name(); + result.replace(pos, regExp.matchedLength(), tmpPath.join("::")); + } ++pos; } } @@ -191,9 +189,12 @@ void CppCodeParser::initializeParser(const Config &config) { CodeParser::initializeParser(config); + /* + All these can appear in a C++ namespace. Don't add + anything that can't be in a C++ namespace. + */ nodeTypeMap.insert(COMMAND_NAMESPACE, Node::Namespace); nodeTypeMap.insert(COMMAND_CLASS, Node::Class); - nodeTypeMap.insert(COMMAND_SERVICE, Node::Class); nodeTypeMap.insert(COMMAND_ENUM, Node::Enum); nodeTypeMap.insert(COMMAND_TYPEDEF, Node::Typedef); nodeTypeMap.insert(COMMAND_PROPERTY, Node::Property); @@ -306,7 +307,13 @@ void CppCodeParser::parseSourceFile(const Location& location, Tokenizer fileTokenizer(fileLocation, in); tokenizer = &fileTokenizer; readToken(); - usedNamespaces.clear(); + + /* + The set of active namespaces is cleared before parsing + each source file. The word "source" here means cpp file. + */ + activeNamespaces_.clear(); + matchDocsAndStuff(); in.close(); } @@ -403,14 +410,14 @@ const FunctionNode *CppCodeParser::findFunctionNode(const QString& synopsis, This is necessary because Roberto's parser resolves typedefs. */ if (!func && fuzzy) { - func = tre->findFunctionNode(parentPath + + func = tree_->findFunctionNode(parentPath + QStringList(clone->name()), relative, flags); if (!func && clone->name().contains('_')) { QStringList path = parentPath; path << clone->name().split('_'); - func = tre->findFunctionNode(path, relative, flags); + func = tree_->findFunctionNode(path, relative, flags); } if (func) { @@ -512,7 +519,6 @@ QSet<QString> CppCodeParser::topicCommands() << COMMAND_NAMESPACE << COMMAND_PAGE << COMMAND_PROPERTY - << COMMAND_SERVICE << COMMAND_TYPEDEF << COMMAND_VARIABLE << COMMAND_QMLCLASS @@ -543,21 +549,21 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, doc.location().warning(tr("Invalid syntax in '\\%1'").arg(COMMAND_FN)); } else { - if (!usedNamespaces.isEmpty()) { - foreach (const QString &usedNamespace, usedNamespaces) { - QStringList newPath = usedNamespace.split("::") + parentPath; - func = tre->findFunctionNode(newPath, clone); + if (!activeNamespaces_.isEmpty()) { + foreach (const QString& usedNamespace_, activeNamespaces_) { + QStringList newPath = usedNamespace_.split("::") + parentPath; + func = tree_->findFunctionNode(newPath, clone); if (func) break; } } // Search the root namespace if no match was found. if (func == 0) - func = tre->findFunctionNode(parentPath, clone); + func = tree_->findFunctionNode(parentPath, clone); if (func == 0) { if (parentPath.isEmpty() && !lastPath.isEmpty()) - func = tre->findFunctionNode(lastPath, clone); + func = tree_->findFunctionNode(lastPath, clone); if (func == 0) { doc.location().warning(tr("Cannot find '%1' in '\\%2'") .arg(clone->name() + "(...)") @@ -589,7 +595,7 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, QStringList parentPath; FunctionNode *func = 0; - if (makeFunctionNode(arg, &parentPath, &func, tre->root())) { + if (makeFunctionNode(arg, &parentPath, &func, tree_->root())) { if (!parentPath.isEmpty()) { doc.location().warning(tr("Invalid syntax in '\\%1'") .arg(COMMAND_MACRO)); @@ -610,7 +616,7 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, return func; } else if (QRegExp("[A-Za-z_][A-Za-z0-9_]+").exactMatch(arg)) { - func = new FunctionNode(tre->root(), arg); + func = new FunctionNode(tree_->root(), arg); func->setAccess(Node::Public); func->setLocation(doc.location()); func->setMetaness(FunctionNode::MacroWithoutParams); @@ -624,25 +630,45 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, } else if (nodeTypeMap.contains(command)) { /* - The command was neither "fn" nor "macro" . + We should only get in here if the command refers to + something that can appear in a C++ namespace, + i.e. a class, another namespace, an enum, a typedef, + a property or a variable. I think these are handled + this way to allow the writer to refer to the entity + without including the namespace qualifier. */ - // ### split(QLatin1Char(' ')) hack is there to support header file syntax + Node::Type type = nodeTypeMap[command]; + Node::SubType subtype = Node::NoSubType; + if (type == Node::Fake) + subtype = Node::QmlClass; + QStringList paths = arg.split(QLatin1Char(' ')); QStringList path = paths[0].split("::"); Node *node = 0; - if (!usedNamespaces.isEmpty()) { - foreach (const QString &usedNamespace, usedNamespaces) { - QStringList newPath = usedNamespace.split("::") + path; - node = tre->findNode(newPath, nodeTypeMap[command]); + + /* + If the command refers to something that can be in a + C++ namespace, search for it first in all the known + C++ namespaces. + */ + if (!activeNamespaces_.isEmpty()) { + foreach (const QString& usedNamespace_, activeNamespaces_) { + QStringList newPath = usedNamespace_.split("::") + path; + node = tree_->findNodeByNameAndType(newPath, type, subtype, 0); if (node) { path = newPath; break; } } } - // Search the root namespace if no match was found. - if (node == 0) - node = tre->findNode(path, nodeTypeMap[command]); + + /* + If the node was not found in a C++ namespace, search + for it in the root namespace. + */ + if (node == 0) { + node = tree_->findNodeByNameAndType(path, type, subtype, 0); + } if (node == 0) { doc.location().warning(tr("Cannot find '%1' specified with '\\%2' in any header file") @@ -650,61 +676,40 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, lastPath = path; } - else if (command == COMMAND_SERVICE) { - // If the command is "\service", then we need to tag the - // class with the actual service name. - QStringList args = arg.split(QLatin1Char(' ')); - if (args.size() > 1) { - ClassNode *cnode = static_cast<ClassNode *>(node); - cnode->setServiceName(args[1]); - cnode->setHideFromMainList(true); - } - } else if (node->isInnerNode()) { + /* + This treets a class as a namespace. + */ if (path.size() > 1) { path.pop_back(); - usedNamespaces.insert(path.join("::")); + QString ns = path.join("::"); + activeNamespaces_.insert(ns); } } -#if 0 - /* - This code apparently does nothing. After further - investigation to verify it is useless, it will - be removed. - */ - if (command == COMMAND_CLASS) { - if (paths.size() > 1) { - if (!paths[1].endsWith(".h")) { - ClassNode* cnode = static_cast<ClassNode*>(node); - cnode->setQmlElement(paths[1]); - } - } - } -#endif return node; } else if (command == COMMAND_EXAMPLE) { - ExampleNode* en = new ExampleNode(tre->root(), arg); + ExampleNode* en = new ExampleNode(tree_->root(), arg); createExampleFileNodes(en); return en; } else if (command == COMMAND_EXTERNALPAGE) { - return new FakeNode(tre->root(), arg, Node::ExternalPage, Node::ArticlePage); + return new FakeNode(tree_->root(), arg, Node::ExternalPage, Node::ArticlePage); } else if (command == COMMAND_FILE) { - return new FakeNode(tre->root(), arg, Node::File, Node::NoPageType); + return new FakeNode(tree_->root(), arg, Node::File, Node::NoPageType); } else if (command == COMMAND_GROUP) { - return new FakeNode(tre->root(), arg, Node::Group, Node::OverviewPage); + return new FakeNode(tree_->root(), arg, Node::Group, Node::OverviewPage); } else if (command == COMMAND_HEADERFILE) { - return new FakeNode(tre->root(), arg, Node::HeaderFile, Node::ApiPage); + return new FakeNode(tree_->root(), arg, Node::HeaderFile, Node::ApiPage); } else if (command == COMMAND_MODULE) { - return new FakeNode(tre->root(), arg, Node::Module, Node::OverviewPage); + return new FakeNode(tree_->root(), arg, Node::Module, Node::OverviewPage); } else if (command == COMMAND_QMLMODULE) { - return new FakeNode(tre->root(), arg, Node::QmlModule, Node::OverviewPage); + return new FakeNode(tree_->root(), arg, Node::QmlModule, Node::OverviewPage); } else if (command == COMMAND_PAGE) { Node::PageType ptype = Node::ArticlePage; @@ -738,30 +743,27 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, If there is no collision, just create a new Page node and return that one. */ - NameCollisionNode* ncn = tre->checkForCollision(args[0]); + NameCollisionNode* ncn = tree_->checkForCollision(args[0]); FakeNode* fn = 0; if (ptype == Node::DitaMapPage) - fn = new DitaMapNode(tre->root(), args[0]); + fn = new DitaMapNode(tree_->root(), args[0]); else - fn = new FakeNode(tre->root(), args[0], Node::Page, ptype); + fn = new FakeNode(tree_->root(), args[0], Node::Page, ptype); if (ncn) { ncn->addCollision(fn); } return fn; } else if (command == COMMAND_DITAMAP) { - FakeNode* fn = new DitaMapNode(tre->root(), arg); + FakeNode* fn = new DitaMapNode(tree_->root(), arg); return fn; } else if (command == COMMAND_QMLCLASS) { - const ClassNode* classNode = 0; + ClassNode* classNode = 0; QStringList names = arg.split(QLatin1Char(' ')); - if (names.size() > 1) { - Node* n = tre->findNode(names[1].split("::"),Node::Class); - if (n) { - classNode = static_cast<const ClassNode*>(n); - } - } + if (names.size() > 1) + classNode = tree_->findClassNode(names[1].split("::")); + /* Search for a node with the same name. If there is one, then there is a collision, so create a collision node @@ -773,15 +775,14 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, If there is no collision, just create a new QML class node and return that one. */ - NameCollisionNode* ncn = tre->checkForCollision(names[0]); - QmlClassNode* qcn = new QmlClassNode(tre->root(), names[0], classNode); - if (ncn) { + NameCollisionNode* ncn = tree_->checkForCollision(names[0]); + QmlClassNode* qcn = new QmlClassNode(tree_->root(), names[0], classNode); + if (ncn) ncn->addCollision(qcn); - } return qcn; } else if (command == COMMAND_QMLBASICTYPE) { - return new QmlBasicTypeNode(tre->root(), arg); + return new QmlBasicTypeNode(tree_->root(), arg); } else if ((command == COMMAND_QMLSIGNAL) || (command == COMMAND_QMLMETHOD) || @@ -791,7 +792,7 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, QString element; QString type; if (splitQmlMethodArg(doc,arg,type,module,element)) { - QmlClassNode* qmlClass = tre->findQmlClassNode(module,element); + QmlClassNode* qmlClass = tree_->findQmlClassNode(module,element); if (qmlClass) { if (command == COMMAND_QMLSIGNAL) return makeFunctionNode(doc,arg,qmlClass,Node::QmlSignal,false,COMMAND_QMLSIGNAL); @@ -934,18 +935,18 @@ Node *CppCodeParser::processTopicCommandGroup(const Doc& doc, bool attached = (command == COMMAND_QMLATTACHEDPROPERTY); QStringList::ConstIterator arg = args.begin(); if (splitQmlPropertyArg(doc,(*arg),type,module,element,property)) { - QmlClassNode* qmlClass = tre->findQmlClassNode(module,element); + QmlClassNode* qmlClass = tree_->findQmlClassNode(module,element); if (qmlClass) { qmlPropGroup = new QmlPropGroupNode(qmlClass,property,attached); } } if (qmlPropGroup) { - const ClassNode *correspondingClass = static_cast<const QmlClassNode*>(qmlPropGroup->parent())->classNode(); + ClassNode *correspondingClass = static_cast<QmlClassNode*>(qmlPropGroup->parent())->classNode(); QmlPropertyNode *qmlPropNode = new QmlPropertyNode(qmlPropGroup,property,type,attached); const PropertyNode *correspondingProperty = 0; if (correspondingClass) { - correspondingProperty = qmlPropNode->correspondingProperty(tre); + correspondingProperty = qmlPropNode->correspondingProperty(tree_); } if (correspondingProperty) { bool writableList = type.startsWith("list") && correspondingProperty->dataType().endsWith('*'); @@ -1051,28 +1052,37 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, } } else if (command == COMMAND_RELATES) { - InnerNode *pseudoParent; + /* + Find the node that this node relates to. + */ + Node* n = 0; if (arg.startsWith(QLatin1Char('<')) || arg.startsWith('"')) { - pseudoParent = - static_cast<InnerNode *>(tre->findNode(QStringList(arg), - Node::Fake)); + /* + It should be a header file, I think. + */ + n = tree_->findNodeByNameAndType(QStringList(arg), Node::Fake, Node::NoSubType, 0); } else { + /* + If it wasn't a file, it should be either a class or a namespace. + */ QStringList newPath = arg.split("::"); - pseudoParent = - static_cast<InnerNode*>(tre->findNode(QStringList(newPath), - Node::Class)); - if (!pseudoParent) - pseudoParent = - static_cast<InnerNode*>(tre->findNode(QStringList(newPath), - Node::Namespace)); + n = tree_->findClassNode(newPath); + if (!n) + n = tree_->findNamespaceNode(newPath); } - if (!pseudoParent) { - doc.location().warning(tr("Cannot find '%1' in '\\%2'") - .arg(arg).arg(COMMAND_RELATES)); + + if (!n) { + /* + Didn't ind it. Error... + */ + doc.location().warning(tr("Cannot find '%1' in '\\%2'").arg(arg).arg(COMMAND_RELATES)); } else { - node->setRelates(pseudoParent); + /* + Found it. This node relates to it. + */ + node->setRelates(static_cast<InnerNode*>(n)); } } else if (command == COMMAND_CONTENTSPAGE) { @@ -1134,7 +1144,7 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, } } else { - processCommonMetaCommand(doc.location(),command,arg,node,tre); + processCommonMetaCommand(doc.location(),command,arg,node,tree_); } } @@ -1163,7 +1173,7 @@ void CppCodeParser::processOtherMetaCommands(const Doc& doc, Node *node) */ void CppCodeParser::reset(Tree *tree) { - tre = tree; + tree_ = tree; tokenizer = 0; tok = 0; access = Node::Public; @@ -1689,7 +1699,7 @@ bool CppCodeParser::matchBaseSpecifier(ClassNode *classe, bool isClass) if (!matchDataType(&baseClass)) return false; - tre->addBaseClass(classe, + tree_->addBaseClass(classe, access, baseClass.toPath(), baseClass.toString(), @@ -1771,18 +1781,18 @@ bool CppCodeParser::matchNamespaceDecl(InnerNode *parent) So far, so good. We have 'namespace Foo {'. */ QString namespaceName = previousLexeme(); - NamespaceNode *namespasse = 0; + NamespaceNode* ns = 0; if (parent) { - namespasse = static_cast<NamespaceNode*>(parent->findNode(namespaceName, Node::Namespace)); + ns = static_cast<NamespaceNode*>(parent->findChildNodeByNameAndType(namespaceName, Node::Namespace)); } - if (!namespasse) { - namespasse = new NamespaceNode(parent, namespaceName); - namespasse->setAccess(access); - namespasse->setLocation(location()); + if (!ns) { + ns = new NamespaceNode(parent, namespaceName); + ns->setAccess(access); + ns->setLocation(location()); } readToken(); // skip '{' - bool matched = matchDeclList(namespasse); + bool matched = matchDeclList(ns); return matched && match(Tok_RightBrace); } @@ -1815,7 +1825,7 @@ bool CppCodeParser::matchUsingDecl() /* So far, so good. We have 'using namespace Foo;'. */ - usedNamespaces.insert(name); + activeNamespaces_.insert(name); return true; } @@ -1913,10 +1923,10 @@ bool CppCodeParser::matchTypedefDecl(InnerNode *parent) if (!match(Tok_Semicolon)) return false; - if (parent && !parent->findNode(name, Node::Typedef)) { - TypedefNode *typedeffe = new TypedefNode(parent, name); - typedeffe->setAccess(access); - typedeffe->setLocation(location()); + if (parent && !parent->findChildNodeByNameAndType(name, Node::Typedef)) { + TypedefNode* td = new TypedefNode(parent, name); + td->setAccess(access); + td->setLocation(location()); } return true; } @@ -1975,9 +1985,9 @@ bool CppCodeParser::matchProperty(InnerNode *parent) } if (key == "READ") - tre->addPropertyFunction(property, value, PropertyNode::Getter); + tree_->addPropertyFunction(property, value, PropertyNode::Getter); else if (key == "WRITE") { - tre->addPropertyFunction(property, value, PropertyNode::Setter); + tree_->addPropertyFunction(property, value, PropertyNode::Setter); property->setWritable(true); } else if (key == "STORED") @@ -1994,9 +2004,9 @@ bool CppCodeParser::matchProperty(InnerNode *parent) } } else if (key == "RESET") - tre->addPropertyFunction(property, value, PropertyNode::Resetter); + tree_->addPropertyFunction(property, value, PropertyNode::Resetter); else if (key == "NOTIFY") { - tre->addPropertyFunction(property, value, PropertyNode::Notifier); + tree_->addPropertyFunction(property, value, PropertyNode::Notifier); } else if (key == "REVISION") { int revision; bool ok; @@ -2128,15 +2138,13 @@ bool CppCodeParser::matchDeclList(InnerNode *parent) if (match(Tok_LeftParen) && match(Tok_Ident)) { QString flagsType = previousLexeme(); if (match(Tok_Comma) && match(Tok_Ident)) { - QString enumType = previousLexeme(); + QString name = previousLexeme(); TypedefNode *flagsNode = new TypedefNode(parent, flagsType); flagsNode->setAccess(access); flagsNode->setLocation(location()); - EnumNode *enumNode = - static_cast<EnumNode*>(parent->findNode(enumType, - Node::Enum)); - if (enumNode) - enumNode->setFlagsType(flagsNode); + EnumNode* en = static_cast<EnumNode*>(parent->findChildNodeByNameAndType(name, Node::Enum)); + if (en) + en->setFlagsType(flagsNode); } } match(Tok_RightParen); @@ -2217,14 +2225,14 @@ bool CppCodeParser::matchDocsAndStuff() FunctionNode *func = 0; if (matchFunctionDecl(0, &parentPath, &clone)) { - foreach (const QString &usedNamespace, usedNamespaces) { - QStringList newPath = usedNamespace.split("::") + parentPath; - func = tre->findFunctionNode(newPath, clone); + foreach (const QString& usedNamespace_, activeNamespaces_) { + QStringList newPath = usedNamespace_.split("::") + parentPath; + func = tree_->findFunctionNode(newPath, clone); if (func) break; } if (func == 0) - func = tre->findFunctionNode(parentPath, clone); + func = tree_->findFunctionNode(parentPath, clone); if (func) { func->borrowParameterNames(clone); @@ -2278,7 +2286,7 @@ bool CppCodeParser::matchDocsAndStuff() if ((*n)->isInnerNode() && ((InnerNode *)*n)->includes().isEmpty()) { InnerNode *m = static_cast<InnerNode *>(*n); - while (m->parent() != tre->root()) + while (m->parent() != tree_->root()) m = m->parent(); if (m == *n) ((InnerNode *)*n)->addInclude((*n)->name()); @@ -2307,7 +2315,7 @@ bool CppCodeParser::matchDocsAndStuff() Signals are implemented in uninteresting files generated by moc. */ - node = tre->findFunctionNode(parentPath, clone); + node = tree_->findFunctionNode(parentPath, clone); if (node != 0 && node->metaness() != FunctionNode::Signal) node->setLocation(clone->location()); delete clone; @@ -2419,7 +2427,7 @@ void CppCodeParser::instantiateIteratorMacro(const QString &container, Tokenizer stringTokenizer(loc, latin1); tokenizer = &stringTokenizer; readToken(); - matchDeclList(tre->root()); + matchDeclList(tree_->root()); } void CppCodeParser::createExampleFileNodes(FakeNode *fake) diff --git a/src/tools/qdoc/cppcodeparser.h b/src/tools/qdoc/cppcodeparser.h index f33ff6430d9..74abb994d9a 100644 --- a/src/tools/qdoc/cppcodeparser.h +++ b/src/tools/qdoc/cppcodeparser.h @@ -165,7 +165,7 @@ private: void createExampleFileNodes(FakeNode *fake); QMap<QString, Node::Type> nodeTypeMap; - Tree *tre; + Tree* tree_; Tokenizer *tokenizer; int tok; Node::Access access; @@ -179,7 +179,7 @@ private: QString mutableSequentialIteratorDefinition; QString associativeIteratorDefinition; QString mutableAssociativeIteratorDefinition; - QSet<QString> usedNamespaces; + QSet<QString> activeNamespaces_; QMap<QString, QString> sequentialIteratorClasses; QMap<QString, QString> mutableSequentialIteratorClasses; QMap<QString, QString> associativeIteratorClasses; diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp index 25c92fb44f7..3f1e8c02e9b 100644 --- a/src/tools/qdoc/ditaxmlgenerator.cpp +++ b/src/tools/qdoc/ditaxmlgenerator.cpp @@ -240,6 +240,7 @@ QString DitaXmlGenerator::ditaTags[] = "topicref", "tt", "u", + "uicontrol", "ul", "unknown", "vrm", @@ -417,7 +418,6 @@ DitaXmlGenerator::DitaXmlGenerator() sectionNestingLevel(0), tableColumnCount(0), funcLeftParen("\\S(\\()"), - tree_(0), nodeTypeMaps(Node::LastType,0), nodeSubtypeMaps(Node::LastSubtype,0), pageTypeMaps(Node::OnBeyondZebra,0) @@ -617,7 +617,7 @@ GuidMap* DitaXmlGenerator::lookupGuidMap(const QString& fileName) This is where the DITA XML files are written. \note The file is created in PageGenerator::generateTree(). */ -void DitaXmlGenerator::generateTree(const Tree *tree) +void DitaXmlGenerator::generateTree(Tree *tree) { tree_ = tree; nonCompatClasses.clear(); @@ -637,6 +637,7 @@ void DitaXmlGenerator::generateTree(const Tree *tree) findAllSince(tree->root()); Generator::generateTree(tree); + generateCollisionPages(); writeDitaMap(tree); } @@ -717,40 +718,39 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, case Atom::BaseName: break; case Atom::BriefLeft: - //if (relative->type() == Node::Fake) { - //skipAhead = skipAtoms(atom, Atom::BriefRight); - //break; - //} - if (inSection()) { - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","brief"); - } - else { - noLinks = true; - writeStartTag(DT_shortdesc); - } - if (relative->type() == Node::Property || - relative->type() == Node::Variable) { - xmlWriter().writeCharacters("This "); - if (relative->type() == Node::Property) - xmlWriter().writeCharacters("property"); - else if (relative->type() == Node::Variable) - xmlWriter().writeCharacters("variable"); - xmlWriter().writeCharacters(" holds "); - } - if (noLinks) { - atom = atom->next(); - while (atom != 0 && atom->type() != Atom::BriefRight) { - if (atom->type() == Atom::String || - atom->type() == Atom::AutoLink) - str += atom->string(); - skipAhead++; - atom = atom->next(); + { + Node::Type t = relative->type(); + if (inSection()) { + writeStartTag(DT_p); + xmlWriter().writeAttribute("outputclass","brief"); + } + else { + noLinks = true; + writeStartTag(DT_shortdesc); + } + if (t == Node::Property || t == Node::Variable) { + xmlWriter().writeCharacters("This "); + if (relative->type() == Node::Property) + xmlWriter().writeCharacters("property"); + else if (relative->type() == Node::Variable) + xmlWriter().writeCharacters("variable"); + xmlWriter().writeCharacters(" holds "); + } + if (noLinks) { + atom = atom->next(); + while (atom != 0 && atom->type() != Atom::BriefRight) { + if (atom->type() == Atom::String || + atom->type() == Atom::AutoLink) + str += atom->string(); + skipAhead++; + atom = atom->next(); + } + if (t == Node::Property || t == Node::Variable) + str[0] = str[0].toLower(); + if (str.endsWith(QLatin1Char('.'))) + str.truncate(str.length() - 1); + writeCharacters(str + QLatin1Char('.')); } - str[0] = str[0].toLower(); - if (str.endsWith(QLatin1Char('.'))) - str.truncate(str.length() - 1); - writeCharacters(str + QLatin1Char('.')); } break; case Atom::BriefRight: @@ -879,6 +879,8 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, else if (atom->string().startsWith("span ")) { t = DT_keyword; } + else if (atom->string() == ATOM_FORMATTING_UICONTROL) + t = DT_uicontrol; else if (atom->string() == ATOM_FORMATTING_UNDERLINE) t = DT_u; else if (atom->string() == ATOM_FORMATTING_INDEX) @@ -1191,6 +1193,11 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, } } break; + case Atom::HR: //<p outputclass="horizontal-rule" /> + writeStartTag(DT_p); + xmlWriter().writeAttribute("outputclass","horizontal-rule"); + writeEndTag(); // </p> + break; case Atom::Image: case Atom::InlineImage: { @@ -1202,7 +1209,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, QString images = "images"; if (!baseDir().isEmpty()) images.prepend("../"); - if (atom->string()[0] != '/') + if (!atom->string().isEmpty() && atom->string()[0] != '/') images.append(QLatin1Char('/')); fileName = images + atom->string(); } @@ -1266,19 +1273,15 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, const Node *node = 0; QString myLink = getLink(atom, relative, marker, &node); if (myLink.isEmpty()) { - relative->doc().location().warning(tr("Can't link to '%1' in %2") - .arg(atom->string()) - .arg(marker->plainFullName(relative))); + myLink = getCollisionLink(atom); + } + if (myLink.isEmpty()) { + relative->doc().location().warning(tr("Can't link to '%1'") + .arg(atom->string())); } else if (!inSectionHeading) { beginLink(myLink); } -#if 0 - else { - //xmlWriter().writeCharacters(atom->string()); - //qDebug() << "MYLINK:" << myLink << outFileName() << atom->string(); - } -#endif skipAhead = 1; } break; @@ -1741,7 +1744,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, for marking up the code. I don't know what that means exactly. */ void -DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* marker) +DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) { QList<Section>::ConstIterator s; @@ -1783,7 +1786,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark generateThreadSafeness(nsn, marker); generateSince(nsn, marker); - enterSection("h2","Detailed Description"); + enterSection("",""); generateBody(nsn, marker); generateAlsoList(nsn, marker); leaveSection(); @@ -1920,7 +1923,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark generateInheritedBy(cn, marker); generateThreadSafeness(cn, marker); generateSince(cn, marker); - enterSection("h2","Detailed Description"); + enterSection("",""); generateBody(cn, marker); generateAlsoList(cn, marker); leaveSection(); @@ -2045,7 +2048,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark generateThreadSafeness(fn, marker); generateSince(fn, marker); generateSince(fn, marker); - enterSection("h2","Detailed Description"); + enterSection("",""); generateBody(fn, marker); generateAlsoList(fn, marker); leaveSection(); @@ -2140,8 +2143,8 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark writeEndTag(); // </cxxClass> } else if ((inner->type() == Node::Fake) && (inner->subType() == Node::QmlClass)) { - const QmlClassNode* qcn = const_cast<QmlClassNode*>(static_cast<const QmlClassNode*>(inner)); - const ClassNode* cn = qcn->classNode(); + QmlClassNode* qcn = const_cast<QmlClassNode*>(static_cast<const QmlClassNode*>(inner)); + ClassNode* cn = qcn->classNode(); rawTitle = marker->plainName(inner); fullTitle = marker->plainFullName(inner); title = rawTitle + " Element"; @@ -2167,7 +2170,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark generateQmlInherits(qcn, marker); generateQmlInheritedBy(qcn, marker); generateSince(qcn, marker); - enterSection("h2","Detailed Description"); + enterSection("",""); generateBody(qcn, marker); if (cn) { generateQmlText(cn->doc().body(), cn, marker, qcn->name()); @@ -2245,7 +2248,7 @@ void DitaXmlGenerator::writeXrefListItem(const QString& link, const QString& tex Generate the DITA page for a qdoc file that doesn't map to an underlying c++ file. */ -void DitaXmlGenerator::generateFakeNode(const FakeNode* fake, CodeMarker* marker) +void DitaXmlGenerator::generateFakeNode(FakeNode* fake, CodeMarker* marker) { /* If the fake node is a page node, and if the page type @@ -2307,7 +2310,7 @@ void DitaXmlGenerator::generateFakeNode(const FakeNode* fake, CodeMarker* marker } else { if (fake->subType() == Node::Module) { - enterSection("h2","Detailed Description"); + enterSection("",""); generateBody(fake, marker); leaveSection(); } @@ -2496,6 +2499,9 @@ void DitaXmlGenerator::generateHeader(const Node* node, case Node::ExternalPage: // not used outputclass = "externalpage"; break; + case Node::Collision: + outputclass = "collision"; + break; default: outputclass = "page"; } @@ -3299,16 +3305,11 @@ void DitaXmlGenerator::generateOverviewList(const Node* relative, CodeMarker* /* else if (!isGroupPage) { // If we encounter a page that belongs to a group then // we add that page to the list for that group. - const FakeNode* groupNode = - static_cast<const FakeNode*>(tree_->root()->findNode(group, Node::Fake)); - if (groupNode) - fakeNodeMap[groupNode].insert(sortKey, fakeNode); - //else - // uncategorizedNodeMap.insert(sortKey, fakeNode); - }// else - // uncategorizedNodeMap.insert(sortKey, fakeNode); - }// else - // uncategorizedNodeMap.insert(sortKey, fakeNode); + const FakeNode* gn = tree_->findGroupNode(QStringList(group)); + if (gn) + fakeNodeMap[gn].insert(sortKey, fakeNode); + } + } } } @@ -3874,8 +3875,6 @@ QString DitaXmlGenerator::guidForNode(const Node* node) return node->guid(); case Node::Variable: return node->guid(); - case Node::Target: - return node->guid(); } return QString(); } @@ -3883,12 +3882,14 @@ QString DitaXmlGenerator::guidForNode(const Node* node) /*! Constructs a file name appropriate for the \a node and returns it. If the \a node is not a fake node, or if it is a fake node but - it is neither an external page node nor an image node, call the - PageGenerator::fileName() function. + it is neither an external page node nor an image node or a ditamap, + call the PageGenerator::fileName() function. */ QString DitaXmlGenerator::fileName(const Node* node) { if (node->type() == Node::Fake) { + if (static_cast<const FakeNode*>(node)->pageType() == Node::DitaMapPage) + return node->name(); if (static_cast<const FakeNode*>(node)->subType() == Node::ExternalPage) return node->name(); if (static_cast<const FakeNode*>(node)->subType() == Node::Image) @@ -4138,7 +4139,7 @@ const Node* DitaXmlGenerator::findNodeForTarget(const QString& target, node = relative; } else if (target.endsWith(".html")) { - node = tree_->root()->findNode(target, Node::Fake); + node = tree_->root()->findChildNodeByNameAndType(target, Node::Fake); } else if (marker) { node = marker->resolveTarget(target, tree_, relative); @@ -4199,7 +4200,7 @@ QString DitaXmlGenerator::getLink(const Atom* atom, *node = relative; } else if (first.endsWith(".html")) { - *node = tree_->root()->findNode(first, Node::Fake); + *node = tree_->root()->findChildNodeByNameAndType(first, Node::Fake); } else { *node = marker->resolveTarget(first, tree_, relative); @@ -4283,22 +4284,10 @@ QString DitaXmlGenerator::getLink(const Atom* atom, } if (!link.isEmpty() && link[0] == '#') { link.prepend(outFileName()); - qDebug() << "LOCAL LINK:" << link; } return link; } -/*! - This function can be called if getLink() returns an empty - string. - */ -QString DitaXmlGenerator::getDisambiguationLink(const Atom *, CodeMarker *) -{ - qDebug() << "Unimplemented function called: " - << "QString DitaXmlGenerator::getDisambiguationLink()"; - return QString(); -} - void DitaXmlGenerator::generateIndex(const QString& fileBase, const QString& url, const QString& title) @@ -4415,19 +4404,19 @@ void DitaXmlGenerator::generateQmlSummary(const Section& section, Outputs the DITA detailed documentation for a section on a QML element reference page. */ -void DitaXmlGenerator::generateDetailedQmlMember(const Node* node, +void DitaXmlGenerator::generateDetailedQmlMember(Node* node, const InnerNode* relative, CodeMarker* marker) { QString marked; - const QmlPropertyNode* qpn = 0; + QmlPropertyNode* qpn = 0; if (node->subType() == Node::QmlPropertyGroup) { const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node); NodeList::ConstIterator p = qpgn->childNodes().begin(); writeStartTag(DT_ul); while (p != qpgn->childNodes().end()) { if ((*p)->type() == Node::QmlProperty) { - qpn = static_cast<const QmlPropertyNode*>(*p); + qpn = static_cast<QmlPropertyNode*>(*p); writeStartTag(DT_li); writeGuidAttribute((Node*)qpn); QString attr; @@ -4453,7 +4442,7 @@ void DitaXmlGenerator::generateDetailedQmlMember(const Node* node, writeEndTag(); // </ul> } else if (node->type() == Node::QmlProperty) { - qpn = static_cast<const QmlPropertyNode*>(node); + qpn = static_cast<QmlPropertyNode*>(node); /* If the QML property node has a single subproperty, override, replace qpn with that override node and @@ -4462,7 +4451,7 @@ void DitaXmlGenerator::generateDetailedQmlMember(const Node* node, if (qpn->qmlPropNodes().size() == 1) { Node* n = qpn->qmlPropNodes().at(0); if (n->type() == Node::QmlProperty) - qpn = static_cast<const QmlPropertyNode*>(n); + qpn = static_cast<QmlPropertyNode*>(n); } /* Now qpn either has no overrides, or it has more @@ -4596,10 +4585,9 @@ void DitaXmlGenerator::generateQmlInherits(const QmlClassNode* qcn, CodeMarker* If there is no class node, or if the class node status is set to Node::Internal, do nothing. */ -void DitaXmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn, - CodeMarker* marker) +void DitaXmlGenerator::generateQmlInstantiates(QmlClassNode* qcn, CodeMarker* marker) { - const ClassNode* cn = qcn->classNode(); + ClassNode* cn = qcn->classNode(); if (cn && (cn->status() != Node::Internal)) { writeStartTag(DT_p); xmlWriter().writeAttribute("outputclass","instantiates"); @@ -4627,8 +4615,7 @@ void DitaXmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn, If there is no QML element, or if the class node status is set to Node::Internal, do nothing. */ -void DitaXmlGenerator::generateInstantiatedBy(const ClassNode* cn, - CodeMarker* marker) +void DitaXmlGenerator::generateInstantiatedBy(ClassNode* cn, CodeMarker* marker) { if (cn && cn->status() != Node::Internal && cn->qmlElement() != 0) { const QmlClassNode* qcn = cn->qmlElement(); @@ -4815,13 +4802,13 @@ void DitaXmlGenerator::writeFunctions(const Section& s, FunctionNode* fn = const_cast<FunctionNode*>(static_cast<const FunctionNode*>(*m)); writeStartTag(DT_cxxFunction); xmlWriter().writeAttribute("id",fn->guid()); + if (fn->metaness() == FunctionNode::Signal) + xmlWriter().writeAttribute("otherprops","signal"); + else if (fn->metaness() == FunctionNode::Slot) + xmlWriter().writeAttribute("otherprops","slot"); if (!attribute.isEmpty()) xmlWriter().writeAttribute("outputclass",attribute); writeStartTag(DT_apiName); - if (fn->metaness() == FunctionNode::Signal) - xmlWriter().writeAttribute("outputclass","signal"); - else if (fn->metaness() == FunctionNode::Slot) - xmlWriter().writeAttribute("outputclass","slot"); writeCharacters(fn->name()); writeEndTag(); // </apiName> generateBrief(fn,marker); @@ -4973,6 +4960,11 @@ void DitaXmlGenerator::replaceTypesWithLinks(const Node* n, else addLink(linkForNode(tn,parent),arg,DT_apiRelation); } + else { + // Write simple arguments, like void and bool, + // which do not have a Qt defined target. + writeCharacters(arg.toString()); + } } } else { @@ -5619,13 +5611,13 @@ void DitaXmlGenerator::writeNestedClasses(const Section& s, Recursive writing of DITA XML files from the root \a node. */ void -DitaXmlGenerator::generateInnerNode(const InnerNode* node) +DitaXmlGenerator::generateInnerNode(InnerNode* node) { if (!node->url().isNull()) return; if (node->type() == Node::Fake) { - const FakeNode *fakeNode = static_cast<const FakeNode *>(node); + FakeNode* fakeNode = static_cast<FakeNode*>(node); if (fakeNode->subType() == Node::ExternalPage) return; if (fakeNode->subType() == Node::Image) @@ -5644,27 +5636,38 @@ DitaXmlGenerator::generateInnerNode(const InnerNode* node) CodeMarker *marker = CodeMarker::markerForFileName(node->location().filePath()); if (node->parent() != 0) { - if (!node->name().endsWith(".ditamap")) - beginSubPage(node, fileName(node)); - if (node->type() == Node::Namespace || node->type() == Node::Class) { - generateClassLikeNode(node, marker); + /* + Skip name collision nodes here and process them + later in generateCollisionPages(). Each one is + appended to a list for later. + */ + if ((node->type() == Node::Fake) && (node->subType() == Node::Collision)) { + NameCollisionNode* ncn = static_cast<NameCollisionNode*>(node); + collisionNodes.append(const_cast<NameCollisionNode*>(ncn)); } - else if (node->type() == Node::Fake) { - if (node->subType() == Node::HeaderFile) + else { + if (!node->name().endsWith(".ditamap")) + beginSubPage(node, fileName(node)); + if (node->type() == Node::Namespace || node->type() == Node::Class) { generateClassLikeNode(node, marker); - else if (node->subType() == Node::QmlClass) - generateClassLikeNode(node, marker); - else - generateFakeNode(static_cast<const FakeNode*>(node), marker); + } + else if (node->type() == Node::Fake) { + if (node->subType() == Node::HeaderFile) + generateClassLikeNode(node, marker); + else if (node->subType() == Node::QmlClass) + generateClassLikeNode(node, marker); + else + generateFakeNode(static_cast<FakeNode*>(node), marker); + } + if (!node->name().endsWith(".ditamap")) + endSubPage(); } - if (!node->name().endsWith(".ditamap")) - endSubPage(); } NodeList::ConstIterator c = node->childNodes().begin(); while (c != node->childNodes().end()) { if ((*c)->isInnerNode() && (*c)->access() != Node::Private) - generateInnerNode((const InnerNode*) *c); + generateInnerNode((InnerNode*)*c); ++c; } } @@ -5734,7 +5737,7 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent) if (!child || child->isInternal() || child->doc().isEmpty()) continue; - if (child->name() == "index.html") { + if (child->name() == "index.html" || child->name() == "index") { rootPageNode = child; } @@ -5810,8 +5813,6 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent) break; case Node::Variable: break; - case Node::Target: - break; case Node::QmlProperty: break; case Node::QmlSignal: @@ -5831,10 +5832,13 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent) Creates the DITA map for the qdoc run. The map is written to the file \e{qt.ditamap" in the DITA XML output directory. */ -void DitaXmlGenerator::writeDitaMap(const Tree *tree) +void DitaXmlGenerator::writeDitaMap(Tree *tree) { QString doctype; +/* + Remove #if 0 to get a flat ditamap. +*/ #if 0 beginSubPage(tree->root(),"qt.ditamap"); doctype = "<!DOCTYPE map PUBLIC \"-//OASIS//DTD DITA Map//EN\" \"map.dtd\">"; @@ -5892,7 +5896,7 @@ void DitaXmlGenerator::writeDitaMap(const Tree *tree) writeTopicrefs(pageTypeMaps[Node::FAQPage], "faqs"); writeTopicrefs(pageTypeMaps[Node::ArticlePage], "articles"); writeTopicrefs(nodeSubtypeMaps[Node::Example], "examples"); - writeTopicrefs(nodeSubtypeMaps[Node::QmlClass], "QML classes"); + writeTopicrefs(nodeSubtypeMaps[Node::QmlClass], "QML types"); writeTopicrefs(nodeTypeMaps[Node::Class], "C++ classes"); writeTopicrefs(nodeTypeMaps[Node::Namespace], "C++ namespaces"); writeTopicrefs(nodeSubtypeMaps[Node::HeaderFile], "header files"); @@ -5964,79 +5968,78 @@ void DitaXmlGenerator::writeTopicrefs(NodeMultiMap* nmm, const QString& navtitle return; writeStartTag(DT_topicref); xmlWriter().writeAttribute("navtitle",navtitle); - NodeMultiMap::iterator i = nmm->begin(); - while (i != nmm->end()) { - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",i.key()); - xmlWriter().writeAttribute("href",fileName(i.value())); - switch (i.value()->type()) { - case Node::Fake: { - const FakeNode* fn = static_cast<const FakeNode*>(i.value()); - switch (fn->subType()) { - case Node::Group: { - const NodeList& members = fn->groupMembers(); - for (int j=0; j<members.size(); ++j) { - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",members[j]->name()); - xmlWriter().writeAttribute("href",fileName(members[j])); - writeEndTag(); // </topicref> - } - break; + NodeMultiMap::iterator i; + NodeMultiMap *ditaMaps = pageTypeMaps[Node::DitaMapPage]; + + /*! + Put all pages that are already in a hand-written ditamap not in + the qt.ditamap separately. It loops through all ditamaps recursively + before deciding to write an article to qt.ditamap. + */ + if ((navtitle == "articles" && ditaMaps && ditaMaps->size() > 0)) { + NodeMultiMap::iterator mapIterator = ditaMaps->begin(); + while (mapIterator != ditaMaps->end()) { + writeStartTag(DT_mapref); + xmlWriter().writeAttribute("navtitle",mapIterator.key()); + xmlWriter().writeAttribute("href",fileName(mapIterator.value())); + writeEndTag(); + ++mapIterator; + } + i = nmm->begin(); + while (i != nmm->end()) { + // Hardcode not writing index.dita multiple times in the tree. + // index.dita should only appear at the top of the ditamap. + if (fileName(i.value()) == "index.dita") { + i++; + continue; } - case Node::QmlModule: { - const NodeList& members = fn->qmlModuleMembers(); - for (int j=0; j<members.size(); ++j) { - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",members[j]->name()); - xmlWriter().writeAttribute("href",fileName(members[j])); - writeEndTag(); // </topicref> - } - break; - } - case Node::Example: { - const ExampleNode* en = static_cast<const ExampleNode*>(fn); - if (!en->imageFileName().isEmpty()) { - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle","image"); - xmlWriter().writeAttribute("href",en->imageFileName()); - writeEndTag(); // </topicref> - } - const NodeList& files = en->childNodes(); - for (int j=0; j<files.size(); ++j) { - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("href",files[j]->name()); - writeEndTag(); // </topicref> - } - break; - } - case Node::Module: { - if (moduleNamespaceMap.contains(fn->name())) { - const NodeMap& nodeMap = moduleNamespaceMap[fn->name()]; - foreach (const QString& name, nodeMap.keys()) { - const Node* node = nodeMap[name]; - if (node->status() == Node::Obsolete || - node->isInternal() || - node->access() == Node::Private || - node->doc().isEmpty()) - continue; - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",node->name()); - xmlWriter().writeAttribute("href",fileName(node)); - writeEndTag(); // </topicref> + bool foundInDitaMap = false; + mapIterator = ditaMaps->begin(); + while (mapIterator != ditaMaps->end()) { + const DitaMapNode *dmNode = static_cast<const DitaMapNode *>(mapIterator.value()); + for (int count = 0; count < dmNode->map().count(); count++) { + if (dmNode->map().at(count)->navtitle() == i.key()) { + foundInDitaMap = true; } + ++mapIterator; } - if (moduleClassMap.contains(fn->name())) { - const NodeMap& nodeMap = moduleClassMap[fn->name()]; - foreach (const QString& name, nodeMap.keys()) { - const Node* node = nodeMap[name]; - if (node->status() == Node::Obsolete || - node->isInternal() || - node->access() == Node::Private || - node->doc().isEmpty()) - continue; + } + if (!foundInDitaMap) { + writeStartTag(DT_topicref); + xmlWriter().writeAttribute("navtitle",i.key()); + xmlWriter().writeAttribute("href",fileName(i.value())); + writeEndTag(); // </topicref> + } + ++i; + } + } + /*! + Shortcut when there are no hand-written ditamaps or when we are + not generating the articles list. + */ + else { + i = nmm->begin(); + while (i != nmm->end()) { + // Hardcode not writing index.dita multiple times in the tree. + // index.dita should only appear at the top of the ditamap. + if (fileName(i.value()) == "index.dita") { + i++; + continue; + } + writeStartTag(DT_topicref); + xmlWriter().writeAttribute("navtitle",i.key()); + xmlWriter().writeAttribute("href",fileName(i.value())); + switch (i.value()->type()) { + case Node::Class: { + const NamespaceNode* nn = static_cast<const NamespaceNode*>(i.value()); + const NodeList& c = nn->childNodes(); + for (int j=0; j<c.size(); ++j) { + if (c[j]->isInternal() || c[j]->access() == Node::Private || c[j]->doc().isEmpty()) + continue; + if (c[j]->type() == Node::Class) { writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",node->name()); - xmlWriter().writeAttribute("href",fileName(node)); + xmlWriter().writeAttribute("navtitle",c[j]->name()); + xmlWriter().writeAttribute("href",fileName(c[j])); writeEndTag(); // </topicref> } } @@ -6045,43 +6048,9 @@ void DitaXmlGenerator::writeTopicrefs(NodeMultiMap* nmm, const QString& navtitle default: break; } - break; + writeEndTag(); // </topicref> + ++i; } - case Node::Namespace: { - const NamespaceNode* nn = static_cast<const NamespaceNode*>(i.value()); - const NodeList& c = nn->childNodes(); - for (int j=0; j<c.size(); ++j) { - if (c[j]->isInternal() || c[j]->access() == Node::Private || c[j]->doc().isEmpty()) - continue; - if (c[j]->type() == Node::Class) { - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",c[j]->name()); - xmlWriter().writeAttribute("href",fileName(c[j])); - writeEndTag(); // </topicref> - } - } - break; - } - case Node::Class: { - const NamespaceNode* nn = static_cast<const NamespaceNode*>(i.value()); - const NodeList& c = nn->childNodes(); - for (int j=0; j<c.size(); ++j) { - if (c[j]->isInternal() || c[j]->access() == Node::Private || c[j]->doc().isEmpty()) - continue; - if (c[j]->type() == Node::Class) { - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",c[j]->name()); - xmlWriter().writeAttribute("href",fileName(c[j])); - writeEndTag(); // </topicref> - } - } - break; - } - default: - break; - } - writeEndTag(); // </topicref> - ++i; } writeEndTag(); // </topicref> } @@ -6397,5 +6366,125 @@ QString DitaXmlGenerator::stripMarkup(const QString& src) const return text; } +/*! + We delayed generation of the collision pages until now, after + all the other pages have been generated. We do this because we might + encounter a link command that tries to link to a target on a QML + type page, but the link doesn't specify the module identifer + for the QML type, and the QML type name without a module + identifier is ambiguous. When such a link is found, qdoc can't find + the target, so it appends the target to the NameCollisionNode. After + the tree has been traversed and all these ambiguous links have been + added to the name collision nodes, this function is called. The list + of collision nodes is traversed here, and the collision page for + each collision is generated. The collision page will not only + disambiguate links to the QML type pages, but it will also disambiguate + links to properties, section headers, etc. + */ +void DitaXmlGenerator::generateCollisionPages() +{ + if (collisionNodes.isEmpty()) + return; + + for (int i=0; i<collisionNodes.size(); ++i) { + NameCollisionNode* ncn = collisionNodes.at(i); + if (!ncn) + continue; + + NodeList collisions; + const NodeList& nl = ncn->childNodes(); + if (!nl.isEmpty()) { + NodeList::ConstIterator it = nl.begin(); + while (it != nl.end()) { + if (!(*it)->isInternal()) + collisions.append(*it); + ++it; + } + } + if (collisions.size() <= 1) + continue; + + ncn->clearCurrentChild(); + beginSubPage(ncn, Generator::fileName(ncn)); + QString fullTitle = ncn->fullTitle(); + QString ditaTitle = fullTitle; + CodeMarker* marker = CodeMarker::markerForFileName(ncn->location().filePath()); + if (ncn->isQmlNode()) { + // Replace the marker with a QML code marker. + if (ncn->isQmlNode()) + marker = CodeMarker::markerForLanguage(QLatin1String("QML")); + } + + generateHeader(ncn, ditaTitle); + writeProlog(ncn); + writeStartTag(DT_body); + enterSection(QString(),QString()); + + NodeMap nm; + for (int i=0; i<collisions.size(); ++i) { + Node* n = collisions.at(i); + QString t; + if (!n->qmlModuleIdentifier().isEmpty()) + t = n->qmlModuleIdentifier() + " "; + t += protectEnc(fullTitle); + nm.insertMulti(t,n); + } + generateAnnotatedList(ncn, marker, nm); + + QList<QString> targets; + if (!ncn->linkTargets().isEmpty()) { + QMap<QString,QString>::ConstIterator t = ncn->linkTargets().begin(); + while (t != ncn->linkTargets().end()) { + int count = 0; + for (int i=0; i<collisions.size(); ++i) { + InnerNode* n = static_cast<InnerNode*>(collisions.at(i)); + if (n->findChildNodeByName(t.key())) { + ++count; + if (count > 1) { + targets.append(t.key()); + break; + } + } + } + ++t; + } + } + if (!targets.isEmpty()) { + QList<QString>::ConstIterator t = targets.begin(); + while (t != targets.end()) { + writeStartTag(DT_p); + writeGuidAttribute(Doc::canonicalTitle(*t)); + xmlWriter().writeAttribute("outputclass","h2"); + writeCharacters(protectEnc(*t)); + writeEndTag(); // </p> + writeStartTag(DT_ul); + for (int i=0; i<collisions.size(); ++i) { + InnerNode* n = static_cast<InnerNode*>(collisions.at(i)); + Node* p = n->findChildNodeByName(*t); + if (p) { + QString link = linkForNode(p,0); + QString label; + if (!n->qmlModuleIdentifier().isEmpty()) + label = n->qmlModuleIdentifier() + "::"; + label += n->name() + "::" + p->name(); + writeStartTag(DT_li); + writeStartTag(DT_xref); + xmlWriter().writeAttribute("href", link); + writeCharacters(protectEnc(label)); + writeEndTag(); // </xref> + writeEndTag(); // </li> + } + } + writeEndTag(); // </ul> + ++t; + } + } + leaveSection(); // </section> + writeEndTag(); // </body> + endSubPage(); + } +} + + QT_END_NAMESPACE diff --git a/src/tools/qdoc/ditaxmlgenerator.h b/src/tools/qdoc/ditaxmlgenerator.h index a4fc890ddec..6eea6dc0634 100644 --- a/src/tools/qdoc/ditaxmlgenerator.h +++ b/src/tools/qdoc/ditaxmlgenerator.h @@ -249,6 +249,7 @@ public: DT_topicref, DT_tt, DT_u, + DT_uicontrol, DT_ul, DT_unknown, DT_vrm, @@ -265,8 +266,8 @@ public: virtual void terminateGenerator(); virtual QString format(); virtual bool canHandleFormat(const QString& format); - virtual void generateTree(const Tree *tree); - virtual void generateDisambiguationPages() { } + virtual void generateTree(Tree *tree); + void generateCollisionPages(); QString protectEnc(const QString& string); static QString protect(const QString& string, const QString& encoding = "ISO-8859-1"); @@ -278,8 +279,8 @@ protected: virtual int generateAtom(const Atom* atom, const Node* relative, CodeMarker* marker); - virtual void generateClassLikeNode(const InnerNode* inner, CodeMarker* marker); - virtual void generateFakeNode(const FakeNode* fake, CodeMarker* marker); + virtual void generateClassLikeNode(InnerNode* inner, CodeMarker* marker); + virtual void generateFakeNode(FakeNode* fake, CodeMarker* marker); virtual QString fileExtension(const Node* node) const; virtual QString guidForNode(const Node* node); virtual QString linkForNode(const Node* node, const Node* relative); @@ -376,12 +377,12 @@ private: const Node* relative, CodeMarker* marker, bool summary); - void generateDetailedQmlMember(const Node* node, + void generateDetailedQmlMember(Node* node, const InnerNode* relative, CodeMarker* marker); void generateQmlInherits(const QmlClassNode* qcn, CodeMarker* marker); - void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker); - void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker); + void generateQmlInstantiates(QmlClassNode* qcn, CodeMarker* marker); + void generateInstantiatedBy(ClassNode* cn, CodeMarker* marker); void generateSection(const NodeList& nl, const Node* relative, @@ -420,7 +421,6 @@ private: const Node *relative, CodeMarker *marker, const Node **node); - QString getDisambiguationLink(const Atom* atom, CodeMarker* marker); virtual void generateIndex(const QString& fileBase, const QString& url, const QString& title); @@ -436,11 +436,11 @@ private: GuidMap* lookupGuidMap(const QString& fileName); virtual void beginSubPage(const InnerNode* node, const QString& fileName); virtual void endSubPage(); - virtual void generateInnerNode(const InnerNode* node); + virtual void generateInnerNode(InnerNode* node); QXmlStreamWriter& xmlWriter(); void writeApiDesc(const Node* node, CodeMarker* marker, const QString& title); void addLink(const QString& href, const QStringRef& text, DitaTag t = DT_xref); - void writeDitaMap(const Tree* tree); + void writeDitaMap(Tree* tree); void writeDitaMap(const DitaMapNode* node); void writeStartTag(DitaTag t); bool writeEndTag(DitaTag t=DT_NONE); @@ -500,7 +500,6 @@ private: QStringList vrm; QStringList stylesheets; QStringList customHeadElements; - const Tree* tree_; QMap<QString, QString> refMap; QMap<QString, QString> name2guidMap; GuidMaps guidMaps; diff --git a/src/tools/qdoc/doc.cpp b/src/tools/qdoc/doc.cpp index 7572799eba1..3c1bab17af9 100644 --- a/src/tools/qdoc/doc.cpp +++ b/src/tools/qdoc/doc.cpp @@ -118,6 +118,7 @@ enum { CMD_GENERATELIST, CMD_GRANULARITY, CMD_HEADER, + CMD_HR, CMD_I, CMD_IF, CMD_IMAGE, @@ -169,6 +170,7 @@ enum { CMD_TARGET, CMD_TOPICREF, CMD_TT, + CMD_UICONTROL, CMD_UNDERLINE, CMD_UNICODE, CMD_VALUE, @@ -234,6 +236,7 @@ static struct { { "generatelist", CMD_GENERATELIST, 0 }, { "granularity", CMD_GRANULARITY, 0 }, // ### don't document for now { "header", CMD_HEADER, 0 }, + { "hr", CMD_HR, 0 }, { "i", CMD_I, 0 }, { "if", CMD_IF, 0 }, { "image", CMD_IMAGE, 0 }, @@ -285,6 +288,7 @@ static struct { { "target", CMD_TARGET, 0 }, { "topicref", CMD_TOPICREF, 0 }, { "tt", CMD_TT, 0 }, + { "uicontrol", CMD_UICONTROL, 0 }, { "underline", CMD_UNDERLINE, 0 }, { "unicode", CMD_UNICODE, 0 }, { "value", CMD_VALUE, 0 }, @@ -902,6 +906,10 @@ void DocParser::parse(const QString& source, case CMD_E: startFormat(ATOM_FORMATTING_ITALIC, cmd); break; + case CMD_HR: + leavePara(); + append(Atom::HR); + break; case CMD_IF: preprocessorSkipping.push(!Tokenizer::isTrue(getRestOfLine())); if (preprocessorSkipping.top()) @@ -1313,6 +1321,9 @@ void DocParser::parse(const QString& source, case CMD_TT: startFormat(ATOM_FORMATTING_TELETYPE, cmd); break; + case CMD_UICONTROL: + startFormat(ATOM_FORMATTING_UICONTROL, cmd); + break; case CMD_UNDERLINE: startFormat(ATOM_FORMATTING_UNDERLINE, cmd); break; diff --git a/src/tools/qdoc/doc/qdoc-manual.qdoc b/src/tools/qdoc/doc/qdoc-manual.qdoc index 342cabc4321..29147494fa1 100644 --- a/src/tools/qdoc/doc/qdoc-manual.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual.qdoc @@ -301,6 +301,7 @@ \li \l {11-qdoc-commands-specialcontent.html#tableofcontents-command} {\\tableofcontents} \li \l {08-qdoc-commands-creatinglinks.html#target-command} {\\target} \li \l {04-qdoc-commands-textmarkup.html#tt-command} {\\tt} + \li \l {04-qdoc-commands-textmarkup.html#uicontrol-command} {\\uicontrol} {(new 25/3/2012)} \li \l {04-qdoc-commands-textmarkup.html#underline-command} {\\underline} \li \l {12-0-qdoc-commands-miscellaneous.html#raw-command} {\\unicode} \li \l {11-qdoc-commands-specialcontent.html#warning-command} {\\warning} @@ -837,6 +838,15 @@ If the argument contains spaces or other punctuation, enclose the argument in curly brackets. + \target uicontrol-command + \section1 \\uicontrol + + The \\uicontrol command is used to mark content as being used for UI + control elements. When using HTML the output is rendered in bold. + When using DITA XML the content is enclosed in a \c{uicontrol} tag. + + \sa \\b + \target underline-command \section1 \\underline @@ -5541,25 +5551,18 @@ \target qmlsignal-command \section1 \\qmlsignal - The \\qmlsignal command is for documenting a - \l{http://doc.qt.nokia.com/4.7/qdeclarativeintroduction.html#signal-handlers} - {signal handler}. - The argument is the rest of the line. It should be the QML type where the - signal handler is declared, the \c{::} qualifier, and finally the signal - handler name. If we have a QML signal handler named \c onAdd() in QML - element \c MouseArea, the \\qmlsignal for it would look like this: + The \\qmlsignal command is for documenting a QML signal. + The argument is the rest of the line. The arguments should be: the QML type + where the signal is declared, the \c{::} qualifier, and finally the signal + name. If we have a QML signal named \c clicked(), the documentation for it + would look like this: \code / *! - \qmlsignal MouseArea::onEntered() - - This handler is called when the mouse enters the mouse area. - - By default the onEntered handler is only called while a button is - pressed. Setting hoverEnabled to true enables handling of - onEntered when no mouse button is pressed. - - \sa hoverEnabled + \qmlsignal UIComponents::Button::clicked() + This signal is emitted when the user clicks the button. A click is defined + as a press followed by a release. The corresponding handler is + \c onClicked. * / \endcode @@ -8751,6 +8754,7 @@ \li \l {21-0-qdoc-creating-dita-maps.html#topicref-command} {\\topicref} \span {class="newStuff"} {(new 05/03/12)} \li \l {04-qdoc-commands-textmarkup.html#tt-command} {\\tt} \li \l {13-qdoc-commands-topics.html#typedef-command} {\\typedef} + \li \l {04-qdoc-commands-textmarkup.html#uicontrol-command} {\\uicontrol} {(new 25/3/2012)} \li \l {04-qdoc-commands-textmarkup.html#underline-command} {\\underline} \li \l {13-qdoc-commands-topics.html#variable-command} {\\variable} \li \l {10-qdoc-commands-tablesandlists.html#value-command} {\\value} diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp index 97ab5652ae8..8cda8b7667d 100644 --- a/src/tools/qdoc/generator.cpp +++ b/src/tools/qdoc/generator.cpp @@ -102,7 +102,8 @@ Generator::Generator() gt(">"), lt("<"), quot("""), - tag("</?@[^>]*>") + tag("</?@[^>]*>"), + tree_(0) { generators.prepend(this); } @@ -293,6 +294,13 @@ QString Generator::fileBase(const Node *node) const //Was QDOC2_COMPAT, required for index.html if (base.endsWith(".html")) base.truncate(base.length() - 5); + + if (node->subType() == Node::QmlModule) { + base.prepend("qmlmodule-"); + } + if (node->subType() == Node::Module) { + base.append("-module"); + } } // the code below is effectively equivalent to: @@ -445,11 +453,12 @@ QString Generator::fullName(const Node *node, { if (node->type() == Node::Fake) { const FakeNode* fn = static_cast<const FakeNode *>(node); -#if 0 + // Removed for QTBUG-22870 + // Unremoved by mws 30/03/12 if (!fn->qmlModuleIdentifier().isEmpty()) - return fn->qmlModuleIdentifier() + QLatin1Char(' ') + fn->title(); -#endif + return fn->qmlModuleIdentifier() + "::" + fn->title(); + return fn->title(); } else if (node->type() == Node::Class && @@ -693,8 +702,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } } -void Generator::generateClassLikeNode(const InnerNode * /* classe */, - CodeMarker * /* marker */) +void Generator::generateClassLikeNode(InnerNode* /* classe */, CodeMarker* /* marker */) { } @@ -706,8 +714,7 @@ void Generator::generateExampleFiles(const FakeNode *fake, CodeMarker *marker) generateFileList(fake, marker, Node::Image, QString("Images:")); } -void Generator::generateFakeNode(const FakeNode * /* fake */, - CodeMarker * /* marker */) +void Generator::generateFakeNode(FakeNode* /* fake */, CodeMarker* /* marker */) { } @@ -830,16 +837,16 @@ void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker) Recursive writing of HTML files from the root \a node. \note NameCollisionNodes are skipped here and processed - later. See HtmlGenerator::generateDisambiguationPages() - for more on this. + later. See HtmlGenerator::generateCollisionPages() for + more on this. */ -void Generator::generateInnerNode(const InnerNode* node) +void Generator::generateInnerNode(InnerNode* node) { if (!node->url().isNull()) return; if (node->type() == Node::Fake) { - const FakeNode *fakeNode = static_cast<const FakeNode *>(node); + FakeNode* fakeNode = static_cast<FakeNode*>(node); if (fakeNode->subType() == Node::ExternalPage) return; if (fakeNode->subType() == Node::Image) @@ -860,11 +867,11 @@ void Generator::generateInnerNode(const InnerNode* node) if (node->parent() != 0) { /* Skip name collision nodes here and process them - later in generateDisambiguationPages(). Each one - is appended to a list for later. + later in generateCollisionPages(). Each one is + appended to a list for later. */ if ((node->type() == Node::Fake) && (node->subType() == Node::Collision)) { - const NameCollisionNode* ncn = static_cast<const NameCollisionNode*>(node); + NameCollisionNode* ncn = static_cast<NameCollisionNode*>(node); collisionNodes.append(const_cast<NameCollisionNode*>(ncn)); } else { @@ -873,7 +880,7 @@ void Generator::generateInnerNode(const InnerNode* node) generateClassLikeNode(node, marker); } else if (node->type() == Node::Fake) { - generateFakeNode(static_cast<const FakeNode *>(node), marker); + generateFakeNode(static_cast<FakeNode*>(node), marker); } endSubPage(); } @@ -882,7 +889,7 @@ void Generator::generateInnerNode(const InnerNode* node) NodeList::ConstIterator c = node->childNodes().begin(); while (c != node->childNodes().end()) { if ((*c)->isInnerNode() && (*c)->access() != Node::Private) { - generateInnerNode((const InnerNode *) *c); + generateInnerNode((InnerNode*)*c); } ++c; } @@ -1242,8 +1249,9 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker) /*! This function is recursive. */ -void Generator::generateTree(const Tree *tree) +void Generator::generateTree(Tree *tree) { + tree_ = tree; generateInnerNode(tree->root()); } @@ -1258,6 +1266,40 @@ Generator *Generator::generatorForFormat(const QString& format) return 0; } +/*! + This function can be called if getLink() returns an empty + string. It tests the \a atom string to see if it is a link + of the form <element> :: <name>, where <element> is a QML + element or component without a module qualifier. If so, it + constructs a link to the <name> clause on the disambiguation + page for <element> and returns that link string. It also + adds the <name> as a target in the NameCollisionNode for + <element>. These clauses are then constructed when the + disambiguation page is actually generated. + */ +QString Generator::getCollisionLink(const Atom* atom) +{ + QString link; + if (!atom->string().contains("::")) + return link; + QStringList path = atom->string().split("::"); + NameCollisionNode* ncn = tree_->findCollisionNode(path[0]); + if (ncn) { + QString label; + if (atom->next() && atom->next()->next()) { + if (atom->next()->type() == Atom::FormattingLeft && + atom->next()->next()->type() == Atom::String) + label = atom->next()->next()->string(); + } + ncn->addLinkTarget(path[1],label); + link = fileName(ncn); + link += QLatin1Char('#'); + link += Doc::canonicalTitle(path[1]); + } + return link; +} + + /*! Looks up the tag \a t in the map of metadata values for the current topic in \a inner. If a value for the tag is found, @@ -1546,6 +1588,11 @@ QTextStream &Generator::out() return *outStreamStack.top(); } +QString Generator::outFileName() +{ + return QFileInfo(static_cast<QFile*>(out().device())->fileName()).fileName(); +} + QString Generator::outputPrefix(const QString &nodeType) { return outputPrefixes[nodeType]; diff --git a/src/tools/qdoc/generator.h b/src/tools/qdoc/generator.h index bc1b12b958a..c97e59602dd 100644 --- a/src/tools/qdoc/generator.h +++ b/src/tools/qdoc/generator.h @@ -46,6 +46,8 @@ #ifndef GENERATOR_H #define GENERATOR_H +#include <QFile> +#include <QFileInfo> #include <QList> #include <QMap> #include <QRegExp> @@ -83,7 +85,7 @@ public: virtual bool canHandleFormat(const QString &format) { return format == this->format(); } virtual QString format() = 0; - virtual void generateTree(const Tree *tree); + virtual void generateTree(Tree *tree); virtual void initializeGenerator(const Config &config); virtual void terminateGenerator(); @@ -107,13 +109,13 @@ protected: const Node *relative, CodeMarker *marker); virtual void generateBody(const Node *node, CodeMarker *marker); - virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker); - virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker); + virtual void generateClassLikeNode(InnerNode* inner, CodeMarker* marker); + virtual void generateFakeNode(FakeNode* fake, CodeMarker* marker); virtual void generateInheritedBy(const ClassNode *classe, CodeMarker *marker); virtual void generateInherits(const ClassNode *classe, CodeMarker *marker); - virtual void generateInnerNode(const InnerNode *node); + virtual void generateInnerNode(InnerNode* node); virtual void generateMaintainerList(const InnerNode* node, CodeMarker* marker); virtual void generateQmlInheritedBy(const QmlClassNode* qcn, CodeMarker* marker); virtual void generateQmlInherits(const QmlClassNode* qcn, CodeMarker* marker); @@ -125,8 +127,7 @@ protected: const Node *relative, CodeMarker *marker); virtual QString imageFileName(const Node *relative, const QString& fileBase); - virtual QString outFileName() { return QString(); } - virtual int skipAtoms(const Atom *atom, Atom::Type type) const; + virtual int skipAtoms(const Atom *atom, Atom::Type type) const; virtual void startText(const Node *relative, CodeMarker *marker); virtual QString typeString(const Node *node); @@ -154,10 +155,12 @@ protected: void generateSince(const Node *node, CodeMarker *marker); void generateStatus(const Node *node, CodeMarker *marker); void generateThreadSafeness(const Node *node, CodeMarker *marker); + QString getCollisionLink(const Atom* atom); QString getMetadataElement(const InnerNode* inner, const QString& t); QStringList getMetadataElements(const InnerNode* inner, const QString& t); QString indent(int level, const QString& markedCode); QTextStream& out(); + QString outFileName(); bool parseArg(const QString& src, const QString& tag, int* pos, @@ -228,6 +231,9 @@ private: QString lt; QString quot; QRegExp tag; + + protected: + Tree* tree_; }; QT_END_NAMESPACE diff --git a/src/tools/qdoc/helpprojectwriter.cpp b/src/tools/qdoc/helpprojectwriter.cpp index 5efd6ef928f..da2a43d7e81 100644 --- a/src/tools/qdoc/helpprojectwriter.cpp +++ b/src/tools/qdoc/helpprojectwriter.cpp @@ -117,13 +117,10 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList typeHash["function"] = Node::Function; typeHash["property"] = Node::Property; typeHash["variable"] = Node::Variable; - typeHash["target"] = Node::Target; -#ifdef QDOC_QML typeHash["qmlproperty"] = Node::QmlProperty; typeHash["qmlsignal"] = Node::QmlSignal; typeHash["qmlsignalhandler"] = Node::QmlSignalHandler; typeHash["qmlmethod"] = Node::QmlMethod; -#endif QHash<QString, Node::SubType> subTypeHash; subTypeHash["example"] = Node::Example; @@ -133,11 +130,9 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList subTypeHash["module"] = Node::Module; subTypeHash["page"] = Node::Page; subTypeHash["externalpage"] = Node::ExternalPage; -#ifdef QDOC_QML subTypeHash["qmlclass"] = Node::QmlClass; subTypeHash["qmlpropertygroup"] = Node::QmlPropertyGroup; subTypeHash["qmlbasictype"] = Node::QmlBasicType; -#endif QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values()); diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index b8ad119466f..9434ced42f1 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -100,7 +100,6 @@ HtmlGenerator::HtmlGenerator() numTableRows(0), threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"), - myTree(0), obsoleteLinks(false) { } @@ -128,6 +127,7 @@ void HtmlGenerator::initializeGenerator(const Config &config) { ATOM_FORMATTING_SUBSCRIPT, "<sub>", "</sub>" }, { ATOM_FORMATTING_SUPERSCRIPT, "<sup>", "</sup>" }, { ATOM_FORMATTING_TELETYPE, "<tt>", "</tt>" }, + { ATOM_FORMATTING_UICONTROL, "<b>", "</b>" }, { ATOM_FORMATTING_UNDERLINE, "<u>", "</u>" }, { 0, 0, 0 } }; @@ -254,9 +254,9 @@ QString HtmlGenerator::format() \note The HTML file generation is done in the base class, PageGenerator::generateTree(). */ -void HtmlGenerator::generateTree(const Tree *tree) +void HtmlGenerator::generateTree(Tree *tree) { - myTree = tree; + tree_ = tree; nonCompatClasses.clear(); mainClasses.clear(); compatClasses.clear(); @@ -267,6 +267,7 @@ void HtmlGenerator::generateTree(const Tree *tree) legaleseTexts.clear(); serviceClasses.clear(); qmlClasses.clear(); + findAllClasses(tree->root()); findAllFunctions(tree->root()); findAllLegaleseTexts(tree->root()); @@ -274,13 +275,13 @@ void HtmlGenerator::generateTree(const Tree *tree) findAllSince(tree->root()); Generator::generateTree(tree); - reportOrphans(tree->root()); - generateDisambiguationPages(); + //reportOrphans(tree->root()); + generateCollisionPages(); QString fileBase = project.toLower().simplified().replace(" ", "-"); generateIndex(fileBase, projectUrl, projectDescription); - helpProjectWriter->generate(myTree); + helpProjectWriter->generate(tree_); generateManifestFiles(); } @@ -491,7 +492,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, break; case Atom::AnnotatedList: { - QList<Node*> values = myTree->groups().values(atom->string()); + QList<Node*> values = tree_->groups().values(atom->string()); NodeMap nodeMap; for (int i = 0; i < values.size(); ++i) { const Node* n = values.at(i); @@ -537,7 +538,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, // Add additional groups and remove groups of classes that // should be excluded from the edition. - QMultiMap <QString, Node *> groups = myTree->groups(); + QMultiMap <QString, Node *> groups = tree_->groups(); foreach (const QString &groupName, editionGroupMap[editionName]) { QList<Node *> groupClasses; if (groupName.startsWith(QLatin1Char('-'))) { @@ -761,6 +762,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, } } break; + case Atom::HR: + out() << "<hr />\n"; + break; case Atom::Image: case Atom::InlineImage: { @@ -832,7 +836,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *node = 0; QString myLink = getLink(atom, relative, marker, &node); if (myLink.isEmpty()) { - myLink = getDisambiguationLink(atom, marker); + myLink = getCollisionLink(atom); if (myLink.isEmpty()) { relative->doc().location().warning(tr("Can't create link to '%1'") .arg(atom->string())); @@ -1159,13 +1163,12 @@ int HtmlGenerator::generateAtom(const Atom *atom, /*! Generate a reference page for a C++ class. */ -void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, - CodeMarker *marker) +void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) { QList<Section> sections; QList<Section>::ConstIterator s; - const ClassNode *classe = 0; + ClassNode* classe = 0; QString title; QString rawTitle; @@ -1176,7 +1179,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, title = rawTitle + " Namespace"; } else if (inner->type() == Node::Class) { - classe = static_cast<const ClassNode *>(inner); + classe = static_cast<ClassNode*>(inner); rawTitle = marker->plainName(inner); fullTitle = marker->plainFullName(inner); title = rawTitle + " Class"; @@ -1369,15 +1372,32 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, disambiguate links to the component pages, but it will also disambiguate links to properties, section headers, etc. */ -void HtmlGenerator::generateDisambiguationPages() +void HtmlGenerator::generateCollisionPages() { if (collisionNodes.isEmpty()) return; + for (int i=0; i<collisionNodes.size(); ++i) { NameCollisionNode* ncn = collisionNodes.at(i); + if (!ncn) + continue; + + NodeList collisions; + const NodeList& nl = ncn->childNodes(); + if (!nl.isEmpty()) { + NodeList::ConstIterator it = nl.begin(); + while (it != nl.end()) { + if (!(*it)->isInternal()) + collisions.append(*it); + ++it; + } + } + if (collisions.size() <= 1) + continue; + ncn->clearCurrentChild(); beginSubPage(ncn, Generator::fileName(ncn)); - QString fullTitle = "Name Collision: " + ncn->fullTitle(); + QString fullTitle = ncn->fullTitle(); QString htmlTitle = fullTitle; CodeMarker* marker = CodeMarker::markerForFileName(ncn->location().filePath()); if (ncn->isQmlNode()) { @@ -1389,36 +1409,56 @@ void HtmlGenerator::generateDisambiguationPages() generateHeader(htmlTitle, ncn, marker); if (!fullTitle.isEmpty()) out() << "<h1 class=\"title\">" << protectEnc(fullTitle) << "</h1>\n"; - const NodeList& nl = ncn->childNodes(); + NodeMap nm; - NodeList::ConstIterator it = nl.begin(); - while (it != nl.end()) { - QString t = (*it)->qmlModuleIdentifier() + " " + protectEnc(fullTitle); - nm.insertMulti(t,(*it)); - ++it; + for (int i=0; i<collisions.size(); ++i) { + Node* n = collisions.at(i); + QString t; + if (!n->qmlModuleIdentifier().isEmpty()) + t = n->qmlModuleIdentifier() + "::"; + t += protectEnc(fullTitle); + nm.insertMulti(t,n); } generateAnnotatedList(ncn, marker, nm, true); - const QMap<QString,QString>& targets = ncn->linkTargets(); + QList<QString> targets; + if (!ncn->linkTargets().isEmpty()) { + QMap<QString,QString>::ConstIterator t = ncn->linkTargets().begin(); + while (t != ncn->linkTargets().end()) { + int count = 0; + for (int i=0; i<collisions.size(); ++i) { + InnerNode* n = static_cast<InnerNode*>(collisions.at(i)); + if (n->findChildNodeByName(t.key())) { + ++count; + if (count > 1) { + targets.append(t.key()); + break; + } + } + } + ++t; + } + } if (!targets.isEmpty()) { - QMap<QString,QString>::ConstIterator t = targets.begin(); + QList<QString>::ConstIterator t = targets.begin(); while (t != targets.end()) { - out() << "<a name=\"" << Doc::canonicalTitle(t.key()) << "\"></a>"; - out() << "<h2 class=\"title\">" << protectEnc(t.key()) << "</h2>\n"; + out() << "<a name=\"" << Doc::canonicalTitle(*t) << "\"></a>"; + out() << "<h2 class=\"title\">" << protectEnc(*t) << "</h2>\n"; out() << "<ul>\n"; - it = nl.begin(); - while (it != nl.end()) { - InnerNode* n = static_cast<InnerNode*>(*it); - Node* p = n->findNode(t.key()); + for (int i=0; i<collisions.size(); ++i) { + InnerNode* n = static_cast<InnerNode*>(collisions.at(i)); + Node* p = n->findChildNodeByName(*t); if (p) { QString link = linkForNode(p,0); - QString label = n->qmlModuleIdentifier() + "::" + n->name() + "::" + p->name(); + QString label; + if (!n->qmlModuleIdentifier().isEmpty()) + label = n->qmlModuleIdentifier() + "::"; + label += n->name() + "::" + p->name(); out() << "<li>"; out() << "<a href=\"" << link << "\">"; out() << protectEnc(label) << "</a>"; out() << "</li>\n"; } - ++it; } out() << "</ul>\n"; ++t; @@ -1434,7 +1474,7 @@ void HtmlGenerator::generateDisambiguationPages() Generate the HTML page for an entity that doesn't map to any underlying parsable C++ class or QML component. */ -void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) +void HtmlGenerator::generateFakeNode(FakeNode* fake, CodeMarker* marker) { /* If the fake node is a page node, and if the page type @@ -1470,9 +1510,9 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) Generate the TOC for the new doc format. Don't generate a TOC for the home page. */ - const QmlClassNode* qml_cn = 0; + QmlClassNode* qml_cn = 0; if (fake->subType() == Node::QmlClass) { - qml_cn = static_cast<const QmlClassNode*>(fake); + qml_cn = static_cast<QmlClassNode*>(fake); sections = marker->qmlSections(qml_cn,CodeMarker::Summary); generateTableOfContents(fake,marker,§ions); @@ -1536,7 +1576,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) } else if (fake->subType() == Node::QmlClass) { const_cast<FakeNode*>(fake)->setCurrentChild(); - const ClassNode* cn = qml_cn->classNode(); + ClassNode* cn = qml_cn->classNode(); generateBrief(qml_cn, marker); generateQmlInherits(qml_cn, marker); generateQmlInheritedBy(qml_cn, marker); @@ -1792,7 +1832,7 @@ void HtmlGenerator::generateHeader(const QString& title, if (node && !node->doc().location().isEmpty()) out() << "<!-- " << node->doc().location().fileName() << " -->\n"; - QString shortVersion = myTree->version(); + QString shortVersion = tree_->version(); if (shortVersion.count(QChar('.')) == 2) shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); if (!project.isEmpty()) @@ -1813,9 +1853,9 @@ void HtmlGenerator::generateHeader(const QString& title, generateMacRef(node, marker); #endif - out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version()); + out() << QString(postHeader).replace("\\" + COMMAND_VERSION, tree_->version()); generateBreadCrumbs(title,node,marker); - out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version()); + out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, tree_->version()); navigationLinks.clear(); @@ -1900,8 +1940,8 @@ void HtmlGenerator::generateFooter(const Node *node) if (node && !node->links().empty()) out() << "<p class=\"naviNextPrevious footerNavi\">\n" << navigationLinks << "</p>\n"; - out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version()) - << QString(address).replace("\\" + COMMAND_VERSION, myTree->version()); + out() << QString(footer).replace("\\" + COMMAND_VERSION, tree_->version()) + << QString(address).replace("\\" + COMMAND_VERSION, tree_->version()); out() << "</body>\n"; out() << "</html>\n"; @@ -2632,7 +2672,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m QMap<QString, FakeNode *> uncategorizedNodeMap; QRegExp singleDigit("\\b([0-9])\\b"); - const NodeList children = myTree->root()->childNodes(); + const NodeList children = tree_->root()->childNodes(); foreach (Node *child, children) { if (child->type() == Node::Fake && child != relative) { FakeNode *fakeNode = static_cast<FakeNode *>(child); @@ -2684,15 +2724,11 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m else if (!isGroupPage) { // If we encounter a page that belongs to a group then // we add that page to the list for that group. - const FakeNode *groupNode = static_cast<const FakeNode *>(myTree->root()->findNode(group, Node::Fake)); - if (groupNode) - fakeNodeMap[groupNode].insert(sortKey, fakeNode); - //else - // uncategorizedNodeMap.insert(sortKey, fakeNode); - }// else - // uncategorizedNodeMap.insert(sortKey, fakeNode); - }// else - // uncategorizedNodeMap.insert(sortKey, fakeNode); + const FakeNode* gn = tree_->findGroupNode(QStringList(group)); + if (gn) + fakeNodeMap[gn].insert(sortKey, fakeNode); + } + } } } @@ -2993,7 +3029,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { const Node* n = marker->resolveTarget(par1.toString(), - myTree, + tree_, relative); QString link = linkForNode(n, relative); addLink(link, arg, &html); @@ -3019,7 +3055,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, bool handled = false; if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); - const Node* n = marker->resolveTarget(arg.toString(), myTree, relative, self); + const Node* n = marker->resolveTarget(arg.toString(), tree_, relative, self); html += QLatin1String("<span class=\"type\">"); if (n && n->subType() == Node::QmlBasicType) { if (relative && relative->subType() == Node::QmlClass) @@ -3034,13 +3070,13 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, } else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); - const Node* n = marker->resolveTarget(arg.toString(), myTree, relative); + const Node* n = marker->resolveTarget(arg.toString(), tree_, relative); addLink(linkForNode(n,relative), arg, &html); handled = true; } else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); - const Node* n = marker->resolveTarget(arg.toString(), myTree, relative); + const Node* n = marker->resolveTarget(arg.toString(), tree_, relative); addLink(linkForNode(n,relative), arg, &html); handled = true; } @@ -3351,8 +3387,6 @@ QString HtmlGenerator::refForNode(const Node *node) case Node::Variable: ref = node->name() + "-var"; break; - case Node::Target: - return protectEnc(node->name()); } return registerRef(ref); } @@ -3698,15 +3732,15 @@ const Node *HtmlGenerator::findNodeForTarget(const QString &target, node = relative; } else if (target.endsWith(".html")) { - node = myTree->root()->findNode(target, Node::Fake); + node = tree_->root()->findChildNodeByNameAndType(target, Node::Fake); } else if (marker) { - node = marker->resolveTarget(target, myTree, relative); + node = marker->resolveTarget(target, tree_, relative); if (!node) { - node = myTree->findFakeNodeByTitle(target, relative); + node = tree_->findFakeNodeByTitle(target, relative); } if (!node && atom) { - node = myTree->findUnambiguousTarget(target, *const_cast<Atom**>(&atom), relative); + node = tree_->findUnambiguousTarget(target, *const_cast<Atom**>(&atom), relative); } } @@ -3761,15 +3795,21 @@ QString HtmlGenerator::getLink(const Atom *atom, *node = relative; } else if (first.endsWith(".html")) { - *node = myTree->root()->findNode(first, Node::Fake); + /* + This is not a recursive search. That's ok in + this case, because we are searching for a page + node, which must be a direct child of the tree + root. + */ + *node = tree_->root()->findChildNodeByNameAndType(first, Node::Fake); } else { - *node = marker->resolveTarget(first, myTree, relative); + *node = marker->resolveTarget(first, tree_, relative); if (!*node) { - *node = myTree->findFakeNodeByTitle(first, relative); + *node = tree_->findFakeNodeByTitle(first, relative); } if (!*node) { - *node = myTree->findUnambiguousTarget(first, targetAtom, relative); + *node = tree_->findUnambiguousTarget(first, targetAtom, relative); } } if (*node) { @@ -3823,7 +3863,7 @@ QString HtmlGenerator::getLink(const Atom *atom, target. */ while (!path.isEmpty()) { - targetAtom = myTree->findTarget(path.first(), *node); + targetAtom = tree_->findTarget(path.first(), *node); if (targetAtom == 0) break; path.removeFirst(); @@ -3860,44 +3900,11 @@ QString HtmlGenerator::getLink(const Atom *atom, return link; } -/*! - This function can be called if getLink() returns an empty - string. It tests the \a atom string to see if it is a link - of the form <element> :: <name>, where <element> is a QML - element or component without a module qualifier. If so, it - constructs a link to the <name> clause on the disambiguation - page for <element> and returns that link string. It also - adds the <name> as a target in the NameCollisionNode for - <element>. These clauses are then constructed when the - disambiguation page is actually generated. - */ -QString HtmlGenerator::getDisambiguationLink(const Atom *atom, CodeMarker *) -{ - QString link; - if (!atom->string().contains("::")) - return link; - QStringList path = atom->string().split("::"); - NameCollisionNode* ncn = myTree->findCollisionNode(path[0]); - if (ncn) { - QString label; - if (atom->next() && atom->next()->next()) { - if (atom->next()->type() == Atom::FormattingLeft && - atom->next()->next()->type() == Atom::String) - label = atom->next()->next()->string(); - } - ncn->addLinkTarget(path[1],label); - link = fileName(ncn); - link += QLatin1Char('#'); - link += Doc::canonicalTitle(path[1]); - } - return link; -} - void HtmlGenerator::generateIndex(const QString &fileBase, const QString &url, const QString &title) { - myTree->generateIndex(outputDir() + QLatin1Char('/') + fileBase + ".index", url, title); + tree_->generateIndex(outputDir() + QLatin1Char('/') + fileBase + ".index", url, title); } void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker) @@ -3921,12 +3928,12 @@ void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker) << "We strongly advise against " << "using it in new code. See "; - const FakeNode *fakeNode = myTree->findFakeNodeByTitle("Porting To Qt 4"); + const FakeNode *fakeNode = tree_->findFakeNodeByTitle("Porting To Qt 4"); Atom *targetAtom = 0; if (fakeNode && node->type() == Node::Class) { QString oldName(node->name()); oldName.remove(QLatin1Char('3')); - targetAtom = myTree->findTarget(oldName, + targetAtom = tree_->findTarget(oldName, fakeNode); } @@ -4043,11 +4050,11 @@ void HtmlGenerator::generateQmlSummary(const Section& section, Outputs the html detailed documentation for a section on a QML element reference page. */ -void HtmlGenerator::generateDetailedQmlMember(const Node *node, +void HtmlGenerator::generateDetailedQmlMember(Node *node, const InnerNode *relative, CodeMarker *marker) { - const QmlPropertyNode* qpn = 0; + QmlPropertyNode* qpn = 0; #ifdef GENERATE_MAC_REFS generateMacRef(node, marker); #endif @@ -4060,14 +4067,14 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node, out() << "<table class=\"qmlname\">"; while (p != qpgn->childNodes().end()) { if ((*p)->type() == Node::QmlProperty) { - qpn = static_cast<const QmlPropertyNode*>(*p); + qpn = static_cast<QmlPropertyNode*>(*p); out() << "<tr valign=\"top\" class=\"odd\">"; out() << "<td class=\"tblQmlPropNode\"><p>"; out() << "<a name=\"" + refForNode(qpn) + "\"></a>"; int ro = qpn->getReadOnly(); if (ro < 0) { - if (!qpn->isWritable(myTree)) { + if (!qpn->isWritable(tree_)) { out() << "<span class=\"qmlreadonly\">read-only</span>"; } } @@ -4085,7 +4092,7 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node, out() << "</div>"; } else if (node->type() == Node::QmlProperty) { - qpn = static_cast<const QmlPropertyNode*>(node); + qpn = static_cast<QmlPropertyNode*>(node); /* If the QML property node has a single subproperty, override, replace qpn with that override node and @@ -4094,7 +4101,7 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node, if (qpn->qmlPropNodes().size() == 1) { Node* n = qpn->qmlPropNodes().at(0); if (n->type() == Node::QmlProperty) - qpn = static_cast<const QmlPropertyNode*>(n); + qpn = static_cast<QmlPropertyNode*>(n); } /* Now qpn either has no overrides, or it has more @@ -4109,7 +4116,7 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node, int ro = qpn->getReadOnly(); if (ro < 0) { const ClassNode* cn = qpn->declarativeCppNode(); - if (cn && !qpn->isWritable(myTree)) { + if (cn && !qpn->isWritable(tree_)) { out() << "<span class=\"qmlreadonly\">read-only</span>"; } } @@ -4141,7 +4148,7 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node, int ro = qpn->getReadOnly(); if (ro < 0) { - if (!qpn->isWritable(myTree)) { + if (!qpn->isWritable(tree_)) { out() << "<span class=\"qmlreadonly\">read-only</span>"; } } @@ -4234,9 +4241,9 @@ void HtmlGenerator::generateQmlInherits(const QmlClassNode* qcn, CodeMarker* mar If there is no class node, or if the class node status is set to Node::Internal, do nothing. */ -void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker) +void HtmlGenerator::generateQmlInstantiates(QmlClassNode* qcn, CodeMarker* marker) { - const ClassNode* cn = qcn->classNode(); + ClassNode* cn = qcn->classNode(); if (cn && (cn->status() != Node::Internal)) { Text text; text << Atom::ParaLeft; @@ -4268,7 +4275,7 @@ void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* If there is no QML element, or if the class node status is set to Node::Internal, do nothing. */ -void HtmlGenerator::generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker) +void HtmlGenerator::generateInstantiatedBy(ClassNode* cn, CodeMarker* marker) { if (cn && cn->status() != Node::Internal && cn->qmlElement() != 0) { const QmlClassNode* qcn = cn->qmlElement(); @@ -4459,9 +4466,6 @@ QString HtmlGenerator::fullDocumentLocation(const Node *node, bool subdir) case Node::Variable: anchorRef = QLatin1Char('#') + node->name() + "-var"; break; - case Node::Target: - anchorRef = QLatin1Char('#') + Doc::canonicalTitle(node->name()); - break; case Node::Fake: { /* @@ -4752,8 +4756,6 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent) if (!related) child->location().warning(tr("Global variable, %1, %2").arg(child->name()).arg(message)); break; - case Node::Target: - break; case Node::QmlProperty: if (!related) child->location().warning(tr("Global QML property, %1, %2").arg(child->name()).arg(message)); @@ -4862,7 +4864,7 @@ void HtmlGenerator::writeDitaRefs(const DitaRefList& ditarefs) xmlWriter().writeStartElement("topicref"); xmlWriter().writeAttribute("navtitle",t->navtitle()); if (t->href().isEmpty()) { - const FakeNode* fn = myTree->findFakeNodeByTitle(t->navtitle()); + const FakeNode* fn = tree_->findFakeNodeByTitle(t->navtitle()); if (fn) xmlWriter().writeAttribute("href",fileName(fn)); } diff --git a/src/tools/qdoc/htmlgenerator.h b/src/tools/qdoc/htmlgenerator.h index 1ba88f83df7..403c1f0899f 100644 --- a/src/tools/qdoc/htmlgenerator.h +++ b/src/tools/qdoc/htmlgenerator.h @@ -86,8 +86,8 @@ public: virtual void initializeGenerator(const Config& config); virtual void terminateGenerator(); virtual QString format(); - virtual void generateTree(const Tree *tree); - virtual void generateDisambiguationPages(); + virtual void generateTree(Tree *tree); + void generateCollisionPages(); void generateManifestFiles(); QString protectEnc(const QString &string); @@ -101,8 +101,8 @@ protected: virtual int generateAtom(const Atom *atom, const Node *relative, CodeMarker *marker); - virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker); - virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker); + virtual void generateClassLikeNode(InnerNode* inner, CodeMarker* marker); + virtual void generateFakeNode(FakeNode* fake, CodeMarker* marker); virtual QString fileExtension(const Node *node) const; virtual QString refForNode(const Node *node); virtual QString linkForNode(const Node *node, const Node *relative); @@ -176,12 +176,12 @@ private: const Node *relative, CodeMarker *marker, bool summary); - void generateDetailedQmlMember(const Node *node, + void generateDetailedQmlMember(Node *node, const InnerNode *relative, CodeMarker *marker); void generateQmlInherits(const QmlClassNode* qcn, CodeMarker* marker); - void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker); - void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker); + void generateQmlInstantiates(QmlClassNode* qcn, CodeMarker* marker); + void generateInstantiatedBy(ClassNode* cn, CodeMarker* marker); void generateSection(const NodeList& nl, const Node *relative, @@ -227,7 +227,6 @@ private: const Node *relative, CodeMarker *marker, const Node** node); - QString getDisambiguationLink(const Atom* atom, CodeMarker* marker); virtual void generateIndex(const QString &fileBase, const QString &url, const QString &title); @@ -278,7 +277,6 @@ private: QString manifestDir; QStringList stylesheets; QStringList customHeadElements; - const Tree *myTree; bool obsoleteLinks; QMap<QString, NodeMap > moduleClassMap; QMap<QString, NodeMap > moduleNamespaceMap; diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index 85e97cdec93..de268e11779 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -108,22 +108,24 @@ static void printHelp() { Location::information(tr("Usage: qdoc [options] file1.qdocconf ...\n" "Options:\n" - " -help " - "Display this information and exit\n" - " -version " - "Display version of qdoc and exit\n" " -D<name> " "Define <name> as a macro while parsing sources\n" + " -help " + "Display this information and exit\n" " -highlighting " "Turn on syntax highlighting (makes qdoc run slower)\n" - " -showinternal " - "Include stuff marked internal\n" + " -no-examples " + "Do not generate documentation for examples" " -obsoletelinks " "Report links from obsolete items to non-obsolete items\n" " -outputdir " "Specify output directory, overrides setting in qdocconf file\n" " -outputformat " - "Specify output format, overrides setting in qdocconf file") ); + "Specify output format, overrides setting in qdocconf file" + " -showinternal " + "Include content marked internal\n" + " -version " + "Display version of qdoc and exit\n") ); } /*! @@ -427,6 +429,9 @@ int main(int argc, char **argv) else if (opt == "-showinternal") { showInternal = true; } + else if (opt == "-no-examples") { + Config::generateExamples = false; + } else if (opt == "-obsoletelinks") { obsoleteLinks = true; } diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index fb4a3fe271e..703c0735549 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -237,8 +237,6 @@ QString Node::nodeTypeString(unsigned t) return "property"; case Variable: return "variable"; - case Target: - return "target"; case QmlProperty: return "QML property"; case QmlSignal: @@ -524,14 +522,14 @@ QString Node::ditaXmlHref() If it is a child of a QML class node, return a pointer to the QML class node. Otherwise, return 0; */ -const QmlClassNode* Node::qmlClassNode() const +QmlClassNode* Node::qmlClassNode() { if (isQmlNode()) { - const Node* n = this; + Node* n = this; while (n && n->subType() != Node::QmlClass) n = n->parent(); if (n && n->subType() == Node::QmlClass) - return static_cast<const QmlClassNode*>(n); + return static_cast<QmlClassNode*>(n); } return 0; } @@ -543,14 +541,29 @@ const QmlClassNode* Node::qmlClassNode() const class node is a component. It will be non-null if the QML class node is a QML element. */ -const ClassNode* Node::declarativeCppNode() const +ClassNode* Node::declarativeCppNode() { - const QmlClassNode* qcn = qmlClassNode(); + QmlClassNode* qcn = qmlClassNode(); if (qcn) return qcn->classNode(); return 0; } +/*! + Returns true if the node's status is Internal, or if its + parent is a class with internal status. + */ +bool Node::isInternal() const +{ + if (status() == Internal) + return true; + if (parent() && parent()->status() == Internal) + return true; + if (relates() && relates()->status() == Internal) + return true; + return false; +} + /*! \class InnerNode */ @@ -571,7 +584,7 @@ InnerNode::~InnerNode() sure to also look in the children of its property group nodes. Return the matching node or 0. */ -Node *InnerNode::findNode(const QString& name) +Node *InnerNode::findChildNodeByName(const QString& name) { Node *node = childMap.value(name); if (node && node->subType() != QmlPropertyGroup) @@ -580,7 +593,7 @@ Node *InnerNode::findNode(const QString& name) for (int i=0; i<children.size(); ++i) { Node* n = children.at(i); if (n->subType() == QmlPropertyGroup) { - node = static_cast<InnerNode*>(n)->findNode(name); + node = static_cast<InnerNode*>(n)->findChildNodeByName(name); if (node) return node; } @@ -604,7 +617,7 @@ void InnerNode::findNodes(const QString& name, QList<Node*>& n) for (int i=0; i<children.size(); ++i) { node = children.at(i); if (node->subType() == QmlPropertyGroup) { - node = static_cast<InnerNode*>(node)->findNode(name); + node = static_cast<InnerNode*>(node)->findChildNodeByName(name); if (node) { n.append(node); return; @@ -628,7 +641,7 @@ void InnerNode::findNodes(const QString& name, QList<Node*>& n) if (node->subType() != QmlPropertyGroup) n.append(node); else { - node = static_cast<InnerNode*>(node)->findNode(name); + node = static_cast<InnerNode*>(node)->findChildNodeByName(name); if (node) n.append(node); } @@ -644,13 +657,14 @@ void InnerNode::findNodes(const QString& name, QList<Node*>& n) /*! Find the node in this node's children that has the given \a name. If this node is a QML class node, be sure to also look in the children - of its property group nodes. Return the matching node or 0. + of its property group nodes. Return the matching node or 0. This is + not a recearsive search. If \a qml is true, only match a node for which node->isQmlNode() returns true. If \a qml is false, only match a node for which node->isQmlNode() returns false. */ -Node* InnerNode::findNode(const QString& name, bool qml) +Node* InnerNode::findChildNodeByName(const QString& name, bool qml) { QList<Node*> nodes = childMap.values(name); if (!nodes.isEmpty()) { @@ -668,7 +682,7 @@ Node* InnerNode::findNode(const QString& name, bool qml) for (int i=0; i<children.size(); ++i) { Node* node = children.at(i); if (node->subType() == QmlPropertyGroup) { - node = static_cast<InnerNode*>(node)->findNode(name); + node = static_cast<InnerNode*>(node)->findChildNodeByName(name); if (node) return node; } @@ -678,28 +692,31 @@ Node* InnerNode::findNode(const QString& name, bool qml) } /*! - Same as the other findNode(), but if the node with the - specified \a name is not of the specified \a type, return - 0. + This function is like findChildNodeByName(), but if a node + with the specified \a name is found but it is not of the + specified \a type, 0 is returned. + + This function is not recursive and therefore can't handle + collisions. If it finds a collision node named \a name, it + will return that node. But it might not find the collision + node because it looks up \a name in the child map, not the + list. */ -Node *InnerNode::findNode(const QString& name, Type type) +Node* InnerNode::findChildNodeByNameAndType(const QString& name, Type type) { - if (type == Function) { + if (type == Function) return primaryFunctionMap.value(name); - } else { Node *node = childMap.value(name); - if (node && node->type() == type) { + if (node && node->type() == type) return node; - } - else { - return 0; - } } + return 0; } /*! - Find the function node in this node for the function named \a name. + Find a function node that is a child of this nose, such + that the function node has the specified \a name. */ FunctionNode *InnerNode::findFunctionNode(const QString& name) { @@ -707,12 +724,13 @@ FunctionNode *InnerNode::findFunctionNode(const QString& name) } /*! - Find the function node in this node that has the same name as \a clone. + Find the function node that is a child of this node, such + that the function has the same name and signature as the + \a clone node. */ FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) { - QMap<QString, Node *>::ConstIterator c = - primaryFunctionMap.find(clone->name()); + QMap<QString,Node*>::ConstIterator c = primaryFunctionMap.find(clone->name()); if (c != primaryFunctionMap.end()) { if (isSameSignature(clone, (FunctionNode *) *c)) { return (FunctionNode *) *c; @@ -907,10 +925,10 @@ void InnerNode::deleteChildren() /*! */ -const Node *InnerNode::findNode(const QString& name) const +const Node *InnerNode::findChildNodeByName(const QString& name) const { InnerNode *that = (InnerNode *) this; - return that->findNode(name); + return that->findChildNodeByName(name); } /*! @@ -918,22 +936,26 @@ const Node *InnerNode::findNode(const QString& name) const returns true. If \a qml is false, only match a node for which node->isQmlNode() returns false. */ -const Node* InnerNode::findNode(const QString& name, bool qml) const +const Node* InnerNode::findChildNodeByName(const QString& name, bool qml) const { InnerNode*that = (InnerNode*) this; - return that->findNode(name, qml); + return that->findChildNodeByName(name, qml); } /*! + Searches this node's children for a child named \a name + with the specified node \a type. */ -const Node *InnerNode::findNode(const QString& name, Type type) const +const Node* InnerNode::findChildNodeByNameAndType(const QString& name, Type type) const { InnerNode *that = (InnerNode *) this; - return that->findNode(name, type); + return that->findChildNodeByNameAndType(name, type); } /*! - Find the function node in this node that has the given \a name. + Find a function node that is a child of this nose, such + that the function node has the specified \a name. This + function calls the non-const version of itself. */ const FunctionNode *InnerNode::findFunctionNode(const QString& name) const { @@ -942,7 +964,9 @@ const FunctionNode *InnerNode::findFunctionNode(const QString& name) const } /*! - Find the function node in this node that has the same name as \a clone. + Find the function node that is a child of this node, such + that the function has the same name and signature as the + \a clone node. This function calls the non-const version. */ const FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) const { @@ -1196,13 +1220,9 @@ void InnerNode::removeRelated(Node *pseudoChild) \class LeafNode */ -/*! +/*! \fn bool LeafNode::isInnerNode() const Returns false because this is a LeafNode. */ -bool LeafNode::isInnerNode() const -{ - return false; -} /*! Constructs a leaf node named \a name of the specified @@ -1339,19 +1359,19 @@ void ClassNode::fixBaseClasses() Search the child list to find the property node with the specified \a name. */ -const PropertyNode *ClassNode::findPropertyNode(const QString &name) const +PropertyNode* ClassNode::findPropertyNode(const QString& name) { - const Node *n = findNode(name, Node::Property); + Node* n = findChildNodeByNameAndType(name, Node::Property); if (n) - return static_cast<const PropertyNode*>(n); + return static_cast<PropertyNode*>(n); - const PropertyNode *pn = 0; + PropertyNode* pn = 0; const QList<RelatedClass> &bases = baseClasses(); if (!bases.isEmpty()) { for (int i = 0; i < bases.size(); ++i) { - const ClassNode *cn = bases[i].node; + ClassNode* cn = bases[i].node; pn = cn->findPropertyNode(name); if (pn) break; @@ -1360,7 +1380,7 @@ const PropertyNode *ClassNode::findPropertyNode(const QString &name) const const QList<RelatedClass>& ignoredBases = ignoredBaseClasses(); if (!ignoredBases.isEmpty()) { for (int i = 0; i < ignoredBases.size(); ++i) { - const ClassNode *cn = ignoredBases[i].node; + ClassNode* cn = ignoredBases[i].node; pn = cn->findPropertyNode(name); if (pn) break; @@ -1376,20 +1396,20 @@ const PropertyNode *ClassNode::findPropertyNode(const QString &name) const finds one, it returns the pointer to that QML element. If it doesn't find one, it returns null. */ -const QmlClassNode* ClassNode::findQmlBaseNode() const +QmlClassNode* ClassNode::findQmlBaseNode() { - const QmlClassNode* result = 0; + QmlClassNode* result = 0; const QList<RelatedClass>& bases = baseClasses(); if (!bases.isEmpty()) { for (int i = 0; i < bases.size(); ++i) { - const ClassNode* cn = bases[i].node; + ClassNode* cn = bases[i].node; if (cn && cn->qmlElement()) { return cn->qmlElement(); } } for (int i = 0; i < bases.size(); ++i) { - const ClassNode* cn = bases[i].node; + ClassNode* cn = bases[i].node; if (cn) { result = cn->findQmlBaseNode(); if (result != 0) { @@ -1467,12 +1487,15 @@ QString FakeNode::fullTitle() const else return title(); } - else if ((nodeSubtype_ == HeaderFile) || (nodeSubtype_ == Collision)) { + else if (nodeSubtype_ == HeaderFile) { if (title().isEmpty()) return name(); else return name() + " - " + title(); } + else if (nodeSubtype_ == Collision) { + return title(); + } else { return title(); } @@ -1832,21 +1855,6 @@ QString FunctionNode::signature(bool values) const return s; } -/*! - Returns true if the node's status is Internal, or if its - parent is a class with internal status. - */ -bool FunctionNode::isInternal() const -{ - if (status() == Internal) - return true; - if (parent() && parent()->status() == Internal) - return true; - if (relates() && relates()->status() == Internal) - return true; - return false; -} - /*! Print some debugging stuff. */ @@ -1964,25 +1972,6 @@ bool PropertyNode::fromTrool(Trool troolean, bool defaultValue) } } -/*! - \class TargetNode - */ - -/*! - */ -TargetNode::TargetNode(InnerNode *parent, const QString& name) - : LeafNode(Target, parent, name) -{ -} - -/*! - Returns false because this is a TargetNode. - */ -bool TargetNode::isInnerNode() const -{ - return false; -} - bool QmlClassNode::qmlOnly = false; QMultiMap<QString,Node*> QmlClassNode::inheritedBy; QMap<QString, QmlClassNode*> QmlClassNode::moduleMap; @@ -1996,7 +1985,7 @@ QMap<QString, QmlClassNode*> QmlClassNode::moduleMap; */ QmlClassNode::QmlClassNode(InnerNode *parent, const QString& name, - const ClassNode* cn) + ClassNode* cn) : FakeNode(parent, name, QmlClass, Node::ApiPage), abstract(false), cnode_(cn), @@ -2132,15 +2121,15 @@ void QmlClassNode::clearCurrentChild() to output the line in the documentation that specifies the QML element that a QML element inherits. */ -void QmlClassNode::resolveInheritance(const Tree* tree) +void QmlClassNode::resolveInheritance(Tree* tree) { if (!links().empty() && links().contains(Node::InheritsLink)) { QPair<QString,QString> linkPair; linkPair = links()[Node::InheritsLink]; QStringList strList = linkPair.first.split("::"); - const Node* n = tree->findNode(strList,Node::Fake); - if (n && (n->subType() == Node::QmlClass || n->subType() == Node::Collision)) { - base_ = static_cast<const FakeNode*>(n); + Node* n = tree->findQmlClassNode(strList); + if (n) { + base_ = static_cast<FakeNode*>(n); if (base_ && base_->subType() == Node::QmlClass) { return; } @@ -2152,7 +2141,7 @@ void QmlClassNode::resolveInheritance(const Tree* tree) QString qmid = importList_.at(i).first + importList_.at(i).second; for (int j=0; j<children.size(); ++j) { if (qmid == children.at(j)->qmlModuleIdentifier()) { - base_ = static_cast<const FakeNode*>(children.at(j)); + base_ = static_cast<FakeNode*>(children.at(j)); return; } } @@ -2160,7 +2149,7 @@ void QmlClassNode::resolveInheritance(const Tree* tree) QString qmid = qmlModuleIdentifier(); for (int k=0; k<children.size(); ++k) { if (qmid == children.at(k)->qmlModuleIdentifier()) { - base_ = static_cast<const QmlClassNode*>(children.at(k)); + base_ = static_cast<QmlClassNode*>(children.at(k)); return; } } @@ -2169,7 +2158,7 @@ void QmlClassNode::resolveInheritance(const Tree* tree) return; } if (cnode_) { - const QmlClassNode* qcn = cnode_->findQmlBaseNode(); + QmlClassNode* qcn = cnode_->findQmlBaseNode(); if (qcn != 0) base_ = qcn; } @@ -2302,12 +2291,12 @@ bool QmlPropertyNode::fromTrool(Trool troolean, bool defaultValue) doesn't work for qmlproperty bool PropertyChanges::explicit, because the tokenizer gets confused on "explicit". */ -bool QmlPropertyNode::isWritable(const Tree* tree) const +bool QmlPropertyNode::isWritable(Tree* tree) { if (wri != Trool_Default) return fromTrool(wri, false); - const PropertyNode *pn = correspondingProperty(tree); + PropertyNode* pn = correspondingProperty(tree); if (pn) return pn->isWritable(); else { @@ -2316,16 +2305,16 @@ bool QmlPropertyNode::isWritable(const Tree* tree) const } } -const PropertyNode *QmlPropertyNode::correspondingProperty(const Tree *tree) const +PropertyNode* QmlPropertyNode::correspondingProperty(Tree *tree) { - const PropertyNode *pn; + PropertyNode* pn; Node* n = parent(); while (n && n->subType() != Node::QmlClass) n = n->parent(); if (n) { - const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n); - const ClassNode* cn = qcn->classNode(); + QmlClassNode* qcn = static_cast<QmlClassNode*>(n); + ClassNode* cn = qcn->classNode(); if (cn) { QStringList dotSplit = name().split(QChar('.')); pn = cn->findPropertyNode(dotSplit[0]); @@ -2335,10 +2324,10 @@ const PropertyNode *QmlPropertyNode::correspondingProperty(const Tree *tree) con // the property group, <group>.<property>. QStringList path(extractClassName(pn->qualifiedDataType())); - const Node* nn = tree->findNode(path,Class); + Node* nn = tree->findClassNode(path); if (nn) { - const ClassNode* cn = static_cast<const ClassNode*>(nn); - const PropertyNode *pn2 = cn->findPropertyNode(dotSplit[1]); + ClassNode* cn = static_cast<ClassNode*>(nn); + PropertyNode *pn2 = cn->findPropertyNode(dotSplit[1]); if (pn2) return pn2; // Return the property for the QML property. else @@ -2374,7 +2363,7 @@ const PropertyNode *QmlPropertyNode::correspondingProperty(const Tree *tree) con NameCollisionNode::NameCollisionNode(InnerNode* child) : FakeNode(child->parent(), child->name(), Collision, Node::NoPageType) { - setTitle("Name Collisions For: " + child->name()); + setTitle("Name Collision: " + child->name()); addCollision(child); current = 0; } @@ -2431,7 +2420,7 @@ bool NameCollisionNode::isQmlNode() const Find any of this collision node's children that has type \a t and subtype \a st and return a pointer to it. */ -const InnerNode* NameCollisionNode::findAny(Node::Type t, Node::SubType st) const +InnerNode* NameCollisionNode::findAny(Node::Type t, Node::SubType st) { if (current) { if (current->type() == t && current->subType() == st) @@ -2441,7 +2430,7 @@ const InnerNode* NameCollisionNode::findAny(Node::Type t, Node::SubType st) cons NodeList::ConstIterator i = cn.begin(); while (i != cn.end()) { if ((*i)->type() == t && (*i)->subType() == st) - return static_cast<const InnerNode*>(*i); + return static_cast<InnerNode*>(*i); ++i; } return 0; @@ -2756,9 +2745,6 @@ QString Node::idForNode() const case Node::Variable: str = "var-" + name(); break; - case Node::Target: - str = name(); - break; default: qDebug() << "ERROR: A case was not handled in Node::idForNode():" << "type():" << type() << "subType():" << subType(); diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h index 5b1eb211134..cfd446dd895 100644 --- a/src/tools/qdoc/node.h +++ b/src/tools/qdoc/node.h @@ -83,7 +83,6 @@ public: Function, Property, Variable, - Target, QmlProperty, QmlSignal, QmlSignalHandler, @@ -177,14 +176,17 @@ public: virtual void setOutputFileName(const QString& ) { } virtual bool isInnerNode() const = 0; + virtual bool isLeaf() const { return false; } virtual bool isReimp() const { return false; } virtual bool isFunction() const { return false; } virtual bool isQmlNode() const { return false; } - virtual bool isInternal() const { return false; } virtual bool isQtQuickNode() const { return false; } virtual bool isAbstract() const { return false; } + virtual bool isQmlPropertyGroup() const { return false; } + virtual bool isCollisionNode() const { return false; } virtual void setAbstract(bool ) { } virtual QString title() const { return QString(); } + bool isInternal() const; bool isIndexNode() const { return indexNodeFlag_; } Type type() const { return nodeType_; } virtual SubType subType() const { return NoSubType; } @@ -196,6 +198,8 @@ public: QString url() const; virtual QString nameForLists() const { return name_; } virtual QString outputFileName() const { return QString(); } + virtual void addGroupMember(Node* ) { } + virtual void addQmlModuleMember(Node* ) { } Access access() const { return access_; } QString accessString() const; @@ -223,13 +227,13 @@ public: virtual QString qmlModuleVersion() const { return qmlModuleVersion_; } virtual QString qmlModuleIdentifier() const { return qmlModuleName_ + qmlModuleVersion_; } virtual void setQmlModuleName(const QString& ); - virtual const ClassNode* classNode() const { return 0; } + virtual ClassNode* classNode() { return 0; } virtual void clearCurrentChild() { } virtual const ImportList* importList() const { return 0; } virtual void setImportList(const ImportList& ) { } virtual const Node* applyModuleIdentifier(const Node* ) const { return 0; } - const QmlClassNode* qmlClassNode() const; - const ClassNode* declarativeCppNode() const; + QmlClassNode* qmlClassNode(); + ClassNode* declarativeCppNode(); const QString& outputSubdirectory() const { return outSubDir_; } QString fullDocumentName() const; static QString cleanId(QString str); @@ -290,9 +294,9 @@ class InnerNode : public Node public: virtual ~InnerNode(); - Node* findNode(const QString& name); - Node* findNode(const QString& name, bool qml); - Node* findNode(const QString& name, Type type); + Node* findChildNodeByName(const QString& name); + Node* findChildNodeByName(const QString& name, bool qml); + Node* findChildNodeByNameAndType(const QString& name, Type type); void findNodes(const QString& name, QList<Node*>& n); FunctionNode* findFunctionNode(const QString& name); FunctionNode* findFunctionNode(const FunctionNode* clone); @@ -306,9 +310,10 @@ public: void removeFromRelated(); virtual bool isInnerNode() const { return true; } - const Node* findNode(const QString& name) const; - const Node* findNode(const QString& name, bool qml) const; - const Node* findNode(const QString& name, Type type) const; + virtual bool isLeaf() const { return false; } + const Node* findChildNodeByName(const QString& name) const; + const Node* findChildNodeByName(const QString& name, bool qml) const; + const Node* findChildNodeByNameAndType(const QString& name, Type type) const; const FunctionNode* findFunctionNode(const QString& name) const; const FunctionNode* findFunctionNode(const FunctionNode* clone) const; const EnumNode* findEnumNodeForValue(const QString &enumValue) const; @@ -358,7 +363,8 @@ public: LeafNode(); virtual ~LeafNode() { } - virtual bool isInnerNode() const; + virtual bool isInnerNode() const { return false; } + virtual bool isLeaf() const { return true; } protected: LeafNode(Type type, InnerNode* parent, const QString& name); @@ -412,12 +418,12 @@ public: QString serviceName() const { return sname; } void setServiceName(const QString& value) { sname = value; } - const QmlClassNode* qmlElement() const { return qmlelement; } + QmlClassNode* qmlElement() { return qmlelement; } void setQmlElement(QmlClassNode* qcn) { qmlelement = qcn; } virtual bool isAbstract() const { return abstract; } virtual void setAbstract(bool b) { abstract = b; } - const PropertyNode* findPropertyNode(const QString& name) const; - const QmlClassNode* findQmlBaseNode() const; + PropertyNode* findPropertyNode(const QString& name); + QmlClassNode* findQmlBaseNode(); private: QList<RelatedClass> bases; @@ -441,8 +447,8 @@ public: void setTitle(const QString &title) { title_ = title; } void setSubTitle(const QString &subTitle) { subtitle_ = subTitle; } - void addGroupMember(Node* node) { nodeList.append(node); } - void addQmlModuleMember(Node* node) { nodeList.append(node); } + virtual void addGroupMember(Node* node) { nodeList.append(node); } + virtual void addQmlModuleMember(Node* node) { nodeList.append(node); } SubType subType() const { return nodeSubtype_; } virtual QString title() const; @@ -453,6 +459,7 @@ public: const NodeList& qmlModuleMembers() const { return nodeList; } virtual QString nameForLists() const { return title(); } virtual void setImageFileName(const QString& ) { } + virtual bool isQmlPropertyGroup() const { return (nodeSubtype_ == QmlPropertyGroup); } protected: SubType nodeSubtype_; @@ -470,8 +477,9 @@ public: virtual void setCurrentChild(InnerNode* child) { current = child; } virtual void clearCurrentChild() { current = 0; } virtual bool isQmlNode() const; + virtual bool isCollisionNode() const { return true; } virtual const Node* applyModuleIdentifier(const Node* origin) const; - const InnerNode* findAny(Node::Type t, Node::SubType st) const; + InnerNode* findAny(Node::Type t, Node::SubType st); void addCollision(InnerNode* child); const QMap<QString,QString>& linkTargets() const { return targets; } void addLinkTarget(const QString& t, const QString& v) { targets.insert(t,v); } @@ -503,11 +511,11 @@ class QmlClassNode : public FakeNode public: QmlClassNode(InnerNode* parent, const QString& name, - const ClassNode* cn); + ClassNode* cn); virtual ~QmlClassNode(); virtual bool isQmlNode() const { return true; } virtual bool isQtQuickNode() const { return (qmlModuleName() == QLatin1String("QtQuick")); } - virtual const ClassNode* classNode() const { return cnode_; } + virtual ClassNode* classNode() { return cnode_; } virtual QString fileBase() const; virtual void setCurrentChild(); virtual void clearCurrentChild(); @@ -516,7 +524,7 @@ public: virtual bool isAbstract() const { return abstract; } virtual void setAbstract(bool b) { abstract = b; } const FakeNode* qmlBase() const { return base_; } - void resolveInheritance(const Tree* tree); + void resolveInheritance(Tree* tree); static void addInheritedBy(const QString& base, Node* sub); static void subclasses(const QString& base, NodeList& subs); static void terminate(); @@ -528,8 +536,8 @@ public: private: bool abstract; - const ClassNode* cnode_; - const FakeNode* base_; + ClassNode* cnode_; + FakeNode* base_; ImportList importList_; }; @@ -601,7 +609,7 @@ public: bool isDefault() const { return isdefault_; } bool isStored() const { return fromTrool(sto,true); } bool isDesignable() const { return fromTrool(des,false); } - bool isWritable(const Tree* tree) const; + bool isWritable(Tree* tree); bool isAttached() const { return attached_; } bool isReadOnly() const { return (readOnly_ > 0); } virtual bool isQmlNode() const { return true; } @@ -610,7 +618,7 @@ public: virtual QString qmlModuleVersion() const { return parent()->qmlModuleVersion(); } virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); } - const PropertyNode *correspondingProperty(const Tree *tree) const; + PropertyNode* correspondingProperty(Tree* tree); const QString& element() const { return static_cast<QmlPropGroupNode*>(parent())->element(); } void appendQmlPropNode(QmlPropertyNode* p) { qmlPropNodes_.append(p); } @@ -784,7 +792,6 @@ public: QString signature(bool values = false) const; const QString& element() const { return parent()->name(); } bool isAttached() const { return attached_; } - virtual bool isInternal() const; virtual bool isQmlNode() const { return ((type() == QmlSignal) || (type() == QmlMethod) || @@ -945,15 +952,6 @@ inline VariableNode::VariableNode(InnerNode* parent, const QString &name) // nothing. } -class TargetNode : public LeafNode -{ -public: - TargetNode(InnerNode* parent, const QString& name); - virtual ~TargetNode() { } - - virtual bool isInnerNode() const; -}; - class DitaMapNode : public FakeNode { public: diff --git a/src/tools/qdoc/tokenizer.cpp b/src/tools/qdoc/tokenizer.cpp index c87764b9349..7d9039e2997 100644 --- a/src/tools/qdoc/tokenizer.cpp +++ b/src/tools/qdoc/tokenizer.cpp @@ -116,7 +116,7 @@ static int hashKword(const char *s, int len) static void insertKwordIntoHash(const char *s, int number) { - int k = hashKword(s, strlen(s)); + int k = hashKword(s, int(strlen(s))); while (kwordHashTable[k]) { if (++k == KwordHashTableSize) k = 0; @@ -166,7 +166,7 @@ int Tokenizer::getToken() yyCh = getChar(); } while (isalnum(yyCh) || yyCh == '_'); - int k = hashKword(yyLex, yyLexLen); + int k = hashKword(yyLex, int(yyLexLen)); for (;;) { int i = kwordHashTable[k]; if (i == 0) { diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp index 450f2d777cc..3dfcfea48b8 100644 --- a/src/tools/qdoc/tree.cpp +++ b/src/tools/qdoc/tree.cpp @@ -124,18 +124,7 @@ Tree::~Tree() delete priv; } -/*! - This function simply calls the const version of itself and - returns the result. - */ -Node* Tree::findNode(const QStringList& path, Node* relative, int findFlags, const Node* self) -{ - return const_cast<Node*>(const_cast<const Tree*>(this)->findNode(path, - relative, - findFlags, - self)); -} - +// 1 calls 2 /*! Searches the tree for a node that matches the \a path. The search begins at \a start but can move up the parent chain @@ -162,16 +151,16 @@ const Node* Tree::findNode(const QStringList& path, return n; } +// 2 is private; it is only called by 1. /*! - This code in this function was extracted from the other - version of findNode() that has the same signature without - the last bool parameter \a qml. This function is called - only by that other findNode(). It can be called a second - time if the first call returns null. If \a qml is false, - the search will only match a node that is not a QML node. - If \a qml is true, the search will only match a node that - is a QML node. - */ + This overload function was extracted from the one above that has the + same signature without the last bool parameter, \a qml. This version + is called only by that other one. It is therefore private. It can + be called a second time by that other version, if the first call + returns null. If \a qml is false, the search will only match a node + that is not a QML node. If \a qml is true, the search will only + match a node that is a QML node. +*/ const Node* Tree::findNode(const QStringList& path, const Node* start, int findFlags, @@ -204,7 +193,7 @@ const Node* Tree::findNode(const QStringList& path, if (node == 0 || !node->isInnerNode()) break; - const Node* next = static_cast<const InnerNode*>(node)->findNode(path.at(i), qml); + const Node* next = static_cast<const InnerNode*>(node)->findChildNodeByName(path.at(i), qml); if (!next && (findFlags & SearchEnumValues) && i == path.size()-1) next = static_cast<const InnerNode*>(node)->findEnumNodeForValue(path.at(i)); @@ -212,10 +201,9 @@ const Node* Tree::findNode(const QStringList& path, if (!next && !qml && node->type() == Node::Class && (findFlags & SearchBaseClasses)) { NodeList baseClasses = allBaseClasses(static_cast<const ClassNode*>(node)); foreach (const Node* baseClass, baseClasses) { - next = static_cast<const InnerNode*>(baseClass)->findNode(path.at(i)); + next = static_cast<const InnerNode*>(baseClass)->findChildNodeByName(path.at(i)); if (!next && (findFlags & SearchEnumValues) && i == path.size() - 1) - next = static_cast<const InnerNode*>(baseClass) - ->findEnumNodeForValue(path.at(i)); + next = static_cast<const InnerNode*>(baseClass)->findEnumNodeForValue(path.at(i)); if (next) break; } @@ -238,45 +226,6 @@ const Node* Tree::findNode(const QStringList& path, return 0; } -/*! - Find the node with the specified \a path name of the - specified \a type. - */ -Node* Tree::findNode(const QStringList& path, - Node::Type type, - Node* relative, - int findFlags) -{ - return const_cast<Node*>(const_cast<const Tree*>(this)->findNode(path, - type, - relative, - findFlags)); -} - -/*! - This function just calls the const version of itself and returns - a pointer to the QML class node, or null. - */ -QmlClassNode* Tree::findQmlClassNode(const QString& module, const QString& element) -{ - return const_cast<QmlClassNode*>(const_cast<const Tree*>(this)->findQmlClassNode(module, element)); -} - -/*! - Find the node with the specified \a path name of the - specified \a type. - */ -const Node* Tree::findNode(const QStringList& path, - Node::Type type, - const Node* relative, - int findFlags) const -{ - const Node* node = findNode(path, relative, findFlags); - if (node != 0 && node->type() == type) - return node; - return 0; -} - /*! Find the QML class node for the specified \a module and \a name identifiers. The \a module identifier may be empty. If the module @@ -286,17 +235,17 @@ const Node* Tree::findNode(const QStringList& path, child is a QML class. If the collision node does not have a child that is a QML class node, return 0. */ -const QmlClassNode* Tree::findQmlClassNode(const QString& module, const QString& name) const +QmlClassNode* Tree::findQmlClassNode(const QString& module, const QString& name) { if (module.isEmpty()) { - const Node* n = findNode(QStringList(name), Node::Fake); + Node* n = findQmlClassNode(QStringList(name)); if (n) { if (n->subType() == Node::QmlClass) - return static_cast<const QmlClassNode*>(n); + return static_cast<QmlClassNode*>(n); else if (n->subType() == Node::Collision) { - const NameCollisionNode* ncn; - ncn = static_cast<const NameCollisionNode*>(n); - return static_cast<const QmlClassNode*>(ncn->findAny(Node::Fake,Node::QmlClass)); + NameCollisionNode* ncn; + ncn = static_cast<NameCollisionNode*>(n); + return static_cast<QmlClassNode*>(ncn->findAny(Node::Fake,Node::QmlClass)); } } return 0; @@ -397,16 +346,15 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path, if (i == path.size() - 1) next = ((InnerNode*) node)->findFunctionNode(path.at(i)); else - next = ((InnerNode*) node)->findNode(path.at(i)); + next = ((InnerNode*) node)->findChildNodeByName(path.at(i)); - if (!next && node->type() == Node::Class && - (findFlags & SearchBaseClasses)) { + if (!next && node->type() == Node::Class && (findFlags & SearchBaseClasses)) { NodeList baseClasses = allBaseClasses(static_cast<const ClassNode*>(node)); foreach (const Node* baseClass, baseClasses) { if (i == path.size() - 1) next = static_cast<const InnerNode*>(baseClass)->findFunctionNode(path.at(i)); else - next = static_cast<const InnerNode*>(baseClass)->findNode(path.at(i)); + next = static_cast<const InnerNode*>(baseClass)->findChildNodeByName(path.at(i)); if (next) break; @@ -474,6 +422,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& parentPath, return ((InnerNode*)parent)->findFunctionNode(clone); } } +//findNode(parameter.leftType().split("::"), 0, SearchBaseClasses|NonFunction); static const int NumSuffixes = 3; static const char* const suffixes[NumSuffixes] = { "", "s", "es" }; @@ -768,17 +717,12 @@ void Tree::resolveInheritance(int pass, ClassNode* classe) QList<InheritanceBound> bounds = priv->unresolvedInheritanceMap[classe]; QList<InheritanceBound>::ConstIterator b = bounds.begin(); while (b != bounds.end()) { - ClassNode* baseClass = (ClassNode*)findNode((*b).basePath, - Node::Class); - if (!baseClass && (*b).parent) { - baseClass = (ClassNode*)findNode((*b).basePath, - Node::Class, - (*b).parent); + Node* n = findClassNode((*b).basePath); + if (!n && (*b).parent) { + n = findClassNode((*b).basePath, (*b).parent); } - if (baseClass) { - classe->addBaseClass((*b).access, - baseClass, - (*b).dataTypeWithTemplateArgs); + if (n) { + classe->addBaseClass((*b).access, static_cast<ClassNode*>(n), (*b).dataTypeWithTemplateArgs); } ++b; } @@ -814,11 +758,9 @@ void Tree::resolveGroups() if (i.value()->access() == Node::Private) continue; - FakeNode* fake = - static_cast<FakeNode*>(findNode(QStringList(i.key()),Node::Fake)); - if (fake && fake->subType() == Node::Group) { - fake->addGroupMember(i.value()); - } + Node* n = findGroupNode(QStringList(i.key())); + if (n) + n->addGroupMember(i.value()); } } @@ -830,11 +772,9 @@ void Tree::resolveQmlModules() { NodeMultiMap::const_iterator i; for (i = priv->qmlModuleMap.constBegin(); i != priv->qmlModuleMap.constEnd(); ++i) { - FakeNode* fake = - static_cast<FakeNode*>(findNode(QStringList(i.key()),Node::Fake)); - if (fake && fake->subType() == Node::QmlModule) { - fake->addQmlModuleMember(i.value()); - } + Node* n = findQmlModuleNode(QStringList(i.key())); + if (n) + n->addQmlModuleMember(i.value()); } } @@ -978,15 +918,13 @@ FunctionNode* Tree::findVirtualFunctionInBaseClasses(ClassNode* classe, /*! */ -void Tree::fixPropertyUsingBaseClasses(ClassNode* classe, - PropertyNode* property) +void Tree::fixPropertyUsingBaseClasses(ClassNode* classe, PropertyNode* property) { QList<RelatedClass>::const_iterator r = classe->baseClasses().begin(); while (r != classe->baseClasses().end()) { - PropertyNode* baseProperty = - static_cast<PropertyNode*>(r->node->findNode(property->name(), - Node::Property)); - if (baseProperty) { + Node* n = r->node->findChildNodeByNameAndType(property->name(), Node::Property); + if (n) { + PropertyNode* baseProperty = static_cast<PropertyNode*>(n); fixPropertyUsingBaseClasses(r->node, baseProperty); property->setOverriddenFrom(baseProperty); } @@ -1414,10 +1352,9 @@ void Tree::resolveIndex() foreach (pair, priv->basesList) { foreach (const QString& base, pair.second.split(QLatin1Char(','))) { - Node* baseClass = root()->findNode(base, Node::Class); - if (baseClass) { - pair.first->addBaseClass(Node::Public, - static_cast<ClassNode*>(baseClass)); + Node* n = root()->findChildNodeByNameAndType(base, Node::Class); + if (n) { + pair.first->addBaseClass(Node::Public, static_cast<ClassNode*>(n)); } } } @@ -1425,9 +1362,9 @@ void Tree::resolveIndex() QPair<FunctionNode*,QString> relatedPair; foreach (relatedPair, priv->relatedList) { - Node* classNode = root()->findNode(relatedPair.second, Node::Class); - if (classNode) - relatedPair.first->setRelates(static_cast<ClassNode*>(classNode)); + Node* n = root()->findChildNodeByNameAndType(relatedPair.second, Node::Class); + if (n) + relatedPair.first->setRelates(static_cast<ClassNode*>(n)); } } @@ -1437,8 +1374,8 @@ void Tree::resolveIndex() false. */ bool Tree::generateIndexSection(QXmlStreamWriter& writer, - const Node* node, - bool generateInternalNodes) const + Node* node, + bool generateInternalNodes) { if (!node->url().isEmpty()) return false; @@ -1473,9 +1410,6 @@ bool Tree::generateIndexSection(QXmlStreamWriter& writer, case Node::Variable: nodeName = "variable"; break; - case Node::Target: - nodeName = "target"; - break; case Node::QmlProperty: nodeName = "qmlproperty"; break; @@ -1716,7 +1650,7 @@ bool Tree::generateIndexSection(QXmlStreamWriter& writer, case Node::QmlProperty: { - const QmlPropertyNode* qpn = static_cast<const QmlPropertyNode*>(node); + QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node); writer.writeAttribute("type", qpn->dataType()); writer.writeAttribute("attached", qpn->isAttached() ? "true" : "false"); writer.writeAttribute("writable", qpn->isWritable(this) ? "true" : "false"); @@ -1840,22 +1774,18 @@ bool Tree::generateIndexSection(QXmlStreamWriter& writer, foreach (const Parameter& parameter, functionNode->parameters()) { QString leftType = parameter.leftType(); - const Node* leftNode = - const_cast<Tree*>(this)->findNode(parameter.leftType().split("::"), - Node::Typedef, 0, SearchBaseClasses|NonFunction); - if (!leftNode) { - leftNode = const_cast<Tree*>(this)->findNode( - parameter.leftType().split("::"), Node::Typedef, + const Node* leftNode = const_cast<Tree*>(this)->findNode(parameter.leftType().split("::"), + 0, SearchBaseClasses|NonFunction); + if (!leftNode || leftNode->type() != Node::Typedef) { + leftNode = const_cast<Tree*>(this)->findNode(parameter.leftType().split("::"), node->parent(), SearchBaseClasses|NonFunction); } - if (leftNode) { + if (leftNode && leftNode->type() == Node::Typedef) { if (leftNode->type() == Node::Typedef) { const TypedefNode* typedefNode = static_cast<const TypedefNode*>(leftNode); if (typedefNode->associatedEnum()) { - leftType = "QFlags<" + - typedefNode->associatedEnum()->fullDocumentName() + - QLatin1Char('>'); + leftType = "QFlags<" + typedefNode->associatedEnum()->fullDocumentName() + QLatin1Char('>'); } } else @@ -1973,8 +1903,8 @@ bool compareNodes(const Node* n1, const Node* n2) they will be omitted. */ void Tree::generateIndexSections(QXmlStreamWriter& writer, - const Node* node, - bool generateInternalNodes) const + Node* node, + bool generateInternalNodes) { if (generateIndexSection(writer, node, generateInternalNodes)) { @@ -1984,7 +1914,7 @@ void Tree::generateIndexSections(QXmlStreamWriter& writer, NodeList cnodes = inner->childNodes(); qSort(cnodes.begin(), cnodes.end(), compareNodes); - foreach (const Node* child, cnodes) { + foreach (Node* child, cnodes) { /* Don't generate anything for a QML property group node. It is just a place holder for a collection of QML property @@ -1993,7 +1923,7 @@ void Tree::generateIndexSections(QXmlStreamWriter& writer, */ if (child->subType() == Node::QmlPropertyGroup) { const InnerNode* pgn = static_cast<const InnerNode*>(child); - foreach (const Node* c, pgn->childNodes()) { + foreach (Node* c, pgn->childNodes()) { generateIndexSections(writer, c, generateInternalNodes); } } @@ -2018,7 +1948,7 @@ void Tree::generateIndexSections(QXmlStreamWriter& writer, void Tree::generateIndex(const QString& fileName, const QString& url, const QString& title, - bool generateInternalNodes) const + bool generateInternalNodes) { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) @@ -2047,8 +1977,7 @@ void Tree::generateIndex(const QString& fileName, specified, returning true if an element was written; otherwise returns false. */ -void Tree::generateTagFileCompounds(QXmlStreamWriter& writer, - const InnerNode* inner) const +void Tree::generateTagFileCompounds(QXmlStreamWriter& writer, const InnerNode* inner) { foreach (const Node* node, inner->childNodes()) { @@ -2068,7 +1997,6 @@ void Tree::generateTagFileCompounds(QXmlStreamWriter& writer, case Node::Property: case Node::Function: case Node::Variable: - case Node::Target: default: continue; } @@ -2130,8 +2058,7 @@ void Tree::generateTagFileCompounds(QXmlStreamWriter& writer, /*! */ -void Tree::generateTagFileMembers(QXmlStreamWriter& writer, - const InnerNode* inner) const +void Tree::generateTagFileMembers(QXmlStreamWriter& writer, const InnerNode* inner) { foreach (const Node* node, inner->childNodes()) { @@ -2164,7 +2091,6 @@ void Tree::generateTagFileMembers(QXmlStreamWriter& writer, nodeName = "class"; break; case Node::Variable: - case Node::Target: default: continue; } @@ -2247,18 +2173,15 @@ void Tree::generateTagFileMembers(QXmlStreamWriter& writer, foreach (const Parameter& parameter, functionNode->parameters()) { QString leftType = parameter.leftType(); const Node* leftNode = const_cast<Tree*>(this)->findNode(parameter.leftType().split("::"), - Node::Typedef, 0, SearchBaseClasses|NonFunction); - if (!leftNode) { - leftNode = const_cast<Tree*>(this)->findNode( - parameter.leftType().split("::"), Node::Typedef, - node->parent(), SearchBaseClasses|NonFunction); + 0, SearchBaseClasses|NonFunction); + if (!leftNode || leftNode->type() != Node::Typedef) { + leftNode = const_cast<Tree*>(this)->findNode(parameter.leftType().split("::"), + node->parent(), SearchBaseClasses|NonFunction); } - if (leftNode) { + if (leftNode && leftNode->type() == Node::Typedef) { const TypedefNode* typedefNode = static_cast<const TypedefNode*>(leftNode); if (typedefNode->associatedEnum()) { - leftType = "QFlags<" + - typedefNode->associatedEnum()->fullDocumentName() + - QLatin1Char('>'); + leftType = "QFlags<" + typedefNode->associatedEnum()->fullDocumentName() + QLatin1Char('>'); } } signatureList.append(leftType + QLatin1Char(' ') + parameter.name()); @@ -2324,7 +2247,6 @@ void Tree::generateTagFileMembers(QXmlStreamWriter& writer, break; case Node::Variable: - case Node::Target: default: break; } @@ -2332,8 +2254,9 @@ void Tree::generateTagFileMembers(QXmlStreamWriter& writer, } /*! + Writes a tag file named \a fileName. */ -void Tree::generateTagFile(const QString& fileName) const +void Tree::generateTagFile(const QString& fileName) { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) @@ -2366,4 +2289,251 @@ void Tree::addExternalLink(const QString& url, const Node* relative) fakeNode->setDoc(doc); } +/*! + Find the node with the specified \a path name that is of + the specified \a type and \a subtype. Begin the search at + the \a start node. If the \a start node is 0, begin the + search at the tree root. \a subtype is not used unless + \a type is \c{Fake}. + */ +Node* Tree::findNodeByNameAndType(const QStringList& path, + Node::Type type, + Node::SubType subtype, + Node* start, + bool acceptCollision) +{ + if (!start) + start = const_cast<NamespaceNode*>(root()); + Node* result = findNodeRecursive(path, 0, start, type, subtype, acceptCollision); + return result; +} + +#if 0 + if (result) + qDebug() << "FOUND:" << path << Node::nodeTypeString(type) + << Node::nodeSubtypeString(subtype); + else + qDebug() << "NOT FOUND:" << path << Node::nodeTypeString(type) + << Node::nodeSubtypeString(subtype); +#endif + +/*! + Recursive search for a node identified by \a path. Each + path element is a name. \a pathIndex specifies the index + of the name in \a path to try to match. \a start is the + node whose children shoulod be searched for one that has + that name. Each time a match is found, increment the + \a pathIndex and call this function recursively. + + If the end of the path is reached (i.e. if a matching + node is found for each name in the \a path), the \a type + must match the type of the last matching node, and if the + type is \e{Fake}, the \a subtype must match as well. + + If the algorithm is successful, the pointer to the final + node is returned. Otherwise 0 is returned. + */ +Node* Tree::findNodeRecursive(const QStringList& path, + int pathIndex, + Node* start, + Node::Type type, + Node::SubType subtype, + bool acceptCollision) +{ + if (!start || path.isEmpty()) + return 0; // no place to start, or nothing to search for. + if (start->isLeaf()) { + if (pathIndex >= path.size()) + return start; // found a match. + return 0; // premature leaf + } + if (pathIndex >= path.size()) + return 0; // end of search path. + + InnerNode* current = static_cast<InnerNode*>(start); + const NodeList& children = current->childNodes(); + const QString& name = path.at(pathIndex); + for (int i=0; i<children.size(); ++i) { + Node* n = children.at(i); + if (!n) + continue; + if (n->isQmlPropertyGroup()) { + if (type == Node::QmlProperty) { + n = findNodeRecursive(path, pathIndex, n, type, subtype); + if (n) + return n; + } + } + else if (n->name() == name) { + if (pathIndex+1 >= path.size()) { + if (n->type() == type) { + if (type == Node::Fake) { + if (n->subType() == subtype) + return n; + else if (n->subType() == Node::Collision && acceptCollision) + return n; + else if (subtype == Node::NoSubType) + return n; // don't care what subtype is. + return 0; + } + else + return n; + } + else if (n->isCollisionNode()) { + if (acceptCollision) + return n; + return n = findNodeRecursive(path, pathIndex, n, type, subtype); + if (n) + return n; + } + else + return 0; + } + else { // Not at the end of the path. + n = findNodeRecursive(path, pathIndex+1, n, type, subtype); + if (n) + return n; + } + } + } + return 0; +} + +/*! + Find the Enum type node named \a path. Begin the search at the + \a start node. If the \a start node is 0, begin the search + at the root of the tree. Only an Enum type node named \a path is + acceptible. If one is not found, 0 is returned. + */ +EnumNode* Tree::findEnumNode(const QStringList& path, Node* start) +{ + if (!start) + start = const_cast<NamespaceNode*>(root()); + return static_cast<EnumNode*>(findNodeRecursive(path, 0, start, Node::Enum, Node::NoSubType)); +} + +/*! + Find the C++ class node named \a path. Begin the search at the + \a start node. If the \a start node is 0, begin the search + at the root of the tree. Only a C++ class node named \a path is + acceptible. If one is not found, 0 is returned. + */ +ClassNode* Tree::findClassNode(const QStringList& path, Node* start) +{ + if (!start) + start = const_cast<NamespaceNode*>(root()); + return static_cast<ClassNode*>(findNodeRecursive(path, 0, start, Node::Class, Node::NoSubType)); +} + +/*! + Find the Qml class node named \a path. Begin the search at the + \a start node. If the \a start node is 0, begin the search + at the root of the tree. Only a Qml class node named \a path is + acceptible. If one is not found, 0 is returned. + */ +QmlClassNode* Tree::findQmlClassNode(const QStringList& path, Node* start) +{ + /* + If the path contains one or two double colons ("::"), + check first to see if the first two path strings refer + to a QML element. If yes, that reference identifies a + QML class node. + */ + if (path.size() >= 2) { + QmlClassNode* qcn = QmlClassNode::moduleMap.value(path[0]+ "::" +path[1]); + if (qcn) + return qcn; + } + + if (!start) + start = const_cast<NamespaceNode*>(root()); + return static_cast<QmlClassNode*>(findNodeRecursive(path, 0, start, Node::Fake, Node::QmlClass)); +} + +/*! + Find the Namespace node named \a path. Begin the search at the + \a start node. If the \a start node is 0, begin the search + at the root of the tree. Only a Namespace node named \a path is + acceptible. If one is not found, 0 is returned. + */ +NamespaceNode* Tree::findNamespaceNode(const QStringList& path, Node* start) +{ + if (!start) + start = const_cast<NamespaceNode*>(root()); + return static_cast<NamespaceNode*>(findNodeRecursive(path, 0, start, Node::Namespace, Node::NoSubType)); +} + +/*! + Find the Group node named \a path. Begin the search at the + \a start node. If the \a start node is 0, begin the search + at the root of the tree. Only a Group node named \a path is + acceptible. If one is not found, 0 is returned. + */ +FakeNode* Tree::findGroupNode(const QStringList& path, Node* start) +{ + if (!start) + start = const_cast<NamespaceNode*>(root()); + return static_cast<FakeNode*>(findNodeRecursive(path, 0, start, Node::Fake, Node::Group)); +} + +/*! + Find the Qml module node named \a path. Begin the search at the + \a start node. If the \a start node is 0, begin the search + at the root of the tree. Only a Qml module node named \a path is + acceptible. If one is not found, 0 is returned. + */ +FakeNode* Tree::findQmlModuleNode(const QStringList& path, Node* start) +{ + if (!start) + start = const_cast<NamespaceNode*>(root()); + return static_cast<FakeNode*>(findNodeRecursive(path, 0, start, Node::Fake, Node::QmlModule)); +} + QT_END_NAMESPACE + +#if 0 +const Node* Tree::findNodeXXX(const QStringList& path, bool qml) const +{ + const Node* current = root(); + do { + const Node* node = current; + int i; + int start_idx = 0; + + /* + If the path contains one or two double colons ("::"), + check first to see if the first two path strings refer + to a QML element. If yes, that reference identifies a + QML class node. + */ + if (qml && path.size() >= 2) { + QmlClassNode* qcn = QmlClassNode::moduleMap.value(path[0]+ "::" +path[1]); + if (qcn) { + node = qcn; + if (path.size() == 2) + return node; + start_idx = 2; + } + } + + for (i = start_idx; i < path.size(); ++i) { + if (node == 0 || !node->isInnerNode()) + break; + + const Node* next = static_cast<const InnerNode*>(node)->findChildNodeByName(path.at(i), qml); + node = next; + } + if (node && i == path.size()) { + if (node->subType() != Node::QmlPropertyGroup) { + if (node->subType() == Node::Collision) { + node = node->applyModuleIdentifier(start); + } + return node; + } + } + current = current->parent(); + } while (current); + + return 0; +} +#endif diff --git a/src/tools/qdoc/tree.h b/src/tools/qdoc/tree.h index d39babfab0f..62f599598ea 100644 --- a/src/tools/qdoc/tree.h +++ b/src/tools/qdoc/tree.h @@ -65,19 +65,39 @@ public: Tree(); ~Tree(); - Node* findNode(const QStringList &path, - Node* relative=0, - int findFlags=0, - const Node* self=0); - Node* findNode(const QStringList &path, - Node::Type type, - Node* relative = 0, - int findFlags = 0); + EnumNode* findEnumNode(const QStringList& path, Node* start = 0); + ClassNode* findClassNode(const QStringList& path, Node* start = 0); + QmlClassNode* findQmlClassNode(const QStringList& path, Node* start = 0); + NamespaceNode* findNamespaceNode(const QStringList& path, Node* start = 0); + FakeNode* findGroupNode(const QStringList& path, Node* start = 0); + FakeNode* findQmlModuleNode(const QStringList& path, Node* start = 0); + + Node* findNodeByNameAndType(const QStringList& path, + Node::Type type, + Node::SubType subtype, + Node* start, + bool acceptCollision = false); + + Node* findNodeRecursive(const QStringList& path, + int pathIndex, + Node* start, + Node::Type type, + Node::SubType subtype, + bool acceptCollision = false); + + const Node* findNode(const QStringList &path, + const Node* relative = 0, + int findFlags = 0, + const Node* self=0) const; + + private: const Node* findNode(const QStringList& path, const Node* start, int findFlags, const Node* self, bool qml) const; + + public: QmlClassNode* findQmlClassNode(const QString& module, const QString& name); NameCollisionNode* checkForCollision(const QString& name) const; NameCollisionNode* findCollisionNode(const QString& name) const; @@ -111,17 +131,8 @@ public: void fixInheritance(NamespaceNode *rootNode = 0); void setVersion(const QString &version) { vers = version; } NamespaceNode *root() { return &roo; } - QString version() const { return vers; } - const Node* findNode(const QStringList &path, - const Node* relative = 0, - int findFlags = 0, - const Node* self=0) const; - const Node* findNode(const QStringList &path, - Node::Type type, const - Node* relative = 0, - int findFlags = 0) const; - const QmlClassNode* findQmlClassNode(const QString& module, const QString& element) const; + const FunctionNode *findFunctionNode(const QStringList &path, const Node *relative = 0, int findFlags = 0) const; @@ -134,19 +145,17 @@ public: Atom *findTarget(const QString &target, const Node *node) const; const NamespaceNode *root() const { return &roo; } void readIndexes(const QStringList &indexFiles); - bool generateIndexSection(QXmlStreamWriter &writer, const Node *node, - bool generateInternalNodes = false) const; - void generateIndexSections(QXmlStreamWriter &writer, const Node *node, - bool generateInternalNodes = false) const; + bool generateIndexSection(QXmlStreamWriter& writer, Node* node, bool generateInternalNodes = false); + void generateIndexSections(QXmlStreamWriter& writer, Node* node, bool generateInternalNodes = false); void generateIndex(const QString &fileName, const QString &url, const QString &title, - bool generateInternalNodes = false) const; + bool generateInternalNodes = false); void generateTagFileCompounds(QXmlStreamWriter &writer, - const InnerNode *inner) const; + const InnerNode *inner); void generateTagFileMembers(QXmlStreamWriter &writer, - const InnerNode *inner) const; - void generateTagFile(const QString &fileName) const; + const InnerNode *inner); + void generateTagFile(const QString &fileName); void addExternalLink(const QString &url, const Node *relative); QString fullDocumentLocation(const Node *node) const; void resolveQmlInheritance(); diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 46dec1d6cab..2f2cfb679b2 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -52,6 +52,8 @@ #include <QtCore/QStack> #include <QtCore/QXmlStreamReader> +// Note: A copy of this file is used in Qt Designer (qttools/src/designer/src/lib/shared/rcc.cpp) + QT_BEGIN_NAMESPACE enum { diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h index 6fe80595519..a808f576c58 100644 --- a/src/tools/rcc/rcc.h +++ b/src/tools/rcc/rcc.h @@ -39,6 +39,8 @@ ** ****************************************************************************/ +// Note: A copy of this file is used in Qt Designer (qttools/src/designer/src/lib/shared/rcc_p.h) + #ifndef RCC_H #define RCC_H diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 263d3a623c2..569a10653fd 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -2000,12 +2000,3 @@ QT_END_NAMESPACE #endif // QT_NO_COLORDIALOG -/*! - \fn QColor QColorDialog::getColor(const QColor &init, QWidget *parent, const char *name) - \compat -*/ - -/*! - \fn QRgb QColorDialog::getRgba(QRgb rgba, bool *ok, QWidget *parent, const char *name) - \compat -*/ diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index f7125b7af1f..ea33dc8d0b6 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1771,7 +1771,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) msgBox->setText(translatedTextAboutQtCaption); msgBox->setInformativeText(translatedTextAboutQtText); - QPixmap pm(QLatin1String(":/trolltech/qmessagebox/images/qtlogo-64.png")); + QPixmap pm(QLatin1String(":/qt-project.org/qmessagebox/images/qtlogo-64.png")); if (!pm.isNull()) msgBox->setIconPixmap(pm); #if defined(Q_OS_WINCE) diff --git a/src/widgets/dialogs/qmessagebox.qrc b/src/widgets/dialogs/qmessagebox.qrc index 8e6d7af671b..de217773ec2 100644 --- a/src/widgets/dialogs/qmessagebox.qrc +++ b/src/widgets/dialogs/qmessagebox.qrc @@ -1,5 +1,5 @@ <!DOCTYPE RCC><RCC version="1.0"> -<qresource prefix="/trolltech/qmessagebox"> +<qresource prefix="/qt-project.org/qmessagebox"> <file>images/qtlogo-64.png</file> </qresource> </RCC> diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index 8d1795c3c24..583e6da90a8 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -815,20 +815,19 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, lastFocusItem = focusItem; #ifndef QT_NO_IM - if (lastFocusItem - && (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { + if (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod) { // Close any external input method panel. This happens // automatically by removing WA_InputMethodEnabled on // the views, but if we are changing focus, we have to // do it ourselves. if (qApp) - qApp->inputMethod()->reset(); + qApp->inputMethod()->commit(); } +#endif //QT_NO_IM focusItem = 0; QFocusEvent event(QEvent::FocusOut, focusReason); sendEvent(lastFocusItem, &event); -#endif //QT_NO_IM } // This handles the case that the item has been removed from the diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index ea692f6f674..d7e7cb3ebcf 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -370,8 +370,6 @@ QListView::LayoutMode QListView::layoutMode() const \sa viewMode */ -// ### Qt5: Use same semantic as layouts (spacing is the size of space -// *between* items) void QListView::setSpacing(int space) { Q_D(QListView); diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 22589a4170f..b910d21cb82 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1965,12 +1965,11 @@ void QApplication::syncX() void QApplicationPrivate::notifyLayoutDirectionChange() { - Q_Q(QApplication); - QWidgetList list = q->topLevelWidgets(); + QWidgetList list = QApplication::topLevelWidgets(); for (int i = 0; i < list.size(); ++i) { QWidget *w = list.at(i); QEvent ev(QEvent::ApplicationLayoutDirectionChange); - q->sendEvent(w, &ev); + QCoreApplication::sendEvent(w, &ev); } } @@ -2030,7 +2029,7 @@ void QApplication::setActiveWindow(QWidget* act) if (QApplicationPrivate::focus_widget) { if (QApplicationPrivate::focus_widget->testAttribute(Qt::WA_InputMethodEnabled)) - qApp->inputMethod()->reset(); + qApp->inputMethod()->commit(); QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange, Qt::ActiveWindowFocusReason); QApplication::sendEvent(QApplicationPrivate::focus_widget, &focusAboutToChange); @@ -3912,13 +3911,6 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e) \sa isPhase2() */ -/*! - \typedef QApplication::ColorMode - \compat - - Use ColorSpec instead. -*/ - /*! \fn Qt::MacintoshVersion QApplication::macVersion() @@ -4011,18 +4003,6 @@ bool QApplicationPrivate::inPopupMode() const return QApplicationPrivate::popupWidgets != 0; } -/*! \variable QApplication::NormalColors - \compat - - Use \l NormalColor instead. -*/ - -/*! \variable QApplication::CustomColors - \compat - - Use \l CustomColor instead. -*/ - #ifdef QT_KEYPAD_NAVIGATION /*! Sets the kind of focus navigation Qt should use to \a mode. diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index da6a02a41df..74a299ba549 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -162,12 +162,11 @@ QWidget *qt_tlw_for_window(QWindow *wnd) void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) { Q_UNUSED(previous); - Q_Q(QApplication); QWindow *wnd = QGuiApplicationPrivate::focus_window; if (inPopupMode()) // some delayed focus event to ignore return; QWidget *tlw = qt_tlw_for_window(wnd); - q->setActiveWindow(tlw); + QApplication::setActiveWindow(tlw); } static void ungrabKeyboardForPopup(QWidget *popup) @@ -201,7 +200,6 @@ static void grabForPopup(QWidget *popup) void QApplicationPrivate::closePopup(QWidget *popup) { - Q_Q(QApplication); if (!popupWidgets) return; popupWidgets->removeAll(popup); @@ -241,7 +239,7 @@ void QApplicationPrivate::closePopup(QWidget *popup) fw->setFocus(Qt::PopupFocusReason); } else { QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason); - q->sendEvent(fw, &e); + QCoreApplication::sendEvent(fw, &e); } } } diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index 296d8d31e71..f4bf667ef8b 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -285,106 +285,104 @@ bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *, } } } - if (triggeredGestures.isEmpty() && finishedGestures.isEmpty() - && newMaybeGestures.isEmpty() && notGestures.isEmpty()) - return consumeEventHint; + if (!triggeredGestures.isEmpty() || !finishedGestures.isEmpty() + || !newMaybeGestures.isEmpty() || !notGestures.isEmpty()) { + QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures; + triggeredGestures &= m_activeGestures; - QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures; - triggeredGestures &= m_activeGestures; + // check if a running gesture switched back to maybe state + QSet<QGesture *> activeToMaybeGestures = m_activeGestures & newMaybeGestures; - // check if a running gesture switched back to maybe state - QSet<QGesture *> activeToMaybeGestures = m_activeGestures & newMaybeGestures; + // check if a maybe gesture switched to canceled - reset it but don't send an event + QSet<QGesture *> maybeToCanceledGestures = m_maybeGestures & notGestures; - // check if a maybe gesture switched to canceled - reset it but don't send an event - QSet<QGesture *> maybeToCanceledGestures = m_maybeGestures & notGestures; + // check if a running gesture switched back to not gesture state, + // i.e. were canceled + QSet<QGesture *> canceledGestures = m_activeGestures & notGestures; - // check if a running gesture switched back to not gesture state, - // i.e. were canceled - QSet<QGesture *> canceledGestures = m_activeGestures & notGestures; + // new gestures in maybe state + m_maybeGestures += newMaybeGestures; - // new gestures in maybe state - m_maybeGestures += newMaybeGestures; + // gestures that were in maybe state + QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures + | finishedGestures | canceledGestures + | notGestures); + m_maybeGestures -= notMaybeGestures; - // gestures that were in maybe state - QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures - | finishedGestures | canceledGestures - | notGestures); - m_maybeGestures -= notMaybeGestures; + Q_ASSERT((startedGestures & finishedGestures).isEmpty()); + Q_ASSERT((startedGestures & newMaybeGestures).isEmpty()); + Q_ASSERT((startedGestures & canceledGestures).isEmpty()); + Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty()); + Q_ASSERT((finishedGestures & canceledGestures).isEmpty()); + Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty()); - Q_ASSERT((startedGestures & finishedGestures).isEmpty()); - Q_ASSERT((startedGestures & newMaybeGestures).isEmpty()); - Q_ASSERT((startedGestures & canceledGestures).isEmpty()); - Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty()); - Q_ASSERT((finishedGestures & canceledGestures).isEmpty()); - Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty()); + QSet<QGesture *> notStarted = finishedGestures - m_activeGestures; + if (!notStarted.isEmpty()) { + // there are some gestures that claim to be finished, but never started. + // probably those are "singleshot" gestures so we'll fake the started state. + foreach (QGesture *gesture, notStarted) + gesture->d_func()->state = Qt::GestureStarted; + QSet<QGesture *> undeliveredGestures; + deliverEvents(notStarted, &undeliveredGestures); + finishedGestures -= undeliveredGestures; + } - QSet<QGesture *> notStarted = finishedGestures - m_activeGestures; - if (!notStarted.isEmpty()) { - // there are some gestures that claim to be finished, but never started. - // probably those are "singleshot" gestures so we'll fake the started state. - foreach (QGesture *gesture, notStarted) + m_activeGestures += startedGestures; + // sanity check: all triggered gestures should already be in active gestures list + Q_ASSERT((m_activeGestures & triggeredGestures).size() == triggeredGestures.size()); + m_activeGestures -= finishedGestures; + m_activeGestures -= activeToMaybeGestures; + m_activeGestures -= canceledGestures; + + // set the proper gesture state on each gesture + foreach (QGesture *gesture, startedGestures) gesture->d_func()->state = Qt::GestureStarted; + foreach (QGesture *gesture, triggeredGestures) + gesture->d_func()->state = Qt::GestureUpdated; + foreach (QGesture *gesture, finishedGestures) + gesture->d_func()->state = Qt::GestureFinished; + foreach (QGesture *gesture, canceledGestures) + gesture->d_func()->state = Qt::GestureCanceled; + foreach (QGesture *gesture, activeToMaybeGestures) + gesture->d_func()->state = Qt::GestureFinished; + + if (!m_activeGestures.isEmpty() || !m_maybeGestures.isEmpty() || + !startedGestures.isEmpty() || !triggeredGestures.isEmpty() || + !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) { + DEBUG() << "QGestureManager::filterEventThroughContexts:" + << "\n\tactiveGestures:" << m_activeGestures + << "\n\tmaybeGestures:" << m_maybeGestures + << "\n\tstarted:" << startedGestures + << "\n\ttriggered:" << triggeredGestures + << "\n\tfinished:" << finishedGestures + << "\n\tcanceled:" << canceledGestures + << "\n\tmaybe-canceled:" << maybeToCanceledGestures; + } + QSet<QGesture *> undeliveredGestures; - deliverEvents(notStarted, &undeliveredGestures); - finishedGestures -= undeliveredGestures; - } + deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures, + &undeliveredGestures); - m_activeGestures += startedGestures; - // sanity check: all triggered gestures should already be in active gestures list - Q_ASSERT((m_activeGestures & triggeredGestures).size() == triggeredGestures.size()); - m_activeGestures -= finishedGestures; - m_activeGestures -= activeToMaybeGestures; - m_activeGestures -= canceledGestures; + foreach (QGesture *g, startedGestures) { + if (undeliveredGestures.contains(g)) + continue; + if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) { + DEBUG() << "lets try to cancel some"; + // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them + cancelGesturesForChildren(g); + } + } - // set the proper gesture state on each gesture - foreach (QGesture *gesture, startedGestures) - gesture->d_func()->state = Qt::GestureStarted; - foreach (QGesture *gesture, triggeredGestures) - gesture->d_func()->state = Qt::GestureUpdated; - foreach (QGesture *gesture, finishedGestures) - gesture->d_func()->state = Qt::GestureFinished; - foreach (QGesture *gesture, canceledGestures) - gesture->d_func()->state = Qt::GestureCanceled; - foreach (QGesture *gesture, activeToMaybeGestures) - gesture->d_func()->state = Qt::GestureFinished; + m_activeGestures -= undeliveredGestures; - if (!m_activeGestures.isEmpty() || !m_maybeGestures.isEmpty() || - !startedGestures.isEmpty() || !triggeredGestures.isEmpty() || - !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) { - DEBUG() << "QGestureManager::filterEventThroughContexts:" - << "\n\tactiveGestures:" << m_activeGestures - << "\n\tmaybeGestures:" << m_maybeGestures - << "\n\tstarted:" << startedGestures - << "\n\ttriggered:" << triggeredGestures - << "\n\tfinished:" << finishedGestures - << "\n\tcanceled:" << canceledGestures - << "\n\tmaybe-canceled:" << maybeToCanceledGestures; - } - - QSet<QGesture *> undeliveredGestures; - deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures, - &undeliveredGestures); - - foreach (QGesture *g, startedGestures) { - if (undeliveredGestures.contains(g)) - continue; - if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) { - DEBUG() << "lets try to cancel some"; - // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them - cancelGesturesForChildren(g); + // reset gestures that ended + QSet<QGesture *> endedGestures = + finishedGestures + canceledGestures + undeliveredGestures + maybeToCanceledGestures; + foreach (QGesture *gesture, endedGestures) { + recycle(gesture); + m_gestureTargets.remove(gesture); } } - - m_activeGestures -= undeliveredGestures; - - // reset gestures that ended - QSet<QGesture *> endedGestures = - finishedGestures + canceledGestures + undeliveredGestures + maybeToCanceledGestures; - foreach (QGesture *gesture, endedGestures) { - recycle(gesture); - m_gestureTargets.remove(gesture); - } - //Clean up the Gestures qDeleteAll(m_gesturesToDelete); m_gesturesToDelete.clear(); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 8e6e4368e85..3ab777ad609 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -3090,7 +3090,7 @@ void QWidgetPrivate::setEnabled_helper(bool enable) if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) qApp->inputMethod()->update(Qt::ImEnabled); } else { - qApp->inputMethod()->reset(); + qApp->inputMethod()->commit(); qApp->inputMethod()->update(Qt::ImEnabled); } } @@ -5948,7 +5948,7 @@ void QWidget::setFocus(Qt::FocusReason reason) if (prev) { if (reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason && prev->testAttribute(Qt::WA_InputMethodEnabled)) { - qApp->inputMethod()->reset(); + qApp->inputMethod()->commit(); } if (reason != Qt::NoFocusReason) { @@ -6057,7 +6057,7 @@ void QWidget::clearFocus() { if (hasFocus()) { if (testAttribute(Qt::WA_InputMethodEnabled)) - qApp->inputMethod()->reset(); + qApp->inputMethod()->commit(); QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange); QApplication::sendEvent(this, &focusAboutToChange); @@ -10087,7 +10087,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) QWidget *focusWidget = d->effectiveFocusWidget(); if (on && !internalWinId() && hasFocus() && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) { - qApp->inputMethod()->reset(); + qApp->inputMethod()->commit(); qApp->inputMethod()->update(Qt::ImEnabled); } if (!qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget() @@ -10137,7 +10137,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) #ifndef QT_NO_IM if (qApp->focusObject() == this) { if (!on) - qApp->inputMethod()->reset(); + qApp->inputMethod()->commit(); qApp->inputMethod()->update(Qt::ImEnabled); } #endif //QT_NO_IM diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index 47239016252..40b6f486bea 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -374,7 +374,7 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event) QPoint mapped = widget->mapFrom(m_widget, event->pos()); - QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->pixelDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers()); + QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers()); QGuiApplication::sendSpontaneousEvent(widget, &translated); } diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 148d7bcfb5a..b2b1d3fec59 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -374,13 +374,13 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q case PE_IndicatorTabClose: { if (d->tabBarcloseButtonIcon.isNull()) { d->tabBarcloseButtonIcon.addPixmap(QPixmap( - QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-closetab-16.png")), + QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-16.png")), QIcon::Normal, QIcon::Off); d->tabBarcloseButtonIcon.addPixmap(QPixmap( - QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-closetab-down-16.png")), + QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-down-16.png")), QIcon::Normal, QIcon::On); d->tabBarcloseButtonIcon.addPixmap(QPixmap( - QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-closetab-hover-16.png")), + QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-hover-16.png")), QIcon::Active, QIcon::Off); } @@ -5094,99 +5094,99 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti return proxy()->standardPixmap(SP_ArrowRight, option, widget); return proxy()->standardPixmap(SP_ArrowLeft, option, widget); case SP_ArrowLeft: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/left-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-16.png")); case SP_ArrowRight: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/right-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-16.png")); case SP_ArrowUp: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/up-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-16.png")); case SP_ArrowDown: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/down-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-16.png")); case SP_FileDialogToParent: return proxy()->standardPixmap(SP_ArrowUp, option, widget); case SP_FileDialogNewFolder: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/newdirectory-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png")); case SP_FileDialogDetailedView: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/viewdetailed-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-16.png")); case SP_FileDialogInfoView: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/fileinfo-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-16.png")); case SP_FileDialogContentsView: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/filecontents-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-16.png")); case SP_FileDialogListView: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/viewlist-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-16.png")); case SP_FileDialogBack: return proxy()->standardPixmap(SP_ArrowBack, option, widget); case SP_DriveHDIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/harddrive-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/harddrive-16.png")); case SP_TrashIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/trash-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-16.png")); case SP_DriveFDIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/floppy-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/floppy-16.png")); case SP_DriveNetIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/networkdrive-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/networkdrive-16.png")); case SP_DesktopIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/desktop-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/desktop-16.png")); case SP_ComputerIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/computer-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/computer-16.png")); case SP_DriveCDIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/cdr-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-16.png")); case SP_DriveDVDIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/dvd-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-16.png")); case SP_DirHomeIcon: case SP_DirOpenIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/diropen-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-16.png")); case SP_DirIcon: case SP_DirClosedIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/dirclosed-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-16.png")); case SP_DirLinkIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/dirlink-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirlink-16.png")); case SP_FileIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/file-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png")); case SP_FileLinkIcon: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/filelink-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-16.png")); case SP_DialogOkButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-ok-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-16.png")); case SP_DialogCancelButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-cancel-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-16.png")); case SP_DialogHelpButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-help-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-16.png")); case SP_DialogOpenButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png")); case SP_DialogSaveButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png")); case SP_DialogCloseButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-close-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-16.png")); case SP_DialogApplyButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-apply-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-16.png")); case SP_DialogResetButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-clear-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-16.png")); case SP_DialogDiscardButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-delete-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-16.png")); case SP_DialogYesButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-yes-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-16.png")); case SP_DialogNoButton: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-no-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-16.png")); case SP_BrowserReload: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/refresh-24.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-24.png")); case SP_BrowserStop: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/stop-24.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-24.png")); case SP_MediaPlay: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-play-32.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-32.png")); case SP_MediaPause: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-pause-32.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-32.png")); case SP_MediaStop: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-stop-32.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-32.png")); case SP_MediaSeekForward: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-forward-32.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-32.png")); case SP_MediaSeekBackward: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-backward-32.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-32.png")); case SP_MediaSkipForward: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-forward-32.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-32.png")); case SP_MediaSkipBackward: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-backward-32.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-32.png")); case SP_MediaVolume: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-volume-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png")); case SP_MediaVolumeMuted: - return QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/media-volume-muted-16.png")); + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png")); #endif // QT_NO_IMAGEFORMAT_PNG default: break; @@ -5444,11 +5444,11 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons case SP_TitleBarCloseButton: { QIcon titleBarIcon; if (standardIcon == SP_TitleBarCloseButton) { - titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-16.png")); - titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On); + titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/closedock-16.png")); + titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/closedock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On); } else { - titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-16.png")); - titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On); + titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/dockdock-16.png")); + titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/dockdock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On); } return titleBarIcon; } @@ -5485,88 +5485,88 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons switch (standardIcon) { #ifndef QT_NO_IMAGEFORMAT_PNG case SP_FileDialogNewFolder: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/newdirectory-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/newdirectory-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/newdirectory-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-128.png"), QSize(128, 128)); break; case SP_FileDialogBack: return standardIconImplementation(SP_ArrowBack, option, widget); case SP_FileDialogToParent: return standardIconImplementation(SP_ArrowUp, option, widget); case SP_FileDialogDetailedView: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewdetailed-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewdetailed-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewdetailed-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-128.png"), QSize(128, 128)); break; case SP_FileDialogInfoView: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/fileinfo-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/fileinfo-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/fileinfo-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-128.png"), QSize(128, 128)); break; case SP_FileDialogContentsView: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filecontents-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filecontents-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filecontents-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-128.png"), QSize(128, 128)); break; case SP_FileDialogListView: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewlist-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewlist-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/viewlist-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-128.png"), QSize(128, 128)); break; case SP_DialogOkButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-ok-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-ok-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-ok-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-128.png"), QSize(128, 128)); break; case SP_DialogCancelButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-cancel-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-cancel-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-cancel-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-128.png"), QSize(128, 128)); break; case SP_DialogHelpButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-help-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-help-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-help-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-128.png"), QSize(128, 128)); break; case SP_DialogOpenButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-128.png"), QSize(128, 128)); break; case SP_DialogSaveButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-128.png"), QSize(128, 128)); break; case SP_DialogCloseButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-close-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-close-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-close-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-128.png"), QSize(128, 128)); break; case SP_DialogApplyButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-apply-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-apply-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-apply-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-128.png"), QSize(128, 128)); break; case SP_DialogResetButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-clear-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-clear-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-clear-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-128.png"), QSize(128, 128)); break; case SP_DialogDiscardButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-delete-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-delete-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-delete-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-128.png"), QSize(128, 128)); break; case SP_DialogYesButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-yes-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-yes-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-yes-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-128.png"), QSize(128, 128)); break; case SP_DialogNoButton: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-no-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-no-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-no-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-128.png"), QSize(128, 128)); break; case SP_ArrowForward: if (rtl) @@ -5577,106 +5577,106 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons return standardIconImplementation(SP_ArrowRight, option, widget); return standardIconImplementation(SP_ArrowLeft, option, widget); case SP_ArrowLeft: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/left-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/left-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/left-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-128.png"), QSize(128, 128)); break; case SP_ArrowRight: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/right-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/right-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/right-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-128.png"), QSize(128, 128)); break; case SP_ArrowUp: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/up-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/up-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/up-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-128.png"), QSize(128, 128)); break; case SP_ArrowDown: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/down-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/down-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/down-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-128.png"), QSize(128, 128)); break; case SP_DirHomeIcon: case SP_DirIcon: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dirclosed-16.png"), + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-16.png"), QSize(), QIcon::Normal, QIcon::Off); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/diropen-16.png"), + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-16.png"), QSize(), QIcon::Normal, QIcon::On); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dirclosed-32.png"), + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-32.png"), QSize(32, 32), QIcon::Normal, QIcon::Off); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/diropen-32.png"), + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-32.png"), QSize(32, 32), QIcon::Normal, QIcon::On); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dirclosed-128.png"), + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-128.png"), QSize(128, 128), QIcon::Normal, QIcon::Off); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/diropen-128.png"), + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-128.png"), QSize(128, 128), QIcon::Normal, QIcon::On); break; case SP_DriveCDIcon: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/cdr-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/cdr-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/cdr-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-128.png"), QSize(128, 128)); break; case SP_DriveDVDIcon: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dvd-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dvd-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/dvd-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-128.png"), QSize(128, 128)); break; case SP_FileIcon: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/file-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/file-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/file-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-128.png"), QSize(128, 128)); break; case SP_FileLinkIcon: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filelink-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filelink-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/filelink-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-128.png"), QSize(128, 128)); break; case SP_TrashIcon: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/trash-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/trash-32.png"), QSize(32, 32)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/trash-128.png"), QSize(128, 128)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-128.png"), QSize(128, 128)); break; case SP_BrowserReload: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/refresh-24.png"), QSize(24, 24)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/refresh-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-24.png"), QSize(24, 24)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-32.png"), QSize(32, 32)); break; case SP_BrowserStop: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/stop-24.png"), QSize(24, 24)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/stop-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-24.png"), QSize(24, 24)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-32.png"), QSize(32, 32)); break; case SP_MediaPlay: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-play-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-play-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-32.png"), QSize(32, 32)); break; case SP_MediaPause: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-pause-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-pause-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-32.png"), QSize(32, 32)); break; case SP_MediaStop: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-stop-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-stop-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-32.png"), QSize(32, 32)); break; case SP_MediaSeekForward: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-forward-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-forward-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-32.png"), QSize(32, 32)); break; case SP_MediaSeekBackward: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-backward-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-seek-backward-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-32.png"), QSize(32, 32)); break; case SP_MediaSkipForward: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-forward-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-forward-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-32.png"), QSize(32, 32)); break; case SP_MediaSkipBackward: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-backward-16.png"), QSize(16, 16)); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-skip-backward-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-32.png"), QSize(32, 32)); break; case SP_MediaVolume: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-volume-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png"), QSize(16, 16)); break; case SP_MediaVolumeMuted: - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/media-volume-muted-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png"), QSize(16, 16)); break; #endif // QT_NO_IMAGEFORMAT_PNG default: diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index ef6947088e6..05bd90abef2 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -5153,7 +5153,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex } if (tb->state & State_On) { if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { - static QPixmap pm(QLatin1String(":/trolltech/mac/style/images/leopard-unified-toolbar-on.png")); + static QPixmap pm(QLatin1String(":/qt-project.org/mac/style/images/leopard-unified-toolbar-on.png")); p->setRenderHint(QPainter::SmoothPixmapTransform); QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2); } else { diff --git a/src/widgets/styles/qstyle.qrc b/src/widgets/styles/qstyle.qrc index 8654e66a37a..6e04540f511 100644 --- a/src/widgets/styles/qstyle.qrc +++ b/src/widgets/styles/qstyle.qrc @@ -1,5 +1,5 @@ <!DOCTYPE RCC><RCC version="1.0"> -<qresource prefix="/trolltech/styles/commonstyle"> +<qresource prefix="/qt-project.org/styles/commonstyle"> <file>images/filelink-16.png</file> <file>images/filelink-32.png</file> <file>images/filelink-128.png</file> @@ -126,7 +126,7 @@ <file>images/media-volume-16.png</file> <file>images/media-volume-muted-16.png</file> </qresource> -<qresource prefix="/trolltech/styles/macstyle"> +<qresource prefix="/qt-project.org/styles/macstyle"> <file>images/closedock-16.png</file> <file>images/closedock-down-16.png</file> <file>images/dockdock-16.png</file> diff --git a/src/widgets/styles/qstyle_wince.qrc b/src/widgets/styles/qstyle_wince.qrc index bdcf6046253..c3d643fac70 100644 --- a/src/widgets/styles/qstyle_wince.qrc +++ b/src/widgets/styles/qstyle_wince.qrc @@ -1,5 +1,5 @@ <!DOCTYPE RCC><RCC version="1.0"> -<qresource prefix="/trolltech/styles/commonstyle"> +<qresource prefix="/qt-project.org/styles/commonstyle"> <file>images/filelink-16.png</file> <file>images/filelink-32.png</file> <file>images/file-16.png</file> diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 78d4e7b9ce0..86574f25876 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -482,16 +482,18 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt int stateId = HSAS_SORTEDDOWN; if (header->sortIndicator & QStyleOptionHeader::SortDown) stateId = HSAS_SORTEDUP; //note that the uxtheme sort down indicator is the inverse of ours - XPThemeData theme(widget, painter, QLatin1String("HEADER"), HP_HEADERSORTARROW, stateId, option->rect); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::HeaderTheme, + HP_HEADERSORTARROW, stateId, option->rect); d->drawBackground(theme); } break; case PE_IndicatorBranch: { - XPThemeData theme(d->treeViewHelper(), painter, QLatin1String("TREEVIEW")); + XPThemeData theme(0, painter, QWindowsXPStylePrivate::TreeViewTheme); static int decoration_size = 0; - if (theme.isValid() && !decoration_size) { + if (d->initTreeViewTheming() && theme.isValid() && !decoration_size) { SIZE size; pGetThemePartSize(theme.handle(), 0, TVP_HOTGLYPH, GLPS_OPENED, 0, TS_TRUE, &size); decoration_size = qMax(size.cx, size.cy); @@ -546,7 +548,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt case PE_FrameMenu: { int stateId = option->state & State_Active ? MB_ACTIVE : MB_INACTIVE; - XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPBORDERS, stateId, option->rect); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPBORDERS, stateId, option->rect); d->drawBackground(theme); } break; @@ -561,7 +565,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt stateId = ETS_READONLY; else if (state & State_HasFocus) stateId = ETS_SELECTED; - XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_HVSCROLL, stateId, option->rect); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::EditTheme, + EP_EDITBORDER_HVSCROLL, stateId, option->rect); uint resolve_mask = option->palette.resolve(); if (resolve_mask & (1 << QPalette::Base)) { // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping @@ -611,7 +617,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt else if (state & State_MouseOver) stateId = EBS_HOT; - XPThemeData theme(0, painter, QLatin1String("EDIT"), partId, stateId, rect); + XPThemeData theme(0, painter, QWindowsXPStylePrivate::EditTheme, + partId, stateId, rect); if (!theme.isValid()) { QWindowsStyle::drawPrimitive(element, option, painter, widget); return; @@ -678,7 +685,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt stateId = ETS_HOT; else if (state & State_HasFocus) stateId = ETS_SELECTED; - XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_NOSCROLL, stateId, option->rect); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::EditTheme, + EP_EDITBORDER_NOSCROLL, stateId, option->rect); painter->save(); QRegion clipRegion = option->rect; clipRegion -= option->rect.adjusted(2, 2, -2, -2); @@ -694,11 +703,14 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt XPThemeData theme; QRect rect; if (option->state & State_Horizontal) { - theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2)); + theme = XPThemeData(widget, painter, + QWindowsXPStylePrivate::RebarTheme, + RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2)); rect = option->rect.adjusted(0, 1, 0, -2); rect.setWidth(4); } else { - theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2)); + theme = XPThemeData(widget, painter, QWindowsXPStylePrivate::RebarTheme, + RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2)); rect = option->rect.adjusted(1, 0, -1, 0); rect.setHeight(4); } @@ -724,7 +736,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt break; case PE_PanelTipLabel: { - XPThemeData theme(widget, painter, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::ToolTipTheme, + TTP_STANDARD, TTSS_NORMAL, option->rect); d->drawBackground(theme); break; } @@ -788,9 +802,10 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt state = LISS_HOT; QPainter pixmapPainter(&pixmap); - XPThemeData theme(d->treeViewHelper(), &pixmapPainter, QLatin1String("TREEVIEW"), + XPThemeData theme(0, &pixmapPainter, + QWindowsXPStylePrivate::TreeViewTheme, LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height())); - if (theme.isValid()) { + if (d->initTreeViewTheming() && theme.isValid()) { d->drawBackground(theme); } else { QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget); @@ -849,7 +864,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt if (buttonBox) { //draw white panel part - XPThemeData theme(widget, painter, QLatin1String("TASKDIALOG"), TDLG_PRIMARYPANEL, 0, option->rect); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::TaskDialogTheme, + TDLG_PRIMARYPANEL, 0, option->rect); QRect toprect = option->rect; toprect.setBottom(buttonBox->geometry().top()); theme.rect = toprect; @@ -891,7 +908,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption bool disabled = !(option->state & State_Enabled); int state = option->state; - QString name; + int themeNumber = -1; QRect rect(option->rect); State flags = option->state; @@ -971,12 +988,11 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption case CE_PushButtonBevel: if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { - QWindowsVistaAnimation *anim = d->widgetAnimation(widget); if (anim && (btn->state & State_Enabled)) { anim->paint(painter, option); } else { - name = QLatin1String("BUTTON"); + themeNumber = QWindowsXPStylePrivate::ButtonTheme; partId = BP_PUSHBUTTON; if (btn->features & QStyleOptionButton::CommandLinkButton) partId = BP_COMMANDLINK; @@ -1011,7 +1027,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QPainter startPainter(&startImage); stateId = PBS_DEFAULTED; - XPThemeData theme(widget, &startPainter, name, partId, stateId, rect); + XPThemeData theme(widget, &startPainter, themeNumber, partId, stateId, rect); d->drawBackground(theme); QPainter alternatePainter(&alternateImage); @@ -1029,20 +1045,21 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (anim) anim->paint(painter, option); else { - XPThemeData theme(widget, painter, name, partId, stateId, rect); + XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect); d->drawBackground(theme); } } else { d->stopAnimation(widget); - XPThemeData theme(widget, painter, name, partId, stateId, rect); + XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect); d->drawBackground(theme); } } } if (btn->features & QStyleOptionButton::HasMenu) { int mbiw = 0, mbih = 0; - XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_DROPDOWNBUTTON); + XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme, + TP_DROPDOWNBUTTON); if (theme.isValid()) { SIZE size; if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) { @@ -1086,7 +1103,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption } } - XPThemeData theme(widget, painter, QLatin1String("PROGRESS"), vertical ? PP_FILLVERT : PP_FILL); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::ProgressTheme, + vertical ? PP_FILLVERT : PP_FILL); theme.rect = option->rect; bool reverse = (bar->direction == Qt::LeftToRight && inverted) || (bar->direction == Qt::RightToLeft && !inverted); QTime current = QTime::currentTime(); @@ -1208,7 +1227,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption alignment |= Qt::TextHideMnemonic; //The rect adjustment is a workaround for the menu not really filling its background. - XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1)); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1)); d->drawBackground(theme); int stateId = MBI_NORMAL; @@ -1219,7 +1240,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption else if (selected) stateId = MBI_HOT; - XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_BARITEM, stateId, option->rect); + XPThemeData theme2(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_BARITEM, stateId, option->rect); d->drawBackground(theme2); if (!pix.isNull()) @@ -1237,7 +1260,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption { SIZE size; MARGINS margins; - XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT); + XPThemeData theme(widget, 0, QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPCHECKBACKGROUND, MBI_HOT); pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size); pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins); checkcol = qMax(menuitem->maxIconWidth, int(6 + size.cx + margins.cxLeftWidth + margins.cxRightWidth)); @@ -1248,7 +1272,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QPoint p1 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.top())); QPoint p2 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.bottom())); QRect gutterRect(p1.x(), p1.y(), 3, p2.y() - p1.y() + 1); - XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPGUTTER, stateId, gutterRect); + XPThemeData theme2(widget, painter, QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPGUTTER, stateId, gutterRect); d->drawBackground(theme2); int x, y, w, h; @@ -1266,7 +1291,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption stateId = MBI_HOT; QRect subRect(p1.x(), p1.y(), p2.x() - p1.x(), 6); subRect = QStyle::visualRect(option->direction, option->rect, subRect ); - XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPSEPARATOR, stateId, subRect); + XPThemeData theme2(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPSEPARATOR, stateId, subRect); d->drawBackground(theme2); return; } @@ -1276,12 +1303,16 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (act) { stateId = MBI_HOT; - XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPITEM, stateId, option->rect); + XPThemeData theme2(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPITEM, stateId, option->rect); d->drawBackground(theme2); } if (checked) { - XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPCHECKBACKGROUND, menuitem->icon.isNull() ? MBI_HOT : MBI_PUSHED, vCheckRect); SIZE size; MARGINS margins; @@ -1377,7 +1408,6 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption #endif // QT_NO_MENU case CE_HeaderSection: if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { - name = QLatin1String("HEADER"); partId = HP_HEADERITEM; if (flags & State_Sunken) stateId = HIS_PRESSED; @@ -1389,7 +1419,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (header->sortIndicator != QStyleOptionHeader::None) stateId += 3; - XPThemeData theme(widget, painter, name, partId, stateId, option->rect); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::HeaderTheme, + partId, stateId, option->rect); d->drawBackground(theme); } break; @@ -1398,7 +1430,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption stateId = MBI_NORMAL; if (!(state & State_Enabled)) stateId = MBI_DISABLED; - XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, stateId, option->rect); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_BARBACKGROUND, stateId, option->rect); d->drawBackground(theme); } break; @@ -1669,13 +1703,15 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle else stateId = ETS_NORMAL; - XPThemeData theme(widget, painter, QLatin1String("EDIT"), partId, stateId, r); + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::EditTheme, + partId, stateId, r); d->drawBackground(theme); } if (sub & SC_ComboBoxArrow) { QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget); - XPThemeData theme(widget, painter, QLatin1String("COMBOBOX")); + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme); theme.rect = subRect; partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT; @@ -1708,8 +1744,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle case CC_ScrollBar: if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) { - XPThemeData theme(widget, painter, QLatin1String("SCROLLBAR")); - + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ScrollBarTheme); bool maxedOut = (scrollbar->maximum == scrollbar->minimum); if (maxedOut) flags &= ~State_Enabled; @@ -1855,7 +1890,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle case CC_SpinBox: if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { - XPThemeData theme(widget, painter, QLatin1String("SPIN")); + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::SpinTheme); if (sb->frame && (sub & SC_SpinBoxFrame)) { partId = EP_EDITBORDER_NOSCROLL; if (!(flags & State_Enabled)) @@ -1867,7 +1902,9 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle else stateId = ETS_NORMAL; - XPThemeData ftheme(widget, painter, QLatin1String("EDIT"), partId, stateId, r); + XPThemeData ftheme(widget, painter, + QWindowsXPStylePrivate::EditTheme, + partId, stateId, r); ftheme.noContent = true; d->drawBackground(ftheme); } @@ -1927,7 +1964,9 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption { SIZE size; MARGINS margins; - XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT); + XPThemeData theme(widget, 0, + QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPCHECKBACKGROUND, MBI_HOT); pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size); pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins); minimumHeight = qMax<qint32>(size.cy + margins.cyBottomHeight+ margins.cyTopHeight, sz.height()); @@ -2019,7 +2058,9 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption int y = option->rect.y(); int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget); - XPThemeData theme(widget, 0, QLatin1String("HEADER"), HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect); + XPThemeData theme(widget, 0, + QWindowsXPStylePrivate::HeaderTheme, + HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect); int arrowWidth = 13; int arrowHeight = 5; @@ -2148,7 +2189,9 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co if (option) { if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) { ret = true; - XPThemeData themeData(widget, 0, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect); + XPThemeData themeData(widget, 0, + QWindowsXPStylePrivate::ToolTipTheme, + TTP_STANDARD, TTSS_NORMAL, option->rect); mask->region = d->region(themeData); } } @@ -2489,7 +2532,8 @@ QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() : QWindowsVistaStylePrivate::~QWindowsVistaStylePrivate() { qDeleteAll(animations); - delete m_treeViewHelper; + if (m_treeViewHelper) + DestroyWindow(m_treeViewHelper); } void QWindowsVistaStylePrivate::timerEvent() @@ -2597,19 +2641,48 @@ bool QWindowsVistaStylePrivate::resolveSymbols() } /* - * We need to set the windows explorer theme explicitly on a native widget - * in order to get Vista-style item view themes + * We need to set the windows "explorer" theme explicitly on a native + * window and open the "TREEVIEW" theme handle passing its window handle + * in order to get Vista-style item view themes (particulary drawBackground() + * for selected items needs this). + * We invoke a service of the native Windows interface to create + * a non-visible window handle, open the theme on it and insert it into + * the cache so that it is found by XPThemeData::handle() first. */ -QWidget *QWindowsVistaStylePrivate::treeViewHelper() + +static inline HWND createTreeViewHelperWindow() { - if (!m_treeViewHelper) { - m_treeViewHelper = new QWidget(0); - HWND handle = QApplicationPrivate::getHWNDForWidget(m_treeViewHelper); - pSetWindowTheme(handle, L"explorer", NULL); + if (QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface()) { + void *hwnd = 0; + void *wndProc = reinterpret_cast<void *>(DefWindowProc); + if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection, + Q_RETURN_ARG(void *, hwnd), + Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindowClass")), + Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindow")), + Q_ARG(void *, wndProc)) && hwnd) { + return reinterpret_cast<HWND>(hwnd); + } } - return m_treeViewHelper; + return 0; } +bool QWindowsVistaStylePrivate::initTreeViewTheming() +{ + if (m_treeViewHelper) + return true; + + m_treeViewHelper = createTreeViewHelperWindow(); + if (!m_treeViewHelper) { + qWarning("%s: Unable to create the treeview helper window.", Q_FUNC_INFO); + return false; + } + const HRESULT hr = pSetWindowTheme(m_treeViewHelper, L"explorer", NULL); + if (hr != S_OK) { + qErrnoWarning("%s: SetWindowTheme() failed.", Q_FUNC_INFO); + return false; + } + return QWindowsXPStylePrivate::createTheme(QWindowsXPStylePrivate::TreeViewTheme, m_treeViewHelper); +} /*! \internal @@ -2626,7 +2699,9 @@ QIcon QWindowsVistaStyle::standardIconImplementation(StandardPixmap standardIcon switch(standardIcon) { case SP_CommandLink: { - XPThemeData theme(0, 0, QLatin1String("BUTTON"), BP_COMMANDLINKGLYPH, CMDLGS_NORMAL); + XPThemeData theme(0, 0, + QWindowsXPStylePrivate::ButtonTheme, + BP_COMMANDLINKGLYPH, CMDLGS_NORMAL); if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size); diff --git a/src/widgets/styles/qwindowsvistastyle_p.h b/src/widgets/styles/qwindowsvistastyle_p.h index 7205ad2d192..78282d01ef6 100644 --- a/src/widgets/styles/qwindowsvistastyle_p.h +++ b/src/widgets/styles/qwindowsvistastyle_p.h @@ -205,12 +205,13 @@ public: QWindowsVistaAnimation* widgetAnimation(const QWidget *) const; void timerEvent(); bool transitionsEnabled() const; - QWidget *treeViewHelper(); private: + bool initTreeViewTheming(); + QList <QWindowsVistaAnimation*> animations; QBasicTimer animationTimer; - QWidget *m_treeViewHelper; + HWND m_treeViewHelper; }; QT_END_NAMESPACE diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index 9af57ce894d..c911670442e 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -136,6 +136,15 @@ static const int windowsRightBorder = 12; // right border on windows extern Q_WIDGETS_EXPORT HDC qt_win_display_dc(); extern QRegion qt_region_from_HRGN(HRGN rgn); +// Theme names matching the QWindowsXPStylePrivate::Theme enumeration. +static const wchar_t *themeNames[QWindowsXPStylePrivate::NThemes] = +{ + L"BUTTON", L"COMBOBOX", L"EDIT", L"HEADER", L"LISTVIEW", + L"MENU", L"PROGRESS", L"REBAR", L"SCROLLBAR", L"SPIN", + L"TAB", L"TASKDIALOG", L"TOOLBAR", L"TOOLTIP", L"TRACKBAR", + L"TREEVIEW", L"WINDOW", L"STATUS" +}; + static inline QBackingStore *backingStoreForWidget(const QWidget *widget) { if (QBackingStore *backingStore = widget->backingStore()) @@ -161,7 +170,7 @@ static inline HDC hdcForWidgetBackingStore(const QWidget *widget) */ bool XPThemeData::isValid() { - return QWindowsXPStylePrivate::useXP() && name.size() && handle(); + return QWindowsXPStylePrivate::useXP() && theme >= 0 && handle(); } @@ -175,18 +184,8 @@ HTHEME XPThemeData::handle() if (!QWindowsXPStylePrivate::useXP()) return 0; - if (!htheme && QWindowsXPStylePrivate::handleMap) - htheme = QWindowsXPStylePrivate::handleMap->value(name); - - if (!htheme) { - htheme = pOpenThemeData(QWindowsXPStylePrivate::winId(widget), (wchar_t*)name.utf16()); - if (htheme) { - if (!QWindowsXPStylePrivate::handleMap) - QWindowsXPStylePrivate::handleMap = new QWindowsXPStylePrivate::ThemeHandleMap; - QWindowsXPStylePrivate::handleMap->insert(name, htheme); - } - } - + if (!htheme) + htheme = QWindowsXPStylePrivate::createTheme(theme, QWindowsXPStylePrivate::winId(widget)); return htheme; } @@ -224,7 +223,7 @@ HRGN XPThemeData::mask(QWidget *widget) // QWindowsXPStylePrivate ------------------------------------------------------------------------- // Static initializations QPixmap *QWindowsXPStylePrivate::tabbody = 0; -QMap<QString,HTHEME> *QWindowsXPStylePrivate::handleMap = 0; +HTHEME QWindowsXPStylePrivate::m_themes[NThemes]; bool QWindowsXPStylePrivate::use_xp = false; QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting @@ -277,6 +276,7 @@ void QWindowsXPStylePrivate::init(bool force) ref.ref(); useXP(true); + qFill(m_themes, m_themes + NThemes, HTHEME(0)); } /* \internal @@ -313,16 +313,34 @@ void QWindowsXPStylePrivate::cleanup(bool force) */ void QWindowsXPStylePrivate::cleanupHandleMap() { - typedef ThemeHandleMap::const_iterator ConstIterator; + for (int i = 0; i < NThemes; ++i) + if (m_themes[i]) { + pCloseThemeData(m_themes[i]); + m_themes[i] = 0; + } +} - if (!handleMap) - return; +HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd) +{ + if (theme < 0 || theme >= NThemes || !hwnd) { + qWarning("%s: Invalid parameters #%d, %p", theme, hwnd); + return 0; + } + if (!m_themes[theme]) { + const wchar_t *name = themeNames[theme]; + m_themes[theme] = pOpenThemeData(hwnd, name); + if (!m_themes[theme]) + qErrnoWarning("%s: OpenThemeData() failed for theme %d (%s).", + Q_FUNC_INFO, theme, qPrintable(themeName(theme))); + } + return m_themes[theme]; +} - const ConstIterator cend = handleMap->constEnd(); - for (ConstIterator it = handleMap->constBegin(); it != cend; ++it) - pCloseThemeData(it.value()); - delete handleMap; - handleMap = 0; +QString QWindowsXPStylePrivate::themeName(int theme) +{ + return theme >= 0 && theme < NThemes ? + QString::fromWCharArray(themeNames[theme]) : + QString(); } /*! \internal @@ -361,7 +379,7 @@ const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *) { if (!tabbody) { SIZE sz; - XPThemeData theme(0, 0, QLatin1String("TAB"), TABP_BODY); + XPThemeData theme(0, 0, QWindowsXPStylePrivate::TabTheme, TABP_BODY); pGetThemePartSize(theme.handle(), qt_win_display_dc(), TABP_BODY, 0, 0, TS_TRUE, &sz); tabbody = new QPixmap(sz.cx, QApplication::desktop()->screenGeometry().height()); @@ -828,9 +846,21 @@ void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa bool inspectData; bool potentialInvalidAlpha; - QString pixmapCacheKey = QString::fromLatin1("$qt_xp_%1p%2s%3s%4b%5c%6w%7h").arg(themeData.name) - .arg(partId).arg(stateId).arg(!themeData.noBorder).arg(!themeData.noContent) - .arg(w).arg(h); + QString pixmapCacheKey = QStringLiteral("$qt_xp_"); + pixmapCacheKey.append(themeName(themeData.theme)); + pixmapCacheKey.append(QLatin1Char('p')); + pixmapCacheKey.append(QString::number(partId)); + pixmapCacheKey.append(QLatin1Char('s')); + pixmapCacheKey.append(QString::number(stateId)); + pixmapCacheKey.append(QLatin1Char('s')); + pixmapCacheKey.append(themeData.noBorder ? QLatin1Char('0') : QLatin1Char('1')); + pixmapCacheKey.append(QLatin1Char('b')); + pixmapCacheKey.append(themeData.noContent ? QLatin1Char('0') : QLatin1Char('1')); + pixmapCacheKey.append(QString::number(w)); + pixmapCacheKey.append(QLatin1Char('w')); + pixmapCacheKey.append(QString::number(h)); + pixmapCacheKey.append(QLatin1Char('h')); + QPixmap cachedPixmap; ThemeMapKey key(themeData); ThemeMapData data = alphaCache.value(key); @@ -1195,7 +1225,7 @@ void QWindowsXPStyle::polish(QWidget *widget) if (!d->hasInitColors) { // Get text color for group box labels COLORREF cref; - XPThemeData theme(0, 0, QLatin1String("BUTTON"), 0, 0); + XPThemeData theme(0, 0, QWindowsXPStylePrivate::ButtonTheme, 0, 0); pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref); d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref)); pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref); @@ -1305,7 +1335,7 @@ QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option, if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { MARGINS borderSize; if (widget) { - XPThemeData buttontheme(widget, 0, QLatin1String("Button")); + XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme); HTHEME theme = buttontheme.handle(); if (theme) { int stateId; @@ -1366,7 +1396,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt return; } - QString name; + int themeNumber = -1; int partId = 0; int stateId = 0; QRect rect = option->rect; @@ -1412,7 +1442,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt } return; case PE_PanelButtonBevel: - name = QLatin1String("BUTTON"); + themeNumber = QWindowsXPStylePrivate::ButtonTheme; partId = BP_PUSHBUTTON; if (!(flags & State_Enabled)) stateId = PBS_DISABLED; @@ -1432,7 +1462,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt if (dw->isWindow()) return; } - name = QLatin1String("TOOLBAR"); + themeNumber = QWindowsXPStylePrivate::ToolBarTheme; partId = TP_BUTTON; if (!(flags & State_Enabled)) stateId = TS_DISABLED; @@ -1449,7 +1479,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt break; case PE_IndicatorButtonDropDown: - name = QLatin1String("TOOLBAR"); + themeNumber = QWindowsXPStylePrivate::ToolBarTheme; partId = TP_SPLITBUTTONDROPDOWN; if (!(flags & State_Enabled)) stateId = TS_DISABLED; @@ -1468,7 +1498,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt break; case PE_IndicatorCheckBox: - name = QLatin1String("BUTTON"); + themeNumber = QWindowsXPStylePrivate::ButtonTheme; partId = BP_CHECKBOX; if (!(flags & State_Enabled)) stateId = CBS_UNCHECKEDDISABLED; @@ -1487,7 +1517,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt break; case PE_IndicatorRadioButton: - name = QLatin1String("BUTTON"); + themeNumber = QWindowsXPStylePrivate::ButtonTheme; partId = BP_RADIOBUTTON; if (!(flags & State_Enabled)) stateId = RBS_UNCHECKEDDISABLED; @@ -1509,9 +1539,9 @@ case PE_Frame: { if (flags & State_Raised) return; - name = QLatin1String("LISTVIEW"); + themeNumber = QWindowsXPStylePrivate::ListViewTheme; partId = LVP_LISTGROUP; - XPThemeData theme(0, 0, name, partId, 0); + XPThemeData theme(0, 0, themeNumber, partId, 0); if (!(flags & State_Enabled)) stateId = ETS_DISABLED; @@ -1561,7 +1591,7 @@ case PE_Frame: p->setPen(oldPen); return; } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) { - name = QLatin1String("EDIT"); + themeNumber = QWindowsXPStylePrivate::EditTheme; partId = EP_EDITTEXT; noContent = true; if (!(flags & State_Enabled)) @@ -1574,7 +1604,7 @@ case PE_Frame: case PE_PanelLineEdit: if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - name = QLatin1String("EDIT"); + themeNumber = QWindowsXPStylePrivate::EditTheme; partId = EP_EDITTEXT; noBorder = true; QBrush bg; @@ -1602,7 +1632,7 @@ case PE_Frame: if (usePalette) { p->fillRect(panel->rect, bg); } else { - XPThemeData theme(0, p, name, partId, stateId, rect); + XPThemeData theme(0, p, themeNumber, partId, stateId, rect); if (!theme.isValid()) { QWindowsStyle::drawPrimitive(pe, option, p, widget); return; @@ -1646,7 +1676,7 @@ case PE_Frame: case PE_FrameTabWidget: if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) { - name = QLatin1String("TAB"); + themeNumber = QWindowsXPStylePrivate::TabTheme; partId = TABP_PANE; if (widget) { @@ -1673,7 +1703,7 @@ case PE_Frame: QRegion reg = option->rect; reg -= contentsRect; p->setClipRegion(reg); - XPThemeData theme(widget, p, name, partId, stateId, rect); + XPThemeData theme(widget, p, themeNumber, partId, stateId, rect); theme.mirrorHorizontally = hMirrored; theme.mirrorVertically = vMirrored; d->drawBackground(theme); @@ -1717,7 +1747,7 @@ case PE_Frame: case PE_FrameDockWidget: if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - name = QLatin1String("WINDOW"); + themeNumber = QWindowsXPStylePrivate::WindowTheme; if (flags & State_Active) stateId = FS_ACTIVE; else @@ -1725,7 +1755,7 @@ case PE_Frame: int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm, widget); - XPThemeData theme(widget, p, name, 0, stateId); + XPThemeData theme(widget, p, themeNumber, 0, stateId); if (!theme.isValid()) break; theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth); theme.partId = WP_SMALLFRAMELEFT; @@ -1743,7 +1773,7 @@ case PE_Frame: case PE_IndicatorHeaderArrow: { #if 0 // XP theme engine doesn't know about this :( - name = QLatin1String("HEADER"); + name = QWindowsXPStylePrivate::HEADER"); partId = HP_HEADERSORTARROW; if (flags & State_Down) stateId = HSAS_SORTEDDOWN; @@ -1775,12 +1805,12 @@ case PE_Frame: break; case PE_FrameStatusBarItem: - name = QLatin1String("STATUS"); + themeNumber = QWindowsXPStylePrivate::StatusTheme; partId = SP_PANE; break; case PE_FrameGroupBox: - name = QLatin1String("BUTTON"); + themeNumber = QWindowsXPStylePrivate::ButtonTheme; partId = BP_GROUPBOX; if (!(flags & State_Enabled)) stateId = GBS_DISABLED; @@ -1794,7 +1824,7 @@ case PE_Frame: QPoint p1(fr.x(), fr.y() + 1); QPoint p2(fr.x() + fr.width(), p1.y() + 1); rect = QRect(p1, p2); - name = QLatin1String(""); + themeNumber = -1; } } break; @@ -1817,7 +1847,7 @@ case PE_Frame: partId = PP_CHUNKVERT; rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height()); } - name = QLatin1String("PROGRESS"); + themeNumber = QWindowsXPStylePrivate::ProgressTheme; stateId = 1; } break; @@ -1825,7 +1855,7 @@ case PE_Frame: case PE_FrameWindow: if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - name = QLatin1String("WINDOW"); + themeNumber = QWindowsXPStylePrivate::WindowTheme; if (flags & State_Active) stateId = FS_ACTIVE; else @@ -1833,7 +1863,7 @@ case PE_Frame: int fwidth = frm->lineWidth + frm->midLineWidth; - XPThemeData theme(0, p, name, 0, stateId); + XPThemeData theme(0, p, themeNumber, 0, stateId); if (!theme.isValid()) break; @@ -1879,7 +1909,7 @@ case PE_Frame: bef_v -= delta; aft_h += delta; aft_v += delta; - XPThemeData theme(0, p, QLatin1String("TREEVIEW")); + XPThemeData theme(0, p, QWindowsXPStylePrivate::TreeViewTheme); theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size); theme.partId = TVP_GLYPH; theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED; @@ -1895,7 +1925,7 @@ case PE_Frame: QWindowsStyle::drawPrimitive(pe, option, p, widget); return; } - name = QLatin1String("TOOLBAR"); + themeNumber = QWindowsXPStylePrivate::ToolBarTheme; partId = TP_SEPARATOR; if (option->state & State_Horizontal) @@ -1907,7 +1937,7 @@ case PE_Frame: case PE_IndicatorToolBarHandle: - name = QLatin1String("REBAR"); + themeNumber = QWindowsXPStylePrivate::RebarTheme; partId = RP_GRIPPER; if (option->state & State_Horizontal) { partId = RP_GRIPPER; @@ -1931,7 +1961,7 @@ case PE_Frame: break; } - XPThemeData theme(0, p, name, partId, stateId, rect); + XPThemeData theme(0, p, themeNumber, partId, stateId, rect); if (!theme.isValid()) { QWindowsStyle::drawPrimitive(pe, option, p, widget); return; @@ -1963,16 +1993,16 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op bool hMirrored = false; bool vMirrored = false; - QString name; + int themeNumber = -1; int partId = 0; int stateId = 0; switch (element) { case CE_SizeGrip: { - name = QLatin1String("STATUS"); + themeNumber = QWindowsXPStylePrivate::StatusTheme; partId = SP_GRIPPER; SIZE sz; - XPThemeData theme(0, p, name, partId, 0); + XPThemeData theme(0, p, themeNumber, partId, 0); pGetThemePartSize(theme.handle(), 0, partId, 0, 0, TS_TRUE, &sz); --sz.cy; if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) { @@ -1997,7 +2027,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op break; case CE_HeaderSection: - name = QLatin1String("HEADER"); + themeNumber = QWindowsXPStylePrivate::HeaderTheme; partId = HP_HEADERITEM; if (flags & State_Sunken) stateId = HIS_PRESSED; @@ -2014,7 +2044,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op case CE_PushButtonBevel: if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { - name = QLatin1String("BUTTON"); + themeNumber = QWindowsXPStylePrivate::ButtonTheme; partId = BP_PUSHBUTTON; bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken))) || ((btn->features & QStyleOptionButton::CommandLinkButton) @@ -2034,13 +2064,15 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op stateId = PBS_NORMAL; if (!justFlat) { - XPThemeData theme(widget, p, name, partId, stateId, rect); + XPThemeData theme(widget, p, themeNumber, partId, stateId, rect); d->drawBackground(theme); } if (btn->features & QStyleOptionButton::HasMenu) { int mbiw = 0, mbih = 0; - XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_SPLITBUTTONDROPDOWN); + XPThemeData theme(widget, 0, + QWindowsXPStylePrivate::ToolBarTheme, + TP_SPLITBUTTONDROPDOWN); if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size); @@ -2066,7 +2098,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op case CE_TabBarTabShape: if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) { - name = QLatin1String("TAB"); + themeNumber = QWindowsXPStylePrivate::TabTheme; bool isDisabled = !(tab->state & State_Enabled); bool hasFocus = tab->state & State_HasFocus; bool isHot = tab->state & State_MouseOver; @@ -2145,7 +2177,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op } break; default: - name = QLatin1String(""); // Do our own painting for triangular + themeNumber = -1; // Do our own painting for triangular break; } @@ -2176,7 +2208,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) orient = pb2->orientation; partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT; - name = QLatin1String("PROGRESS"); + themeNumber = QWindowsXPStylePrivate::ProgressTheme; stateId = 1; } break; @@ -2398,7 +2430,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op p->setPen(oldPen); } else { - name = QLatin1String("WINDOW"); + themeNumber = QWindowsXPStylePrivate::WindowTheme; if (isActive) stateId = CS_ACTIVE; else @@ -2407,7 +2439,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op int titleHeight = rect.height() - 2; rect = rect.adjusted(-fw, -fw, fw, 0); - XPThemeData theme(widget, p, name, 0, stateId); + XPThemeData theme(widget, p, themeNumber, 0, stateId); if (!theme.isValid()) break; @@ -2483,7 +2515,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op case CE_HeaderEmptyArea: if (option->state & State_Horizontal) { - name = QLatin1String("HEADER"); + themeNumber = QWindowsXPStylePrivate::HeaderTheme; stateId = HIS_NORMAL; } else { @@ -2495,7 +2527,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op break; } - XPThemeData theme(widget, p, name, partId, stateId, rect); + XPThemeData theme(widget, p, themeNumber, partId, stateId, rect); if (!theme.isValid()) { QWindowsStyle::drawControl(element, option, p, widget); return; @@ -2535,7 +2567,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo case CC_SpinBox: if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { - XPThemeData theme(widget, p, QLatin1String("SPIN")); + XPThemeData theme(widget, p, QWindowsXPStylePrivate::SpinTheme); if (sb->frame && (sub & SC_SpinBoxFrame)) { partId = EP_EDITTEXT; @@ -2546,7 +2578,8 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo else stateId = ETS_NORMAL; - XPThemeData ftheme(widget, p, QLatin1String("EDIT"), partId, stateId, r); + XPThemeData ftheme(widget, p, QWindowsXPStylePrivate::EditTheme, + partId, stateId, r); ftheme.noContent = true; d->drawBackground(ftheme); } @@ -2596,7 +2629,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo stateId = ETS_FOCUSED; else stateId = ETS_NORMAL; - XPThemeData theme(widget, p, QLatin1String("EDIT"), partId, stateId, r); + XPThemeData theme(widget, p, QWindowsXPStylePrivate::EditTheme, partId, stateId, r); d->drawBackground(theme); } else { QBrush editBrush = cmb->palette.brush(QPalette::Base); @@ -2617,7 +2650,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo } if (sub & SC_ComboBoxArrow) { - XPThemeData theme(widget, p, QLatin1String("COMBOBOX")); + XPThemeData theme(widget, p, QWindowsXPStylePrivate::ComboboxTheme); theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget); partId = CP_DROPDOWNBUTTON; if (!(flags & State_Enabled)) @@ -2638,7 +2671,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo case CC_ScrollBar: if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) { - XPThemeData theme(widget, p, QLatin1String("SCROLLBAR")); + XPThemeData theme(widget, p, QWindowsXPStylePrivate::ScrollBarTheme); bool maxedOut = (scrollbar->maximum == scrollbar->minimum); if (maxedOut) flags &= ~State_Enabled; @@ -2776,7 +2809,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo case CC_Slider: if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { - XPThemeData theme(widget, p, QLatin1String("TRACKBAR")); + XPThemeData theme(widget, p, QWindowsXPStylePrivate::TrackBarTheme); QRect slrect = slider->rect; QRegion tickreg = slrect; if (sub & SC_SliderGroove) { @@ -2939,7 +2972,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo if (toolbutton->subControls & SC_ToolButton) { if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) { if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) { - XPThemeData theme(widget, p, QLatin1String("TOOLBAR")); + XPThemeData theme(widget, p, QWindowsXPStylePrivate::ToolBarTheme); theme.partId = TP_SPLITBUTTON; theme.rect = button; if (!(bflags & State_Enabled)) @@ -3029,7 +3062,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) { bool isActive = tb->titleBarState & QStyle::State_Active; - XPThemeData theme(widget, p, QLatin1String("WINDOW")); + XPThemeData theme(widget, p, QWindowsXPStylePrivate::WindowTheme); if (sub & SC_TitleBarLabel) { partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION; @@ -3298,7 +3331,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con case PM_IndicatorWidth: case PM_IndicatorHeight: { - XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_CHECKBOX, CBS_UNCHECKEDNORMAL); + XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL); if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size); @@ -3310,7 +3343,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con case PM_ExclusiveIndicatorWidth: case PM_ExclusiveIndicatorHeight: { - XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL); + XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL); if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size); @@ -3324,7 +3357,8 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con Qt::Orientation orient = Qt::Horizontal; if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) orient = pb2->orientation; - XPThemeData theme(widget, 0, QLatin1String("PROGRESS"), (orient == Qt::Horizontal) ? PP_CHUNK : PP_CHUNKVERT); + XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ProgressTheme, + (orient == Qt::Horizontal) ? PP_CHUNK : PP_CHUNKVERT); if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size); @@ -3335,7 +3369,8 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con case PM_SliderThickness: { - XPThemeData theme(widget, 0, QLatin1String("TRACKBAR"), TKP_THUMB); + XPThemeData theme(widget, 0, QWindowsXPStylePrivate::TrackBarTheme, + TKP_THUMB); if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size); @@ -3355,7 +3390,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con case PM_MdiSubWindowFrameWidth: { - XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_FRAMELEFT, FS_ACTIVE); + XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_FRAMELEFT, FS_ACTIVE); if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, WP_FRAMELEFT, FS_ACTIVE, 0, TS_TRUE, &size); @@ -3376,7 +3411,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con #endif // QT_NO_TOOLBAR case PM_DockWidgetFrameWidth: { - XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLFRAMERIGHT, FS_ACTIVE); + XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLFRAMERIGHT, FS_ACTIVE); if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size); @@ -3635,7 +3670,7 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt case CT_LineEdit: case CT_ComboBox: { - XPThemeData buttontheme(widget, 0, QLatin1String("Button")); + XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme); HTHEME theme = buttontheme.handle(); MARGINS borderSize; if (theme) { @@ -3761,9 +3796,13 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const titleBarRect.setHeight(tbHeight); XPThemeData themeData; if (titlebar->titleBarState & Qt::WindowMinimized) { - themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, titleBarRect); + themeData = XPThemeData(widget, 0, + QWindowsXPStylePrivate::WindowTheme, + WP_MINCAPTION, CS_ACTIVE, titleBarRect); } else - themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, titleBarRect); + themeData = XPThemeData(widget, 0, + QWindowsXPStylePrivate::WindowTheme, + WP_CAPTION, CS_ACTIVE, titleBarRect); mask->region = d->region(themeData) + QRect(0, tbHeight, option->rect.width(), option->rect.height() - tbHeight); } @@ -3812,7 +3851,7 @@ QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QSt if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { if (widget && widget->isWindow()) { - XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL); + XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); if (theme.isValid()) { SIZE sz; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &sz); @@ -3844,8 +3883,10 @@ QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon, if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { if (d->dockFloat.isNull()) { - XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL); - XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_MAXBUTTON, MAXBS_NORMAL); + XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme, + WP_SMALLCLOSEBUTTON, CBS_NORMAL); + XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, + WP_MAXBUTTON, MAXBS_NORMAL); if (theme.isValid()) { SIZE size; pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size); @@ -3879,7 +3920,8 @@ QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon, if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { if (d->dockClose.isNull()) { - XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL); + XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, + WP_SMALLCLOSEBUTTON, CBS_NORMAL); if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size); @@ -3913,8 +3955,10 @@ QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon, if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { if (d->dockFloat.isNull()) { - XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL); - XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_RESTOREBUTTON, RBS_NORMAL); + XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme, + WP_SMALLCLOSEBUTTON, CBS_NORMAL); + XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, + WP_RESTOREBUTTON, RBS_NORMAL); if (theme.isValid()) { SIZE size; pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size); diff --git a/src/widgets/styles/qwindowsxpstyle_p.h b/src/widgets/styles/qwindowsxpstyle_p.h index 0e42bbfa396..058668d3fb1 100644 --- a/src/widgets/styles/qwindowsxpstyle_p.h +++ b/src/widgets/styles/qwindowsxpstyle_p.h @@ -209,9 +209,9 @@ QT_BEGIN_NAMESPACE class XPThemeData { public: - XPThemeData(const QWidget *w = 0, QPainter *p = 0, const QString &theme = QString(), + XPThemeData(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, int part = 0, int state = 0, const QRect &r = QRect()) - : widget(w), painter(p), name(theme), htheme(0), partId(part), stateId(state), + : widget(w), painter(p), theme(themeIn), htheme(0), partId(part), stateId(state), mirrorHorizontally(false), mirrorVertically(false), noBorder(false), noContent(false), rotate(0), rect(r) {} @@ -224,7 +224,8 @@ public: const QWidget *widget; QPainter *painter; - QString name; + + int theme; HTHEME htheme; int partId; int stateId; @@ -238,7 +239,7 @@ public: }; struct ThemeMapKey { - QString name; + int theme; int partId; int stateId; bool noBorder; @@ -246,17 +247,17 @@ struct ThemeMapKey { ThemeMapKey() : partId(-1), stateId(-1) {} ThemeMapKey(const XPThemeData &data) - : name(data.name), partId(data.partId), stateId(data.stateId), + : theme(data.theme), partId(data.partId), stateId(data.stateId), noBorder(data.noBorder), noContent(data.noContent) {} }; inline uint qHash(const ThemeMapKey &key) -{ return qHash(key.name) ^ key.partId ^ key.stateId; } +{ return key.theme ^ key.partId ^ key.stateId; } inline bool operator==(const ThemeMapKey &k1, const ThemeMapKey &k2) { - return k1.name == k2.name + return k1.theme == k2.theme && k1.partId == k2.partId && k1.stateId == k2.stateId; } @@ -286,7 +287,27 @@ class QWindowsXPStylePrivate : public QWindowsStylePrivate { Q_DECLARE_PUBLIC(QWindowsXPStyle) public: - typedef QMap<QString, HTHEME> ThemeHandleMap; + enum Theme { + ButtonTheme, + ComboboxTheme, + EditTheme, + HeaderTheme, + ListViewTheme, + MenuTheme, + ProgressTheme, + RebarTheme, + ScrollBarTheme, + SpinTheme, + TabTheme, + TaskDialogTheme, + ToolBarTheme, + ToolTipTheme, + TrackBarTheme, + TreeViewTheme, + WindowTheme, + StatusTheme, + NThemes + }; QWindowsXPStylePrivate() : QWindowsStylePrivate(), hasInitColors(false), bufferDC(0), bufferBitmap(0), nullBitmap(0), @@ -328,7 +349,8 @@ public: QRgb sliderTickColor; bool hasInitColors; - static ThemeHandleMap *handleMap; + static HTHEME createTheme(int theme, HWND hwnd); + static QString themeName(int theme); QIcon dockFloat, dockClose; @@ -348,6 +370,8 @@ private: HBITMAP nullBitmap; uchar *bufferPixels; int bufferW, bufferH; + + static HTHEME m_themes[NThemes]; }; #endif // QT_NO_STYLE_WINDOWS diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp index 8c0bcc098f3..5f75bd39138 100644 --- a/src/widgets/widgets/qabstractbutton.cpp +++ b/src/widgets/widgets/qabstractbutton.cpp @@ -1178,11 +1178,11 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e) } break; case Qt::Key_Up: - case Qt::Key_Left: next = false; // fall through + case Qt::Key_Left: case Qt::Key_Right: - case Qt::Key_Down: + case Qt::Key_Down: { #ifdef QT_KEYPAD_NAVIGATION if ((QApplication::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right)) @@ -1192,13 +1192,13 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e) return; } #endif - QWidget *pw; + QWidget *pw = parentWidget(); if (d->autoExclusive #ifndef QT_NO_BUTTONGROUP || d->group #endif #ifndef QT_NO_ITEMVIEWS - || ((pw = parentWidget()) && qobject_cast<QAbstractItemView *>(pw->parentWidget())) + || (pw && qobject_cast<QAbstractItemView *>(pw->parentWidget())) #endif ) { // ### Using qobject_cast to check if the parent is a viewport of @@ -1209,9 +1209,17 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e) if (hasFocus()) // nothing happend, propagate e->ignore(); } else { + // Prefer parent widget, use this if parent is absent + QWidget *w = pw ? pw : this; + bool reverse = (w->layoutDirection() == Qt::RightToLeft); + if ((e->key() == Qt::Key_Left && !reverse) + || (e->key() == Qt::Key_Right && reverse)) { + next = false; + } focusNextPrevChild(next); } break; + } case Qt::Key_Escape: if (d->down) { setDown(false); diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index dc1e0dbfabc..bea40610761 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2468,7 +2468,7 @@ void QComboBox::showPopup() } container->setGeometry(listRect); -#ifndef Q_WS_MAC +#ifndef Q_OS_MAC const bool updatesEnabled = container->updatesEnabled(); #endif @@ -2484,7 +2484,7 @@ void QComboBox::showPopup() // If updates are disabled at this point we'll miss our chance at painting the popup // menu before it's shown, causing flicker since the window then displays the standard gray // background. -#ifndef Q_WS_MAC +#ifndef Q_OS_MAC container->setUpdatesEnabled(false); #endif @@ -2498,7 +2498,7 @@ void QComboBox::showPopup() ? QAbstractItemView::PositionAtCenter : QAbstractItemView::EnsureVisible); -#ifndef Q_WS_MAC +#ifndef Q_OS_MAC container->setUpdatesEnabled(updatesEnabled); #endif diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp index 5a8e083e44b..09cbfd663db 100644 --- a/src/widgets/widgets/qfontcombobox.cpp +++ b/src/widgets/widgets/qfontcombobox.cpp @@ -120,8 +120,8 @@ public: QFontFamilyDelegate::QFontFamilyDelegate(QObject *parent) : QAbstractItemDelegate(parent) { - truetype = QIcon(QLatin1String(":/trolltech/styles/commonstyle/images/fonttruetype-16.png")); - bitmap = QIcon(QLatin1String(":/trolltech/styles/commonstyle/images/fontbitmap-16.png")); + truetype = QIcon(QLatin1String(":/qt-project.org/styles/commonstyle/images/fonttruetype-16.png")); + bitmap = QIcon(QLatin1String(":/qt-project.org/styles/commonstyle/images/fontbitmap-16.png")); writingSystem = QFontDatabase::Any; } diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 07843136ffd..1ea636ffb21 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -1669,7 +1669,7 @@ QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const case Qt::ImCursorPosition: return QVariant(d->control->cursor()); case Qt::ImSurroundingText: - return QVariant(d->control->realText()); + return QVariant(d->control->text()); case Qt::ImCurrentSelection: return QVariant(selectedText()); case Qt::ImMaximumTextLength: @@ -1748,7 +1748,6 @@ void QLineEdit::focusOutEvent(QFocusEvent *e) reason != Qt::PopupFocusReason) deselect(); - d->control->commitPreedit(); d->setCursorVisible(false); d->control->setCursorBlinkPeriod(0); #ifdef QT_KEYPAD_NAVIGATION diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 3b7a0d1b91e..d6af91fd654 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE -class QLineEditPrivate : public QWidgetPrivate +class Q_AUTOTEST_EXPORT QLineEditPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QLineEdit) public: @@ -109,6 +109,10 @@ public: return !control->isReadOnly(); } + static inline QLineEditPrivate *get(QLineEdit *lineEdit) { + return lineEdit->d_func(); + } + QPoint tripleClick; QBasicTimer tripleClickTimer; uint frame : 1; diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 5ec41b8ba6e..c9818e056c8 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1905,16 +1905,6 @@ QAction *QMenuBar::defaultAction() const \sa triggered(), QAction::hovered() */ -/*! - \enum QMenuBar::Separator - - \compat - - \value Never - \value InWindowsStyle - -*/ - /*! \fn void QMenuBar::addAction(QAction *action) \overload diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp index 3e5b78fe2b3..c02aa0e8757 100644 --- a/src/widgets/widgets/qprogressbar.cpp +++ b/src/widgets/widgets/qprogressbar.cpp @@ -526,9 +526,9 @@ void QProgressBar::setInvertedAppearance(bool invert) update(); } -bool QProgressBar::invertedAppearance() +bool QProgressBar::invertedAppearance() const { - Q_D(QProgressBar); + Q_D(const QProgressBar); return d->invertedAppearance; } @@ -549,9 +549,9 @@ void QProgressBar::setTextDirection(QProgressBar::Direction textDirection) update(); } -QProgressBar::Direction QProgressBar::textDirection() +QProgressBar::Direction QProgressBar::textDirection() const { - Q_D(QProgressBar); + Q_D(const QProgressBar); return d->textDirection; } diff --git a/src/widgets/widgets/qprogressbar.h b/src/widgets/widgets/qprogressbar.h index fad1ee4e0b8..65ec5fa4046 100644 --- a/src/widgets/widgets/qprogressbar.h +++ b/src/widgets/widgets/qprogressbar.h @@ -92,11 +92,9 @@ public: Qt::Orientation orientation() const; void setInvertedAppearance(bool invert); - bool invertedAppearance(); //### Qt5 make const - bool invertedAppearance() const { return const_cast<QProgressBar *>(this)->invertedAppearance(); } + bool invertedAppearance() const; void setTextDirection(QProgressBar::Direction textDirection); - QProgressBar::Direction textDirection(); //### Qt5 make const - QProgressBar::Direction textDirection() const { return const_cast<QProgressBar *>(this)->textDirection(); } + QProgressBar::Direction textDirection() const; void setFormat(const QString &format); QString format() const; diff --git a/src/widgets/widgets/qslider.cpp b/src/widgets/widgets/qslider.cpp index 7f77bc9d034..5f37240d67e 100644 --- a/src/widgets/widgets/qslider.cpp +++ b/src/widgets/widgets/qslider.cpp @@ -535,20 +535,6 @@ QSlider::TickPosition QSlider::tickPosition() const return d_func()->tickPosition; } -/*! - \fn TickPosition QSlider::tickmarks() const - \compat - - Use tickPosition() instead. -*/ - -/*! - \fn QSlider::setTickmarks(TickPosition position) - \compat - - Use setTickPosition() instead. -*/ - /*! \property QSlider::tickInterval \brief the interval between tickmarks diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp index 4b7e1b5978b..217fda61dc2 100644 --- a/src/widgets/widgets/qtextedit.cpp +++ b/src/widgets/widgets/qtextedit.cpp @@ -2490,19 +2490,6 @@ void QTextEdit::ensureCursorVisible() d->control->ensureCursorVisible(); } -/*! - \enum QTextEdit::KeyboardAction - - \compat - - \value ActionBackspace - \value ActionDelete - \value ActionReturn - \value ActionKill - \value ActionWordBackspace - \value ActionWordDelete -*/ - /*! \fn bool QTextEdit::find(const QString &exp, bool cs, bool wo) diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp index 84cb5fd10c2..6ba29c13b80 100644 --- a/src/widgets/widgets/qtoolbar.cpp +++ b/src/widgets/widgets/qtoolbar.cpp @@ -1279,22 +1279,6 @@ void QToolBar::initStyleOption(QStyleOptionToolBar *option) const layout->getStyleOptionInfo(option, const_cast<QToolBar *>(this)); } -/*! - \reimp -*/ -void QToolBar::childEvent(QChildEvent *event) // ### remove me in 5.0 -{ - QWidget::childEvent(event); -} - -/*! - \reimp -*/ -void QToolBar::resizeEvent(QResizeEvent *event) // ### remove me in 5.0 -{ - QWidget::resizeEvent(event); -} - QT_END_NAMESPACE #include "moc_qtoolbar.cpp" diff --git a/src/widgets/widgets/qtoolbar.h b/src/widgets/widgets/qtoolbar.h index ac59d9803a5..1fd5da797b2 100644 --- a/src/widgets/widgets/qtoolbar.h +++ b/src/widgets/widgets/qtoolbar.h @@ -147,9 +147,7 @@ Q_SIGNALS: protected: void actionEvent(QActionEvent *event); void changeEvent(QEvent *event); - void childEvent(QChildEvent *event); void paintEvent(QPaintEvent *event); - void resizeEvent(QResizeEvent *event); bool event(QEvent *event); void initStyleOption(QStyleOptionToolBar *option) const; diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index b4a70071906..c9300d3cdd9 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -184,21 +184,15 @@ void QWidgetLineControl::paste(QClipboard::Mode clipboardMode) /*! \internal - - Exits preedit mode and commits parts marked as tentative commit */ void QWidgetLineControl::commitPreedit() { if (!composeMode()) return; - qApp->inputMethod()->reset(); - - if (!m_tentativeCommit.isEmpty()) { - internalInsert(m_tentativeCommit); - m_tentativeCommit.clear(); - finishChange(-1, true/*not used, not documented*/, false); - } + qApp->inputMethod()->commit(); + if (!composeMode()) + return; m_preeditCursor = 0; setPreeditArea(-1, QString()); @@ -573,13 +567,7 @@ void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event) else if (m_preeditCursor != oldPreeditCursor) emit updateMicroFocus(); - bool tentativeCommitChanged = (m_tentativeCommit != event->tentativeCommitString()); - if (tentativeCommitChanged) { - m_textDirty = true; - m_tentativeCommit = event->tentativeCommitString(); - } - - if (isGettingInput || tentativeCommitChanged) + if (isGettingInput) finishChange(priorState); if (selectionChange) @@ -687,15 +675,6 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e return true; } m_cursor = cursorCopy; - - if (!m_tentativeCommit.isEmpty()) { - textCopy.insert(m_cursor, m_tentativeCommit); - bool validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid); - if (!validInput) - m_tentativeCommit.clear(); - } - } else { - m_tentativeCommit.clear(); } } #endif @@ -806,6 +785,11 @@ void QWidgetLineControl::internalInsert(const QString &s) if (m_passwordEchoTimer != 0) killTimer(m_passwordEchoTimer); int delay = qGuiApp->styleHints()->passwordMaskDelay(); +#ifdef QT_BUILD_INTERNAL + if (m_passwordMaskDelayOverride >= 0) + delay = m_passwordMaskDelayOverride; +#endif + if (delay > 0) m_passwordEchoTimer = startTimer(delay); } diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h index 62184a27bbf..ba3b202bda2 100644 --- a/src/widgets/widgets/qwidgetlinecontrol_p.h +++ b/src/widgets/widgets/qwidgetlinecontrol_p.h @@ -98,6 +98,9 @@ public: , m_threadChecks(false) , m_textLayoutThread(0) #endif +#if defined(QT_BUILD_INTERNAL) + , m_passwordMaskDelayOverride(-1) +#endif , m_keyboardScheme(0) { init(txt); @@ -217,22 +220,13 @@ public: QString text() const { QString content = m_text; - if (!m_tentativeCommit.isEmpty()) - content.insert(m_cursor, m_tentativeCommit); QString res = m_maskData ? stripString(content) : content; return (res.isNull() ? QString::fromLatin1("") : res); } - // like text() but doesn't include preedit - QString realText() const - { - QString res = m_maskData ? stripString(m_text) : m_text; - return (res.isNull() ? QString::fromLatin1("") : res); - } void setText(const QString &txt) { if (composeMode()) qApp->inputMethod()->reset(); - m_tentativeCommit.clear(); internalSetText(txt, -1, false); } void commitPreedit(); @@ -286,7 +280,18 @@ public: bool hasAcceptableInput() const { return hasAcceptableInput(m_text); } bool fixup(); - QString inputMask() const { return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); } + QString inputMask() const + { + QString mask; + if (m_maskData) { + mask = m_inputMask; + if (m_blank != QLatin1Char(' ')) { + mask += QLatin1Char(';'); + mask += m_blank; + } + } + return mask; + } void setInputMask(const QString &mask) { parseInputMask(mask); @@ -402,7 +407,6 @@ private: int m_cursor; int m_preeditCursor; int m_cursorWidth; - QString m_tentativeCommit; Qt::LayoutDirection m_layoutDirection; uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas uint m_separator : 1; @@ -495,6 +499,11 @@ private: mutable QThread *m_textLayoutThread; #endif +public: +#if defined(QT_BUILD_INTERNAL) + int m_passwordMaskDelayOverride; +#endif + Q_SIGNALS: void cursorPositionChanged(int, int); void selectionChanged(); diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 86dfb303898..d602d6daa5d 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -2000,7 +2000,6 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) } } layout->setAdditionalFormats(overrides); - tentativeCommit = e->tentativeCommitString(); cursor.endEditBlock(); @@ -2057,7 +2056,6 @@ void QWidgetTextControlPrivate::focusEvent(QFocusEvent *e) } #endif } else { - commitPreedit(); setBlinkingCursorEnabled(false); if (cursorIsFocusIndicator @@ -2755,17 +2753,15 @@ bool QWidgetTextControlPrivate::isPreediting() const void QWidgetTextControlPrivate::commitPreedit() { + if (!isPreediting()) + return; + + qApp->inputMethod()->commit(); + if (!isPreediting()) return; cursor.beginEditBlock(); - qApp->inputMethod()->reset(); - - if (!tentativeCommit.isEmpty()) { - cursor.insertText(tentativeCommit); - tentativeCommit.clear(); - } - preeditCursor = 0; QTextBlock block = cursor.block(); QTextLayout *layout = block.layout(); @@ -2936,17 +2932,12 @@ bool QWidgetTextControl::find(const QString &exp, QTextDocument::FindFlags optio QString QWidgetTextControl::toPlainText() const { - Q_D(const QWidgetTextControl); - QString plainText = document()->toPlainText(); - if (!d->tentativeCommit.isEmpty()) - plainText.insert(textCursor().position(), d->tentativeCommit); - return plainText; + return document()->toPlainText(); } #ifndef QT_NO_TEXTHTMLPARSER QString QWidgetTextControl::toHtml() const { - // note: currently not including tentative commit return document()->toHtml(); } #endif diff --git a/src/widgets/widgets/qwidgettextcontrol_p_p.h b/src/widgets/widgets/qwidgettextcontrol_p_p.h index d0d940e521a..4efb59152af 100644 --- a/src/widgets/widgets/qwidgettextcontrol_p_p.h +++ b/src/widgets/widgets/qwidgettextcontrol_p_p.h @@ -209,7 +209,6 @@ public: int preeditCursor; bool hideCursor; // used to hide the cursor in the preedit area - QString tentativeCommit; QVector<QAbstractTextDocumentLayout::Selection> extraSelections; diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp index 86e3433c128..81084dbaf49 100644 --- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp +++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp @@ -381,7 +381,7 @@ void tst_QtConcurrentRun::exceptions() bool caught = false; try { QtConcurrent::run(throwFunction).waitForFinished(); - } catch (Exception &e) { + } catch (Exception &) { caught = true; } if (!caught) @@ -390,7 +390,7 @@ void tst_QtConcurrentRun::exceptions() caught = false; try { QtConcurrent::run(throwFunctionReturn).waitForFinished(); - } catch (Exception &e) { + } catch (Exception &) { caught = true; } if (!caught) diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp index 025bb349d6f..07ea4c4545e 100644 --- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp +++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp @@ -185,7 +185,7 @@ void tst_Utf8::charByChar() } if (encoded.startsWith(utf8bom)) - encoded = encoded.mid(strlen(utf8bom)); + encoded = encoded.mid(int(strlen(utf8bom))); QCOMPARE(encoded, utf8); } { diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index b7fc366a39d..250575bea01 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -53,7 +53,7 @@ #include "../../../network-settings.h" #endif -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) && !defined(_WIN32_WINNT) #define _WIN32_WINNT 0x500 #endif diff --git a/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp b/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp index a8a17b69516..3bae41e83e0 100644 --- a/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp +++ b/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp @@ -42,10 +42,10 @@ #include <windows.h> -int APIENTRY WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) +int APIENTRY WinMain(HINSTANCE /* hInstance */, + HINSTANCE /* hPrevInstance */, + LPSTR /* lpCmdLine */, + int /* nCmdShow */) { HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); @@ -64,4 +64,4 @@ int APIENTRY WinMain(HINSTANCE hInstance, WriteFile(hStderr, &c, 1, &wrote, 0); } return 0; -} \ No newline at end of file +} diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index d294eec2483..dbb844d204c 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -1486,11 +1486,9 @@ void tst_QSettings::sync() settings1.sync(); QCOMPARE(settings1.allKeys().count(), 0); -/* - // Now "some other app" will change software.org.conf - unlink((userConfDir + "software.org.ini").toLatin1()); - rename((userConfDir + "other.software.org.ini").toLatin1(), - (userConfDir + "software.org.ini").toLatin1()); + // Now "some other app" will change software.org.ini + QVERIFY(QFile::rename((userConfDir + "other.software.org.ini").toLatin1(), + (userConfDir + "software.org.ini").toLatin1())); settings1.sync(); QCOMPARE(settings1.value("alpha/beta/geometry").toInt(), -7); @@ -1505,7 +1503,6 @@ void tst_QSettings::sync() QCOMPARE(settings1.value("moo/beta/geometry/height").toInt(), 4); QCOMPARE(settings1.value("moo/gamma/splitter").toInt(), 5); QCOMPARE(settings1.allKeys().count(), 11); -*/ } void tst_QSettings::setFallbacksEnabled_data() diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index ed396d33442..9b1d5c0b686 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -239,18 +239,12 @@ void tst_qstandardpaths::testDataLocation() { // On all platforms, DataLocation should be GenericDataLocation / organization name / app name // This allows one app to access the data of another app. - { - const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); - const QString app = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - QCOMPARE(base, app); - } + const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), base + "/tst_qstandardpaths"); QCoreApplication::instance()->setOrganizationName("Qt"); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), base + "/Qt/tst_qstandardpaths"); QCoreApplication::instance()->setApplicationName("QtTest"); - { - const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); - const QString app = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - QCOMPARE(app, base + "/Qt/QtTest"); - } + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), base + "/Qt/QtTest"); #ifdef Q_XDG_PLATFORM setDefaultLocations(); diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 87820d2e780..4ab4b78da16 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -122,6 +122,7 @@ private Q_SLOTS: void assignArrays(); void testTrailingComma(); + void testDetachBug(); private: QString testDataDir; }; @@ -1186,7 +1187,7 @@ void TestQtJson::fromJsonErrors() QByteArray json = "[\n 11111"; QJsonDocument doc = QJsonDocument::fromJson(json, &error); QVERIFY(doc.isEmpty()); - QCOMPARE(error.error, QJsonParseError::EndOfNumber); + QCOMPARE(error.error, QJsonParseError::TerminationByNumber); QCOMPARE(error.offset, 11); } { @@ -1210,7 +1211,7 @@ void TestQtJson::fromJsonErrors() QByteArray json = "[\n \"\\u12\"]"; QJsonDocument doc = QJsonDocument::fromJson(json, &error); QVERIFY(doc.isEmpty()); - QCOMPARE(error.error, QJsonParseError::StringEscapeSequence); + QCOMPARE(error.error, QJsonParseError::IllegalEscapeSequence); QCOMPARE(error.offset, 11); } { @@ -1218,7 +1219,7 @@ void TestQtJson::fromJsonErrors() QByteArray json = "[\n \"foo" INVALID_UNICODE "bar\"]"; QJsonDocument doc = QJsonDocument::fromJson(json, &error); QVERIFY(doc.isEmpty()); - QCOMPARE(error.error, QJsonParseError::StringUTF8Scan); + QCOMPARE(error.error, QJsonParseError::IllegalUTF8String); QCOMPARE(error.offset, 13); } { @@ -1226,7 +1227,7 @@ void TestQtJson::fromJsonErrors() QByteArray json = "[\n \""; QJsonDocument doc = QJsonDocument::fromJson(json, &error); QVERIFY(doc.isEmpty()); - QCOMPARE(error.error, QJsonParseError::EndOfString); + QCOMPARE(error.error, QJsonParseError::UnterminatedString); QCOMPARE(error.offset, 8); } { @@ -1234,7 +1235,7 @@ void TestQtJson::fromJsonErrors() QByteArray json = "[\n \"c" UNICODE_DJE "a\\u12\"]"; QJsonDocument doc = QJsonDocument::fromJson(json, &error); QVERIFY(doc.isEmpty()); - QCOMPARE(error.error, QJsonParseError::StringEscapeSequence); + QCOMPARE(error.error, QJsonParseError::IllegalEscapeSequence); QCOMPARE(error.offset, 15); } { @@ -1242,7 +1243,7 @@ void TestQtJson::fromJsonErrors() QByteArray json = "[\n \"c" UNICODE_DJE "a" INVALID_UNICODE "bar\"]"; QJsonDocument doc = QJsonDocument::fromJson(json, &error); QVERIFY(doc.isEmpty()); - QCOMPARE(error.error, QJsonParseError::StringUTF8Scan); + QCOMPARE(error.error, QJsonParseError::IllegalUTF8String); QCOMPARE(error.offset, 14); } { @@ -1250,7 +1251,7 @@ void TestQtJson::fromJsonErrors() QByteArray json = "[\n \"c" UNICODE_DJE "a ]"; QJsonDocument doc = QJsonDocument::fromJson(json, &error); QVERIFY(doc.isEmpty()); - QCOMPARE(error.error, QJsonParseError::EndOfString); + QCOMPARE(error.error, QJsonParseError::UnterminatedString); QCOMPARE(error.offset, 14); } } @@ -1820,5 +1821,29 @@ void TestQtJson::testTrailingComma() } } +void TestQtJson::testDetachBug() +{ + QJsonObject dynamic; + QJsonObject embedded; + + QJsonObject local; + + embedded.insert("Key1", QString("Value1")); + embedded.insert("Key2", QString("Value2")); + dynamic.insert(QStringLiteral("Bogus"), QString("bogusValue")); + dynamic.insert("embedded", embedded); + local = dynamic.value("embedded").toObject(); + + dynamic.remove("embedded"); + + QCOMPARE(local.keys().size(),2); + local.remove("Key1"); + local.remove("Key2"); + QCOMPARE(local.keys().size(), 0); + + local.insert("Key1", QString("anotherValue")); + QCOMPARE(local.keys().size(), 1); +} + QTEST_MAIN(TestQtJson) #include "tst_qtjson.moc" diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 29fa98b8bb5..e8f6c29a948 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -121,7 +121,8 @@ void tst_QCoreApplication::qAppName() int argc = 1; char *argv[] = { const_cast<char*>("tst_qcoreapplication") }; QCoreApplication app(argc, argv); - QVERIFY(!::qAppName().isEmpty()); + QCOMPARE(::qAppName(), QString::fromLatin1("tst_qcoreapplication")); + QCOMPARE(QCoreApplication::applicationName(), QString::fromLatin1("tst_qcoreapplication")); } void tst_QCoreApplication::argc() diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 9f4944b44b3..4eb26928ac0 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -450,7 +450,7 @@ template<> struct TestValueFactory<QMetaType::UChar> { static uchar *create() { return new uchar('u'); } }; template<> struct TestValueFactory<QMetaType::Float> { - static float *create() { return new float(3.14); } + static float *create() { return new float(3.14f); } }; template<> struct TestValueFactory<QMetaType::QObjectStar> { static QObject * *create() { return new QObject *(0); } diff --git a/tests/auto/corelib/plugin/plugin.pro b/tests/auto/corelib/plugin/plugin.pro index 24de36e4ecc..506f6abaebb 100644 --- a/tests/auto/corelib/plugin/plugin.pro +++ b/tests/auto/corelib/plugin/plugin.pro @@ -1,5 +1,6 @@ TEMPLATE=subdirs SUBDIRS=\ + qfactoryloader \ qlibrary \ qplugin \ qpluginloader \ diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp new file mode 100644 index 00000000000..542b58a5bfd --- /dev/null +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtCore/qstring.h> +#include "plugin1.h" + +QString Plugin1::pluginName() const +{ + return QLatin1String("Plugin1 ok"); +} diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h new file mode 100644 index 00000000000..02d814e1fa2 --- /dev/null +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef THEPLUGIN_H +#define THEPLUGIN_H + +#include <QtCore/qobject.h> +#include <QtCore/qplugin.h> +#include "plugininterface1.h" + +class Plugin1 : public QObject, public PluginInterface1 +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.autotests.plugininterface1") + Q_INTERFACES(PluginInterface1) + +public: + virtual QString pluginName() const; +}; + +#endif // THEPLUGIN_H diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro new file mode 100644 index 00000000000..1d578c0b2ed --- /dev/null +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro @@ -0,0 +1,10 @@ +TEMPLATE = lib +CONFIG += plugin +HEADERS = plugin1.h +SOURCES = plugin1.cpp +TARGET = $$qtLibraryTarget(plugin1) +DESTDIR = ../bin + +# This is testdata for the tst_qpluginloader test. +target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin +INSTALLS += target diff --git a/src/plugins/platforms/xlib/qxlibdisplay.cpp b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugininterface1.h similarity index 72% rename from src/plugins/platforms/xlib/qxlibdisplay.cpp rename to tests/auto/corelib/plugin/qfactoryloader/plugin1/plugininterface1.h index 57472534aed..37f53c9c891 100644 --- a/src/plugins/platforms/xlib/qxlibdisplay.cpp +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugininterface1.h @@ -3,7 +3,7 @@ ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -38,41 +38,22 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +#ifndef PLUGININTERFACE1_H +#define PLUGININTERFACE1_H -#include "qxlibdisplay.h" +#include <QtCore/QtGlobal> -QXlibDisplay::QXlibDisplay(Display *display) - : mDisplay(display) -{ - if (!mDisplay) { - qFatal("Cannot connect to X server"); - } - mDisplayName = QString::fromLocal8Bit(DisplayString(mDisplay)); -} +struct PluginInterface1 { + virtual ~PluginInterface1() {} + virtual QString pluginName() const = 0; +}; -QXlibDisplay::~QXlibDisplay() -{ - XCloseDisplay(mDisplay); -} +QT_BEGIN_NAMESPACE -QString QXlibDisplay::displayName() const -{ - { return mDisplayName; } -} +#define PluginInterface1_iid "org.qt-project.Qt.autotests.plugininterface1" +Q_DECLARE_INTERFACE(PluginInterface1, PluginInterface1_iid) +QT_END_NAMESPACE -Display * QXlibDisplay::nativeDisplay() const -{ - return mDisplay; -} - -void QXlibDisplay::sync() const -{ - XSync(mDisplay, False); -} - -void QXlibDisplay::flush() const -{ - XFlush(mDisplay); -} +#endif // PLUGININTERFACE1_H diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp new file mode 100644 index 00000000000..b0a8f08495b --- /dev/null +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtCore/qstring.h> +#include "plugin2.h" + +QString Plugin2::pluginName() const +{ + return QLatin1String("Plugin2 ok"); +} diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.h b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.h new file mode 100644 index 00000000000..f5741246aba --- /dev/null +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef THEPLUGIN_H +#define THEPLUGIN_H + +#include <QtCore/qobject.h> +#include <QtCore/qplugin.h> +#include "plugininterface2.h" + +class Plugin2 : public QObject, public PluginInterface2 +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.autotests.plugininterface2") + Q_INTERFACES(PluginInterface2) + +public: + virtual QString pluginName() const; +}; + +#endif // THEPLUGIN_H diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro new file mode 100644 index 00000000000..1a8bd3a7216 --- /dev/null +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro @@ -0,0 +1,10 @@ +TEMPLATE = lib +CONFIG += plugin +HEADERS = plugin2.h +SOURCES = plugin2.cpp +TARGET = $$qtLibraryTarget(plugin2) +DESTDIR = ../bin + +# This is testdata for the tst_qpluginloader test. +target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin +INSTALLS += target diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugininterface2.h b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugininterface2.h new file mode 100644 index 00000000000..3fc57f1df24 --- /dev/null +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugininterface2.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef PLUGININTERFACE2_H +#define PLUGININTERFACE2_H + +#include <QtCore/QtGlobal> + +struct PluginInterface2 { + virtual ~PluginInterface2() {} + virtual QString pluginName() const = 0; +}; + +QT_BEGIN_NAMESPACE + +#define PluginInterface2_iid "org.qt-project.Qt.autotests.plugininterface2" + +Q_DECLARE_INTERFACE(PluginInterface2, PluginInterface2_iid) + +QT_END_NAMESPACE + +#endif // PLUGININTERFACE2_H diff --git a/tests/auto/corelib/plugin/qfactoryloader/qfactoryloader.pro b/tests/auto/corelib/plugin/qfactoryloader/qfactoryloader.pro new file mode 100644 index 00000000000..42bc01e2edb --- /dev/null +++ b/tests/auto/corelib/plugin/qfactoryloader/qfactoryloader.pro @@ -0,0 +1,15 @@ +QT = core-private +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS = \ + plugin1 \ + plugin2 \ + test + +TARGET = tst_qpluginloader + +# no special install rule for subdir +INSTALLS = + + +CONFIG += parallel_test diff --git a/tests/auto/corelib/plugin/qfactoryloader/test/test.pro b/tests/auto/corelib/plugin/qfactoryloader/test/test.pro new file mode 100644 index 00000000000..d03af231aa5 --- /dev/null +++ b/tests/auto/corelib/plugin/qfactoryloader/test/test.pro @@ -0,0 +1,21 @@ +CONFIG += testcase +TARGET = ../tst_qfactoryloader +QT = core-private testlib + +SOURCES = \ + ../tst_qfactoryloader.cpp + +HEADERS = \ + ../plugin1/plugininterface1.h \ + ../plugin2/plugininterface2.h + +win32 { + CONFIG(debug, debug|release) { + TARGET = ../../debug/tst_qfactoryloader + } else { + TARGET = ../../release/tst_qfactoryloader + } +} + +mac: CONFIG -= app_bundle +mac: CONFIG += insignificant_test # QTBUG-22765 diff --git a/src/plugins/platforms/xlib/qxlibmime.h b/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp similarity index 50% rename from src/plugins/platforms/xlib/qxlibmime.h rename to tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp index 2ce65a3bded..d4ed63dc37f 100644 --- a/src/plugins/platforms/xlib/qxlibmime.h +++ b/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -39,29 +39,53 @@ ** ****************************************************************************/ -#ifndef QTESTLITEMIME_H -#define QTESTLITEMIME_H +#include <QtTest/qtest.h> +#include <QtCore/qdir.h> +#include <QtCore/qfileinfo.h> +#include <private/qfactoryloader_p.h> +#include "plugin1/plugininterface1.h" +#include "plugin2/plugininterface2.h" -#include <private/qdnd_p.h> - -#include <QtGui/QClipboard> - -#include "qxlibintegration.h" -#include "qxlibclipboard.h" - -class QXlibMime : public QInternalMimeData { +class tst_QFactoryLoader : public QObject +{ Q_OBJECT -public: - QXlibMime(); - ~QXlibMime(); +public slots: + void initTestCase(); - static QList<Atom> mimeAtomsForFormat(Display *display, const QString &format); - static QString mimeAtomToString(Display *display, Atom a); - static bool mimeDataForAtom(Display *display, Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat); - static QStringList mimeFormatsForAtom(Display *display, Atom a); - static Atom mimeStringToAtom(Display *display, const QString &mimeType); - static QVariant mimeConvertToFormat(Display *display, Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding); - static Atom mimeAtomForFormat(Display *display, const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *requestedEncoding); +private slots: + void usingTwoFactoriesFromSameDir(); }; -#endif // QTESTLITEMIME_H +static const char binFolderC[] = "bin"; + +void tst_QFactoryLoader::initTestCase() +{ + const QString binFolder = QFINDTESTDATA(binFolderC); + QVERIFY2(!binFolder.isEmpty(), "Unable to locate 'bin' folder"); + + QCoreApplication::setLibraryPaths(QStringList(QFileInfo(binFolder).absolutePath())); +} + +void tst_QFactoryLoader::usingTwoFactoriesFromSameDir() +{ + const QString suffix = QLatin1Char('/') + QLatin1String(binFolderC); + QFactoryLoader loader1(PluginInterface1_iid, suffix); + + PluginInterface1 *plugin1 = qobject_cast<PluginInterface1 *>(loader1.instance(0)); + QVERIFY2(plugin1, + qPrintable(QString::fromLatin1("Cannot load plugin '%1'") + .arg(QLatin1String(PluginInterface1_iid)))); + + QFactoryLoader loader2(PluginInterface2_iid, suffix); + + PluginInterface2 *plugin2 = qobject_cast<PluginInterface2 *>(loader2.instance(0)); + QVERIFY2(plugin2, + qPrintable(QString::fromLatin1("Cannot load plugin '%1'") + .arg(QLatin1String(PluginInterface2_iid)))); + + QCOMPARE(plugin1->pluginName(), QLatin1String("Plugin1 ok")); + QCOMPARE(plugin2->pluginName(), QLatin1String("Plugin2 ok")); +} + +QTEST_MAIN(tst_QFactoryLoader) +#include "tst_qfactoryloader.moc" diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 7afd435e52a..1905c9c049a 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -780,6 +780,11 @@ void tst_QString::acc_01() } } +#ifdef Q_CC_GNU +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wformat-security" +#endif + void tst_QString::isNull() { QString a; @@ -790,6 +795,10 @@ void tst_QString::isNull() QVERIFY(!a.isNull()); } +#ifdef Q_CC_GNU +# pragma GCC diagnostic pop +#endif + void tst_QString::isEmpty() { QString a; diff --git a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp index bd9fa2a8db5..8a60bb18764 100644 --- a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp @@ -984,7 +984,7 @@ void tst_QXmlStream::writeAttributesWithSpace() const QXmlStreamWriter writer(&buffer); writer.writeStartDocument(); writer.writeEmptyElement("A"); - writer.writeAttribute("attribute", QString("value")+QChar::Nbsp); + writer.writeAttribute("attribute", QStringLiteral("value") + QChar(QChar::Nbsp)); writer.writeEndDocument(); QString s = QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><A attribute=\"value%1\"/>\n").arg(QChar(QChar::Nbsp)); QCOMPARE(buffer.buffer().data(), s.toUtf8().data()); @@ -1512,35 +1512,38 @@ void tst_QXmlStream::hasError() const // Failure caused by write(QString) FakeBuffer fb; QVERIFY(fb.open(QBuffer::ReadWrite)); - fb.setCapacity(strlen("<?xml version=\"")); + const QByteArray expected = QByteArrayLiteral("<?xml version=\""); + fb.setCapacity(expected.size()); QXmlStreamWriter writer(&fb); writer.writeStartDocument(); QVERIFY(writer.hasError()); - QCOMPARE(fb.data(), QByteArray("<?xml version=\"")); + QCOMPARE(fb.data(), expected); } { // Failure caused by write(char *) FakeBuffer fb; QVERIFY(fb.open(QBuffer::ReadWrite)); - fb.setCapacity(strlen("<?xml version=\"1.0")); + const QByteArray expected = QByteArrayLiteral("<?xml version=\"1.0"); + fb.setCapacity(expected.size()); QXmlStreamWriter writer(&fb); writer.writeStartDocument(); QVERIFY(writer.hasError()); - QCOMPARE(fb.data(), QByteArray("<?xml version=\"1.0")); + QCOMPARE(fb.data(), expected); } { // Failure caused by write(QStringRef) FakeBuffer fb; QVERIFY(fb.open(QBuffer::ReadWrite)); - fb.setCapacity(strlen("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test xmlns:")); + const QByteArray expected = QByteArrayLiteral("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test xmlns:"); + fb.setCapacity(expected.size()); QXmlStreamWriter writer(&fb); writer.writeStartDocument(); writer.writeStartElement("test"); writer.writeNamespace("http://foo.bar", "foo"); QVERIFY(writer.hasError()); - QCOMPARE(fb.data(), QByteArray("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test xmlns:")); + QCOMPARE(fb.data(), expected); } { diff --git a/tests/auto/dbus/qdbusmarshall/common.h b/tests/auto/dbus/qdbusmarshall/common.h index 3efb8de499e..ed5c03ea64d 100644 --- a/tests/auto/dbus/qdbusmarshall/common.h +++ b/tests/auto/dbus/qdbusmarshall/common.h @@ -350,8 +350,6 @@ QT_END_NAMESPACE #endif -//bool compare(const QVariantList &l1, const QVariantList &l2); -//bool compare(const QVariantMap &m1, const QVariantMap &m2); template<typename T> bool compare(const T &t1, const T &t2) { return t1 == t2; } diff --git a/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp b/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp index 3810546146b..cfe26d23e74 100644 --- a/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp +++ b/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp @@ -122,6 +122,8 @@ private slots: void update(); void query(); void inputDirection(); + void inputMethodAccepted(); + private: InputItem m_inputItem; PlatformInputContext m_platformInputContext; @@ -304,5 +306,23 @@ void tst_qinputmethod::inputDirection() QCOMPARE(m_platformInputContext.m_localeCallCount, 1); } +void tst_qinputmethod::inputMethodAccepted() +{ + InputItem disabledItem; + disabledItem.setEnabled(false); + + DummyWindow window; + window.show(); + QTest::qWaitForWindowShown(&window); + window.requestActivateWindow(); + QTRY_COMPARE(qApp->focusWindow(), &window); + window.setFocusObject(&disabledItem); + + QCOMPARE(m_platformInputContext.inputMethodAccepted(), false); + + window.setFocusObject(&m_inputItem); + QCOMPARE(m_platformInputContext.inputMethodAccepted(), true); +} + QTEST_MAIN(tst_qinputmethod) #include "tst_qinputmethod.moc" diff --git a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp index 861ad3835d7..c4db74b6ecb 100644 --- a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp @@ -422,7 +422,9 @@ void tst_QKeySequence::mnemonic() QFETCH(QString, key); QFETCH(bool, warning); -#ifndef QT_NO_DEBUG +#ifdef QT_NO_DEBUG + Q_UNUSED(warning) +#else if (warning) { QString str = QString::fromLatin1("QKeySequence::mnemonic: \"%1\" contains multiple occurrences of '&'").arg(string); QTest::ignoreMessage(QtWarningMsg, qPrintable(str)); diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index df58d8340b8..3dc2886b806 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -69,6 +69,7 @@ private slots: void close(); void activateAndClose(); void mouseEventSequence(); + void windowModality(); void initTestCase() { @@ -223,6 +224,9 @@ void tst_QWindow::isExposed() window.hide(); +#ifdef Q_OS_MAC + QEXPECT_FAIL("", "This test fails on Mac OS X, see QTBUG-23059", Abort); +#endif QTRY_VERIFY(window.received(QEvent::Expose) > 1); QTRY_VERIFY(!window.isExposed()); } @@ -804,5 +808,36 @@ void tst_QWindow::mouseEventSequence() QCOMPARE(window.mouseSequenceSignature, QLatin1String("prprprpr")); } +void tst_QWindow::windowModality() +{ + qRegisterMetaType<Qt::WindowModality>("Qt::WindowModality"); + + QWindow window; + QSignalSpy spy(&window, SIGNAL(windowModalityChanged(Qt::WindowModality))); + + QCOMPARE(window.windowModality(), Qt::NonModal); + window.setWindowModality(Qt::NonModal); + QCOMPARE(window.windowModality(), Qt::NonModal); + QCOMPARE(spy.count(), 0); + + window.setWindowModality(Qt::WindowModal); + QCOMPARE(window.windowModality(), Qt::WindowModal); + QCOMPARE(spy.count(), 1); + window.setWindowModality(Qt::WindowModal); + QCOMPARE(window.windowModality(), Qt::WindowModal); + QCOMPARE(spy.count(), 1); + + window.setWindowModality(Qt::ApplicationModal); + QCOMPARE(window.windowModality(), Qt::ApplicationModal); + QCOMPARE(spy.count(), 2); + window.setWindowModality(Qt::ApplicationModal); + QCOMPARE(window.windowModality(), Qt::ApplicationModal); + QCOMPARE(spy.count(), 2); + + window.setWindowModality(Qt::NonModal); + QCOMPARE(window.windowModality(), Qt::NonModal); + QCOMPARE(spy.count(), 3); +} + #include <tst_qwindow.moc> QTEST_MAIN(tst_QWindow) diff --git a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp index f4cf586da12..26a68338a68 100644 --- a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp +++ b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp @@ -42,7 +42,7 @@ #include <QtTest/QtTest> #include <qmatrix.h> -#include <math.h> +#include <qmath.h> #include <qpolygon.h> Q_DECLARE_METATYPE(QRect) diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp index e8374b0cae5..38208d27c80 100644 --- a/tests/auto/gui/qopengl/tst_qopengl.cpp +++ b/tests/auto/gui/qopengl/tst_qopengl.cpp @@ -118,6 +118,7 @@ struct SharedResource : public QOpenGLSharedResource void freeResource(QOpenGLContext *context) { Q_ASSERT(context == QOpenGLContext::currentContext()); + Q_UNUSED(context) resource = 0; if (tracker) tracker->freeResourceCalls++; diff --git a/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp b/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp index c609b4a1ed6..a33e3cd13b0 100644 --- a/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp +++ b/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp @@ -47,6 +47,7 @@ #include <qabstracttextdocumentlayout.h> #include <qimage.h> #include <qtextobject.h> +#include <qfontmetrics.h> class tst_QAbstractTextDocumentLayout : public QObject { @@ -59,6 +60,7 @@ public: private slots: void getSetCheck(); void maximumBlockCount(); + void anchorAt(); }; tst_QAbstractTextDocumentLayout::tst_QAbstractTextDocumentLayout() @@ -152,5 +154,35 @@ void tst_QAbstractTextDocumentLayout::maximumBlockCount() QCOMPARE(layout.blockCount, 10); } +void tst_QAbstractTextDocumentLayout::anchorAt() +{ + QTextDocument doc; + doc.setHtml("<a href=\"link\">foo</a>"); + QAbstractTextDocumentLayout *documentLayout = doc.documentLayout(); + QTextBlock firstBlock = doc.begin(); + QTextLayout *layout = firstBlock.layout(); + layout->setPreeditArea(doc.toPlainText().length(), "xxx"); + + doc.setPageSize(QSizeF(1000, 1000)); + QFontMetrics metrics(layout->font()); + QPointF blockStart = documentLayout->blockBoundingRect(firstBlock).topLeft(); + + // anchorAt on start returns link + QRect linkBr = metrics.boundingRect("foo"); + QPointF linkPoint(linkBr.width() + blockStart.x(), (linkBr.height() / 2) + blockStart.y()); + QCOMPARE(documentLayout->anchorAt(linkPoint), QString("link")); + + // anchorAt() on top of preedit at end should not assert + QRect preeditBr = metrics.boundingRect(doc.toPlainText() + "xx"); + QPointF preeditPoint(preeditBr.width() + blockStart.x(), (preeditBr.height() / 2) + blockStart.y()); + QCOMPARE(documentLayout->anchorAt(preeditPoint), QString()); + + // preedit at start should not return link + layout->setPreeditArea(0, "xxx"); + preeditBr = metrics.boundingRect("xx"); + preeditPoint = QPointF(preeditBr.width() + blockStart.x(), (preeditBr.height() / 2) + blockStart.y()); + QCOMPARE(documentLayout->anchorAt(preeditPoint), QString()); +} + QTEST_MAIN(tst_QAbstractTextDocumentLayout) #include "tst_qabstracttextdocumentlayout.moc" diff --git a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro index 034d08fc8f6..c853aaa1000 100644 --- a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro +++ b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro @@ -11,4 +11,3 @@ wince* { } mac: CONFIG += insignificant_test # QTBUG-23062 -win32:CONFIG += insignificant_test # QTBUG-24193 diff --git a/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro b/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro index bb0d8e3c4a8..f5cf957722d 100644 --- a/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro +++ b/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro @@ -3,5 +3,3 @@ TARGET = tst_qfontmetrics QT += testlib SOURCES += tst_qfontmetrics.cpp RESOURCES += testfont.qrc - -win32:CONFIG += insignificant_test # QTBUG-24195 diff --git a/tests/auto/gui/text/qglyphrun/qglyphrun.pro b/tests/auto/gui/text/qglyphrun/qglyphrun.pro index 97b9806c117..acdff0584fb 100644 --- a/tests/auto/gui/text/qglyphrun/qglyphrun.pro +++ b/tests/auto/gui/text/qglyphrun/qglyphrun.pro @@ -10,5 +10,3 @@ wince* { } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } - -win32:CONFIG += insignificant_test # QTBUG-24196 diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp index a88e93c93ef..d566f0a20db 100644 --- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp @@ -105,7 +105,7 @@ private slots: void thaiIsolatedSaraAm(); void thaiWithZWJ(); - + void thaiMultipleVowels(); private: bool haveTestFonts; }; @@ -1325,5 +1325,27 @@ void tst_QTextScriptEngine::thaiWithZWJ() QCOMPARE((bool)e->layoutData->glyphLayout.attributes[i].dontPrint, (i == 1 || i == 3)); } +void tst_QTextScriptEngine::thaiMultipleVowels() +{ + QString s(QString::fromUtf8("ส")); + for (int i = 0; i < 100; i++) + s += QChar(0x0E47); // Add lots of "VOWEL SIGN MAI TAI KHU N/S-T" stacked on top of the character + s += QChar(0x200D); // Now add a zero width joiner (which adds a circle which is hidden) + for (int i = 0; i < 100; i++) + s += QChar(0x0E47); //Add lots of "VOWEL SIGN MAI TAI KHU N/S-T" stacked on top of the ZWJ + + for (int i = 0; i < 10; i++) + s += s; //Repeat the string to make it more likely to crash if we have a buffer overflow + QTextLayout layout(s); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QTextEngine *e = layout.engine(); + e->width(0, s.length()); //force itemize and shape + + // If we haven't crashed at this point, then the test has passed. +} + QTEST_MAIN(tst_QTextScriptEngine) #include "tst_qtextscriptengine.moc" diff --git a/tests/auto/network-settings.h b/tests/auto/network-settings.h index f2c12bc0929..4c36e2d3080 100644 --- a/tests/auto/network-settings.h +++ b/tests/auto/network-settings.h @@ -78,24 +78,12 @@ public: static bool compareReplyIMAP(QByteArray const& actual) { - QList<QByteArray> expected; - - // Mandriva; old test server - expected << QByteArray( "* OK [CAPABILITY IMAP4 IMAP4rev1 LITERAL+ ID STARTTLS LOGINDISABLED] " ) - .append(QtNetworkSettings::serverName().toAscii()) - .append(" Cyrus IMAP4 v2.3.11-Mandriva-RPM-2.3.11-6mdv2008.1 server ready\r\n"); - - // Ubuntu 10.04; new test server - expected << QByteArray( "* OK " ) - .append(QtNetworkSettings::serverLocalName().toAscii()) - .append(" Cyrus IMAP4 v2.2.13-Debian-2.2.13-19 server ready\r\n"); - - // Feel free to add more as needed - - Q_FOREACH (QByteArray const& ba, expected) { - if (ba == actual) { - return true; - } + // Server greeting may contain capability, version and server name + // But spec only requires "* OK" and "\r\n" + // Match against a prefix and postfix that covers all Cyrus versions + if (actual.startsWith("* OK ") + && actual.endsWith("server ready\r\n")) { + return true; } return false; @@ -103,27 +91,7 @@ public: static bool compareReplyIMAPSSL(QByteArray const& actual) { - QList<QByteArray> expected; - - // Mandriva; old test server - expected << QByteArray( "* OK [CAPABILITY IMAP4 IMAP4rev1 LITERAL+ ID AUTH=PLAIN SASL-IR] " ) - .append(QtNetworkSettings::serverName().toAscii()) - .append(" Cyrus IMAP4 v2.3.11-Mandriva-RPM-2.3.11-6mdv2008.1 server ready\r\n"); - - // Ubuntu 10.04; new test server - expected << QByteArray( "* OK " ) - .append(QtNetworkSettings::serverLocalName().toAscii()) - .append(" Cyrus IMAP4 v2.2.13-Debian-2.2.13-19 server ready\r\n"); - - // Feel free to add more as needed - - Q_FOREACH (QByteArray const& ba, expected) { - if (ba == actual) { - return true; - } - } - - return false; + return compareReplyIMAP(actual); } static bool compareReplyFtp(QByteArray const& actual) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 150f5c46167..185c3eedd80 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -399,6 +399,9 @@ private Q_SLOTS: void closeDuringDownload_data(); void closeDuringDownload(); + void ftpAuthentication_data(); + void ftpAuthentication(); + // NOTE: This test must be last! void parentingRepliesToTheApp(); private: @@ -6775,6 +6778,35 @@ void tst_QNetworkReply::closeDuringDownload() QTest::qWait(1000); //cancelling ftp takes some time, this avoids a warning caused by test's cleanup() destroying the connection cache before the abort is finished } + +void tst_QNetworkReply::ftpAuthentication_data() +{ + QTest::addColumn<QString>("referenceName"); + QTest::addColumn<QString>("url"); + QTest::addColumn<int>("error"); + + QTest::newRow("invalidPassword") << (testDataDir + "/rfc3252.txt") << "ftp://ftptest:invalid@" + QtNetworkSettings::serverName() + "/home/qt-test-server/ftp/qtest/rfc3252.txt" << int(QNetworkReply::AuthenticationRequiredError); + QTest::newRow("validPassword") << (testDataDir + "/rfc3252.txt") << "ftp://ftptest:password@" + QtNetworkSettings::serverName() + "/home/qt-test-server/ftp/qtest/rfc3252.txt" << int(QNetworkReply::NoError); +} + +void tst_QNetworkReply::ftpAuthentication() +{ + QFETCH(QString, referenceName); + QFETCH(QString, url); + QFETCH(int, error); + + QFile reference(referenceName); + QVERIFY(reference.open(QIODevice::ReadOnly)); + + QNetworkRequest request(url); + QNetworkReplyPtr reply; + runSimpleRequest(QNetworkAccessManager::GetOperation, request, reply); + + QCOMPARE(reply->url(), request.url()); + QCOMPARE(reply->error(), QNetworkReply::NetworkError(error)); +} + + // NOTE: This test must be last testcase in tst_qnetworkreply! void tst_QNetworkReply::parentingRepliesToTheApp() { diff --git a/tests/auto/network/socket/qlocalsocket/example/server/main.cpp b/tests/auto/network/socket/qlocalsocket/example/server/main.cpp index d066e4ef517..909bb6856f3 100644 --- a/tests/auto/network/socket/qlocalsocket/example/server/main.cpp +++ b/tests/auto/network/socket/qlocalsocket/example/server/main.cpp @@ -72,7 +72,7 @@ public: if (n == 0) break; qDebug() << "Read" << str; - if ("exit" == str) + if (!qstrcmp(str, "exit")) qApp->quit(); if (socket->write(str, 100) < 0) { diff --git a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp index ac27a621bbd..1f686085421 100644 --- a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp +++ b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp @@ -115,6 +115,10 @@ private slots: void serverAddress_data(); void serverAddress(); + + void qtbug6305_data() { serverAddress_data(); } + void qtbug6305(); + private: #ifndef QT_NO_BEARERMANAGEMENT QNetworkSession *networkSession; @@ -828,10 +832,28 @@ void tst_QTcpServer::serverAddress() QFETCH(QHostAddress, listenAddress); QFETCH(QHostAddress, serverAddress); QTcpServer server; + + // TODO: why does this QSKIP? if (!server.listen(listenAddress)) QSKIP(qPrintable(server.errorString())); QCOMPARE(server.serverAddress(), serverAddress); } +// on OS X, calling listen() multiple times would succeed each time, which is +// most definitely not wanted. +void tst_QTcpServer::qtbug6305() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + QFETCH(QHostAddress, listenAddress); + QTcpServer server; + QVERIFY2(server.listen(listenAddress), qPrintable(server.errorString())); + + QTcpServer server2; + QVERIFY(!server2.listen(listenAddress, server.serverPort())); // second listen should fail +} + QTEST_MAIN(tst_QTcpServer) #include "tst_qtcpserver.moc" diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index c53450eec6f..cab3d56d32f 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -309,9 +309,10 @@ void tst_QUdpSocket::broadcasting() QByteArray arr; arr.resize(serverSocket.pendingDatagramSize() + 1); QHostAddress host; quint16 port; + const int messageLength = int(strlen(message[i])); QCOMPARE((int) serverSocket.readDatagram(arr.data(), arr.size() - 1, &host, &port), - (int) strlen(message[i])); - arr.resize(strlen(message[i])); + messageLength); + arr.resize(messageLength); QCOMPARE(arr, QByteArray(message[i])); } while (serverSocket.hasPendingDatagrams()); } @@ -1202,6 +1203,7 @@ void tst_QUdpSocket::multicast_data() QHostAddress groupAddress = QHostAddress("239.255.118.62"); QHostAddress any6Address = QHostAddress(QHostAddress::AnyIPv6); QHostAddress group6Address = QHostAddress("FF01::114"); + QHostAddress dualAddress = QHostAddress(QHostAddress::Any); QTest::addColumn<QHostAddress>("bindAddress"); QTest::addColumn<bool>("bindResult"); @@ -1213,6 +1215,8 @@ void tst_QUdpSocket::multicast_data() QTest::newRow("valid bind, group ipv6 address") << any6Address << true << group6Address << true; QTest::newRow("valid bind, invalid group ipv6 address") << any6Address << true << any6Address << false; QTest::newRow("same bind, group ipv6 address") << group6Address << true << group6Address << true; + QTest::newRow("dual bind, group ipv4 address") << dualAddress << true << groupAddress << false; + QTest::newRow("dual bind, group ipv6 address") << dualAddress << true << group6Address << true; } void tst_QUdpSocket::multicast() diff --git a/tests/auto/other/networkselftest/tst_networkselftest.cpp b/tests/auto/other/networkselftest/tst_networkselftest.cpp index 8575b11fcaf..1935ef0c235 100644 --- a/tests/auto/other/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/other/networkselftest/tst_networkselftest.cpp @@ -864,7 +864,7 @@ static const char connect2[] = "\5\1\0\3\11localhost\0\25"; // Connect hostname static const char connect2a[] = "\5\1\0\3"; // just "Connect to hostname" static const char connected[] = "\5\0\0"; -#define QBA(x) (QByteArray::fromRawData(x, -1 + sizeof(x))) +#define QBA(x) (QByteArray::fromRawData(x, int(sizeof(x)) - 1)) void tst_NetworkSelfTest::socks5Proxy() { @@ -874,42 +874,48 @@ void tst_NetworkSelfTest::socks5Proxy() } ip4Address; ip4Address.data = qToBigEndian(serverIpAddress().toIPv4Address()); + const QByteArray handshakeNoAuthData = QByteArray(handshakeNoAuth, int(sizeof handshakeNoAuth) - 1); + const QByteArray handshakeOkNoAuthData = QByteArray(handshakeOkNoAuth, int(sizeof handshakeOkNoAuth) - 1); + const QByteArray connect1Data = QByteArray(connect1, int(sizeof connect1) - 1); + const QByteArray connectedData = QByteArray(connected, int(sizeof connected) - 1); + const QByteArray connect2Data = QByteArray(connect2, int(sizeof connect2) - 1); + netChat(1080, QList<Chat>() // IP address connection - << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) - << Chat::expect(QByteArray(handshakeOkNoAuth, -1 + sizeof handshakeOkNoAuth)) - << Chat::send(QByteArray(connect1, -1 + sizeof connect1)) - << Chat::expect(QByteArray(connected, -1 + sizeof connected)) + << Chat::send(handshakeNoAuthData) + << Chat::expect(handshakeOkNoAuthData) + << Chat::send(connect1Data) + << Chat::expect(connectedData) << Chat::expect("\1") // IPv4 address following << Chat::skipBytes(6) // the server's local address and port << ftpChat() // connect by IP << Chat::Reconnect - << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) - << Chat::expect(QByteArray(handshakeOkNoAuth, -1 + sizeof handshakeOkNoAuth)) + << Chat::send(handshakeNoAuthData) + << Chat::expect(handshakeOkNoAuthData) << Chat::send(QBA(connect1a) + QByteArray::fromRawData(ip4Address.buf, 4) + QBA(connect1b)) - << Chat::expect(QByteArray(connected, -1 + sizeof connected)) + << Chat::expect(connectedData) << Chat::expect("\1") // IPv4 address following << Chat::skipBytes(6) // the server's local address and port << ftpChat() // connect to "localhost" by hostname << Chat::Reconnect - << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) - << Chat::expect(QByteArray(handshakeOkNoAuth, -1 + sizeof handshakeOkNoAuth)) - << Chat::send(QByteArray(connect2, -1 + sizeof connect2)) - << Chat::expect(QByteArray(connected, -1 + sizeof connected)) + << Chat::send(handshakeNoAuthData) + << Chat::expect(handshakeOkNoAuthData) + << Chat::send(connect2Data) + << Chat::expect(connectedData) << Chat::expect("\1") // IPv4 address following << Chat::skipBytes(6) // the server's local address and port << ftpChat() // connect to server by its official name << Chat::Reconnect - << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) - << Chat::expect(QByteArray(handshakeOkNoAuth, -1 + sizeof handshakeOkNoAuth)) + << Chat::send(handshakeNoAuthData) + << Chat::expect(handshakeOkNoAuthData) << Chat::send(QBA(connect2a) + char(QtNetworkSettings::serverName().size()) + QtNetworkSettings::serverName().toLatin1() + QBA(connect1b)) - << Chat::expect(QByteArray(connected, -1 + sizeof connected)) + << Chat::expect(connectedData) << Chat::expect("\1") // IPv4 address following << Chat::skipBytes(6) // the server's local address and port << ftpChat() @@ -918,18 +924,25 @@ void tst_NetworkSelfTest::socks5Proxy() void tst_NetworkSelfTest::socks5ProxyAuth() { + const QByteArray handshakeNoAuthData = QByteArray(handshakeNoAuth, int(sizeof handshakeNoAuth) - 1); + const QByteArray connect1Data = QByteArray(connect1, int(sizeof connect1) - 1); + const QByteArray connectedData = QByteArray(connected, int(sizeof connected) - 1); + const QByteArray handshakeAuthNotOkData = QByteArray(handshakeAuthNotOk, int(sizeof(handshakeAuthNotOk)) - 1); + const QByteArray handshakeAuthPasswordData = QByteArray(handshakeAuthPassword, int(sizeof(handshakeAuthPassword)) - 1); + const QByteArray handshakeOkPasswdAuthData = QByteArray(handshakeOkPasswdAuth, int(sizeof(handshakeOkPasswdAuth)) - 1); + netChat(1081, QList<Chat>() // unauthenticated connect -- will get error - << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) - << Chat::expect(QByteArray(handshakeAuthNotOk, -1 + sizeof handshakeAuthNotOk)) + << Chat::send(handshakeNoAuthData) + << Chat::expect(handshakeAuthNotOkData) << Chat::RemoteDisconnect // now try to connect with authentication << Chat::Reconnect - << Chat::send(QByteArray(handshakeAuthPassword, -1 + sizeof handshakeAuthPassword)) - << Chat::expect(QByteArray(handshakeOkPasswdAuth, -1 + sizeof handshakeOkPasswdAuth)) - << Chat::send(QByteArray(connect1, -1 + sizeof connect1)) - << Chat::expect(QByteArray(connected, -1 + sizeof connected)) + << Chat::send(handshakeAuthPasswordData) + << Chat::expect(handshakeOkPasswdAuthData) + << Chat::send(connect1Data) + << Chat::expect(connectedData) << Chat::expect("\1") // IPv4 address following << Chat::skipBytes(6) // the server's local address and port << ftpChat() diff --git a/tests/auto/other/qaccessibility/qaccessibility.pro b/tests/auto/other/qaccessibility/qaccessibility.pro index 0019cc94c85..388e6ab29da 100644 --- a/tests/auto/other/qaccessibility/qaccessibility.pro +++ b/tests/auto/other/qaccessibility/qaccessibility.pro @@ -13,3 +13,8 @@ wince*: { } mac: CONFIG += insignificant_test # QTBUG-22812 + +win32 { + !*g++: include(../../../../src/3rdparty/iaccessible2/iaccessible2.pri) + LIBS += -loleacc -loleaut32 -lole32 +} diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 262d185bd1d..ee49d679f01 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -40,6 +40,18 @@ ****************************************************************************/ +#include <QtCore/qglobal.h> +#ifdef Q_OS_WIN +# include <QtCore/qt_windows.h> +# include <oleacc.h> +# include <servprov.h> +# include <winuser.h> +# ifndef Q_CC_MINGW +# include <Accessible2.h> +# include <AccessibleAction.h> +# include <AccessibleComponent.h> +# endif +#endif #include <QtTest/QtTest> #include <QtGui> #include <QtWidgets> @@ -269,6 +281,7 @@ private slots: void accessibleName(); void labelTest(); void accelerators(); + void bridgeTest(); protected slots: void onClicked(); @@ -2915,5 +2928,100 @@ void tst_QAccessibility::accelerators() QTestAccessibility::clearEvents(); } +void tst_QAccessibility::bridgeTest() +{ + // For now this is a simple test to see if the bridge is working at all. + // Ideally it should be extended to test all aspects of the bridge. +#ifdef Q_OS_WIN + // First, test MSAA part of bridge + QWidget *window = new QWidget; + QVBoxLayout *lay = new QVBoxLayout(window); + QPushButton *button = new QPushButton(tr("Push me"), window); + QLineEdit *le = new QLineEdit(window); + lay->addWidget(button); + lay->addWidget(le); + + window->show(); + QTest::qWaitForWindowShown(window); + + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(button); + QPoint buttonPos = button->mapToGlobal(QPoint(0,0)); + QRect buttonRect = iface->rect(); + QCOMPARE(buttonRect.topLeft(), buttonPos); + + + // All set, now test the bridge. + POINT pt; + pt.x = buttonRect.center().x(); + pt.y = buttonRect.center().y(); + IAccessible *iacc; + + VARIANT varChild; + HRESULT hr = ::AccessibleObjectFromPoint(pt, &iacc, &varChild); + QVERIFY(SUCCEEDED(hr)); + VARIANT varSELF; + varSELF.vt = VT_I4; + varSELF.lVal = 0; + + // **** Test get_accRole **** + VARIANT varRole; + hr = iacc->get_accRole(varSELF, &varRole); + QVERIFY(SUCCEEDED(hr)); + + QCOMPARE(varRole.vt, (VARTYPE)VT_I4); + QCOMPARE(varRole.lVal, (LONG)ROLE_SYSTEM_PUSHBUTTON); + + // **** Test accLocation **** + long x, y, w, h; + hr = iacc->accLocation(&x, &y, &w, &h, varSELF); + QCOMPARE(buttonRect, QRect(x, y, w, h)); + +#ifndef Q_CC_MINGW + // Test IAccessible2 part of bridge + IServiceProvider *pService = 0; + hr = iacc->QueryInterface(IID_IServiceProvider, (void **)&pService); + if (SUCCEEDED(hr)) { + IAccessible2 *pIA2 = 0; + hr = pService->QueryService(IID_IAccessible, IID_IAccessible2, (void**)&pIA2); + if (SUCCEEDED(hr) && pIA2) { + // The control supports IAccessible2. + // pIA2 is the reference to the accessible object's IAccessible2 interface. + + /***** Test IAccessibleComponent *****/ + IAccessibleComponent *ia2Component = 0; + hr = pIA2->QueryInterface(IID_IAccessibleComponent, (void**)&ia2Component); + QVERIFY(SUCCEEDED(hr)); + long x, y; + hr = ia2Component->get_locationInParent(&x, &y); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(button->pos(), QPoint(x, y)); + ia2Component->Release(); + + /***** Test IAccessibleAction *****/ + IAccessibleAction *ia2Action = 0; + hr = pIA2->QueryInterface(IID_IAccessibleAction, (void**)&ia2Action); + QVERIFY(SUCCEEDED(hr)); + QVERIFY(ia2Action); + long nActions; + ia2Action->nActions(&nActions); + QVERIFY(nActions >= 1); // "Press" and "SetFocus" + BSTR actionName; + ia2Action->get_name(0, &actionName); + QString name((QChar*)actionName); + QCOMPARE(name, QAccessibleActionInterface::pressAction()); + ia2Action->Release(); + + // Done testing + pIA2->Release(); + } + pService->Release(); + } +#endif + iacc->Release(); + + QTestAccessibility::clearEvents(); +#endif +} + QTEST_MAIN(tst_QAccessibility) #include "tst_qaccessibility.moc" diff --git a/tests/auto/printsupport/kernel/qprinter/qprinter.pro b/tests/auto/printsupport/kernel/qprinter/qprinter.pro index 7543e91f8c2..ebf8edea328 100644 --- a/tests/auto/printsupport/kernel/qprinter/qprinter.pro +++ b/tests/auto/printsupport/kernel/qprinter/qprinter.pro @@ -4,4 +4,3 @@ QT += printsupport widgets testlib SOURCES += tst_qprinter.cpp mac*:CONFIG+=insignificant_test -win32:CONFIG += insignificant_test # QTBUG-24191 diff --git a/tests/auto/printsupport/kernel/qprinterinfo/tst_qprinterinfo.cpp b/tests/auto/printsupport/kernel/qprinterinfo/tst_qprinterinfo.cpp index 48d38a8146e..404aa06399d 100644 --- a/tests/auto/printsupport/kernel/qprinterinfo/tst_qprinterinfo.cpp +++ b/tests/auto/printsupport/kernel/qprinterinfo/tst_qprinterinfo.cpp @@ -199,7 +199,8 @@ QString tst_QPrinterInfo::getOutputFromCommand(const QStringList& command) return QString(array); } #else - return QString(); + Q_UNUSED(command) + return QString(); #endif } diff --git a/tests/auto/shared/platforminputcontext.h b/tests/auto/shared/platforminputcontext.h index cddeca39452..2049ec7d614 100644 --- a/tests/auto/shared/platforminputcontext.h +++ b/tests/auto/shared/platforminputcontext.h @@ -55,13 +55,26 @@ public: m_lastQueries(Qt::ImhNone), m_action(QInputMethod::Click), m_cursorPosition(0), - m_lastEventType(QEvent::None) + m_lastEventType(QEvent::None), + m_setFocusObjectCallCount(0) {} virtual QRectF keyboardRect() const { return m_keyboardRect; } virtual bool isAnimating() const { return m_animating; } virtual void reset() { m_resetCallCount++; } - virtual void commit() { m_commitCallCount++; } + virtual void commit() { + m_commitCallCount++; + QInputMethodEvent commitEvent; + commitEvent.setCommitString(m_commitString); + if (qGuiApp->focusObject()) + qGuiApp->sendEvent(qGuiApp->focusObject(), &commitEvent); + else + qWarning("Test input context to commit without focused object"); + } + void setCommitString(const QString &commitString) + { + m_commitString = commitString; + } virtual void update(Qt::InputMethodQueries queries) { @@ -99,12 +112,18 @@ public: m_inputDirectionCallCount++; return Qt::LeftToRight; } + virtual void setFocusObject(QObject *object) + { + Q_UNUSED(object); + m_setFocusObjectCallCount++; + } bool m_animating; bool m_visible; int m_updateCallCount; int m_resetCallCount; int m_commitCallCount; + QString m_commitString; mutable int m_localeCallCount; mutable int m_inputDirectionCallCount; Qt::InputMethodQueries m_lastQueries; @@ -112,4 +131,5 @@ public: int m_cursorPosition; int m_lastEventType; QRectF m_keyboardRect; + int m_setFocusObjectCallCount; }; diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index 7acbf816f1b..626c5049f01 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -54,6 +54,8 @@ #include "tst_databases.h" +Q_DECLARE_METATYPE(QSqlDriver::NotificationSource) + QT_FORWARD_DECLARE_CLASS(QSqlDatabase) struct FieldDef; @@ -385,6 +387,7 @@ void tst_QSqlDatabase::populateTestTables(QSqlDatabase db) void tst_QSqlDatabase::initTestCase() { + qRegisterMetaType<QSqlDriver::NotificationSource>("QSqlDriver::NotificationSource"); dbs.open(); for (QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it) { @@ -2064,21 +2067,19 @@ void tst_QSqlDatabase::eventNotificationPSQL() QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); -#if defined(Q_OS_LINUX) - QSKIP( "Event support doesn't work on linux"); -#endif - QSqlQuery query(db); QString procedureName = qTableName("posteventProc", __FILE__); - + QString payload = "payload"; QSqlDriver &driver=*(db.driver()); QVERIFY_SQL(driver, subscribeToNotification(procedureName)); - QSignalSpy spy(db.driver(), SIGNAL(notification(const QString&))); - query.exec(QString("NOTIFY \"%1\"").arg(procedureName)); + QSignalSpy spy(db.driver(), SIGNAL(notification(const QString&,QSqlDriver::NotificationSource,const QVariant&))); + query.exec(QString("NOTIFY \"%1\", '%2'").arg(procedureName).arg(payload)); QCoreApplication::processEvents(); QCOMPARE(spy.count(), 1); QList<QVariant> arguments = spy.takeFirst(); - QVERIFY(arguments.at(0).toString() == procedureName); + QCOMPARE(arguments.at(0).toString(), procedureName); + QCOMPARE(qVariantValue<QSqlDriver::NotificationSource>(arguments.at(1)), QSqlDriver::SelfSource); + QCOMPARE(qvariant_cast<QVariant>(arguments.at(2)).toString(), payload); QVERIFY_SQL(driver, unsubscribeFromNotification(procedureName)); } diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 584fcb045a3..559afc4ef40 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -215,6 +215,8 @@ private slots: void QTBUG_21884(); void QTBUG_16967_data() { generic_data("QSQLITE"); } void QTBUG_16967(); //clean close + void QTBUG_23895_data() { generic_data("QSQLITE"); } + void QTBUG_23895(); //sqlite boolean type void sqlite_constraint_data() { generic_data("QSQLITE"); } void sqlite_constraint(); @@ -331,6 +333,7 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) << qTableName("bug5765", __FILE__) << qTableName("bug6852", __FILE__) << qTableName("bug21884", __FILE__) + << qTableName("bug23895", __FILE__) << qTableName( "qtest_lockedtable", __FILE__ ) << qTableName( "Planet", __FILE__ ) << qTableName( "task_250026", __FILE__ ) @@ -1651,6 +1654,24 @@ void tst_QSqlQuery::synonyms() QCOMPARE( rec.field( 2 ).name().toLower(), QString( "t_varchar" ) ); } +// This class is used to test protected QSqlResult methods +class ResultHelper: public QSqlResult +{ + +public: + ResultHelper(): QSqlResult( 0 ) {} // don't call, it's only for stupid compilers + + bool execBatch( bool bindArray = false ) + { + return QSqlResult::execBatch( bindArray ); + } + + QString boundValueName( int pos ) const + { + return QSqlResult::boundValueName( pos ); + } +}; + // It doesn't make sense to split this into several tests void tst_QSqlQuery::prepare_bind_exec() { @@ -1683,11 +1704,11 @@ void tst_QSqlQuery::prepare_bind_exec() QVERIFY_SQL( q, exec("set client_min_messages='warning'")); if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QTDS" ) ) - createQuery = "create table " + qtest_prepare + " (id int primary key, name nvarchar(200) null)"; + createQuery = "create table " + qtest_prepare + " (id int primary key, name nvarchar(200) null, name2 nvarchar(200) null)"; else if ( tst_Databases::isMySQL(db) && useUnicode ) - createQuery = "create table " + qtest_prepare + " (id int not null primary key, name varchar(200) character set utf8)"; + createQuery = "create table " + qtest_prepare + " (id int not null primary key, name varchar(200) character set utf8, name2 varchar(200) character set utf8)"; else - createQuery = "create table " + qtest_prepare + " (id int not null primary key, name varchar(200))"; + createQuery = "create table " + qtest_prepare + " (id int not null primary key, name varchar(200), name2 varchar(200))"; QVERIFY_SQL( q, exec( createQuery ) ); @@ -1756,7 +1777,7 @@ void tst_QSqlQuery::prepare_bind_exec() QCOMPARE( q.value( 0 ).toInt(), i ); QCOMPARE( q.value( 1 ).toString().trimmed(), values[ i ] ); QSqlRecord rInf = q.record(); - QCOMPARE(( int )rInf.count(), 2 ); + QCOMPARE(( int )rInf.count(), 3 ); QCOMPARE( rInf.field( 0 ).name().toUpper(), QString( "ID" ) ); QCOMPARE( rInf.field( 1 ).name().toUpper(), QString( "NAME" ) ); QVERIFY( !q.next() ); @@ -1764,33 +1785,90 @@ void tst_QSqlQuery::prepare_bind_exec() QVERIFY_SQL( q, exec( "DELETE FROM " + qtest_prepare ) ); + /*** Below we test QSqlQuery::boundValues() with position arguments. + * Due to the fact that the name of a positional argument is not + * specified by the Qt docs, we only test that the QMap contains + * the correct values and that QSqlResult::boundValueName returns + * the key that corrosponds to the correct value. ***/ QVERIFY( q.prepare( "insert into " + qtest_prepare + " (id, name) values (?, ?)" ) ); q.bindValue( 0, 0 ); q.bindValue( 1, values[ 0 ] ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 0 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[0] ); QVERIFY_SQL( q, exec() ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 0 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[0] ); + q.addBindValue( 1 ); q.addBindValue( values[ 1 ] ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 1 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[1] ); QVERIFY_SQL( q, exec() ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 1 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[1] ); + q.addBindValue( 2 ); q.addBindValue( values[ 2 ] ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[2] ); QVERIFY_SQL( q, exec() ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[2] ); + q.addBindValue( 3 ); q.addBindValue( values[ 3 ] ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 3 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[3] ); QVERIFY_SQL( q, exec() ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 3 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[3] ); + q.addBindValue( 4 ); q.addBindValue( values[ 4 ] ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 4 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[4] ); QVERIFY_SQL( q, exec() ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 4 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[4] ); + q.bindValue( 1, values[ 5 ] ); q.bindValue( 0, 5 ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 5 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[5] ); QVERIFY_SQL( q, exec() ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 5 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), values[5] ); + q.bindValue( 0, 6 ); q.bindValue( 1, QString() ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 6 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), QString() ); QVERIFY_SQL( q, exec() ); + QCOMPARE( q.boundValues().size(), 2 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 6 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), QString() ); if ( db.driver()->hasFeature( QSqlDriver::Unicode ) ) { q.bindValue( 0, 7 ); q.bindValue( 1, utf8str ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 7 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), utf8str ); QVERIFY_SQL( q, exec() ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(0) ].toInt(), 7 ); + QCOMPARE( q.boundValues()[ ((ResultHelper*)q.result())->boundValueName(1) ].toString(), utf8str ); } QVERIFY_SQL( q, exec( "SELECT * FROM " + qtest_prepare + " order by id" ) ); @@ -1839,6 +1917,20 @@ void tst_QSqlQuery::prepare_bind_exec() QVERIFY( !q.isActive() ); + QVERIFY( q.prepare( "insert into " + qtest_prepare + " (id, name, name2) values (:id, :name, :name)" ) ); + for ( i = 101; i < 103; ++i ) { + q.bindValue( ":id", i ); + q.bindValue( ":name", "name" ); + QVERIFY( q.exec() ); + } + + // Test for QTBUG-6420 + QVERIFY( q.exec( "select * from " + qtest_prepare + " where id > 100 order by id" ) ); + QVERIFY( q.next() ); + QCOMPARE( q.value(0).toInt(), 101 ); + QCOMPARE( q.value(1).toString(), QString("name") ); + QCOMPARE( q.value(2).toString(), QString("name") ); + } // end of SQLite scope } @@ -1947,18 +2039,6 @@ void tst_QSqlQuery::invalidQuery() QVERIFY( !q.next() ); } -class ResultHelper: public QSqlResult -{ - -public: - ResultHelper(): QSqlResult( 0 ) {} // don't call, it's only for stupid compilers - - bool execBatch( bool bindArray = false ) - { - return QSqlResult::execBatch( bindArray ); - } -}; - void tst_QSqlQuery::batchExec() { QFETCH( QString, dbName ); @@ -3187,6 +3267,64 @@ void tst_QSqlQuery::QTBUG_16967() } } +/** + * In SQLite when a boolean value is bound to a placeholder, it should be converted + * into integer 0/1 rather than text "false"/"true". According to documentation, + * SQLite does not have separate Boolean storage class. Instead, Boolean values are + * stored as integers. + */ +void tst_QSqlQuery::QTBUG_23895() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QSqlQuery q(db); + + QString tableName(qTableName("bug23895", __FILE__ )); + q.prepare("create table " + tableName + "(id integer primary key, val1 bool, val2 boolean)"); + QVERIFY_SQL(q, exec()); + q.prepare("insert into " + tableName + "(id, val1, val2) values(?, ?, ?);"); + q.addBindValue(1); + q.addBindValue(true); + q.addBindValue(false); + QVERIFY_SQL(q, exec()); + + QString sql="select * from " + tableName; + QVERIFY_SQL(q, exec(sql)); + QVERIFY_SQL(q, next()); + + QCOMPARE(q.record().field(0).type(), QVariant::Int); + QCOMPARE(q.value(0).type(), QVariant::LongLong); + QCOMPARE(q.value(0).toInt(), 1); + QCOMPARE(q.record().field(1).type(), QVariant::Bool); + QCOMPARE(q.value(1).type(), QVariant::LongLong); + QCOMPARE(q.value(1).toBool(), true); + QCOMPARE(q.record().field(2).type(), QVariant::Bool); + QCOMPARE(q.value(2).type(), QVariant::LongLong); + QCOMPARE(q.value(2).toBool(), false); + + q.prepare("insert into " + tableName + "(id, val1, val2) values(?, ?, ?);"); + q.addBindValue(2); + q.addBindValue(false); + q.addBindValue(false); + QVERIFY_SQL(q, exec()); + + sql="select * from " + tableName + " where val1"; + QVERIFY_SQL(q, exec(sql)); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toInt(), 1); + QVERIFY(!q.next()); + + sql="select * from " + tableName + " where not val2"; + QVERIFY_SQL(q, exec(sql)); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toInt(), 1); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toInt(), 2); + QVERIFY(!q.next()); +} + void tst_QSqlQuery::oraOCINumber() { QFETCH( QString, dbName ); diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp index afe2c59144f..2cea8b35465 100644 --- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp @@ -133,6 +133,9 @@ private slots: void insertBeforeDelete_data() { generic_data(); } void insertBeforeDelete(); + + void invalidFilterAndHeaderData_data() { generic_data(); } + void invalidFilterAndHeaderData(); //QTBUG-23879 private: void generic_data(const QString& engine=QString()); void generic_data_with_strategies(const QString& engine=QString()); @@ -1681,5 +1684,25 @@ void tst_QSqlTableModel::insertBeforeDelete() QCOMPARE(model.rowCount(), 5); } +void tst_QSqlTableModel::invalidFilterAndHeaderData() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QSqlTableModel model(0, db); + model.setTable(test); + model.setEditStrategy(QSqlTableModel::OnManualSubmit); + QVERIFY_SQL(model, select()); + QVERIFY_SQL(model, setHeaderData(0, Qt::Horizontal, "id")); + QVERIFY_SQL(model, setHeaderData(1, Qt::Horizontal, "name")); + QVERIFY_SQL(model, setHeaderData(2, Qt::Horizontal, "title")); + + model.setFilter("some nonsense"); + + QVariant v = model.headerData(0, Qt::Horizontal, Qt::SizeHintRole); + QVERIFY(!v.isValid()); +} + QTEST_MAIN(tst_QSqlTableModel) #include "tst_qsqltablemodel.moc" diff --git a/tests/auto/testlib/selftests/differentexec/tst_differentexec.cpp b/tests/auto/testlib/selftests/differentexec/tst_differentexec.cpp index 91b14e5051a..f32a5e7cd5e 100644 --- a/tests/auto/testlib/selftests/differentexec/tst_differentexec.cpp +++ b/tests/auto/testlib/selftests/differentexec/tst_differentexec.cpp @@ -76,7 +76,7 @@ private slots: int main() { - char *argv[] = {"appName", "slotName"}; + char *argv[] = { const_cast<char *>("appName"), const_cast<char *>("slotName") }; int argc = 2; tst_TestA testA; diff --git a/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp b/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp index 20bfc2228a2..73de6df5f3d 100644 --- a/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp +++ b/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp @@ -65,7 +65,7 @@ void tst_StrCmp::compareCharStars() const QCOMPARE(str1, "foo"); QCOMPARE(str1, str1); - char *str2 = "foo"; + char *str2 = const_cast<char *>("foo"); QCOMPARE("foo", str2); QCOMPARE(str2, "foo"); QCOMPARE(str2, str2); @@ -88,8 +88,8 @@ void tst_StrCmp::compareByteArray() const QCOMPARE(ba.constData(), "bar"); QCOMPARE(ba.constData(), "foo"); - char *bar = "bar"; - char *foo = "foo"; + char *bar = const_cast<char *>("bar"); + char *foo = const_cast<char *>("foo"); QEXPECT_FAIL("", "Next test should fail", Continue); QCOMPARE(ba.data(), bar); diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 97458abfbf5..26ccd826cab 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -135,7 +135,7 @@ static QList<QByteArray> splitLines(QByteArray ba) if (index == -1) { continue; } - int end = line.indexOf('"', index + strlen(markers[j][0])); + const int end = line.indexOf('"', index + int(strlen(markers[j][0]))); if (end == -1) { continue; } @@ -686,11 +686,12 @@ QString extractXmlAttribute(const QString &line, const char *attribute) int index = line.indexOf(attribute); if (index == -1) return QString(); - int end = line.indexOf('"', index + strlen(attribute)); + const int attributeLength = int(strlen(attribute)); + const int end = line.indexOf('"', index + attributeLength); if (end == -1) return QString(); - QString result = line.mid(index + strlen(attribute), end - index - strlen(attribute)); + const QString result = line.mid(index + attributeLength, end - index - attributeLength); if (result.isEmpty()) return ""; // ensure empty but not null return result; diff --git a/tests/auto/tools/qmake/testcompiler.cpp b/tests/auto/tools/qmake/testcompiler.cpp index 4e5dc26eac3..3b77b1ec63e 100644 --- a/tests/auto/tools/qmake/testcompiler.cpp +++ b/tests/auto/tools/qmake/testcompiler.cpp @@ -128,7 +128,7 @@ TestCompiler::~TestCompiler() bool TestCompiler::errorOut() { - qDebug(qPrintable(testOutput_.join("\n"))); + qDebug("%s", qPrintable(testOutput_.join(QStringLiteral("\n")))); return false; } diff --git a/tests/auto/tools/uic/baseline/tabbedbrowser.ui b/tests/auto/tools/uic/baseline/tabbedbrowser.ui index 7164fb72711..382f49fe5ef 100644 --- a/tests/auto/tools/uic/baseline/tabbedbrowser.ui +++ b/tests/auto/tools/uic/baseline/tabbedbrowser.ui @@ -99,7 +99,7 @@ <string/> </property> <property name="icon" > - <iconset resource="assistant.qrc" >:/trolltech/assistant/images/close.png</iconset> + <iconset resource="assistant.qrc" >:/qt-project.org/assistant/images/close.png</iconset> </property> <property name="autoRaise" > <bool>true</bool> @@ -130,7 +130,7 @@ <string>Previous</string> </property> <property name="icon" > - <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/previous.png</iconset> + <iconset resource="assistant.qrc" >:/qt-project.org/assistant/images/win/previous.png</iconset> </property> <property name="toolButtonStyle" > <enum>Qt::ToolButtonTextBesideIcon</enum> @@ -152,7 +152,7 @@ <string>Next</string> </property> <property name="icon" > - <iconset resource="assistant.qrc" >:/trolltech/assistant/images/win/next.png</iconset> + <iconset resource="assistant.qrc" >:/qt-project.org/assistant/images/win/next.png</iconset> </property> <property name="toolButtonStyle" > <enum>Qt::ToolButtonTextBesideIcon</enum> @@ -194,7 +194,7 @@ </size> </property> <property name="text" > - <string><img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped</string> + <string><img src=":/qt-project.org/assistant/images/wrap.png">&nbsp;Search wrapped</string> </property> <property name="textFormat" > <enum>Qt::RichText</enum> diff --git a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h index 1e99c413125..f2c1f1e3e5c 100644 --- a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h +++ b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h @@ -125,7 +125,7 @@ public: hboxLayout->setObjectName(QStringLiteral("hboxLayout")); toolClose = new QToolButton(frameFind); toolClose->setObjectName(QStringLiteral("toolClose")); - const QIcon icon = QIcon(QString::fromUtf8(":/trolltech/assistant/images/close.png")); + const QIcon icon = QIcon(QString::fromUtf8(":/qt-project.org/assistant/images/close.png")); toolClose->setIcon(icon); toolClose->setAutoRaise(true); @@ -144,7 +144,7 @@ public: toolPrevious = new QToolButton(frameFind); toolPrevious->setObjectName(QStringLiteral("toolPrevious")); - const QIcon icon1 = QIcon(QString::fromUtf8(":/trolltech/assistant/images/win/previous.png")); + const QIcon icon1 = QIcon(QString::fromUtf8(":/qt-project.org/assistant/images/win/previous.png")); toolPrevious->setIcon(icon1); toolPrevious->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); toolPrevious->setAutoRaise(true); @@ -154,7 +154,7 @@ public: toolNext = new QToolButton(frameFind); toolNext->setObjectName(QStringLiteral("toolNext")); toolNext->setMinimumSize(QSize(0, 0)); - const QIcon icon2 = QIcon(QString::fromUtf8(":/trolltech/assistant/images/win/next.png")); + const QIcon icon2 = QIcon(QString::fromUtf8(":/qt-project.org/assistant/images/win/next.png")); toolNext->setIcon(icon2); toolNext->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); toolNext->setAutoRaise(true); @@ -204,7 +204,7 @@ public: toolNext->setText(QApplication::translate("TabbedBrowser", "Next", 0, QApplication::UnicodeUTF8)); checkCase->setText(QApplication::translate("TabbedBrowser", "Case Sensitive", 0, QApplication::UnicodeUTF8)); checkWholeWords->setText(QApplication::translate("TabbedBrowser", "Whole words", 0, QApplication::UnicodeUTF8)); - labelWrapped->setText(QApplication::translate("TabbedBrowser", "<img src=\":/trolltech/assistant/images/wrap.png\"> Search wrapped", 0, QApplication::UnicodeUTF8)); + labelWrapped->setText(QApplication::translate("TabbedBrowser", "<img src=\":/qt-project.org/assistant/images/wrap.png\"> Search wrapped", 0, QApplication::UnicodeUTF8)); } // retranslateUi }; diff --git a/tests/auto/widgets/graphicsview/qgraphicslayoutitem/tst_qgraphicslayoutitem.cpp b/tests/auto/widgets/graphicsview/qgraphicslayoutitem/tst_qgraphicslayoutitem.cpp index acb9155ca84..4f15f96cba1 100644 --- a/tests/auto/widgets/graphicsview/qgraphicslayoutitem/tst_qgraphicslayoutitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicslayoutitem/tst_qgraphicslayoutitem.cpp @@ -287,17 +287,15 @@ void tst_QGraphicsLayoutItem::setMaximumSize() void tst_QGraphicsLayoutItem::setMinimumSize_data() { QTest::addColumn<QSizeF>("size"); - QTest::addColumn<QSizeF>("outputSize"); - QTest::newRow("-1") << QSizeF(-1, -1) << QSizeF(0, 0); - QTest::newRow("0") << QSizeF(0, 0) << QSizeF(0, 0); - QTest::newRow("10") << QSizeF(10, 10) << QSizeF(10, 10); + QTest::newRow("-1") << QSizeF(-1, -1); + QTest::newRow("0") << QSizeF(0, 0); + QTest::newRow("10") << QSizeF(10, 10); } // void setMinimumSize(QSizeF const& size) public void tst_QGraphicsLayoutItem::setMinimumSize() { QFETCH(QSizeF, size); - QFETCH(QSizeF, outputSize); SubQGraphicsLayoutItem layoutItem; QSizeF oldSize = layoutItem.minimumSize(); diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index d7b1ef9199f..df529c60957 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -3766,6 +3766,7 @@ void tst_QGraphicsScene::inputMethod() QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); inputContext.m_resetCallCount = 0; + inputContext.m_commitCallCount = 0; scene.addItem(item); QInputMethodEvent event; @@ -3784,7 +3785,7 @@ void tst_QGraphicsScene::inputMethod() scene.setFocusItem(0); // the input context is reset twice, once because an item has lost focus and again because // the Qt::WA_InputMethodEnabled flag is cleared because no item has focus. - QCOMPARE(inputContext.m_resetCallCount, callFocusItem ? 2 : 0); + QCOMPARE(inputContext.m_resetCallCount + inputContext.m_commitCallCount, callFocusItem ? 2 : 0); QCOMPARE(item->queryCalls, callFocusItem ? 1 : 0); // verify that value is unaffected item->eventCalls = 0; diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index ee7ec7ba579..18389777490 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -3712,7 +3712,7 @@ void tst_QGraphicsView::render() view.show(); QTest::qWaitForWindowShown(&view); QApplication::processEvents(); - QTRY_VERIFY(view.painted > 0); + QTRY_VERIFY(view.painted); RenderTester *r1 = new RenderTester(QRectF(0, 0, 50, 50)); RenderTester *r2 = new RenderTester(QRectF(50, 50, 50, 50)); @@ -4187,21 +4187,22 @@ void tst_QGraphicsView::inputContextReset() item1->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod); inputContext.m_resetCallCount = 0; + inputContext.m_commitCallCount = 0; scene.addItem(item1); QCOMPARE(inputContext.m_resetCallCount, 0); + QCOMPARE(inputContext.m_commitCallCount, 0); - inputContext.m_resetCallCount = 0; scene.setFocusItem(item1); QCOMPARE(scene.focusItem(), (QGraphicsItem *)item1); QVERIFY(view.testAttribute(Qt::WA_InputMethodEnabled)); QCOMPARE(inputContext.m_resetCallCount, 0); + QCOMPARE(inputContext.m_commitCallCount, 0); - inputContext.m_resetCallCount = 0; scene.setFocusItem(0); // the input context is reset twice, once because an item has lost focus and again because // the Qt::WA_InputMethodEnabled flag is cleared because no item has focus. // QEXPECT_FAIL("", "QTBUG-22454", Abort); - QCOMPARE(inputContext.m_resetCallCount, 2); + QCOMPARE(inputContext.m_resetCallCount + inputContext.m_commitCallCount, 2); // introduce another item that is focusable but does not accept input methods QGraphicsItem *item2 = new QGraphicsRectItem; @@ -4209,17 +4210,19 @@ void tst_QGraphicsView::inputContextReset() scene.addItem(item2); inputContext.m_resetCallCount = 0; + inputContext.m_commitCallCount = 0; scene.setFocusItem(item2); QCOMPARE(inputContext.m_resetCallCount, 0); + QCOMPARE(inputContext.m_commitCallCount, 0); - inputContext.m_resetCallCount = 0; scene.setFocusItem(item1); QCOMPARE(inputContext.m_resetCallCount, 0); + QCOMPARE(inputContext.m_commitCallCount, 0); // test changing between between items that accept input methods. item2->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod); scene.setFocusItem(item2); - QCOMPARE(inputContext.m_resetCallCount, 1); + QCOMPARE(inputContext.m_resetCallCount + inputContext.m_commitCallCount, 1); } void tst_QGraphicsView::indirectPainting() diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index be7c58f20bb..c6c81314221 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -238,10 +238,9 @@ public: openedEditor = new QWidget(parent); return openedEditor; } - void destroyEditor(QWidget *editor, const QModelIndex &index) const + void destroyEditor(QWidget *editor, const QModelIndex &) const { calledVirtualDtor = true; - // QAbstractItemDelegate::destroyEditor(editor,index); editor->deleteLater(); } diff --git a/tests/auto/widgets/kernel/qicon/tst_qicon.cpp b/tests/auto/widgets/kernel/qicon/tst_qicon.cpp index 4a9ab93921e..cca0887a21a 100644 --- a/tests/auto/widgets/kernel/qicon/tst_qicon.cpp +++ b/tests/auto/widgets/kernel/qicon/tst_qicon.cpp @@ -374,32 +374,32 @@ void tst_QIcon::detach() void tst_QIcon::addFile() { QIcon icon; - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png")); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-32.png")); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-128.png")); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-16.png"), QSize(), QIcon::Selected); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-32.png"), QSize(), QIcon::Selected); - icon.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-128.png"), QSize(), QIcon::Selected); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png")); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-32.png")); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-128.png")); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png"), QSize(), QIcon::Selected); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-32.png"), QSize(), QIcon::Selected); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-128.png"), QSize(), QIcon::Selected); #ifndef Q_OS_WINCE QVERIFY(icon.pixmap(16, QIcon::Normal).toImage() == - QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png")).toImage()); + QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png")).toImage()); QVERIFY(icon.pixmap(32, QIcon::Normal).toImage() == - QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-32.png")).toImage()); + QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-32.png")).toImage()); QVERIFY(icon.pixmap(128, QIcon::Normal).toImage() == - QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-128.png")).toImage()); + QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-128.png")).toImage()); QVERIFY(icon.pixmap(16, QIcon::Selected).toImage() == - QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-16.png")).toImage()); + QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png")).toImage()); QVERIFY(icon.pixmap(32, QIcon::Selected).toImage() == - QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-32.png")).toImage()); + QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-32.png")).toImage()); QVERIFY(icon.pixmap(128, QIcon::Selected).toImage() == - QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-128.png")).toImage()); + QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-128.png")).toImage()); #else // WinCE only includes the 16x16 images for size reasons QVERIFY(icon.pixmap(16, QIcon::Normal).toImage() == - QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png")).toImage()); + QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png")).toImage()); QVERIFY(icon.pixmap(16, QIcon::Selected).toImage() == - QPixmap(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-save-16.png")).toImage()); + QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png")).toImage()); #endif } @@ -436,7 +436,7 @@ void tst_QIcon::availableSizes() { // we try to load an icon from resources - QIcon icon(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png")); + QIcon icon(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png")); QList<QSize> availableSizes = icon.availableSizes(); QCOMPARE(availableSizes.size(), 1); QCOMPARE(availableSizes.at(0), QSize(16, 16)); @@ -445,7 +445,7 @@ void tst_QIcon::availableSizes() { // load an icon from binary data. QPixmap pix; - QFile file(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png")); + QFile file(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png")); QVERIFY(file.open(QIODevice::ReadOnly)); uchar *data = file.map(0, file.size()); QVERIFY(data != 0); @@ -617,12 +617,12 @@ void tst_QIcon::fromTheme() void tst_QIcon::task223279_inconsistentAddFile() { QIcon icon1; - icon1.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png")); + icon1.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png")); icon1.addFile(QLatin1String("IconThatDoesntExist"), QSize(32, 32)); QPixmap pm1 = icon1.pixmap(32, 32); QIcon icon2; - icon2.addFile(QLatin1String(":/trolltech/styles/commonstyle/images/standardbutton-open-16.png")); + icon2.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png")); icon2.addFile(QLatin1String("IconThatDoesntExist")); QPixmap pm2 = icon1.pixmap(32, 32); diff --git a/tests/auto/widgets/widgets/qlineedit/qlineedit.pro b/tests/auto/widgets/widgets/qlineedit/qlineedit.pro index 83f93f0ba04..74e23338019 100644 --- a/tests/auto/widgets/widgets/qlineedit/qlineedit.pro +++ b/tests/auto/widgets/widgets/qlineedit/qlineedit.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qlineedit -QT += gui-private core-private widgets testlib +QT += gui-private core-private widgets widgets-private testlib SOURCES += tst_qlineedit.cpp # QTBUG-24518 - unstable test diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index a6860006c22..06bf929e4b7 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -62,6 +62,8 @@ #endif #include <qlineedit.h> +#include <private/qlineedit_p.h> +#include <private/qwidgetlinecontrol_p.h> #include <qmenu.h> #include <qlayout.h> #include <qspinbox.h> @@ -72,6 +74,10 @@ #include "qplatformdefs.h" +#include "../../../shared/platforminputcontext.h" +#include <private/qinputmethod_p.h> + + QT_BEGIN_NAMESPACE class QPainter; QT_END_NAMESPACE @@ -275,7 +281,6 @@ private slots: void selectAndCursorPosition(); void inputMethod(); void inputMethodSelection(); - void inputMethodTentativeCommit(); protected slots: void editingFinished(); @@ -301,6 +306,7 @@ private: int newCursorPos; QLineEdit *testWidget; int m_keyboardScheme; + PlatformInputContext m_platformInputContext; }; typedef QList<int> IntList; @@ -357,21 +363,23 @@ void tst_QLineEdit::initTestCase() testWidget->resize(200,50); testWidget->show(); + QTest::qWaitForWindowShown(testWidget); QApplication::setActiveWindow(testWidget); -#ifdef Q_WS_X11 - // to be safe and avoid failing setFocus with window managers - qt_x11_wait_for_window_manager(testWidget); -#endif QTRY_VERIFY(testWidget->hasFocus()); changed_count = 0; edited_count = 0; selection_count = 0; + + QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = &m_platformInputContext; } void tst_QLineEdit::cleanupTestCase() { delete testWidget; + QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = 0; } void tst_QLineEdit::init() @@ -659,14 +667,14 @@ void tst_QLineEdit::inputMask_data() QTest::newRow("nul 2") << QString() << QString(); // try different masks - QTest::newRow("mask 1") << QString("000.000.000.000") << QString("000.000.000.000; "); + QTest::newRow("mask 1") << QString("000.000.000.000") << QString("000.000.000.000"); QTest::newRow("mask 2") << QString("000.000.000.000;#") << QString("000.000.000.000;#"); - QTest::newRow("mask 3") << QString("AAA.aa.999.###;") << QString("AAA.aa.999.###; "); - QTest::newRow("mask 4") << QString(">abcdef<GHIJK") << QString(">abcdef<GHIJK; "); + QTest::newRow("mask 3") << QString("AAA.aa.999.###;") << QString("AAA.aa.999.###"); + QTest::newRow("mask 4") << QString(">abcdef<GHIJK") << QString(">abcdef<GHIJK"); // set an invalid input mask... // the current behaviour is that this exact (faulty) string is returned. - QTest::newRow("invalid") << QString("ABCDEFGHIKLMNOP;") << QString("ABCDEFGHIKLMNOP; "); + QTest::newRow("invalid") << QString("ABCDEFGHIKLMNOP;") << QString("ABCDEFGHIKLMNOP"); // verify that we can unset the mask again QTest::newRow("unset") << QString("") << QString(); @@ -1664,8 +1672,16 @@ void tst_QLineEdit::passwordEchoOnEdit() void tst_QLineEdit::passwordEchoDelay() { - if (qGuiApp->styleHints()->passwordMaskDelay() <= 0) - QSKIP("No mask delay in use"); + int delay = qGuiApp->styleHints()->passwordMaskDelay(); +#if defined QT_BUILD_INTERNAL + QLineEditPrivate *priv = QLineEditPrivate::get(testWidget); + QWidgetLineControl *control = priv->control; + control->m_passwordMaskDelayOverride = 200; + delay = 200; +#endif + if (delay <= 0) + QSKIP("Platform not defining echo delay and overriding only possible in internal build"); + QStyleOptionFrameV2 opt; QChar fillChar = testWidget->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, testWidget); @@ -1685,7 +1701,7 @@ void tst_QLineEdit::passwordEchoDelay() QCOMPARE(testWidget->displayText(), QString(4, fillChar)); QTest::keyPress(testWidget, '4'); QCOMPARE(testWidget->displayText(), QString(4, fillChar) + QLatin1Char('4')); - QTest::qWait(qGuiApp->styleHints()->passwordMaskDelay()); + QTest::qWait(delay); QTRY_COMPARE(testWidget->displayText(), QString(5, fillChar)); QTest::keyPress(testWidget, '5'); QCOMPARE(testWidget->displayText(), QString(5, fillChar) + QLatin1Char('5')); @@ -3828,6 +3844,23 @@ void tst_QLineEdit::inputMethod() testWidget->setEnabled(false); QApplication::sendEvent(testWidget, &queryEvent); QCOMPARE(queryEvent.value(Qt::ImEnabled).toBool(), false); + testWidget->setEnabled(true); + + // removing focus allows input method to commit preedit + testWidget->setText(""); + testWidget->activateWindow(); + QTRY_VERIFY(testWidget->hasFocus()); + QTRY_COMPARE(qApp->focusObject(), testWidget); + + m_platformInputContext.setCommitString("text"); + m_platformInputContext.m_commitCallCount = 0; + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent preeditEvent("preedit text", attributes); + QApplication::sendEvent(testWidget, &preeditEvent); + + testWidget->clearFocus(); + QCOMPARE(m_platformInputContext.m_commitCallCount, 1); + QCOMPARE(testWidget->text(), QString("text")); } void tst_QLineEdit::inputMethodSelection() @@ -3866,37 +3899,6 @@ void tst_QLineEdit::inputMethodSelection() QCOMPARE(selectionSpy.count(), 3); } -void tst_QLineEdit::inputMethodTentativeCommit() -{ - // test that basic tentative commit gets to text property on preedit state - QList<QInputMethodEvent::Attribute> attributes; - QInputMethodEvent event("test", attributes); - event.setTentativeCommitString("test"); - QApplication::sendEvent(testWidget, &event); - QCOMPARE(testWidget->text(), QString("test")); - - // tentative commit not allowed present in surrounding text - QInputMethodQueryEvent queryEvent(Qt::ImSurroundingText); - QApplication::sendEvent(testWidget, &queryEvent); - QCOMPARE(queryEvent.value(Qt::ImSurroundingText).toString(), QString("")); - - // if text with tentative commit does not validate, not allowed to be part of text property - testWidget->setText(""); // ensure input state is reset - QValidator *validator = new QIntValidator(0, 100); - testWidget->setValidator(validator); - QApplication::sendEvent(testWidget, &event); - QCOMPARE(testWidget->text(), QString("")); - testWidget->setValidator(0); - delete validator; - - // text remains when focus is removed - testWidget->setText(""); // ensure input state is reset - QApplication::sendEvent(testWidget, &event); - QFocusEvent lostFocus(QEvent::FocusOut); - QApplication::sendEvent(testWidget, &lostFocus); - QCOMPARE(testWidget->text(), QString("test")); -} - QTEST_MAIN(tst_QLineEdit) #include "tst_qlineedit.moc" diff --git a/tests/auto/widgets/widgets/qtextedit/qtextedit.pro b/tests/auto/widgets/widgets/qtextedit/qtextedit.pro index 85658c222e3..1c2821b2897 100644 --- a/tests/auto/widgets/widgets/qtextedit/qtextedit.pro +++ b/tests/auto/widgets/widgets/qtextedit/qtextedit.pro @@ -1,7 +1,7 @@ CONFIG += testcase TARGET = tst_qtextedit -QT += widgets widgets-private gui-private testlib +QT += widgets widgets-private gui-private core-private testlib INCLUDEPATH += ../ HEADERS += diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index 249e9d7fbe4..9c5a3dbed7a 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -62,6 +62,10 @@ #include <qabstracttextdocumentlayout.h> #include <qtextdocumentfragment.h> +#include "../../../shared/platforminputcontext.h" +#include <private/qinputmethod_p.h> + + //Used in copyAvailable typedef QPair<Qt::Key, Qt::KeyboardModifier> keyPairType; typedef QList<keyPairType> pairListType; @@ -96,6 +100,8 @@ public: tst_QTextEdit(); public slots: + void initTestCase(); + void cleanupTestCase(); void init(); void cleanup(); private slots: @@ -211,6 +217,7 @@ private: QTextEdit *ed; qreal rootFrameMargin; + PlatformInputContext m_platformInputContext; }; bool tst_QTextEdit::nativeClipboardWorking() @@ -372,6 +379,18 @@ public: tst_QTextEdit::tst_QTextEdit() {} +void tst_QTextEdit::initTestCase() +{ + QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = &m_platformInputContext; +} + +void tst_QTextEdit::cleanupTestCase() +{ + QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = 0; +} + void tst_QTextEdit::init() { #ifdef Q_OS_WINCE //disable magic for WindowsCE @@ -2360,6 +2379,8 @@ void tst_QTextEdit::bidiLogicalMovement() void tst_QTextEdit::inputMethodEvent() { + ed->show(); + // test that text change with an input method event triggers change signal QSignalSpy spy(ed, SIGNAL(textChanged())); @@ -2367,14 +2388,23 @@ void tst_QTextEdit::inputMethodEvent() event.setCommitString("text"); QApplication::sendEvent(ed, &event); QCOMPARE(spy.count(), 1); - spy.clear(); + QCOMPARE(ed->toPlainText(), QString("text")); + // test that input method gets chance to commit preedit when removing focus + ed->setText(""); + QApplication::setActiveWindow(ed); + QTRY_VERIFY(QApplication::focusWindow()); + QCOMPARE(qApp->focusObject(), ed); + + m_platformInputContext.setCommitString("text"); + m_platformInputContext.m_commitCallCount = 0; QList<QInputMethodEvent::Attribute> attributes; - QInputMethodEvent event2("preedit", attributes); - event2.setTentativeCommitString("string"); - QApplication::sendEvent(ed, &event2); - QCOMPARE(spy.count(), 1); - QCOMPARE(ed->toPlainText(), QString("textstring")); + QInputMethodEvent preeditEvent("preedit text", attributes); + QApplication::sendEvent(ed, &preeditEvent); + + ed->clearFocus(); + QCOMPARE(m_platformInputContext.m_commitCallCount, 1); + QCOMPARE(ed->toPlainText(), QString("text")); } void tst_QTextEdit::inputMethodSelection() diff --git a/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp b/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp index f93d979169f..d8b193f5c88 100644 --- a/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp +++ b/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp @@ -118,9 +118,9 @@ class ServerAndClient : public QObject public: ServerAndClient(QEventLoop &ev) : success(false) , eventLoop(ev) - , isBody(false) , bodyBytesRead(0) , bodyLength(-1) + , isBody(false) { setObjectName("serverAndClient"); tcpServer = new QTcpServer(this); diff --git a/tests/manual/cmake/CMakeLists.txt b/tests/manual/cmake/CMakeLists.txt index 241454e7633..f7b16946c10 100644 --- a/tests/manual/cmake/CMakeLists.txt +++ b/tests/manual/cmake/CMakeLists.txt @@ -83,7 +83,8 @@ else() message("CMake version older than 2.8.7. Not running test \"pass1\"") endif() expect_pass(pass2) -expect_pass(pass3) +# Modules do not currently find their own dependencies. +# expect_pass(pass3) expect_fail(fail4) expect_fail(fail5) expect_pass("pass(needsquoting)6") diff --git a/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt b/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt index 63f675df18c..7b9561c5881 100644 --- a/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt +++ b/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt @@ -9,14 +9,14 @@ find_package(Qt5Widgets REQUIRED) include_directories(${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS}) -add_definitions(${Qt5Core_DEFINITIONS}) +add_definitions(${Qt5Core_DEFINITIONS} ${Qt5Gui_DEFINITIONS} ${Qt5Widgets_DEFINITIONS}) set(CMAKE_INCLUDE_CURRENT_DIR ON) qt5_wrap_cpp(moc_files mywidget.h) qt5_wrap_ui(ui_files mywidget.ui) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") add_executable(mywidget mywidget.cpp ${moc_files} ${ui_files}) -target_link_libraries(mywidget ${Qt5Widgets_LIBRARIES}) +target_link_libraries(mywidget ${Qt5Widgets_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Core_LIBRARIES}) diff --git a/tests/manual/cmake/pass(needsquoting)6/mywidget.cpp b/tests/manual/cmake/pass(needsquoting)6/mywidget.cpp index d1b26699805..7f8923810d1 100644 --- a/tests/manual/cmake/pass(needsquoting)6/mywidget.cpp +++ b/tests/manual/cmake/pass(needsquoting)6/mywidget.cpp @@ -50,6 +50,7 @@ MyWidget::MyWidget(QWidget *parent) int main(int argc, char **argv) { + QApplication app(argc, argv); MyWidget myWidget; return 0; } diff --git a/tests/manual/cmake/pass1/CMakeLists.txt b/tests/manual/cmake/pass1/CMakeLists.txt index cbe3afc7c4f..970ca330781 100644 --- a/tests/manual/cmake/pass1/CMakeLists.txt +++ b/tests/manual/cmake/pass1/CMakeLists.txt @@ -43,6 +43,9 @@ endmacro() add_executable(two two.cpp) add_executable(three three.cpp) +qt5_use_package(two Core) qt5_use_package(two Test) qt5_use_package(three Widgets) +qt5_use_package(three Gui) +qt5_use_package(three Core) qt5_use_package(three Test) diff --git a/tests/manual/cmake/pass3/mywidget.cpp b/tests/manual/cmake/pass3/mywidget.cpp index d1b26699805..7f8923810d1 100644 --- a/tests/manual/cmake/pass3/mywidget.cpp +++ b/tests/manual/cmake/pass3/mywidget.cpp @@ -50,6 +50,7 @@ MyWidget::MyWidget(QWidget *parent) int main(int argc, char **argv) { + QApplication app(argc, argv); MyWidget myWidget; return 0; } diff --git a/tests/manual/qhttpnetworkconnection/main.cpp b/tests/manual/qhttpnetworkconnection/main.cpp index 2d861530d34..8099e616f73 100644 --- a/tests/manual/qhttpnetworkconnection/main.cpp +++ b/tests/manual/qhttpnetworkconnection/main.cpp @@ -72,7 +72,7 @@ void tst_qhttpnetworkconnection::bigRemoteFile() qDebug() << "Finished!" << endl; qDebug() << "Time:" << t.elapsed() << "msec"; qDebug() << "Bytes:" << size; - qDebug() << "Speed:" << (size / 1024) / (t.elapsed() / 1000) << "KB/sec"; + qDebug() << "Speed:" << (size / qreal(1024)) / (t.elapsed() / qreal(1000)) << "KB/sec"; } QTEST_MAIN(tst_qhttpnetworkconnection) diff --git a/tests/manual/qnetworkaccessmanager/qget/downloadmanager.cpp b/tests/manual/qnetworkaccessmanager/qget/downloadmanager.cpp new file mode 100644 index 00000000000..e3ba3ca88f2 --- /dev/null +++ b/tests/manual/qnetworkaccessmanager/qget/downloadmanager.cpp @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qget.h" +#include <QAuthenticator> +#include <QCoreApplication> +#include <QDebug> +#include <QSslError> + +DownloadManager::DownloadManager() + : queueMode (Parallel) +{ + connect(&nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finished(QNetworkReply*))); + connect(&nam, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*, QAuthenticator*))); + connect(&nam, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*))); +#ifndef QT_NO_SSL + connect(&nam, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(sslErrors(QNetworkReply*, const QList<QSslError>&))); +#endif +} + +DownloadManager::~DownloadManager() +{ + +} + +void DownloadManager::get(const QUrl &url, const QString &user, const QString &password) +{ + DownloadItem *dl = new DownloadItem(QNetworkRequest(url), user, password, nam); + transfers.append(dl); + connect(dl, SIGNAL(downloadFinished(TransferItem*)), SLOT(downloadFinished(TransferItem*))); +} + +void DownloadManager::upload(const QUrl &url, const QString &user, const QString &password, const QString &filename, const QString &contentType, TransferItem::Method method) +{ + QScopedPointer<QFile> file(new QFile(filename)); + if (!file->open(QFile::ReadOnly)) { + qDebug() << "Can't open input file" << file->fileName() << file->errorString(); + return; + } + QNetworkRequest request(url); + if (!contentType.isEmpty()) + request.setHeader(QNetworkRequest::ContentTypeHeader, contentType); + UploadItem *ul = new UploadItem(request, user, password, nam, file.take(), method); + transfers.append(ul); + connect(ul, SIGNAL(downloadFinished(TransferItem*)), SLOT(downloadFinished(TransferItem*))); +} + +void DownloadManager::finished(QNetworkReply *reply) +{ +} + +void DownloadManager::downloadFinished(TransferItem *item) +{ + qDebug() << "finished " << item->reply->url() << " with http status: " << item->reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + if (item->reply->error() != QNetworkReply::NoError) + qDebug() << "and error: " << item->reply->error() << item->reply->errorString(); + transfers.removeOne(item); + item->deleteLater(); + checkForAllDone(); +} + +void DownloadManager::checkForAllDone() +{ + if (transfers.isEmpty()) { + qDebug() << "All Done."; + QCoreApplication::quit(); + } + + foreach (TransferItem *item, transfers) { + if (!item->reply) { + item->start(); + //by default multiple downloads are processed in parallel. + //but in serial mode, only start one transfer at a time. + if (queueMode == Serial) + break; + } + } + +} + +void DownloadManager::authenticationRequired(QNetworkReply *reply, QAuthenticator *auth) +{ + qDebug() << "authenticationRequired" << reply; + TransferItem *transfer = findTransfer(reply); + //provide the credentials exactly once, so that it fails if credentials are incorrect. + if (transfer && !transfer->user.isEmpty() || !transfer->password.isEmpty()) { + auth->setUser(transfer->user); + auth->setPassword(transfer->password); + transfer->user.clear(); + transfer->password.clear(); + } +} + +void DownloadManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth) +{ + //provide the credentials exactly once, so that it fails if credentials are incorrect. + if (!proxyUser.isEmpty() || !proxyPassword.isEmpty()) { + auth->setUser(proxyUser); + auth->setPassword(proxyPassword); + proxyUser.clear(); + proxyPassword.clear(); + } +} + +#ifndef QT_NO_SSL +void DownloadManager::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors) +{ + qDebug() << "sslErrors"; + foreach (const QSslError &error, errors) { + qDebug() << error.errorString(); + qDebug() << error.certificate().toPem(); + } +} +#endif + +TransferItem *DownloadManager::findTransfer(QNetworkReply *reply) +{ + foreach (TransferItem *item, transfers) { + if (item->reply == reply) + return item; + } + return 0; +} + +void DownloadManager::setQueueMode(QueueMode mode) +{ + queueMode = mode; +} diff --git a/tests/manual/qnetworkaccessmanager/qget/qget.cpp b/tests/manual/qnetworkaccessmanager/qget/qget.cpp index 44fb62150be..cd98eff9359 100644 --- a/tests/manual/qnetworkaccessmanager/qget/qget.cpp +++ b/tests/manual/qnetworkaccessmanager/qget/qget.cpp @@ -41,9 +41,7 @@ #include "qget.h" -#include <QSslError> #include <QNetworkProxy> -#include <QAuthenticator> #include <QDebug> #include <QCoreApplication> #include <QList> @@ -52,156 +50,6 @@ #include <QNetworkConfigurationManager> #include <QNetworkSession> -DownloadManager::DownloadManager() -{ - connect(&nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finished(QNetworkReply*))); - connect(&nam, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*, QAuthenticator*))); - connect(&nam, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*))); -#ifndef QT_NO_SSL - connect(&nam, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(sslErrors(QNetworkReply*, const QList<QSslError>&))); -#endif -} - -DownloadManager::~DownloadManager() -{ - -} - -void DownloadManager::get(const QUrl& url) -{ - //currently multiple downloads are processed in parallel. - //could add an option for serial using the downloads list as a queue - //which would require DownloadItem to hold a request rather than a reply - QNetworkReply* reply = nam.get(QNetworkRequest(url)); - DownloadItem *dl = new DownloadItem(reply, nam); - downloads.append(dl); - connect(dl, SIGNAL(downloadFinished(DownloadItem*)), SLOT(downloadFinished(DownloadItem*))); -} - -void DownloadManager::finished(QNetworkReply* reply) -{ -} - -void DownloadManager::downloadFinished(DownloadItem *item) -{ - downloads.removeOne(item); - item->deleteLater(); - checkForAllDone(); -} - -void DownloadManager::checkForAllDone() -{ - if (downloads.isEmpty()) { - qDebug() << "All Done."; - QCoreApplication::quit(); - } -} - -void DownloadManager::authenticationRequired(QNetworkReply* reply, QAuthenticator* auth) -{ - //provide the credentials exactly once, so that it fails if credentials are incorrect. - if (!httpUser.isEmpty() || !httpPassword.isEmpty()) { - auth->setUser(httpUser); - auth->setPassword(httpPassword); - httpUser.clear(); - httpPassword.clear(); - } -} - -void DownloadManager::proxyAuthenticationRequired(const QNetworkProxy& proxy, QAuthenticator* auth) -{ - //provide the credentials exactly once, so that it fails if credentials are incorrect. - if (!proxyUser.isEmpty() || !proxyPassword.isEmpty()) { - auth->setUser(proxyUser); - auth->setPassword(proxyPassword); - proxyUser.clear(); - proxyPassword.clear(); - } -} - -#ifndef QT_NO_SSL -void DownloadManager::sslErrors(QNetworkReply* reply, const QList<QSslError>& errors) -{ - qDebug() << "sslErrors"; - foreach (const QSslError& error, errors) { - qDebug() << error.errorString(); - qDebug() << error.certificate().toPem(); - } -} -#endif - -DownloadItem::DownloadItem(QNetworkReply* r, QNetworkAccessManager& manager) : reply(r), nam(manager) -{ - reply->setParent(this); - connect(reply, SIGNAL(readyRead()), this, SLOT(readyRead())); - connect(reply, SIGNAL(finished()), this, SLOT(finished())); -} - -DownloadItem::~DownloadItem() -{ -} - -void DownloadItem::readyRead() -{ - if (!file.isOpen()) { - qDebug() << reply->header(QNetworkRequest::ContentTypeHeader) << reply->header(QNetworkRequest::ContentLengthHeader); - QString path = reply->url().path(); - path = path.mid(path.lastIndexOf('/') + 1); - if (path.isEmpty()) - path = QLatin1String("index.html"); - file.setFileName(path); - for (int i=1;i<1000;i++) { - if (!file.exists() && file.open(QIODevice::WriteOnly | QIODevice::Truncate)) - break; - file.setFileName(QString(QLatin1String("%1.%2")).arg(path).arg(i)); - } - if (!file.isOpen()) { - qDebug() << "couldn't open output file"; - reply->abort(); - return; - } - qDebug() << reply->url() << " -> " << file.fileName(); - } - file.write(reply->readAll()); -} - -void DownloadItem::finished() -{ - if (reply->attribute(QNetworkRequest::RedirectionTargetAttribute).isValid()) { - QUrl url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); - url = reply->url().resolved(url); - qDebug() << reply->url() << "redirected to " << url; - if (redirects.contains(url)) { - qDebug() << "redirect loop detected"; - } else if (redirects.count() > 10) { - qDebug() << "too many redirects"; - } else { - //follow redirect - if (file.isOpen()) { - if (!file.seek(0) || !file.resize(0)) { - file.close(); - file.remove(); - } - } - reply->deleteLater(); - reply = nam.get(QNetworkRequest(url)); - reply->setParent(this); - connect(reply, SIGNAL(readyRead()), this, SLOT(readyRead())); - connect(reply, SIGNAL(finished()), this, SLOT(finished())); - redirects.append(url); - return; - } - } - if (file.isOpen()) { - file.write(reply->readAll()); - file.close(); - } - qDebug() << "finished " << reply->url() << " with http status: " << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (reply->error() != QNetworkReply::NoError) - qDebug() << "and error: " << reply->error() << reply->errorString(); - emit downloadFinished(this); -} - void printShortUsage() { qDebug() << QCoreApplication::applicationName() << " [options] [list of urls]" << endl @@ -215,8 +63,8 @@ void printUsage() << "Get one or more urls using QNetworkAccessManager" << endl << "Options:" << "--help This message" << endl - << "--http-user=<username> Set username to use for http 401 challenges" << endl - << "--http-password=<password> Set password to use for http 401 challenges" << endl + << "--user=<username> Set username to use for authentication" << endl + << "--password=<password> Set password to use for authentication" << endl << "--proxy-user=<username> Set username to use for proxy authentication" << endl << "--proxy-password=<password> Set password to use for proxy authentication" << endl << "--proxy=on Use system proxy (default)" << endl @@ -225,7 +73,11 @@ void printUsage() << " ,http HTTP proxy (default)" << endl << " ,socks SOCKS5 proxy" << endl << " ,ftp FTP proxy" << endl - << " ,httpcaching HTTP caching proxy (no CONNECT method)" << endl; + << " ,httpcaching HTTP caching proxy (no CONNECT method)" << endl + << "--post=filename upload the file to the next url using HTTP POST" << endl + << "--put=filename upload the file to the next url using HTTP PUT" << endl + << "--content-type=<MIME> set content-type header for upload" << endl + << "--serial don't run requests in parallel" << endl; } int main(int argc, char *argv[]) @@ -240,18 +92,23 @@ int main(int argc, char *argv[]) QNetworkProxyFactory::setUseSystemConfiguration(true); DownloadManager dl; + QString uploadFileName; + QString contentType; + QString httpUser; + QString httpPassword; + TransferItem::Method method = TransferItem::Get; //arguments match wget where possible foreach (QString str, app.arguments().mid(1)) { if (str == "--help") printUsage(); - else if (str.startsWith("--http-user=")) - dl.setHttpUser(str.mid(12)); - else if (str.startsWith("--http-passwd=")) - dl.setHttpPassword(str.mid(14)); + else if (str.startsWith("--user=")) + httpUser = str.mid(7); + else if (str.startsWith("--password=")) + httpPassword = str.mid(11); else if (str.startsWith("--proxy-user=")) dl.setProxyUser(str.mid(13)); - else if (str.startsWith("--proxy-passwd=")) - dl.setProxyPassword(str.mid(15)); + else if (str.startsWith("--proxy-password=")) + dl.setProxyPassword(str.mid(17)); else if (str == "--proxy=off") QNetworkProxyFactory::setUseSystemConfiguration(false); else if (str == "--proxy=on") @@ -294,10 +151,33 @@ int main(int argc, char *argv[]) qDebug() << "proxy:" << proxy.hostName() << proxy.port() << proxy.type(); dl.setProxy(proxy); } + else if (str.startsWith("--put=")) { + method = TransferItem::Put; + uploadFileName = str.mid(6); + } + else if (str.startsWith("--post=")) { + method = TransferItem::Post; + uploadFileName = str.mid(7); + } + else if (str.startsWith("--content-type=")) + contentType=str.mid(15); + else if (str == "--serial") + dl.setQueueMode(DownloadManager::Serial); else if (str.startsWith("-")) qDebug() << "unsupported option" << str; - else - dl.get(QUrl::fromUserInput(str)); + else { + QUrl url(QUrl::fromUserInput(str)); + switch (method) { + case TransferItem::Put: + case TransferItem::Post: + dl.upload(url, httpUser, httpPassword, uploadFileName, contentType, method); + break; + case TransferItem::Get: + dl.get(url, httpUser, httpPassword); + break; + } + method = TransferItem::Get; //default for urls without a request type before it + } } QMetaObject::invokeMethod(&dl, "checkForAllDone", Qt::QueuedConnection); return app.exec(); diff --git a/tests/manual/qnetworkaccessmanager/qget/qget.h b/tests/manual/qnetworkaccessmanager/qget/qget.h index 40d75a39031..bad4f5e4d20 100644 --- a/tests/manual/qnetworkaccessmanager/qget/qget.h +++ b/tests/manual/qnetworkaccessmanager/qget/qget.h @@ -46,25 +46,50 @@ #include <QNetworkReply> #include <QFile> -class DownloadItem : public QObject +class TransferItem : public QObject { Q_OBJECT public: - DownloadItem(QNetworkReply* r, QNetworkAccessManager& nam); + enum Method {Get,Put,Post}; + TransferItem(const QNetworkRequest &r, const QString &u, const QString &p, QNetworkAccessManager &n, Method m); + void start(); +signals: + void downloadFinished(TransferItem *self); +public slots: + void progress(qint64,qint64); +public: + Method method; + QNetworkRequest request; + QNetworkReply *reply; + QNetworkAccessManager &nam; + QFile *inputFile; + QFile *outputFile; + QList<QUrl> redirects; + QString user; + QString password; +}; + +class DownloadItem : public TransferItem +{ + Q_OBJECT +public: + DownloadItem(const QNetworkRequest &r, const QString &user, const QString &password, QNetworkAccessManager &nam); ~DownloadItem(); - QNetworkReply* networkReply() { return reply; } - -signals: - void downloadFinished(DownloadItem *self); private slots: void readyRead(); void finished(); private: - QNetworkAccessManager& nam; - QNetworkReply* reply; - QFile file; - QList<QUrl> redirects; +}; + +class UploadItem : public TransferItem +{ + Q_OBJECT +public: + UploadItem(const QNetworkRequest &r, const QString &user, const QString &password, QNetworkAccessManager &nam, QFile *f, TransferItem::Method method); + ~UploadItem(); +private slots: + void finished(); }; class DownloadManager : public QObject @@ -73,31 +98,31 @@ class DownloadManager : public QObject public: DownloadManager(); ~DownloadManager(); - void get(const QUrl& url); - void setProxy(const QNetworkProxy& proxy) { nam.setProxy(proxy); } - void setHttpUser(const QString& user) { httpUser = user; } - void setHttpPassword(const QString& password) { httpPassword = password; } - void setProxyUser(const QString& user) { proxyUser = user; } - void setProxyPassword(const QString& password) { proxyPassword = password; } + void get(const QUrl &url, const QString &user, const QString &password); + void upload(const QUrl &url, const QString &user, const QString &password, const QString &filename, const QString &contentType, TransferItem::Method method); + void setProxy(const QNetworkProxy &proxy) { nam.setProxy(proxy); } + void setProxyUser(const QString &user) { proxyUser = user; } + void setProxyPassword(const QString &password) { proxyPassword = password; } + enum QueueMode { Parallel, Serial }; + void setQueueMode(QueueMode mode); public slots: void checkForAllDone(); private slots: - void finished(QNetworkReply* reply); - void authenticationRequired(QNetworkReply* reply, QAuthenticator* authenticator); - void proxyAuthenticationRequired(const QNetworkProxy& proxy, QAuthenticator* authenticator); -#ifndef QT_NO_SSL - void sslErrors(QNetworkReply* reply, const QList<QSslError>& errors); -#endif - void downloadFinished(DownloadItem *item); + void finished(QNetworkReply *reply); + void authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator); + void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator); + void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors); + void downloadFinished(TransferItem *item); private: + TransferItem *findTransfer(QNetworkReply *reply); + QNetworkAccessManager nam; - QList<DownloadItem*> downloads; - QString httpUser; - QString httpPassword; + QList<TransferItem*> transfers; QString proxyUser; QString proxyPassword; + QueueMode queueMode; }; #endif // QGET_H diff --git a/tests/manual/qnetworkaccessmanager/qget/qget.pro b/tests/manual/qnetworkaccessmanager/qget/qget.pro index 1f2b497171d..8a632f8d4e9 100644 --- a/tests/manual/qnetworkaccessmanager/qget/qget.pro +++ b/tests/manual/qnetworkaccessmanager/qget/qget.pro @@ -3,4 +3,6 @@ QT = core network CONFIG += console SOURCES += qget.cpp +SOURCES += transferitem.cpp +SOURCES += downloadmanager.cpp HEADERS += qget.h diff --git a/tests/manual/qnetworkaccessmanager/qget/transferitem.cpp b/tests/manual/qnetworkaccessmanager/qget/transferitem.cpp new file mode 100644 index 00000000000..1565292e6da --- /dev/null +++ b/tests/manual/qnetworkaccessmanager/qget/transferitem.cpp @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qget.h" +#include <QDebug> + +TransferItem::TransferItem(const QNetworkRequest &r, const QString &u, const QString &p, QNetworkAccessManager &n, Method m) + : method(m), request(r), reply(0), nam(n), inputFile(0), outputFile(0), user(u), password(p) +{ +} + +void TransferItem::progress(qint64 sent, qint64 total) +{ + if (total > 0) + qDebug() << (sent*100/total) << "%"; + else + qDebug() << sent << "B"; +} + +void TransferItem::start() +{ + switch (method) { + case Get: + reply = nam.get(request); + connect(reply, SIGNAL(readyRead()), this, SLOT(readyRead())); + connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(progress(qint64,qint64))); + break; + case Put: + reply = nam.put(request, inputFile); + connect(reply, SIGNAL(uploadProgress(qint64,qint64)), this, SLOT(progress(qint64,qint64))); + break; + case Post: + reply = nam.post(request, inputFile); + connect(reply, SIGNAL(uploadProgress(qint64,qint64)), this, SLOT(progress(qint64,qint64))); + break; + } + connect(reply, SIGNAL(finished()), this, SLOT(finished())); +} + +DownloadItem::DownloadItem(const QNetworkRequest &r, const QString &user, const QString &password, QNetworkAccessManager &manager) + : TransferItem(r, user, password, manager, Get) +{ +} + +DownloadItem::~DownloadItem() +{ +} + +void DownloadItem::readyRead() +{ + if (!outputFile) + outputFile = new QFile(this); + if (!outputFile->isOpen()) { + qDebug() << reply->header(QNetworkRequest::ContentTypeHeader) << reply->header(QNetworkRequest::ContentLengthHeader); + QString path = reply->url().path(); + path = path.mid(path.lastIndexOf('/') + 1); + if (path.isEmpty()) + path = QLatin1String("index.html"); + outputFile->setFileName(path); + for (int i=1;i<1000;i++) { + if (!outputFile->exists() && outputFile->open(QIODevice::WriteOnly | QIODevice::Truncate)) + break; + outputFile->setFileName(QString(QLatin1String("%1.%2")).arg(path).arg(i)); + } + if (!outputFile->isOpen()) { + qDebug() << "couldn't open output file"; + reply->abort(); + return; + } + qDebug() << reply->url() << " -> " << outputFile->fileName(); + } + outputFile->write(reply->readAll()); +} + +void DownloadItem::finished() +{ + if (reply->attribute(QNetworkRequest::RedirectionTargetAttribute).isValid()) { + QUrl url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + url = reply->url().resolved(url); + qDebug() << reply->url() << "redirected to " << url; + if (redirects.contains(url)) { + qDebug() << "redirect loop detected"; + } else if (redirects.count() > 10) { + qDebug() << "too many redirects"; + } else { + //follow redirect + if (outputFile->isOpen()) { + if (!outputFile->seek(0) || !outputFile->resize(0)) { + outputFile->close(); + outputFile->remove(); + } + } + reply->deleteLater(); + reply = nam.get(QNetworkRequest(url)); + reply->setParent(this); + connect(reply, SIGNAL(readyRead()), this, SLOT(readyRead())); + connect(reply, SIGNAL(finished()), this, SLOT(finished())); + redirects.append(url); + return; + } + } + if (outputFile && outputFile->isOpen()) { + outputFile->write(reply->readAll()); + outputFile->close(); + } + emit downloadFinished(this); +} + +UploadItem::UploadItem(const QNetworkRequest &r, const QString &user, const QString &password, QNetworkAccessManager &n, QFile *f, TransferItem::Method method) + : TransferItem(r,user, password, n,method) +{ + inputFile = f; + f->setParent(this); + qDebug() << f->fileName() << f->isOpen() << f->size(); +} + +UploadItem::~UploadItem() +{ +} + +void UploadItem::finished() +{ + emit downloadFinished(this); +} diff --git a/tests/manual/windowmodality/dialog.ui b/tests/manual/windowmodality/dialog.ui new file mode 100644 index 00000000000..02543115661 --- /dev/null +++ b/tests/manual/windowmodality/dialog.ui @@ -0,0 +1,326 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Dialog</class> + <widget class="QDialog" name="Dialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>515</width> + <height>480</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Select the type of dialog to create:</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0" colspan="3"> + <widget class="QCheckBox" name="useThisAsParentCheckBox"> + <property name="text"> + <string>Use this window as parent for newly created dialogs</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QPushButton" name="modelessCustomDialogButton"> + <property name="text"> + <string>Custom Dialog</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QPushButton" name="modelessColorDialogButton"> + <property name="text"> + <string>Color Dialog</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QPushButton" name="modelessFontDialogButton"> + <property name="text"> + <string>Font Dialog</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QPushButton" name="windowModalCustomDialogButton"> + <property name="text"> + <string>Custom Dialog</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QPushButton" name="windowModalColorDialogButton"> + <property name="text"> + <string>Color Dialog</string> + </property> + </widget> + </item> + <item row="5" column="2"> + <widget class="QPushButton" name="windowModalFileDialogButton"> + <property name="text"> + <string>File Dialog</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QPushButton" name="windowModalFontDialogButton"> + <property name="text"> + <string>Font Dialog</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QPushButton" name="windowModalPageSetupDialogButton"> + <property name="text"> + <string>Page Setup Dialog</string> + </property> + </widget> + </item> + <item row="6" column="2"> + <widget class="QPushButton" name="windowModalPrintDialogButton"> + <property name="text"> + <string>Print Dialog</string> + </property> + </widget> + </item> + <item row="10" column="0"> + <widget class="QPushButton" name="applicationModalCustomDialogButton"> + <property name="text"> + <string>Custom Dialog</string> + </property> + </widget> + </item> + <item row="10" column="1"> + <widget class="QPushButton" name="applicationModalColorDialogButton"> + <property name="text"> + <string>Color Dialog</string> + </property> + </widget> + </item> + <item row="10" column="2"> + <widget class="QPushButton" name="applicationModalFileDialogButton"> + <property name="text"> + <string>File Dialog</string> + </property> + </widget> + </item> + <item row="11" column="0"> + <widget class="QPushButton" name="applicationModalFontDialogButton"> + <property name="text"> + <string>Font Dialog</string> + </property> + </widget> + </item> + <item row="11" column="1"> + <widget class="QPushButton" name="applicationModalPageSetupDialogButton"> + <property name="text"> + <string>Page Setup Dialog</string> + </property> + </widget> + </item> + <item row="11" column="2"> + <widget class="QPushButton" name="applicationModalPrintDialogButton"> + <property name="text"> + <string>Print Dialog</string> + </property> + </widget> + </item> + <item row="12" column="0" colspan="3"> + <widget class="QLabel" name="applicationModalNoteLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <pointsize>11</pointsize> + </font> + </property> + <property name="text"> + <string>Native Application Modal Dialogs use static API instead of exec()</string> + </property> + </widget> + </item> + <item row="9" column="0" colspan="3"> + <widget class="QCheckBox" name="applicationModalUseExecCheckBox"> + <property name="font"> + <font> + <pointsize>11</pointsize> + </font> + </property> + <property name="text"> + <string>Application Modal Dialogs use exec()</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="7" column="0" colspan="3"> + <widget class="QLabel" name="windowModalNoteLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <pointsize>11</pointsize> + </font> + </property> + <property name="text"> + <string>Native Window Modal Dialogs use open()</string> + </property> + </widget> + </item> + <item row="8" column="0" colspan="3"> + <widget class="QLabel" name="applicationModalDialogsLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Application Modal Dialogs</string> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QLabel" name="windowModalDialogsLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Window Modal Dialogs</string> + </property> + </widget> + </item> + <item row="2" column="0" colspan="3"> + <widget class="QLabel" name="modelessDialogsLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Modeless (Non-Modal) Dialogs</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="3"> + <widget class="QCheckBox" name="createSiblingDialogCheckBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Create new dialogs as siblings of this dialog</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout"> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>131</width> + <height>31</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="okButton"> + <property name="text"> + <string>Close</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>Dialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>397</x> + <y>338</y> + </hint> + <hint type="destinationlabel"> + <x>96</x> + <y>254</y> + </hint> + </hints> + </connection> + <connection> + <sender>useThisAsParentCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>createSiblingDialogCheckBox</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>260</x> + <y>39</y> + </hint> + <hint type="destinationlabel"> + <x>260</x> + <y>60</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/tests/manual/windowmodality/main.cpp b/tests/manual/windowmodality/main.cpp new file mode 100644 index 00000000000..35584b5c68d --- /dev/null +++ b/tests/manual/windowmodality/main.cpp @@ -0,0 +1,301 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "ui_dialog.h" +#include "ui_widget.h" + +#include <QtCore/QDebug> +#include <QtCore/QTimer> +#include <QtWidgets/QColorDialog> +#include <QtWidgets/QFileDialog> +#include <QtWidgets/QFontDialog> +#include <QtPrintSupport/QPageSetupDialog> +#include <QtPrintSupport/QPrintDialog> + +enum DialogType +{ + CustomDialogType, + ColorDialogType, + FileDialogType, + FontDialogType, + PageSetupDialogType, + PrintDialogType +}; + +class CustomDialog : public QDialog, public Ui::Dialog +{ + Q_OBJECT +public: + CustomDialog(QWidget *parent = 0) + : QDialog(parent) + { + setupUi(this); + + // hide the "Create new dialogs as siblings of this dialog" button when + // we don't have a parent of our own (they would be parentless anyway) + if (!parent) { + createSiblingDialogCheckBox->setChecked(false); + createSiblingDialogCheckBox->setVisible(false); + } + } + +private slots: + void on_modelessCustomDialogButton_clicked() + { newDialog(CustomDialogType, Qt::NonModal); } + void on_modelessColorDialogButton_clicked() + { newDialog(ColorDialogType, Qt::NonModal); } + void on_modelessFontDialogButton_clicked() + { newDialog(FontDialogType, Qt::NonModal); } + + void on_windowModalCustomDialogButton_clicked() + { newDialog(CustomDialogType, Qt::WindowModal); } + void on_windowModalColorDialogButton_clicked() + { newDialog(ColorDialogType, Qt::WindowModal); } + void on_windowModalFileDialogButton_clicked() + { newDialog(FileDialogType, Qt::WindowModal); } + void on_windowModalFontDialogButton_clicked() + { newDialog(FontDialogType, Qt::WindowModal); } + void on_windowModalPageSetupDialogButton_clicked() + { newDialog(PageSetupDialogType, Qt::WindowModal); } + void on_windowModalPrintDialogButton_clicked() + { newDialog(PrintDialogType, Qt::WindowModal); } + + void on_applicationModalCustomDialogButton_clicked() + { newDialog(CustomDialogType, Qt::ApplicationModal); } + void on_applicationModalColorDialogButton_clicked() + { newDialog(ColorDialogType, Qt::ApplicationModal); } + void on_applicationModalFileDialogButton_clicked() + { newDialog(FileDialogType, Qt::ApplicationModal); } + void on_applicationModalFontDialogButton_clicked() + { newDialog(FontDialogType, Qt::ApplicationModal); } + void on_applicationModalPageSetupDialogButton_clicked() + { newDialog(PageSetupDialogType, Qt::ApplicationModal); } + void on_applicationModalPrintDialogButton_clicked() + { newDialog(PrintDialogType, Qt::ApplicationModal); } + +private: + void newDialog(DialogType dialogType, Qt::WindowModality windowModality) + { + QWidget *parent = 0; + if (useThisAsParentCheckBox->isChecked()) + parent = this; + else if (createSiblingDialogCheckBox->isChecked()) + parent = parentWidget(); + + QDialog *dialog; + switch (dialogType) { + case CustomDialogType: + dialog = new CustomDialog(parent); + break; + case ColorDialogType: + if (windowModality == Qt::ApplicationModal && applicationModalUseExecCheckBox->isChecked()) { + QColorDialog::getColor(Qt::white, parent); + return; + } + dialog = new QColorDialog(parent); + break; + case FileDialogType: + if (windowModality == Qt::ApplicationModal && applicationModalUseExecCheckBox->isChecked()) { + QFileDialog::getOpenFileName(parent); + return; + } + dialog = new QFileDialog(parent); + break; + case FontDialogType: + if (windowModality == Qt::ApplicationModal && applicationModalUseExecCheckBox->isChecked()) { + bool unused = false; + QFontDialog::getFont(&unused, parent); + return; + } + dialog = new QFontDialog(parent); + break; + case PageSetupDialogType: + dialog = new QPageSetupDialog(parent); + break; + case PrintDialogType: + dialog = new QPrintDialog(parent); + break; + } + + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setWindowModality(windowModality); + + if (windowModality == Qt::ApplicationModal && applicationModalUseExecCheckBox->isChecked()) + dialog->exec(); + else if (windowModality == Qt::WindowModal) + dialog->open(); + else + dialog->show(); + } + bool event(QEvent *event) + { + if (event->type() == QEvent::WindowBlocked) + setPalette(Qt::darkGray); + else if (event->type() == QEvent::WindowUnblocked) + setPalette(QPalette()); + return QWidget::event(event); + } +}; + +class Widget : public QWidget, public Ui::Widget +{ + Q_OBJECT +public: + Widget(QWidget *parent = 0) + : QWidget(parent) + { + setupUi(this); + } + +private slots: + void on_windowButton_clicked() + { (new Widget)->show(); } + void on_groupLeaderButton_clicked() + { + Widget *w = new Widget; + w->setAttribute(Qt::WA_GroupLeader); + w->show(); + } + + void on_modelessCustomDialogButton_clicked() + { newDialog(CustomDialogType, Qt::NonModal); } + void on_modelessColorDialogButton_clicked() + { newDialog(ColorDialogType, Qt::NonModal); } + void on_modelessFontDialogButton_clicked() + { newDialog(FontDialogType, Qt::NonModal); } + + void on_windowModalCustomDialogButton_clicked() + { newDialog(CustomDialogType, Qt::WindowModal); } + void on_windowModalColorDialogButton_clicked() + { newDialog(ColorDialogType, Qt::WindowModal); } + void on_windowModalFileDialogButton_clicked() + { newDialog(FileDialogType, Qt::WindowModal); } + void on_windowModalFontDialogButton_clicked() + { newDialog(FontDialogType, Qt::WindowModal); } + void on_windowModalPageSetupDialogButton_clicked() + { newDialog(PageSetupDialogType, Qt::WindowModal); } + void on_windowModalPrintDialogButton_clicked() + { newDialog(PrintDialogType, Qt::WindowModal); } + + void on_applicationModalCustomDialogButton_clicked() + { newDialog(CustomDialogType, Qt::ApplicationModal); } + void on_applicationModalColorDialogButton_clicked() + { newDialog(ColorDialogType, Qt::ApplicationModal); } + void on_applicationModalFileDialogButton_clicked() + { newDialog(FileDialogType, Qt::ApplicationModal); } + void on_applicationModalFontDialogButton_clicked() + { newDialog(FontDialogType, Qt::ApplicationModal); } + void on_applicationModalPageSetupDialogButton_clicked() + { newDialog(PageSetupDialogType, Qt::ApplicationModal); } + void on_applicationModalPrintDialogButton_clicked() + { newDialog(PrintDialogType, Qt::ApplicationModal); } + +private: + void newDialog(DialogType dialogType, Qt::WindowModality windowModality) + { + QWidget *parent = 0; + if (useThisAsParentCheckBox->isChecked()) + parent = this; + + QDialog *dialog; + switch (dialogType) { + case CustomDialogType: + dialog = new CustomDialog(parent); + break; + case ColorDialogType: + if (windowModality == Qt::ApplicationModal && applicationModalUseExecCheckBox->isChecked()) { + QColorDialog::getColor(Qt::white, parent); + return; + } + dialog = new QColorDialog(parent); + break; + case FileDialogType: + if (windowModality == Qt::ApplicationModal && applicationModalUseExecCheckBox->isChecked()) { + QFileDialog::getOpenFileName(parent); + return; + } + dialog = new QFileDialog(parent); + break; + case FontDialogType: + if (windowModality == Qt::ApplicationModal && applicationModalUseExecCheckBox->isChecked()) { + bool unused = false; + QFontDialog::getFont(&unused, parent); + return; + } + dialog = new QFontDialog(parent); + break; + case PageSetupDialogType: + dialog = new QPageSetupDialog(parent); + break; + case PrintDialogType: + dialog = new QPrintDialog(parent); + break; + } + + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setWindowModality(windowModality); + + if (windowModality == Qt::ApplicationModal && applicationModalUseExecCheckBox->isChecked()) + dialog->exec(); + else if (windowModality == Qt::WindowModal) + dialog->open(); + else + dialog->show(); + } + bool event(QEvent *event) + { + if (event->type() == QEvent::WindowBlocked) + setPalette(Qt::darkGray); + else if (event->type() == QEvent::WindowUnblocked) + setPalette(QPalette()); + return QWidget::event(event); + } +}; + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Widget widget; + widget.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/windowmodality/modality.pro b/tests/manual/windowmodality/modality.pro new file mode 100644 index 00000000000..973579c5082 --- /dev/null +++ b/tests/manual/windowmodality/modality.pro @@ -0,0 +1,3 @@ +SOURCES = main.cpp +FORMS = widget.ui dialog.ui +QT += widgets printsupport diff --git a/tests/manual/windowmodality/widget.ui b/tests/manual/windowmodality/widget.ui new file mode 100644 index 00000000000..26d218b79eb --- /dev/null +++ b/tests/manual/windowmodality/widget.ui @@ -0,0 +1,286 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget</class> + <widget class="QWidget" name="Widget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>622</width> + <height>462</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Select the type of window to create:</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="2" column="0" colspan="3"> + <widget class="QLabel" name="topLevelWindowsLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Top-level Windows</string> + </property> + </widget> + </item> + <item row="15" column="0" colspan="3"> + <widget class="QLabel" name="applicationModalNoteLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <pointsize>11</pointsize> + </font> + </property> + <property name="text"> + <string>Note: Native Application Modal Dialogs use static API instead of exec()</string> + </property> + </widget> + </item> + <item row="14" column="2"> + <widget class="QPushButton" name="applicationModalPrintDialogButton"> + <property name="text"> + <string>Print Dialog</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QPushButton" name="windowButton"> + <property name="text"> + <string>Window</string> + </property> + </widget> + </item> + <item row="13" column="1"> + <widget class="QPushButton" name="applicationModalColorDialogButton"> + <property name="text"> + <string>Color Dialog</string> + </property> + </widget> + </item> + <item row="9" column="0"> + <widget class="QPushButton" name="windowModalFontDialogButton"> + <property name="text"> + <string>Font Dialog</string> + </property> + </widget> + </item> + <item row="14" column="0"> + <widget class="QPushButton" name="applicationModalFontDialogButton"> + <property name="text"> + <string>Font Dialog</string> + </property> + </widget> + </item> + <item row="6" column="2"> + <widget class="QPushButton" name="modelessFontDialogButton"> + <property name="text"> + <string>Font Dialog</string> + </property> + </widget> + </item> + <item row="14" column="1"> + <widget class="QPushButton" name="applicationModalPageSetupDialogButton"> + <property name="text"> + <string>Page Setup Dialog</string> + </property> + </widget> + </item> + <item row="8" column="0"> + <widget class="QPushButton" name="windowModalCustomDialogButton"> + <property name="text"> + <string>Custom Dialog</string> + </property> + </widget> + </item> + <item row="9" column="1"> + <widget class="QPushButton" name="windowModalPageSetupDialogButton"> + <property name="text"> + <string>Page Setup Dialog</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QPushButton" name="modelessColorDialogButton"> + <property name="text"> + <string>Color Dialog</string> + </property> + </widget> + </item> + <item row="13" column="2"> + <widget class="QPushButton" name="applicationModalFileDialogButton"> + <property name="text"> + <string>File Dialog</string> + </property> + </widget> + </item> + <item row="7" column="0" colspan="3"> + <widget class="QLabel" name="windowModalDialogsLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Window Modal Dialogs</string> + </property> + </widget> + </item> + <item row="5" column="0" colspan="3"> + <widget class="QLabel" name="modelessDialogsLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Modeless (Non-Modal) Dialogs</string> + </property> + </widget> + </item> + <item row="11" column="0" colspan="2"> + <widget class="QLabel" name="applicationModalDialogsLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Application Modal Dialogs</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QPushButton" name="groupLeaderButton"> + <property name="text"> + <string>Window (Group Leader)</string> + </property> + </widget> + </item> + <item row="9" column="2"> + <widget class="QPushButton" name="windowModalPrintDialogButton"> + <property name="text"> + <string>Print Dialog</string> + </property> + </widget> + </item> + <item row="10" column="0" colspan="3"> + <widget class="QLabel" name="windowModalNoteLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <pointsize>11</pointsize> + </font> + </property> + <property name="text"> + <string>Note: Window Modal Dialogs use open()</string> + </property> + </widget> + </item> + <item row="8" column="1"> + <widget class="QPushButton" name="windowModalColorDialogButton"> + <property name="text"> + <string>Color Dialog</string> + </property> + </widget> + </item> + <item row="12" column="0" colspan="3"> + <widget class="QCheckBox" name="applicationModalUseExecCheckBox"> + <property name="font"> + <font> + <pointsize>11</pointsize> + </font> + </property> + <property name="text"> + <string>Application Modal Dialogs use exec()</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="8" column="2"> + <widget class="QPushButton" name="windowModalFileDialogButton"> + <property name="text"> + <string>File Dialog</string> + </property> + </widget> + </item> + <item row="13" column="0"> + <widget class="QPushButton" name="applicationModalCustomDialogButton"> + <property name="text"> + <string>Custom Dialog</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QPushButton" name="modelessCustomDialogButton"> + <property name="text"> + <string>Custom Dialog</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="3"> + <widget class="QCheckBox" name="useThisAsParentCheckBox"> + <property name="text"> + <string>Use this window as parent for newly created dialogs</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/shared/filesystem.h b/tests/shared/filesystem.h index c681dcfa053..acc8500ba0a 100644 --- a/tests/shared/filesystem.h +++ b/tests/shared/filesystem.h @@ -149,7 +149,7 @@ struct FileSystem memset( reparseInfo, 0, sizeof( *reparseInfo )); reparseInfo->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - reparseInfo->ReparseTargetLength = target.size() * sizeof(wchar_t); + reparseInfo->ReparseTargetLength = DWORD(target.size() * sizeof(wchar_t)); reparseInfo->ReparseTargetMaximumLength = reparseInfo->ReparseTargetLength + sizeof(wchar_t); target.toWCharArray(reparseInfo->ReparseTarget); reparseInfo->ReparseDataLength = reparseInfo->ReparseTargetLength + 12; diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index a45f396ebe1..23b19ecf6e0 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -176,7 +176,7 @@ Configure::Configure(int& argc, char** argv) } } - defaultBuildParts << QStringLiteral("libs") << QStringLiteral("examples") << QStringLiteral("tests"); + defaultBuildParts << QStringLiteral("libs") << QStringLiteral("examples"); dictionary[ "QT_SOURCE_TREE" ] = fixSeparators(sourcePath); dictionary[ "QT_BUILD_TREE" ] = fixSeparators(buildPath); dictionary[ "QT_INSTALL_PREFIX" ] = fixSeparators(installPath); @@ -211,7 +211,7 @@ Configure::Configure(int& argc, char** argv) dictionary[ "WMSDK" ] = "auto"; dictionary[ "DIRECTSHOW" ] = "no"; dictionary[ "V8SNAPSHOT" ] = "auto"; - dictionary[ "DECLARATIVE_DEBUG" ]= "yes"; + dictionary[ "QML_DEBUG" ] = "yes"; dictionary[ "PLUGIN_MANIFESTS" ] = "yes"; dictionary[ "DIRECTWRITE" ] = "no"; @@ -824,10 +824,10 @@ void Configure::parseCmdLine() dictionary[ "PHONON_BACKEND" ] = "yes"; } else if (configCmdLine.at(i) == "-phonon-wince-ds9") { dictionary[ "DIRECTSHOW" ] = "yes"; - } else if (configCmdLine.at(i) == "-no-declarative-debug") { - dictionary[ "DECLARATIVE_DEBUG" ] = "no"; - } else if (configCmdLine.at(i) == "-declarative-debug") { - dictionary[ "DECLARATIVE_DEBUG" ] = "yes"; + } else if (configCmdLine.at(i) == "-no-qml-debug") { + dictionary[ "QML_DEBUG" ] = "no"; + } else if (configCmdLine.at(i) == "-qml-debug") { + dictionary[ "QML_DEBUG" ] = "yes"; } else if (configCmdLine.at(i) == "-no-plugin-manifests") { dictionary[ "PLUGIN_MANIFESTS" ] = "no"; } else if (configCmdLine.at(i) == "-plugin-manifests") { @@ -906,8 +906,6 @@ void Configure::parseCmdLine() sybase = configCmdLine.at(i); } else if (configCmdLine.at(i).startsWith("SYBASE_LIBS=")) { sybaseLibs = configCmdLine.at(i); - } else if (configCmdLine.at(i) == "-qpa") { - dictionary["QPA"] = "yes"; } else if ((configCmdLine.at(i) == "-override-version") || (configCmdLine.at(i) == "-version-override")){ @@ -937,7 +935,7 @@ void Configure::parseCmdLine() ++i; if (i == argCount) break; - nobuildParts.removeAll(configCmdLine.at(i)); + nobuildParts.append(configCmdLine.at(i)); } // Directories ---------------------------------------------- @@ -1457,7 +1455,7 @@ bool Configure::displayHelp() "[-no-multimedia] [-multimedia] [-no-audio-backend] [-audio-backend]\n" "[-no-script] [-script] [-no-scripttools] [-scripttools]\n" "[-no-webkit] [-webkit] [-webkit-debug]\n" - "[-no-directwrite] [-directwrite] [-qpa] [-no-widgets] [-icu]\n\n", 0, 7); + "[-no-directwrite] [-directwrite] [-no-widgets] [-icu]\n\n", 0, 7); desc("Installation options:\n\n"); @@ -1606,8 +1604,8 @@ bool Configure::displayHelp() desc("PHONON_BACKEND","yes","-phonon-backend", "Compile in the platform-specific Phonon backend-plugin"); desc("AUDIO_BACKEND", "no","-no-audio-backend", "Do not compile in the platform audio backend into QtMultimedia"); desc("AUDIO_BACKEND", "yes","-audio-backend", "Compile in the platform audio backend into QtMultimedia"); - desc("DECLARATIVE_DEBUG", "no", "-no-declarative-debug", "Do not build the declarative debugging support"); - desc("DECLARATIVE_DEBUG", "yes", "-declarative-debug", "Build the declarative debugging support"); + desc("QML_DEBUG", "no", "-no-qml-debug", "Do not build the QML debugging support"); + desc("QML_DEBUG", "yes", "-qml-debug", "Build the QML debugging support"); desc("DIRECTWRITE", "no", "-no-directwrite", "Do not build support for DirectWrite font rendering"); desc("DIRECTWRITE", "yes", "-directwrite", "Build support for DirectWrite font rendering (experimental, requires DirectWrite availability on target systems, e.g. Windows Vista with Platform Update, Windows 7, etc.)"); @@ -1957,8 +1955,8 @@ void Configure::autoDetection() dictionary["DBUS"] = checkAvailability("DBUS") ? "yes" : "no"; if (dictionary["V8SNAPSHOT"] == "auto") dictionary["V8SNAPSHOT"] = (dictionary["V8"] == "yes") && checkAvailability("V8SNAPSHOT") ? "yes" : "no"; - if (dictionary["DECLARATIVE_DEBUG"] == "auto") - dictionary["DECLARATIVE_DEBUG"] = dictionary["DECLARATIVE"] == "yes" ? "yes" : "no"; + if (dictionary["QML_DEBUG"] == "auto") + dictionary["QML_DEBUG"] = dictionary["QML"] == "yes" ? "yes" : "no"; if (dictionary["AUDIO_BACKEND"] == "auto") dictionary["AUDIO_BACKEND"] = checkAvailability("AUDIO_BACKEND") ? "yes" : "no"; if (dictionary["WMSDK"] == "auto") @@ -2215,8 +2213,12 @@ void Configure::generateOutputVars() qmakeConfig += dictionary[ "BUILD" ]; dictionary[ "QMAKE_OUTDIR" ] = dictionary[ "BUILD" ]; - if (buildParts.isEmpty()) + if (buildParts.isEmpty()) { buildParts = defaultBuildParts; + + if (dictionary["BUILDDEV"] == "yes") + buildParts += "tests"; + } while (!nobuildParts.isEmpty()) buildParts.removeAll(nobuildParts.takeFirst()); if (!buildParts.contains("libs")) @@ -2596,14 +2598,15 @@ void Configure::generateQConfigPri() configStream << " incredibuild_xge"; if (dictionary["PLUGIN_MANIFESTS"] == "no") configStream << " no_plugin_manifest"; - if (dictionary["QPA"] == "yes") - configStream << " qpa"; if (dictionary["CROSS_COMPILE"] == "yes") configStream << " cross_compile"; if (dictionary["DIRECTWRITE"] == "yes") configStream << "directwrite"; + // ### For compatibility only, should be removed later. + configStream << " qpa"; + configStream << endl; configStream << "QT_ARCH = " << dictionary["QT_ARCH"] << endl; configStream << "QT_HOST_ARCH = " << dictionary["QT_HOST_ARCH"] << endl; @@ -2740,8 +2743,8 @@ void Configure::generateConfigfiles() tmpStream << endl; } - if (dictionary[ "QPA" ] == "yes") - tmpStream << endl << "#define Q_WS_QPA" << endl; + // ### For compatibility only, should be removed later. + tmpStream << endl << "#define Q_WS_QPA" << endl; tmpStream << endl << "// Compile time features" << endl; @@ -2781,7 +2784,7 @@ void Configure::generateConfigfiles() } if (dictionary["OPENSSL"] == "linked") qconfigList += "QT_LINKED_OPENSSL"; if (dictionary["DBUS"] == "no") qconfigList += "QT_NO_DBUS"; - if (dictionary["DECLARATIVE_DEBUG"] == "no") qconfigList += "QDECLARATIVE_NO_DEBUG_PROTOCOL"; + if (dictionary["QML_DEBUG"] == "no") qconfigList += "QT_QML_NO_DEBUGGER"; if (dictionary["FREETYPE"] == "no") qconfigList += "QT_NO_FREETYPE"; if (dictionary["NATIVE_GESTURES"] == "no") qconfigList += "QT_NO_NATIVE_GESTURES"; @@ -3000,7 +3003,7 @@ void Configure::displayConfig() cout << "OpenSSL support............." << dictionary[ "OPENSSL" ] << endl; cout << "QtDBus support.............." << dictionary[ "DBUS" ] << endl; cout << "QtWidgets module support...." << dictionary[ "WIDGETS" ] << endl; - cout << "Declarative debugging......." << dictionary[ "DECLARATIVE_DEBUG" ] << endl; + cout << "QML debugging..............." << dictionary[ "QML_DEBUG" ] << endl; cout << "DirectWrite support........." << dictionary[ "DIRECTWRITE" ] << endl << endl; cout << "Third Party Libraries:" << endl;