diff options
301 files changed, 10411 insertions, 3223 deletions
diff --git a/config.tests/unix/makeabs b/config.tests/unix/makeabs index 9d66108..c415cc7 100755 --- a/config.tests/unix/makeabs +++ b/config.tests/unix/makeabs @@ -3,7 +3,13 @@ FILE="$1" RES="$FILE" -if [ `echo $FILE | cut -b1` = "/" ]; then +CUT_ARG="-b1" +if [ `uname -s` = "QNX" ]; then + # QNX does not understand "-b1" + CUT_ARG="-c1" +fi + +if [ `echo $FILE | cut $CUT_ARG` = "/" ]; then true else RES="$PWD/$FILE" @@ -542,9 +542,12 @@ cp "$QMAKE_VARS_FILE" "$outpath/config.tests/.qmake.cache" QMakeVar add styles "cde mac motif plastique cleanlooks windows" QMakeVar add decorations "default windows styled" -QMakeVar add gfx-drivers "linuxfb" +QMakeVar add mouse-drivers "pc" +if [ "$UNAME_SYSTEM" = "Linux" ] ; then + QMakeVar add gfx-drivers "linuxfb" + QMakeVar add mouse-drivers "linuxtp" +fi QMakeVar add kbd-drivers "tty" -QMakeVar add mouse-drivers "pc linuxtp" if [ "$CFG_DEV" = "yes" ]; then QMakeVar add kbd-drivers "um" @@ -619,6 +622,12 @@ CFG_KBD_ON="tty" #default, see QMakeVar above CFG_MOUSE_AVAILABLE="pc linuxtp linuxinput tslib qvfb" CFG_MOUSE_ON="pc linuxtp" #default, see QMakeVar above +if [ -f "$relpath/src/gui/embedded/qscreenqnx_qws.cpp" ]; then + CFG_KBD_AVAILABLE="${CFG_KBD_AVAILABLE} qnx" + CFG_MOUSE_AVAILABLE="${CFG_MOUSE_AVAILABLE} qnx" + CFG_GFX_AVAILABLE="${CFG_GFX_AVAILABLE} qnx" +fi + CFG_ARCH= CFG_HOST_ARCH= CFG_KBD_PLUGIN_AVAILABLE= @@ -2021,6 +2030,12 @@ for e in gawk nawk awk; do fi done +# find perl +PERL="/usr/bin/perl" +if "$WHICH" perl >/dev/null 2>&1 && ( perl /dev/null ) >/dev/null 2>&1; then + PERL=`$WHICH perl` +fi + ### skip this if the user just needs help... if [ "$OPT_HELP" != "yes" ]; then @@ -2249,6 +2264,13 @@ if [ "$CFG_EMBEDDED" != "no" ]; then XPLATFORM="qws/linux-$CFG_EMBEDDED-g++" fi ;; + QNX:*) + [ -z "$PLATFORM" ] && PLATFORM=unsupported/qws/qnx-generic-g++ + if [ -z "$XPLATFORM" ]; then + [ "$CFG_EMBEDDED" = "auto" ] && CFG_EMBEDDED=generic + XPLATFORM="unsupported/qws/qnx-$CFG_EMBEDDED-g++" + fi + ;; CYGWIN*:*) CFG_EMBEDDED=x86 ;; @@ -2400,6 +2422,9 @@ if [ -z "$PLATFORM" ]; then UNIX_SV:*) PLATFORM=unixware-g++ ;; + QNX:*) + PLATFORM=unsupported/qnx-g++ + ;; *) if [ "$OPT_HELP" != "yes" ]; then echo @@ -2625,6 +2650,16 @@ if [ -z "${CFG_HOST_ARCH}" ]; then fi CFG_HOST_ARCH=sparc ;; + QNX:*:*) + case "$UNAME_MACHINE" in + x86pc) + if [ "$OPT_VERBOSE" = "yes" ]; then + echo " QNX on Intel 80x86 (i386)" + fi + CFG_HOST_ARCH=i386 + ;; + esac + ;; *:*:*) if [ "$OPT_VERBOSE" = "yes" ]; then echo " Trying '$UNAME_MACHINE'..." @@ -5723,6 +5758,13 @@ case "$PLATFORM,$CFG_MAC_COCOA" in ;; esac +# disable Qt 3 support on VxWorks +case "$XPLATFORM" in + unsupported/vxworks*) + CFG_QT3SUPPORT="no" + ;; +esac + # enable Qt 3 support functionality if [ "$CFG_QT3SUPPORT" = "yes" ]; then QT_CONFIG="$QT_CONFIG qt3support" @@ -6092,6 +6134,13 @@ case "$XPLATFORM" in ;; esac ;; + unsupported/vxworks-*-g++*) + canBuildWebKit="no" + ;; + unsupported/vxworks-*-dcc*) + canBuildWebKit="no" + canBuildQtXmlPatterns="no" + ;; *-g++*) # Check gcc's version case "$(${QMAKE_CONF_COMPILER} -dumpversion)" in @@ -6328,10 +6377,8 @@ esac # Different edition modules: # network canvas table xml opengl sql # -# Options: -# stl -# # Things that do not affect the Qt API/ABI: +# stl # system-jpeg no-jpeg jpeg # system-mng no-mng mng # system-png no-png png @@ -6352,7 +6399,7 @@ esac # X11 : x11sm xinerama xcursor xfixes xrandr xrender mitshm fontconfig xkb # Embedded: embedded freetype # -ALL_OPTIONS="stl" +ALL_OPTIONS= BUILD_CONFIG= BUILD_OPTIONS= @@ -6366,12 +6413,6 @@ for config_option in $QMAKE_CONFIG $QT_CONFIG; do BUILD_CONFIG="$config_option" ;; - stl) - # these config options affect the Qt API/ABI. they should influence - # the generation of the buildkey, so we don't skip them - SKIP="no" - ;; - *) # skip all other options since they don't affect the Qt API/ABI. ;; esac diff --git a/demos/demos.pro b/demos/demos.pro index 6084550..eda04dc 100644 --- a/demos/demos.pro +++ b/demos/demos.pro @@ -13,7 +13,8 @@ SUBDIRS = \ demos_textedit \ demos_chip \ demos_embeddeddialogs \ - demos_undo + demos_undo \ + demos_sub-attaq contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles1):!contains(QT_CONFIG, opengles1cl):!contains(QT_CONFIG, opengles2):{ SUBDIRS += demos_boxes @@ -61,6 +62,7 @@ demos_mediaplayer.subdir = mediaplayer demos_browser.subdir = browser demos_boxes.subdir = boxes +demos_sub-attaq.subdir = sub-attaq #CONFIG += ordered !ordered { diff --git a/demos/embedded/embedded.pro b/demos/embedded/embedded.pro index 7428b9f..4fd8f9f 100644 --- a/demos/embedded/embedded.pro +++ b/demos/embedded/embedded.pro @@ -2,8 +2,9 @@ TEMPLATE = subdirs SUBDIRS = styledemo contains(QT_CONFIG, svg) { - SUBDIRS += embeddedsvgviewer \ - fluidlauncher + SUBDIRS += embeddedsvgviewer + # no QProcess + !vxworks:!qnx:SUBDIRS += fluidlauncher } # install diff --git a/demos/qtdemo/xml/examples.xml b/demos/qtdemo/xml/examples.xml index 2560848..006bfd0 100644 --- a/demos/qtdemo/xml/examples.xml +++ b/demos/qtdemo/xml/examples.xml @@ -18,6 +18,7 @@ <example filename="browser" name="Browser" /> <example filename="mediaplayer" name="Media Player" /> <example filename="boxes" name="Boxes" /> + <example filename="sub-attaq" name="Sub-attaq" /> </demos> <category dirname="animation" name="Animation Framework"> <example filename="animatedtiles" name="Animated Tiles" /> @@ -26,7 +27,6 @@ <example filename="moveblocks" name="Moving Blocks" /> <example filename="states" name="UI States" /> <example filename="stickman" name="Stickman" /> - <example filename="sub-attaq" name="Sub-attaq" /> </category> <category dirname="qtconcurrent" name="Concurrent Programming"> <example filename="map" name="Map" executable="false" /> @@ -246,5 +246,6 @@ <example filename="qobjectxmlmodel" name="QObjectXmlModel" /> <example filename="filetree" name="File Tree" /> <example filename="trafficinfo" name="Traffic Info" /> + <example filename="schema" name="XML Schema Validation" /> </category> </categories> diff --git a/examples/animation/sub-attaq/animationmanager.cpp b/demos/sub-attaq/animationmanager.cpp index 13266f9..13266f9 100644 --- a/examples/animation/sub-attaq/animationmanager.cpp +++ b/demos/sub-attaq/animationmanager.cpp diff --git a/examples/animation/sub-attaq/animationmanager.h b/demos/sub-attaq/animationmanager.h index 63ecae6..63ecae6 100644 --- a/examples/animation/sub-attaq/animationmanager.h +++ b/demos/sub-attaq/animationmanager.h diff --git a/examples/animation/sub-attaq/boat.cpp b/demos/sub-attaq/boat.cpp index 68e646e..68e646e 100644 --- a/examples/animation/sub-attaq/boat.cpp +++ b/demos/sub-attaq/boat.cpp diff --git a/examples/animation/sub-attaq/boat.h b/demos/sub-attaq/boat.h index f6b1a90..f6b1a90 100644 --- a/examples/animation/sub-attaq/boat.h +++ b/demos/sub-attaq/boat.h diff --git a/examples/animation/sub-attaq/boat_p.h b/demos/sub-attaq/boat_p.h index 4e962fc..4e962fc 100644 --- a/examples/animation/sub-attaq/boat_p.h +++ b/demos/sub-attaq/boat_p.h diff --git a/examples/animation/sub-attaq/bomb.cpp b/demos/sub-attaq/bomb.cpp index e92a723..e92a723 100644 --- a/examples/animation/sub-attaq/bomb.cpp +++ b/demos/sub-attaq/bomb.cpp diff --git a/examples/animation/sub-attaq/bomb.h b/demos/sub-attaq/bomb.h index ed6b0f5..ed6b0f5 100644 --- a/examples/animation/sub-attaq/bomb.h +++ b/demos/sub-attaq/bomb.h diff --git a/examples/animation/sub-attaq/custompropertyanimation.cpp b/demos/sub-attaq/custompropertyanimation.cpp index 9282f42..9282f42 100644 --- a/examples/animation/sub-attaq/custompropertyanimation.cpp +++ b/demos/sub-attaq/custompropertyanimation.cpp diff --git a/examples/animation/sub-attaq/custompropertyanimation.h b/demos/sub-attaq/custompropertyanimation.h index a984163..a984163 100644 --- a/examples/animation/sub-attaq/custompropertyanimation.h +++ b/demos/sub-attaq/custompropertyanimation.h diff --git a/demos/sub-attaq/data.xml b/demos/sub-attaq/data.xml new file mode 100644 index 0000000..0f30515 --- /dev/null +++ b/demos/sub-attaq/data.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<subattaq> + <submarines> + <submarine type="0" points="10" name="Q1" /> + <submarine type="1" points="20" name="Q2" /> + </submarines> + <levels> + <level id="0" name="Seaman recruit"> + <subinstance type="0" nb="1"/> + </level> + <level id="1" name="Seaman apprentice"> + <subinstance type="0" nb="2"/> + </level> + <level id="2" name="Seaman"> + <subinstance type="0" nb="4"/> + </level> + <level id="3" name="Petty Officer Third Class"> + <subinstance type="0" nb="6"/> + </level> + <level id="4" name="Petty Officer Second Class"> + <subinstance type="0" nb="6"/> + </level> + <level id="5" name="Petty Officer First Class"> + <subinstance type="0" nb="8"/> + </level> + <level id="6" name="Lieutenant"> + <subinstance type="0" nb="10"/> + </level> + <level id="7" name="Commander"> + <subinstance type="0" nb="15"/> + </level> + <level id="8" name="Captain"> + <subinstance type="0" nb="12"/> + </level> + <level id="9" name="Admiral"> + <subinstance type="0" nb="12"/> + </level> + </levels> +</subattaq> diff --git a/examples/animation/sub-attaq/graphicsscene.cpp b/demos/sub-attaq/graphicsscene.cpp index fcbc1b3..fcbc1b3 100644 --- a/examples/animation/sub-attaq/graphicsscene.cpp +++ b/demos/sub-attaq/graphicsscene.cpp diff --git a/examples/animation/sub-attaq/graphicsscene.h b/demos/sub-attaq/graphicsscene.h index 068ee97..068ee97 100644 --- a/examples/animation/sub-attaq/graphicsscene.h +++ b/demos/sub-attaq/graphicsscene.h diff --git a/examples/animation/sub-attaq/main.cpp b/demos/sub-attaq/main.cpp index 4f6f4f9..4f6f4f9 100644 --- a/examples/animation/sub-attaq/main.cpp +++ b/demos/sub-attaq/main.cpp diff --git a/examples/animation/sub-attaq/mainwindow.cpp b/demos/sub-attaq/mainwindow.cpp index bcccd34..bcccd34 100644 --- a/examples/animation/sub-attaq/mainwindow.cpp +++ b/demos/sub-attaq/mainwindow.cpp diff --git a/examples/animation/sub-attaq/mainwindow.h b/demos/sub-attaq/mainwindow.h index 08cfcd9..08cfcd9 100644 --- a/examples/animation/sub-attaq/mainwindow.h +++ b/demos/sub-attaq/mainwindow.h diff --git a/examples/animation/sub-attaq/pics/big/background.png b/demos/sub-attaq/pics/big/background.png Binary files differindex 9f58157..9f58157 100644 --- a/examples/animation/sub-attaq/pics/big/background.png +++ b/demos/sub-attaq/pics/big/background.png diff --git a/examples/animation/sub-attaq/pics/big/boat.png b/demos/sub-attaq/pics/big/boat.png Binary files differindex be82dff..be82dff 100644 --- a/examples/animation/sub-attaq/pics/big/boat.png +++ b/demos/sub-attaq/pics/big/boat.png diff --git a/examples/animation/sub-attaq/pics/small/bomb.png b/demos/sub-attaq/pics/big/bomb.png Binary files differindex 3af5f2f..3af5f2f 100644 --- a/examples/animation/sub-attaq/pics/small/bomb.png +++ b/demos/sub-attaq/pics/big/bomb.png diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png b/demos/sub-attaq/pics/big/explosion/boat/step1.png Binary files differindex c9fd8b0..c9fd8b0 100644 --- a/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png +++ b/demos/sub-attaq/pics/big/explosion/boat/step1.png diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png b/demos/sub-attaq/pics/big/explosion/boat/step2.png Binary files differindex 7528f2d..7528f2d 100644 --- a/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png +++ b/demos/sub-attaq/pics/big/explosion/boat/step2.png diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png b/demos/sub-attaq/pics/big/explosion/boat/step3.png Binary files differindex aae9c9c..aae9c9c 100644 --- a/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png +++ b/demos/sub-attaq/pics/big/explosion/boat/step3.png diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png b/demos/sub-attaq/pics/big/explosion/boat/step4.png Binary files differindex d697c1b..d697c1b 100644 --- a/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png +++ b/demos/sub-attaq/pics/big/explosion/boat/step4.png diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png b/demos/sub-attaq/pics/big/explosion/submarine/step1.png Binary files differindex 88ca514..88ca514 100644 --- a/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png +++ b/demos/sub-attaq/pics/big/explosion/submarine/step1.png diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png b/demos/sub-attaq/pics/big/explosion/submarine/step2.png Binary files differindex 524f589..524f589 100644 --- a/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png +++ b/demos/sub-attaq/pics/big/explosion/submarine/step2.png diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png b/demos/sub-attaq/pics/big/explosion/submarine/step3.png Binary files differindex 2cca1e8..2cca1e8 100644 --- a/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png +++ b/demos/sub-attaq/pics/big/explosion/submarine/step3.png diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png b/demos/sub-attaq/pics/big/explosion/submarine/step4.png Binary files differindex 82100a8..82100a8 100644 --- a/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png +++ b/demos/sub-attaq/pics/big/explosion/submarine/step4.png diff --git a/examples/animation/sub-attaq/pics/big/submarine.png b/demos/sub-attaq/pics/big/submarine.png Binary files differindex df435dc..df435dc 100644 --- a/examples/animation/sub-attaq/pics/big/submarine.png +++ b/demos/sub-attaq/pics/big/submarine.png diff --git a/examples/animation/sub-attaq/pics/big/surface.png b/demos/sub-attaq/pics/big/surface.png Binary files differindex 4eba29e..4eba29e 100644 --- a/examples/animation/sub-attaq/pics/big/surface.png +++ b/demos/sub-attaq/pics/big/surface.png diff --git a/examples/animation/sub-attaq/pics/small/torpedo.png b/demos/sub-attaq/pics/big/torpedo.png Binary files differindex f9c2687..f9c2687 100644 --- a/examples/animation/sub-attaq/pics/small/torpedo.png +++ b/demos/sub-attaq/pics/big/torpedo.png diff --git a/examples/animation/sub-attaq/pics/scalable/background-n810.svg b/demos/sub-attaq/pics/scalable/background-n810.svg index ece9f7a..ece9f7a 100644 --- a/examples/animation/sub-attaq/pics/scalable/background-n810.svg +++ b/demos/sub-attaq/pics/scalable/background-n810.svg diff --git a/examples/animation/sub-attaq/pics/scalable/background.svg b/demos/sub-attaq/pics/scalable/background.svg index 0be2680..0be2680 100644 --- a/examples/animation/sub-attaq/pics/scalable/background.svg +++ b/demos/sub-attaq/pics/scalable/background.svg diff --git a/examples/animation/sub-attaq/pics/scalable/boat.svg b/demos/sub-attaq/pics/scalable/boat.svg index 5298821b..5298821b 100644 --- a/examples/animation/sub-attaq/pics/scalable/boat.svg +++ b/demos/sub-attaq/pics/scalable/boat.svg diff --git a/examples/animation/sub-attaq/pics/scalable/bomb.svg b/demos/sub-attaq/pics/scalable/bomb.svg index 294771a..294771a 100644 --- a/examples/animation/sub-attaq/pics/scalable/bomb.svg +++ b/demos/sub-attaq/pics/scalable/bomb.svg diff --git a/examples/animation/sub-attaq/pics/scalable/sand.svg b/demos/sub-attaq/pics/scalable/sand.svg index 8af11b7..8af11b7 100644 --- a/examples/animation/sub-attaq/pics/scalable/sand.svg +++ b/demos/sub-attaq/pics/scalable/sand.svg diff --git a/examples/animation/sub-attaq/pics/scalable/see.svg b/demos/sub-attaq/pics/scalable/see.svg index 0666691..0666691 100644 --- a/examples/animation/sub-attaq/pics/scalable/see.svg +++ b/demos/sub-attaq/pics/scalable/see.svg diff --git a/examples/animation/sub-attaq/pics/scalable/sky.svg b/demos/sub-attaq/pics/scalable/sky.svg index 1546c08..1546c08 100644 --- a/examples/animation/sub-attaq/pics/scalable/sky.svg +++ b/demos/sub-attaq/pics/scalable/sky.svg diff --git a/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg b/demos/sub-attaq/pics/scalable/sub-attaq.svg index b075179..b075179 100644 --- a/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg +++ b/demos/sub-attaq/pics/scalable/sub-attaq.svg diff --git a/examples/animation/sub-attaq/pics/scalable/submarine.svg b/demos/sub-attaq/pics/scalable/submarine.svg index 8a0ffdd..8a0ffdd 100644 --- a/examples/animation/sub-attaq/pics/scalable/submarine.svg +++ b/demos/sub-attaq/pics/scalable/submarine.svg diff --git a/examples/animation/sub-attaq/pics/scalable/surface.svg b/demos/sub-attaq/pics/scalable/surface.svg index 40ed239..40ed239 100644 --- a/examples/animation/sub-attaq/pics/scalable/surface.svg +++ b/demos/sub-attaq/pics/scalable/surface.svg diff --git a/examples/animation/sub-attaq/pics/scalable/torpedo.svg b/demos/sub-attaq/pics/scalable/torpedo.svg index 48e429d..48e429d 100644 --- a/examples/animation/sub-attaq/pics/scalable/torpedo.svg +++ b/demos/sub-attaq/pics/scalable/torpedo.svg diff --git a/examples/animation/sub-attaq/pics/small/background.png b/demos/sub-attaq/pics/small/background.png Binary files differindex 5ad3db6..5ad3db6 100644 --- a/examples/animation/sub-attaq/pics/small/background.png +++ b/demos/sub-attaq/pics/small/background.png diff --git a/examples/animation/sub-attaq/pics/small/boat.png b/demos/sub-attaq/pics/small/boat.png Binary files differindex 114ccc3..114ccc3 100644 --- a/examples/animation/sub-attaq/pics/small/boat.png +++ b/demos/sub-attaq/pics/small/boat.png diff --git a/examples/animation/sub-attaq/pics/big/bomb.png b/demos/sub-attaq/pics/small/bomb.png Binary files differindex 3af5f2f..3af5f2f 100644 --- a/examples/animation/sub-attaq/pics/big/bomb.png +++ b/demos/sub-attaq/pics/small/bomb.png diff --git a/examples/animation/sub-attaq/pics/small/submarine.png b/demos/sub-attaq/pics/small/submarine.png Binary files differindex 0c0c350..0c0c350 100644 --- a/examples/animation/sub-attaq/pics/small/submarine.png +++ b/demos/sub-attaq/pics/small/submarine.png diff --git a/examples/animation/sub-attaq/pics/small/surface.png b/demos/sub-attaq/pics/small/surface.png Binary files differindex 06d0e47..06d0e47 100644 --- a/examples/animation/sub-attaq/pics/small/surface.png +++ b/demos/sub-attaq/pics/small/surface.png diff --git a/examples/animation/sub-attaq/pics/big/torpedo.png b/demos/sub-attaq/pics/small/torpedo.png Binary files differindex f9c2687..f9c2687 100644 --- a/examples/animation/sub-attaq/pics/big/torpedo.png +++ b/demos/sub-attaq/pics/small/torpedo.png diff --git a/examples/animation/sub-attaq/pics/welcome/logo-a.png b/demos/sub-attaq/pics/welcome/logo-a.png Binary files differindex 67dd76d..67dd76d 100644 --- a/examples/animation/sub-attaq/pics/welcome/logo-a.png +++ b/demos/sub-attaq/pics/welcome/logo-a.png diff --git a/examples/animation/sub-attaq/pics/welcome/logo-a2.png b/demos/sub-attaq/pics/welcome/logo-a2.png Binary files differindex 17668b0..17668b0 100644 --- a/examples/animation/sub-attaq/pics/welcome/logo-a2.png +++ b/demos/sub-attaq/pics/welcome/logo-a2.png diff --git a/examples/animation/sub-attaq/pics/welcome/logo-b.png b/demos/sub-attaq/pics/welcome/logo-b.png Binary files differindex cf6c045..cf6c045 100644 --- a/examples/animation/sub-attaq/pics/welcome/logo-b.png +++ b/demos/sub-attaq/pics/welcome/logo-b.png diff --git a/examples/animation/sub-attaq/pics/welcome/logo-dash.png b/demos/sub-attaq/pics/welcome/logo-dash.png Binary files differindex 219233c..219233c 100644 --- a/examples/animation/sub-attaq/pics/welcome/logo-dash.png +++ b/demos/sub-attaq/pics/welcome/logo-dash.png diff --git a/examples/animation/sub-attaq/pics/welcome/logo-excl.png b/demos/sub-attaq/pics/welcome/logo-excl.png Binary files differindex 8dd0a2e..8dd0a2e 100644 --- a/examples/animation/sub-attaq/pics/welcome/logo-excl.png +++ b/demos/sub-attaq/pics/welcome/logo-excl.png diff --git a/examples/animation/sub-attaq/pics/welcome/logo-q.png b/demos/sub-attaq/pics/welcome/logo-q.png Binary files differindex 86e588d..86e588d 100644 --- a/examples/animation/sub-attaq/pics/welcome/logo-q.png +++ b/demos/sub-attaq/pics/welcome/logo-q.png diff --git a/examples/animation/sub-attaq/pics/welcome/logo-s.png b/demos/sub-attaq/pics/welcome/logo-s.png Binary files differindex 7b6a36e..7b6a36e 100644 --- a/examples/animation/sub-attaq/pics/welcome/logo-s.png +++ b/demos/sub-attaq/pics/welcome/logo-s.png diff --git a/examples/animation/sub-attaq/pics/welcome/logo-t.png b/demos/sub-attaq/pics/welcome/logo-t.png Binary files differindex b2e3526..b2e3526 100644 --- a/examples/animation/sub-attaq/pics/welcome/logo-t.png +++ b/demos/sub-attaq/pics/welcome/logo-t.png diff --git a/examples/animation/sub-attaq/pics/welcome/logo-t2.png b/demos/sub-attaq/pics/welcome/logo-t2.png Binary files differindex b11a778..b11a778 100644 --- a/examples/animation/sub-attaq/pics/welcome/logo-t2.png +++ b/demos/sub-attaq/pics/welcome/logo-t2.png diff --git a/examples/animation/sub-attaq/pics/welcome/logo-u.png b/demos/sub-attaq/pics/welcome/logo-u.png Binary files differindex 24eede8..24eede8 100644 --- a/examples/animation/sub-attaq/pics/welcome/logo-u.png +++ b/demos/sub-attaq/pics/welcome/logo-u.png diff --git a/examples/animation/sub-attaq/pixmapitem.cpp b/demos/sub-attaq/pixmapitem.cpp index ed0f075..ed0f075 100644 --- a/examples/animation/sub-attaq/pixmapitem.cpp +++ b/demos/sub-attaq/pixmapitem.cpp diff --git a/examples/animation/sub-attaq/pixmapitem.h b/demos/sub-attaq/pixmapitem.h index e32973e..e32973e 100644 --- a/examples/animation/sub-attaq/pixmapitem.h +++ b/demos/sub-attaq/pixmapitem.h diff --git a/examples/animation/sub-attaq/progressitem.cpp b/demos/sub-attaq/progressitem.cpp index 9ccaa72..9ccaa72 100644 --- a/examples/animation/sub-attaq/progressitem.cpp +++ b/demos/sub-attaq/progressitem.cpp diff --git a/examples/animation/sub-attaq/progressitem.h b/demos/sub-attaq/progressitem.h index 7be57c9..7be57c9 100644 --- a/examples/animation/sub-attaq/progressitem.h +++ b/demos/sub-attaq/progressitem.h diff --git a/examples/animation/sub-attaq/qanimationstate.cpp b/demos/sub-attaq/qanimationstate.cpp index 4e6df56..4e6df56 100644 --- a/examples/animation/sub-attaq/qanimationstate.cpp +++ b/demos/sub-attaq/qanimationstate.cpp diff --git a/examples/animation/sub-attaq/qanimationstate.h b/demos/sub-attaq/qanimationstate.h index 6c5b565..6c5b565 100644 --- a/examples/animation/sub-attaq/qanimationstate.h +++ b/demos/sub-attaq/qanimationstate.h diff --git a/examples/animation/sub-attaq/states.cpp b/demos/sub-attaq/states.cpp index d63737f..d63737f 100644 --- a/examples/animation/sub-attaq/states.cpp +++ b/demos/sub-attaq/states.cpp diff --git a/examples/animation/sub-attaq/states.h b/demos/sub-attaq/states.h index c3d81e7..c3d81e7 100644 --- a/examples/animation/sub-attaq/states.h +++ b/demos/sub-attaq/states.h diff --git a/examples/animation/sub-attaq/sub-attaq.pro b/demos/sub-attaq/sub-attaq.pro index d13a099..ad1327d 100644 --- a/examples/animation/sub-attaq/sub-attaq.pro +++ b/demos/sub-attaq/sub-attaq.pro @@ -30,7 +30,8 @@ SOURCES += boat.cpp \ RESOURCES += subattaq.qrc # install -target.path = $$[QT_INSTALL_EXAMPLES]/animation/sub-attaq +target.path = $$[QT_INSTALL_DEMOS]/animation/sub-attaq sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS sub-attaq.pro pics -sources.path = $$[QT_INSTALL_EXAMPLES]/animation/sub-attaq +sources.path = $$[QT_INSTALL_DEMOS]/animation/sub-attaq INSTALLS += target sources + diff --git a/examples/animation/sub-attaq/subattaq.qrc b/demos/sub-attaq/subattaq.qrc index 80a3af1..80a3af1 100644 --- a/examples/animation/sub-attaq/subattaq.qrc +++ b/demos/sub-attaq/subattaq.qrc diff --git a/examples/animation/sub-attaq/submarine.cpp b/demos/sub-attaq/submarine.cpp index 78a9539..029e04b 100644 --- a/examples/animation/sub-attaq/submarine.cpp +++ b/demos/sub-attaq/submarine.cpp @@ -109,7 +109,14 @@ SubMarine::SubMarine(int type, const QString &name, int points, QGraphicsItem * setZValue(5); setFlags(QGraphicsItem::ItemIsMovable); resize(pixmapItem->boundingRect().width(),pixmapItem->boundingRect().height()); - setTransformOrigin(boundingRect().center()); + setTransformOriginPoint(boundingRect().center()); + + graphicsRotation = new QGraphicsRotation3D(this); + graphicsRotation->setAxis(QVector3D(0, 1, 0)); + graphicsRotation->setOrigin(QPointF(size().width()/2, size().height()/2)); + QList<QGraphicsTransform *> r; + r.append(graphicsRotation); + setTransformations(r); //We setup the state machine of the submarine QStateMachine *machine = new QStateMachine(this); @@ -166,7 +173,7 @@ void SubMarine::setCurrentDirection(SubMarine::Movement direction) if (this->direction == direction) return; if (direction == SubMarine::Right && this->direction == SubMarine::None) { - setYRotation(180); + graphicsRotation->setAngle(180); } this->direction = direction; } diff --git a/examples/animation/sub-attaq/submarine.h b/demos/sub-attaq/submarine.h index 481e816..564e9c6 100644 --- a/examples/animation/sub-attaq/submarine.h +++ b/demos/sub-attaq/submarine.h @@ -45,6 +45,7 @@ //Qt #include <QtCore/QVariantAnimation> #include <QtGui/QGraphicsWidget> +#include <QtGui/QGraphicsTransform> class PixmapItem; @@ -75,6 +76,8 @@ public: virtual int type() const; + QGraphicsRotation3D *rotation3d() const { return graphicsRotation; } + signals: void subMarineDestroyed(); void subMarineExecutionFinished(); @@ -87,6 +90,7 @@ private: int speed; Movement direction; PixmapItem *pixmapItem; + QGraphicsRotation3D *graphicsRotation; }; #endif //__SUBMARINE__H__ diff --git a/examples/animation/sub-attaq/submarine_p.h b/demos/sub-attaq/submarine_p.h index e8df877..c04b25b 100644 --- a/examples/animation/sub-attaq/submarine_p.h +++ b/demos/sub-attaq/submarine_p.h @@ -109,7 +109,7 @@ class ReturnState : public QAnimationState public: ReturnState(SubMarine *submarine, QState *parent = 0) : QAnimationState(parent) { - returnAnimation = new QPropertyAnimation(submarine, "yRotation"); + returnAnimation = new QPropertyAnimation(submarine->rotation3d(), "angle"); AnimationManager::self()->registerAnimation(returnAnimation); setAnimation(returnAnimation); this->submarine = submarine; @@ -119,7 +119,7 @@ protected: void onEntry(QEvent *e) { returnAnimation->stop(); - returnAnimation->setStartValue(submarine->yRotation()); + returnAnimation->setStartValue(submarine->rotation3d()->angle()); returnAnimation->setEndValue(submarine->currentDirection() == SubMarine::Right ? 360. : 180.); returnAnimation->setDuration(500); QAnimationState::onEntry(e); diff --git a/examples/animation/sub-attaq/torpedo.cpp b/demos/sub-attaq/torpedo.cpp index fe79488..fe79488 100644 --- a/examples/animation/sub-attaq/torpedo.cpp +++ b/demos/sub-attaq/torpedo.cpp diff --git a/examples/animation/sub-attaq/torpedo.h b/demos/sub-attaq/torpedo.h index c44037f..c44037f 100644 --- a/examples/animation/sub-attaq/torpedo.h +++ b/demos/sub-attaq/torpedo.h diff --git a/dist/changes-4.6.0 b/dist/changes-4.6.0 index 6c7e450..383c6b7 100644 --- a/dist/changes-4.6.0 +++ b/dist/changes-4.6.0 @@ -87,3 +87,17 @@ information about a particular change. That means QUrl no longer accepts some URLs that were invalid before, but weren't interpreted as such. + +- The Unix configure-time check for STL is stricter now in Qt + 4.6.0. This means some legacy STL implementations may fail to pass + the test and, therefore, Qt will automatically disable STL support. + + This is a binary-compatible change: existing code will continue to + work without being recompiled. However, it affects the source code, + since some STL-compatibility API will not be enabled. + + Platforms affected by this change: + * solaris-cc-* with the default (Cstd) C++ STL library + recommendation: use -library=stlport4 + See Sun Studio's documentation for the effects of this option + diff --git a/doc/src/demos/sub-attaq.qdoc b/doc/src/demos/sub-attaq.qdoc new file mode 100644 index 0000000..6bbf763 --- /dev/null +++ b/doc/src/demos/sub-attaq.qdoc @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example demos/sub-attaq + \title Sub-Attaq + + This demo shows Qt's ability to combine \l{The Animation Framework}{the animation framework} + and \l{The State Machine Framework}{the state machine framework} to create a game. + + \image sub-attaq-demo.png + + The purpose of the game is to destroy all submarines to win the current level. + The boat can be controlled using left and right keys. To fire a bomb you can press + up and down keys. +*/ diff --git a/doc/src/images/sub-attaq-demo.png b/doc/src/images/sub-attaq-demo.png Binary files differnew file mode 100644 index 0000000..5a35ec6 --- /dev/null +++ b/doc/src/images/sub-attaq-demo.png diff --git a/doc/src/platform-notes-rtos.qdoc b/doc/src/platform-notes-rtos.qdoc new file mode 100644 index 0000000..8a52d84 --- /dev/null +++ b/doc/src/platform-notes-rtos.qdoc @@ -0,0 +1,220 @@ +/*! + \page platform-notes-vxworks.html + \title Platform Notes - VxWorks + \contentspage Platform Notes + \target VxWorks + + \note VxWorks is a community supported platform. See the + \l{Supported Platforms} page for more information. + + This page contains information about the Qt for VxWorks port. More + information about the combinations of platforms and compilers supported + by Qt can be found on the \l{Supported Platforms} page. + + \tableofcontents + + \section1 Supported Versions + + Qt has been tested on WindRiver VxWorks 6.7 in kernel mode using the + vendor supplied GCC compiler, targetting both the x86 simulator + (simpentium) and Power-PC devices (ppc). + VxWorks' RTP mode is currently not supported. + + \section1 Limitations + + The VxWorks kernel has an optional POSIX compatibility layer, but this + layer does not implement all POSIX functionality needed for a complete + Qt port. + + \table + \header \o Function \o Notes + \row \o QProcess + \o Not available - VxWorks has no concept of processes. + \row \o QSharedMemory + \o Not available - VxWorks has only a global, flat address space. + \row \o QSystemSemaphore + \o Not available - VxWorks has no concept of processes. + \row \o QLibrary + \o QLibrary is only a small stub to make it possible to build + static plugins. + \row \o QCoreApplication + \o Can only be instantiated once. Qt's Q(CoreE)Application is + tightly coupled to one address space and process, while VxWorks + only supports one global address space and has no concept of + processes. + \row \o Phonon + \o There is no standard audio backend, which could be integrated into Phonon. + \row \o Qt3Support + \o The Qt3Support library is not available on QNX. + + \endtable + + \section1 Build Instructions + + Qt for VxWorks needs to be \l{Cross-Compiling Qt for Embedded Linux + Applications}{cross-compiled} on a Linux host. \c configure and \c make + the build like you would with a standard \l{Cross-Compiling Qt for + Embedded Linux Applications}{embedded Linux cross build}. Building the + VxWorks simulator would be done like this: + + \code + <path/to/qt/sources>/configure -xplatform unsupported/vxworks-simpentium-g++ -embedded vxworks -exceptions -no-gfx-linuxfb -no-mouse-linuxtp -no-mouse-pc -no-kbd-tty + make + \endcode + + \list + \o \c{-xplatform unsupported/qws/vxworks-simpentium-g++} - selects the x86 simulator mkspec for VxWorks + \o \c{-embedded vxworks} - builds the embedded version of Qt and sets the architecture to VxWorks + \o \c{-exceptions} - see General Notes below + \o \c{-no-gfx-linuxfb}, \c{-no-mouse-linuxtp}, \c{-no-mouse-pc} and \c{-no-kbd-tty} are Linux specific and won't work on VxWorks + \endlist + + \section1 General Notes + + \list + + \o Configuring with \c{-exceptions} is necessary, because the VxWorks + 6.7 g++ headers require exceptions to be enabled when compiling C++ + code. + + \o Configure's \c{-xplatform} can be any of + \c{unsupported/vxworks-(simpentium|ppc)-(g++|dcc)}, but \c{dcc} + (WindRiver DIAB compiler) has not yet tested been tested with Qt 4.6 and + VxWorks 6.7. + + \o Building shared libraries with \c{-shared} (the default) doesn't + really build shared libraries, like e.g. on Linux, since these are not + supported by VxWorks. Instead, qmake will created partially linked + objects, that can be loaded at runtime with \c{ld}. + + \o Creating static builds with \c{-static} is fully supported. + + \o "Munching" (generating constructors/destructors for static C++ + objects) is done automatically by a special qmake extension (for both + shared libraries and executables) + + \o VxWorks does not have a file system layer, but the low level storage + drivers have to supply a file system like interface to the applications. + Since each driver implements a different subset of the functionality + supported by this interface, Qt's file system auto-tests show wildly + differing results running on different "file systems". The best results + can be achieved when running on a (writable) NFS mount, since that + provides the most Unix-ish interface. The worst results come from the + FTP file system driver, which may crash when accessed by a + \c{QFileInfo}. + + \o Keep in mind that VxWorks doesn't call your \c{main()} function with + the standard \c{argc}/\c{argv} parameters. So either add a special + \c{vxmain()} function or use a tool like \c{callmain} to translate + VxWorks' commandline arguments to an \c{argc}/\c{argv} array. + + \o Some example will fail to build, due to some missing dependencies + (e.g. shared memory) - this will be fixed in a later release. + + \endlist +*/ + +/*! + \page platform-notes-qnx.html + \title Platform Notes - QNX + \contentspage Platform Notes + \target QNX + + \note QNX is a community supported platform. See the + \l{Supported Platforms} page for more information. + + This page contains information about the Qt for QNX port. More + information about the combinations of platforms and compilers supported + by Qt can be found on the \l{Supported Platforms} page. + + Note that Qt for QNX is currently based on \l{Qt for Embedded Linux}, which + contains its own windowing system. Mixing QNX's Photon environment with + Qt for QNX is currently not possible. Building Qt for QNX with Photon's + X11 embedded server is not recommended due to missing support for X11 extensions, + resulting in poor rendering quality. + + Qt for QNX contains experimental screen and input drivers based on QNX's + \c devi-hid and \c io-display. For more information, check the class documentation + for QQnxScreen, QWSQnxKeyboardHandler and QQnxMouseHandler. See the + \l{Porting Qt for Embedded Linux to a New Architecture} document for information + on how to add custom screen or input drivers. + + \tableofcontents + + \section1 Supported Versions + + Qt has been tested on QNX 6.4 on i386 and PowerPC targets with QNX's default + gcc compiler. + + \section1 Limitations + + Some of Qt's functionality is currently not available on QNX: + + \table + \header \o Function \o Notes + \row \o QProcess + \o Not available - QNX doesn't support mixing threads and processes. + \row \o QSharedMemory + \o Not available - QNX doesn't support SYSV style shared memory. + \row \o QSystemSemaphore + \o Not available - QNX doesn't support SYSV style system semaphores. + \row \o QWS Multi Process + \o QT_NO_QWS_MULTIPROCESS is always on due to missing shared memory support. + \row \o Phonon + \o There is no standard audio backend, which could be integrated into Phonon. + \row \o Qt3Support + \o The Qt3Support library is not available on QNX. + \endtable + + \section1 Build Instructions + + Qt for QNX needs to be built either on a QNX system, or \l{Cross-Compiling Qt + for Embedded Linux Applications}{cross-compiled} on a Linux host. In either + case, The QNX Software Development Platform must be installed. + + Example configure line for cross-compiling Qt for QNX on a Linux host for an + i386 QNX target: + + \code + configure -xplatform unsupported/qws/qnx-i386-g++ -embedded i386 -no-gfx-linuxfb -no-mouse-linuxtp -no-kbd-tty -no-qt3support -qt-gfx-qnx -qt-mouse-qnx -qt-kbd-qnx -no-exceptions + \endcode + + \list + \o \c{-xplatform unsupported/qws/qnx-i386-g++} - selects the i386-g++ mkspec for QNX + \o \c{-embedded i386} - builds the embedded version of Qt and sets the architecture to i386 + \o \c{-no-gfx-linuxfb}, \c{-no-mouse-linuxtp} and \c{-no-kbd-tty} are Linux specific and won't work on QNX + \o \c{-no-qt3support} - required since the Qt3 support classes are not supported on QNX + \o \c{-no-exceptions} - reduces the size of the library by disabling exception support + \o \c{-qt-gfx-qnx} - enables the experimental \c{io-graphics} based display driver + \o \c{-qt-mouse-qnx} - enables the experimental \c{devi-hig} based mouse driver + \o \c{-qt-kbd-qnx} - enables the experimental \c{devi-hig} based keyboard driver + \endlist + + \section1 General Notes + + \list + \o To enable the experimental QNX display and input drivers, \c{io-display} needs to be + up and running. The \c devi-hid based Qt input drivers require \c devi-hid to run + in resource mode without Photon support. To enable a standard mouse and keyboard + combination, run \c devi-hid as follows: \c{/usr/photon/bin/devi-hid -Pr kbd mouse}. + Note that your current shell will not accept keyboard and mouse input anymore after + running that command, so run it either from a script that launches a Qt application + afterwards, or make sure to have remote login available to launch a Qt application. + In addition, the \c QWS_DISPLAY, \c QWS_MOUSE_PROTO and \c QWS_KEYBOARD environment + variables should all be set to \c{qnx} before running a Qt application. + + \o The 3rd party TIFF library currently doesn't build due to the missing \c inflateSync + symbol from QNX's \c{libz.so.2}. Workarounds would be to manually replace QNX's libz + with a newer version, or disable the TIFF plugin entierly by appending + \c{QT_CONFIG += no-tiff} to \c{.qmake.cache} after configuring Qt. + + \o Some of the tools, examples and demos do not compile due to dependencies on QProcess + or other classes that are not available on QNX. + \endlist + + \section1 Platform Regressions + + Qt for QNX's behavior is mostly identical with \l{Qt for Embedded Linux}. However, + some regressions were spotted in QDateTime computation around year 0 and year 1970, + which have been tracked back to faulty time zone data on some QNX versions. +*/ diff --git a/doc/src/platform-notes.qdoc b/doc/src/platform-notes.qdoc index c788024..7c97f65 100644 --- a/doc/src/platform-notes.qdoc +++ b/doc/src/platform-notes.qdoc @@ -60,6 +60,10 @@ \tableofcontents{1 Platform Notes - Embedded Linux} \o \l{Platform Notes - Windows CE} \tableofcontents{1 Platform Notes - Windows CE} + \o \l{Platform Notes - QNX} + \tableofcontents{1 Platform Notes - QNX} + \o \l{Platform Notes - VxWorks} + \tableofcontents{1 Platform Notes - VxWorks} \endlist See also the \l{Compiler Notes} for information about compiler-specific @@ -374,6 +378,8 @@ improve support for this feature. */ + \row \o \l{QNX} \o Intel 32-bit, PowerPC \o unsupported/qnx-<arch>-g++ \o QNX 6.4 GCC + \row \o VxWorks \o Intel 32-bit, PowerPC \o unsupported/vxworks-<arch>-g++ \o VxWorks 6.7 GCC /*! \page platform-notes-windows-ce.html diff --git a/doc/src/qtxmlpatterns.qdoc b/doc/src/qtxmlpatterns.qdoc index 9f8677b..3177736 100644 --- a/doc/src/qtxmlpatterns.qdoc +++ b/doc/src/qtxmlpatterns.qdoc @@ -841,6 +841,12 @@ \section2 XML Schema 1.0 + There are two ways QtXmlPatterns can be used to validate schemas: + You can use the C++ API in your Qt application using the classes + QXmlSchema and QXmlSchemaValidator, or you can use the command line + utility named xmlpatternsvalidator (located in the "bin" directory + of your Qt build). + The QtXmlPatterns implementation of XML Schema validation supports the schema specification version 1.0 in large parts. Known problems of the implementation and areas where conformancy may be questionable diff --git a/doc/src/supported-platforms.qdoc b/doc/src/supported-platforms.qdoc index 25251fe..3f35e14 100644 --- a/doc/src/supported-platforms.qdoc +++ b/doc/src/supported-platforms.qdoc @@ -54,7 +54,7 @@ Qt is supported on a variety of 32-bit and 64-bit platforms, and can usually be built on each platform with GCC, a vendor-supplied compiler, or a third party compiler. Although Qt may be built on a range of platform-compiler - combinations, only a subset of these are actively supported by Qt. + combinations, only a subset of these are actively supported by Nokia. \tableofcontents diff --git a/examples/animation/animation.pro b/examples/animation/animation.pro index 9a2874b..c72c532 100644 --- a/examples/animation/animation.pro +++ b/examples/animation/animation.pro @@ -7,7 +7,6 @@ SUBDIRS += \ moveblocks \ states \ stickman \ - sub-attaq # install target.path = $$[QT_INSTALL_EXAMPLES]/animation diff --git a/examples/animation/sub-attaq/data.xml b/examples/animation/sub-attaq/data.xml deleted file mode 100644 index 41d4754..0000000 --- a/examples/animation/sub-attaq/data.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<subattaq> - <submarines> - <submarine type="0" points="10" name="Q1" /> - <submarine type="1" points="20" name="Q2" /> - </submarines> - <levels> - <level id="0" name="Seaman recruit"> - <subinstance type="0" nb="2"/> - </level> - <level id="1" name="Seaman apprentice"> - <subinstance type="0" nb="4"/> - </level> - </levels> -</subattaq> diff --git a/examples/ipc/ipc.pro b/examples/ipc/ipc.pro index 0698f89..9098936 100644 --- a/examples/ipc/ipc.pro +++ b/examples/ipc/ipc.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs -SUBDIRS = sharedmemory +# no QSharedMemory +!vxworks:!qnx:SUBDIRS = sharedmemory !wince*: SUBDIRS += localfortuneserver localfortuneclient # install diff --git a/examples/itemviews/chart/chart.pro b/examples/itemviews/chart/chart.pro index d202451..7a9d197 100644 --- a/examples/itemviews/chart/chart.pro +++ b/examples/itemviews/chart/chart.pro @@ -4,7 +4,7 @@ RESOURCES = chart.qrc SOURCES = main.cpp \ mainwindow.cpp \ pieview.cpp -unix:!mac:LIBS+= -lm +unix:!mac:!vxworks:LIBS+= -lm # install target.path = $$[QT_INSTALL_EXAMPLES]/itemviews/chart diff --git a/examples/network/network.pro b/examples/network/network.pro index 8c45745..adf998f 100644 --- a/examples/network/network.pro +++ b/examples/network/network.pro @@ -2,7 +2,6 @@ TEMPLATE = subdirs SUBDIRS = blockingfortuneclient \ broadcastreceiver \ broadcastsender \ - network-chat \ download \ downloadmanager \ fortuneclient \ @@ -14,6 +13,9 @@ SUBDIRS = blockingfortuneclient \ googlesuggest \ torrent +# no QProcess +!vxworks:!qnx:SUBDIRS += network-chat + contains(QT_CONFIG, openssl):SUBDIRS += securesocketclient # install diff --git a/examples/painting/painterpaths/painterpaths.pro b/examples/painting/painterpaths/painterpaths.pro index 76c9e82..98b9bd1 100644 --- a/examples/painting/painterpaths/painterpaths.pro +++ b/examples/painting/painterpaths/painterpaths.pro @@ -3,7 +3,7 @@ HEADERS = renderarea.h \ SOURCES = main.cpp \ renderarea.cpp \ window.cpp -unix:!mac:LIBS += -lm +unix:!mac:!vxworks:LIBS += -lm # install target.path = $$[QT_INSTALL_EXAMPLES]/painting/painterpaths diff --git a/examples/qws/qws.pro b/examples/qws/qws.pro index fb3c3c7..95e1b44 100644 --- a/examples/qws/qws.pro +++ b/examples/qws/qws.pro @@ -1,5 +1,7 @@ TEMPLATE = subdirs -SUBDIRS = framebuffer mousecalibration simpledecoration +# no /dev/fbX +!qnx:!vxworks:SUBDIRS = framebuffer +SUBDIRS += mousecalibration simpledecoration # install sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS README *.pro diff --git a/examples/threads/mandelbrot/mandelbrot.pro b/examples/threads/mandelbrot/mandelbrot.pro index 437f449..7870ca8 100644 --- a/examples/threads/mandelbrot/mandelbrot.pro +++ b/examples/threads/mandelbrot/mandelbrot.pro @@ -4,7 +4,7 @@ SOURCES = main.cpp \ mandelbrotwidget.cpp \ renderthread.cpp -unix:!mac:LIBS += -lm +unix:!mac:!vxworks:LIBS += -lm # install target.path = $$[QT_INSTALL_EXAMPLES]/threads/mandelbrot diff --git a/mkspecs/features/vxworks.prf b/mkspecs/features/vxworks.prf new file mode 100644 index 0000000..a910c69 --- /dev/null +++ b/mkspecs/features/vxworks.prf @@ -0,0 +1,63 @@ +# VxWorks Munching Feature +# When compiling C++ sources on VxWorks in kernel mode, all .o files have to +# be processed by the so-called 'munch' script which will generate +# additional code for static c'tors and d'tors. The resulting .c file has to +# be compiled in turn and linked to the executable. +# This can only been done when linking applications, since the munch script +# generates a .c file containing static symbols: linking a lib that was +# already munched to a munched application would lead to duplicate symbols! + +isEmpty(VXWORKS_MUNCH_EXT):VXWORKS_MUNCH_EXT = vxm +isEmpty(VXWORKS_MUNCH_TOOL):VXWORKS_MUNCH_TOOL = $(WIND_BASE)/host/resource/hutils/tcl/munch.tcl + + +!exists($$VXWORKS_MUNCH_TOOL) { + error("Could not find VxWorks Munch tool: '$${VXWORKS_MUNCH_TOOL}'. Please set the environment variable WIND_BASE correctly.") +} + +# The following scope is entered for any project that specifies 'shared' as well +# as for any project specifying neither 'shared', nor 'lib', nor 'staticlib'. +# This means that for a static build only the executable is munched, while for +# a shared build, every lib, plugin and executable is munched separately. + +shared|!staticlib:!lib { + *-dcc { + VXWORKS_MUNCH_CMD = (targ=`basename $(TARGET)`; \ + ddump -Ng \"$(TARGET)\" | tclsh $$VXWORKS_MUNCH_TOOL -c $$VXWORKS_ARCH_MUNCH >\"$(OBJECTS_DIR)/\$\${targ}_ctdt.c\" && \ + $$QMAKE_CC -c $$QMAKE_CFLAGS \"$(OBJECTS_DIR)/\$\${targ}_ctdt.c\" -o \"$(OBJECTS_DIR)/\$\${targ}_ctdt.o\" && \ + $$QMAKE_LINK $$QMAKE_LFLAGS -X -r5 -r4 \"$(OBJECTS_DIR)/\$\${targ}_ctdt.o\" \"$(TARGET)\" -o \"$(TARGET).munched\" && \ + mv \"$(TARGET).munched\" \"$(TARGET)\" && \ + chmod +x \"$(TARGET)\") + } + *-g++ { + VXWORKS_MUNCH_CMD = (targ=`basename $(TARGET)`; \ + nm \"$(DESTDIR)$(TARGET)\" | tclsh $$VXWORKS_MUNCH_TOOL -c $$VXWORKS_ARCH_MUNCH >\"$(OBJECTS_DIR)/\$\${targ}_ctdt.c\" && \ + $$QMAKE_CC -c $$QMAKE_CFLAGS -fdollars-in-identifiers \"$(OBJECTS_DIR)/\$\${targ}_ctdt.c\" -o \"$(OBJECTS_DIR)/\$\${targ}_ctdt.o\" && \ + $$QMAKE_LINK $$QMAKE_LFLAGS -nostdlib -Wl,-X -T $(WIND_BASE)/target/h/tool/gnu/ldscripts/link.OUT \"$(OBJECTS_DIR)/\$\${targ}_ctdt.o\" \"$(DESTDIR)$(TARGET)\" -o \"$(DESTDIR)$(TARGET).munched\" && \ + mv \"$(DESTDIR)$(TARGET).munched\" \"$(DESTDIR)$(TARGET)\" && \ + chmod +x \"$(DESTDIR)$(TARGET)\") + } + + # We need to create a dummy lib.a in case someone links against this lib. + # In VxWorks it's the responsibility of the run-time linker ld to resolve + # symbols, since there are no real shared libraries for the toolchain linker + # to link against. + + shared:contains(TEMPLATE, lib) { + VXWORKS_MUNCH_CMD += "&&" + VXWORKS_MUNCH_CMD += (atarg=`basename $(TARGET) .so.$${VERSION}`.a ; touch \"$(DESTDIR)\$\${atarg}\") + } + + QMAKE_POST_LINK = $$VXWORKS_MUNCH_CMD $$QMAKE_POST_LINK + silent:QMAKE_POST_LINK = @echo creating $@.$$VXWORKS_MUNCH_EXT && $$QMAKE_POST_LINK + + isEmpty(DESTDIR) { + target.targets += "`basename $(TARGET)`.$$VXWORKS_MUNCH_EXT" + QMAKE_DISTCLEAN += "`basename $(TARGET)`.$$VXWORKS_MUNCH_EXT" + } else { + target.targets += "$(DESTDIR)/`basename $(TARGET)`.$$VXWORKS_MUNCH_EXT" + QMAKE_DISTCLEAN += "$(DESTDIR)/`basename $(TARGET)`.$$VXWORKS_MUNCH_EXT" + } + *-g++:LIBS += -lgcc +} + diff --git a/mkspecs/unsupported/qnx-g++/qmake.conf b/mkspecs/unsupported/qnx-g++/qmake.conf new file mode 100644 index 0000000..2e568dc --- /dev/null +++ b/mkspecs/unsupported/qnx-g++/qmake.conf @@ -0,0 +1,59 @@ +# +# qmake configuration for qnx-g++ +# +# Written for QNX RTOS v6 with X11 +# + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release link_prl +QT += core gui + +include(../common/g++.conf) +include(../common/unix.conf) + +QMAKE_CFLAGS_THREAD = -D_REENTRANT +QMAKE_CXXFLAGS_THREAD = $$QMAKE_CLFAGS_THREAD +QMAKE_COMPILER_DEFINES += __QNXNTO__ + +QMAKE_INCDIR = +QMAKE_LIBDIR = +QMAKE_INCDIR_X11 = /opt/X11R6/include +QMAKE_LIBDIR_X11 = /opt/X11R6/lib +QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] +QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] +QMAKE_INCDIR_OPENGL = /opt/X11R6/include +QMAKE_LIBDIR_OPENGL = /opt/X11R6/lib + +#QMAKE_LIBS = -lunix +QMAKE_LIBS = +QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_X11 = -lXext -lX11 -lm -lsocket +QMAKE_LIBS_X11SM = -lSM -lICE +QMAKE_LIBS_OPENGL = -lGLU -lGL +QMAKE_LIBS_OPENGL_QT = -lGL +QMAKE_LIBS_THREAD = +QMAKE_LIBS_NETWORK = -lsocket + +QMAKE_MOC = $$[QT_INSTALL_BINS]/moc +QMAKE_UIC = $$[QT_INSTALL_BINS]/uic + +QMAKE_AR = ar cqs +QMAKE_RANLIB = + +QMAKE_TAR = tar -cf +QMAKE_GZIP = gzip -9f + +QMAKE_COPY = cp -f +QMAKE_COPY_FILE = $(COPY) +QMAKE_COPY_DIR = $(COPY) -r +QMAKE_MOVE = mv -f +QMAKE_DEL_FILE = rm -f +QMAKE_DEL_DIR = rmdir +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +QMAKE_STRIP = strip +QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +load(qt_config) diff --git a/mkspecs/unsupported/qnx-g++/qplatformdefs.h b/mkspecs/unsupported/qnx-g++/qplatformdefs.h new file mode 100644 index 0000000..f59922d --- /dev/null +++ b/mkspecs/unsupported/qnx-g++/qplatformdefs.h @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMDEFS_H +#define QPLATFORMDEFS_H + +// Get Qt defines/settings + +#include "qglobal.h" + +// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs + +#include <unistd.h> + + +// We are hot - unistd.h should have turned on the specific APIs we requested + + +#include <pthread.h> +#include <dirent.h> +#include <fcntl.h> +#include <grp.h> +#include <pwd.h> +#include <signal.h> + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/ipc.h> +#include <sys/time.h> +// QNX doesn't have the System V <sys/shm.h> header. This is not a standard +// POSIX header, it's only documented in the Single UNIX Specification. +// The preferred POSIX compliant way to share memory is to use the functions +// in <sys/mman.h> that comply with the POSIX Real Time Interface (1003.1b). +#include <sys/mman.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <netinet/in.h> +#ifndef QT_NO_IPV6IFNAME +#include <net/if.h> +#endif + +// for htonl +#include <arpa/inet.h> + +#ifdef QT_LARGEFILE_SUPPORT +#define QT_FOPEN ::fopen64 +#define QT_FSEEK ::fseeko64 +#define QT_FTELL ::ftello64 +#define QT_FGETPOS ::fgetpos64 +#define QT_FSETPOS ::fsetpos64 +#define QT_FPOS_T fpos64_t +#define QT_OFF_T off64_t +#else +#define QT_FOPEN ::fopen +#define QT_FSEEK ::fseeko +#define QT_FTELL ::ftello +#define QT_FGETPOS ::fgetpos +#define QT_FSETPOS ::fsetpos +#define QT_FPOS_T fpos_t +#define QT_OFF_T off_t +#endif + +#ifdef QT_LARGEFILE_SUPPORT +#define QT_STATBUF struct stat64 +#define QT_STATBUF4TSTAT struct stat64 +#define QT_STAT ::stat64 +#define QT_FSTAT ::fstat64 +#define QT_LSTAT ::lstat64 +#define QT_OPEN ::open64 +#define QT_TRUNCATE ::truncate64 +#define QT_FTRUNCATE ::ftruncate64 +#define QT_LSEEK ::lseek64 +#else +#define QT_STATBUF struct stat +#define QT_STATBUF4TSTAT struct stat +#define QT_STAT ::stat +#define QT_FSTAT ::fstat +#define QT_LSTAT ::lstat +#define QT_OPEN ::open +#define QT_TRUNCATE ::truncate +#define QT_FTRUNCATE ::ftruncate +#define QT_LSEEK ::lseek +#endif + +#define QT_STAT_REG S_IFREG +#define QT_STAT_DIR S_IFDIR +#define QT_STAT_MASK S_IFMT +#define QT_STAT_LNK S_IFLNK +#define QT_SOCKET_CONNECT ::connect +#define QT_SOCKET_BIND ::bind +#define QT_FILENO fileno +#define QT_CLOSE ::close +#define QT_READ ::read +#define QT_WRITE ::write +#define QT_ACCESS ::access +#define QT_GETCWD ::getcwd +#define QT_CHDIR ::chdir +#define QT_MKDIR ::mkdir +#define QT_RMDIR ::rmdir +#define QT_OPEN_LARGEFILE O_LARGEFILE +#define QT_OPEN_RDONLY O_RDONLY +#define QT_OPEN_WRONLY O_WRONLY +#define QT_OPEN_RDWR O_RDWR +#define QT_OPEN_CREAT O_CREAT +#define QT_OPEN_TRUNC O_TRUNC +#define QT_OPEN_APPEND O_APPEND + +#define QT_SIGNAL_RETTYPE void +#define QT_SIGNAL_ARGS int +#define QT_SIGNAL_IGNORE SIG_IGN + +#define QT_SOCKLEN_T socklen_t + +#define QT_SNPRINTF ::snprintf +#define QT_VSNPRINTF ::vsnprintf + +// QNX6 doesn't have getpagesize() +inline int getpagesize() +{ + return ::sysconf(_SC_PAGESIZE); +} + +#include <stdlib.h> + +// QNX6 doesn't have strtof - use strtod instead +inline float strtof(const char *b, char **e) +{ + return float(strtod(b, e)); +} + +#define QT_QWS_TEMP_DIR qgetenv("TMP"); + +#endif // QPLATFORMDEFS_H diff --git a/mkspecs/unsupported/qws/qnx-generic-g++/qmake.conf b/mkspecs/unsupported/qws/qnx-generic-g++/qmake.conf new file mode 100644 index 0000000..51fe697 --- /dev/null +++ b/mkspecs/unsupported/qws/qnx-generic-g++/qmake.conf @@ -0,0 +1,102 @@ +# +# qmake configuration for qnx-g++ +# +# Written for QNX RTOS v6 +# + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release link_prl +QT += core gui + +# +# qmake configuration for common gcc +# + +QMAKE_CC = ntox86-gcc-3.3.5 +QMAKE_CFLAGS += -pipe +QMAKE_CFLAGS_DEPS += -M +QMAKE_CFLAGS_WARN_ON += -Wall -W +QMAKE_CFLAGS_WARN_OFF += -w +QMAKE_CFLAGS_RELEASE += -O2 +QMAKE_CFLAGS_DEBUG += -g +QMAKE_CFLAGS_SHLIB += -fPIC +QMAKE_CFLAGS_STATIC_LIB += -fPIC +QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses +QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden +QMAKE_CFLAGS_PRECOMPILE += -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +QMAKE_CFLAGS_USE_PRECOMPILE += -include ${QMAKE_PCH_OUTPUT_BASE} +QMAKE_COMPILER_DEFINES += __QNXNTO__ + +QMAKE_CXX = ntox86-g++-3.3.5 +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS +QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS +QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON +QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE +QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG +QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB +QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB +QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC +QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden +QMAKE_CXXFLAGS_PRECOMPILE += -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE + +QMAKE_LINK = ntox86-gcc-3.3.5 +QMAKE_LINK_SHLIB = ntox86-gcc-3.3.5 +QMAKE_LFLAGS += -Wl,--no-undefined +QMAKE_LFLAGS_RELEASE += +QMAKE_LFLAGS_DEBUG += +QMAKE_LFLAGS_APP += +QMAKE_LFLAGS_SHLIB += -shared +QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_SONAME += -Wl,-soname, +QMAKE_LFLAGS_THREAD += +QMAKE_RPATH = -Wl,-rpath, + +QMAKE_PCH_OUTPUT_EXT = .gch + +# -Bsymbolic-functions (ld) support +QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions +QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list, + +#include(../../common/g++.conf) +include(../../common/unix.conf) + +QMAKE_CFLAGS_THREAD = -D_REENTRANT +QMAKE_CXXFLAGS_THREAD = $$QMAKE_CLFAGS_THREAD + +QMAKE_INCDIR = +QMAKE_LIBDIR = +QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] +QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] + +#QMAKE_LIBS = -lunix +QMAKE_LIBS = +QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_THREAD = +QMAKE_LIBS_NETWORK += -lsocket +QMAKE_LIBS_GUI += -lsocket + +QMAKE_MOC = $$[QT_INSTALL_BINS]/moc +QMAKE_UIC = $$[QT_INSTALL_BINS]/uic + +QMAKE_AR = ar cqs +QMAKE_RANLIB = + +QMAKE_TAR = tar -cf +QMAKE_GZIP = gzip -9f + +QMAKE_COPY = cp -f +QMAKE_COPY_FILE = $(COPY) +QMAKE_COPY_DIR = $(COPY) -r +QMAKE_MOVE = mv -f +QMAKE_DEL_FILE = rm -f +QMAKE_DEL_DIR = rmdir +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +QMAKE_STRIP = strip +QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +load(qt_config) diff --git a/mkspecs/unsupported/qws/qnx-generic-g++/qplatformdefs.h b/mkspecs/unsupported/qws/qnx-generic-g++/qplatformdefs.h new file mode 100644 index 0000000..7f0d1c4 --- /dev/null +++ b/mkspecs/unsupported/qws/qnx-generic-g++/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../qnx-g++/qplatformdefs.h" diff --git a/mkspecs/unsupported/qws/qnx-i386-g++/qmake.conf b/mkspecs/unsupported/qws/qnx-i386-g++/qmake.conf new file mode 100644 index 0000000..3f24cd9 --- /dev/null +++ b/mkspecs/unsupported/qws/qnx-i386-g++/qmake.conf @@ -0,0 +1,97 @@ +# +# qmake configuration for qnx-g++ +# +# Written for QNX RTOS v6 +# + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release link_prl +QT += core gui + +QMAKE_CC = ntox86-gcc-4.2.4 +QMAKE_CFLAGS += -pipe +QMAKE_CFLAGS_DEPS += -M +QMAKE_CFLAGS_WARN_ON += -Wall -W +QMAKE_CFLAGS_WARN_OFF += -w +QMAKE_CFLAGS_RELEASE += -O2 +QMAKE_CFLAGS_DEBUG += -g +QMAKE_CFLAGS_SHLIB += -fPIC +QMAKE_CFLAGS_STATIC_LIB += -fPIC +QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses +QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden +QMAKE_CFLAGS_PRECOMPILE += -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +QMAKE_CFLAGS_USE_PRECOMPILE += -include ${QMAKE_PCH_OUTPUT_BASE} +QMAKE_COMPILER_DEFINES += __QNXNTO__ + +QMAKE_CXX = ntox86-g++-4.2.4 +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS +QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS +QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON +QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE +QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG +QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB +QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB +QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC +QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden +QMAKE_CXXFLAGS_PRECOMPILE += -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE + +QMAKE_LINK = ntox86-g++-4.2.4 +QMAKE_LINK_SHLIB = ntox86-g++-4.2.4 +QMAKE_LFLAGS += -Wl,--no-undefined +QMAKE_LFLAGS_RELEASE += +QMAKE_LFLAGS_DEBUG += +QMAKE_LFLAGS_APP += +QMAKE_LFLAGS_SHLIB += -shared +QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_SONAME += -Wl,-soname, +QMAKE_LFLAGS_THREAD += +QMAKE_RPATH = -Wl,-rpath, + +QMAKE_PCH_OUTPUT_EXT = .gch + +# -Bsymbolic-functions (ld) support +QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions +QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list, + +include(../../common/unix.conf) + +QMAKE_CFLAGS_THREAD = -D_REENTRANT +QMAKE_CXXFLAGS_THREAD = $$QMAKE_CLFAGS_THREAD + +QMAKE_INCDIR = +QMAKE_LIBDIR = +QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] +QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] + +#QMAKE_LIBS = -lunix +QMAKE_LIBS = +QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_THREAD = +QMAKE_LIBS_NETWORK += -lsocket +QMAKE_LIBS_GUI += -lsocket + +QMAKE_MOC = $$[QT_INSTALL_BINS]/moc +QMAKE_UIC = $$[QT_INSTALL_BINS]/uic + +QMAKE_AR = ar cqs +QMAKE_RANLIB = + +QMAKE_TAR = tar -cf +QMAKE_GZIP = gzip -9f + +QMAKE_COPY = cp -f +QMAKE_COPY_FILE = $(COPY) +QMAKE_COPY_DIR = $(COPY) -r +QMAKE_MOVE = mv -f +QMAKE_DEL_FILE = rm -f +QMAKE_DEL_DIR = rmdir +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +QMAKE_STRIP = strip +QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +load(qt_config) diff --git a/mkspecs/unsupported/qws/qnx-i386-g++/qplatformdefs.h b/mkspecs/unsupported/qws/qnx-i386-g++/qplatformdefs.h new file mode 100644 index 0000000..7f0d1c4 --- /dev/null +++ b/mkspecs/unsupported/qws/qnx-i386-g++/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../qnx-g++/qplatformdefs.h" diff --git a/mkspecs/unsupported/qws/qnx-ppc-g++/qmake.conf b/mkspecs/unsupported/qws/qnx-ppc-g++/qmake.conf new file mode 100644 index 0000000..56a9c66 --- /dev/null +++ b/mkspecs/unsupported/qws/qnx-ppc-g++/qmake.conf @@ -0,0 +1,97 @@ +# +# qmake configuration for qnx-g++ +# +# Written for QNX RTOS v6 +# + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release link_prl +QT += core gui + +QMAKE_CC = ntoppc-gcc-4.3.3 +QMAKE_CFLAGS += -pipe +QMAKE_CFLAGS_DEPS += -M +QMAKE_CFLAGS_WARN_ON += -Wall -W +QMAKE_CFLAGS_WARN_OFF += -w +QMAKE_CFLAGS_RELEASE += -O2 +QMAKE_CFLAGS_DEBUG += -g +QMAKE_CFLAGS_SHLIB += -fPIC +QMAKE_CFLAGS_STATIC_LIB += -fPIC +QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses +QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden +QMAKE_CFLAGS_PRECOMPILE += -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +QMAKE_CFLAGS_USE_PRECOMPILE += -include ${QMAKE_PCH_OUTPUT_BASE} +QMAKE_COMPILER_DEFINES += __QNXNTO__ + +QMAKE_CXX = ntoppc-g++-4.3.3 +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS +QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS +QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON +QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE +QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG +QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB +QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB +QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC +QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden +QMAKE_CXXFLAGS_PRECOMPILE += -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE + +QMAKE_LINK = ntoppc-g++-4.3.3 +QMAKE_LINK_SHLIB = ntoppc-g++-4.3.3 +QMAKE_LFLAGS += -Wl,--no-undefined +QMAKE_LFLAGS_RELEASE += +QMAKE_LFLAGS_DEBUG += +QMAKE_LFLAGS_APP += +QMAKE_LFLAGS_SHLIB += -shared +QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_SONAME += -Wl,-soname, +QMAKE_LFLAGS_THREAD += +QMAKE_RPATH = -Wl,-rpath, + +QMAKE_PCH_OUTPUT_EXT = .gch + +# -Bsymbolic-functions (ld) support +QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions +QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list, + +include(../../common/unix.conf) + +QMAKE_CFLAGS_THREAD = -D_REENTRANT +QMAKE_CXXFLAGS_THREAD = $$QMAKE_CLFAGS_THREAD + +QMAKE_INCDIR = +QMAKE_LIBDIR = +QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] +QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] + +#QMAKE_LIBS = -lunix +QMAKE_LIBS = +QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_THREAD = +QMAKE_LIBS_NETWORK += -lsocket +QMAKE_LIBS_GUI += -lsocket + +QMAKE_MOC = $$[QT_INSTALL_BINS]/moc +QMAKE_UIC = $$[QT_INSTALL_BINS]/uic + +QMAKE_AR = ar cqs +QMAKE_RANLIB = + +QMAKE_TAR = tar -cf +QMAKE_GZIP = gzip -9f + +QMAKE_COPY = cp -f +QMAKE_COPY_FILE = $(COPY) +QMAKE_COPY_DIR = $(COPY) -r +QMAKE_MOVE = mv -f +QMAKE_DEL_FILE = rm -f +QMAKE_DEL_DIR = rmdir +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +QMAKE_STRIP = strip +QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +load(qt_config) diff --git a/mkspecs/unsupported/qws/qnx-ppc-g++/qplatformdefs.h b/mkspecs/unsupported/qws/qnx-ppc-g++/qplatformdefs.h new file mode 100644 index 0000000..7f0d1c4 --- /dev/null +++ b/mkspecs/unsupported/qws/qnx-ppc-g++/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../qnx-g++/qplatformdefs.h" diff --git a/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf b/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf new file mode 100644 index 0000000..a8f7e49 --- /dev/null +++ b/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf @@ -0,0 +1,111 @@ +# +# qmake configuration for vxworks-ppc-dcc +# + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl vxworks +QT += core gui network +QMAKE_INCREMENTAL_STYLE = sublib + +VXWORKS_ARCH = ppc +VXWORKS_CPU = PPC32 +VXWORKS_DIAB_SPEC = -tPPC7400FV:vxworks66 +VXWORKS_ARCH_MUNCH = ppc + +QMAKE_CC = dcc +QMAKE_CFLAGS += $$VXWORKS_DIAB_SPEC -Xkeywords=0x0 -Xcode-absolute-far -Xansi -Xforce-declarations -I$(WIND_BASE)/target/h -I$(WIND_BASE)/target/h/wrn/coreip -DCPU=$$upper($$VXWORKS_ARCH) -DVX_CPU_FAMILY=$$VXWORKS_ARCH -DTOOL_FAMILY=diab -DTOOL=diab -D_WRS_KERNEL -DVXWORKS -D_VSB_CONFIG_FILE=\'<../lib/h/config/vsbConfig.h>\' +QMAKE_CFLAGS_DEPS += +QMAKE_CFLAGS_WARN_ON += +QMAKE_CFLAGS_WARN_OFF += -Xsuppress-warnings +QMAKE_CFLAGS_RELEASE += +QMAKE_CFLAGS_DEBUG += -g +QMAKE_CFLAGS_SHLIB += +QMAKE_CFLAGS_STATIC_LIB += +QMAKE_CFLAGS_YACC += +QMAKE_CFLAGS_HIDESYMS += +QMAKE_CFLAGS_PRECOMPILE += +QMAKE_CFLAGS_USE_PRECOMPILE += + +QMAKE_CXX = dcc +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS +QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS +QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON +QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE +QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG +QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB +QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB +QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC +QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS +QMAKE_CXXFLAGS_PRECOMPILE += +QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE + +QMAKE_LINK = dld +QMAKE_LINK_SHLIB = dld +QMAKE_LFLAGS += $$VXWORKS_DIAB_SPEC +QMAKE_LFLAGS_RELEASE += +QMAKE_LFLAGS_DEBUG += +QMAKE_LFLAGS_APP += -r5 +QMAKE_LFLAGS_SHLIB += +QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_SONAME += +QMAKE_LFLAGS_THREAD += +QMAKE_LFLAGS_NOUNDEF += +QMAKE_RPATH = + +QMAKE_PCH_OUTPUT_EXT = .gch + +# -Bsymbolic-functions (ld) support +QMAKE_LFLAGS_BSYMBOLIC_FUNC = +QMAKE_LFLAGS_DYNAMIC_LIST = + +QMAKE_CFLAGS_THREAD += -D_REENTRANT +QMAKE_CXXFLAGS_THREAD += $$QMAKE_CFLAGS_THREAD + +QMAKE_INCDIR = +QMAKE_LIBDIR = +QMAKE_INCDIR_X11 = $(WIND_HOME)/GSS/include +QMAKE_LIBDIR_X11 = $(WIND_HOME)/GSS/lib +QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] +QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] +QMAKE_INCDIR_OPENGL = $$QMAKE_INCDIR_X11 +QMAKE_LIBDIR_OPENGL = $$QMAKE_LIBDIR_X11 + +QMAKE_LIBS = +QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_X11 = -lXext -lX11 +QMAKE_LIBS_X11SM = -lSM -lICE +QMAKE_LIBS_NIS = -lnsl +QMAKE_LIBS_OPENGL = -lGLU -lGL +QMAKE_LIBS_OPENGL_QT = -lGL +QMAKE_LIBS_THREAD = +QMAKE_LIBS_NETWORK = # -lnetwrap # only needed if kernel is missing gethostbyname and friends + + +QMAKE_MOC = $$[QT_INSTALL_BINS]/moc +QMAKE_UIC = $$[QT_INSTALL_BINS]/uic + +QMAKE_AR = ar cqs +QMAKE_OBJCOPY = objcopy +QMAKE_RANLIB = + +QMAKE_TAR = tar -cf +QMAKE_GZIP = gzip -9f + +QMAKE_COPY = cp -f +QMAKE_COPY_FILE = $(COPY) +QMAKE_COPY_DIR = $(COPY) -r +QMAKE_MOVE = mv -f +QMAKE_DEL_FILE = rm -f +QMAKE_DEL_DIR = rmdir +QMAKE_STRIP = strip +QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +QMAKE_INSTALL_FILE = install -m 644 -p +QMAKE_INSTALL_PROGRAM = install -m 755 -p + +include(../../common/unix.conf) +load(qt_config) + diff --git a/mkspecs/unsupported/vxworks-ppc-dcc/qplatformdefs.h b/mkspecs/unsupported/vxworks-ppc-dcc/qplatformdefs.h new file mode 100644 index 0000000..4b0c24c --- /dev/null +++ b/mkspecs/unsupported/vxworks-ppc-dcc/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../vxworks-simpentium-g++/qplatformdefs.h" diff --git a/mkspecs/unsupported/vxworks-ppc-g++/qmake.conf b/mkspecs/unsupported/vxworks-ppc-g++/qmake.conf new file mode 100644 index 0000000..be8c13d --- /dev/null +++ b/mkspecs/unsupported/vxworks-ppc-g++/qmake.conf @@ -0,0 +1,37 @@ +# +# qmake configuration for vxworks-simpentium-g++ +# + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl vxworks +QT += core gui network +QMAKE_INCREMENTAL_STYLE = sublib +DEFINES += VXWORKS + +VXWORKS_ARCH = ppc +VXWORKS_CPU = PPC32 +VXWORKS_ARCH_MUNCH = ppc + +include(../../common/g++.conf) +include(../../common/linux.conf) + +QMAKE_CC = cc$$VXWORKS_ARCH_MUNCH +QMAKE_CFLAGS = -fno-builtin -I$(WIND_BASE)/target/h -I$(WIND_BASE)/target/h/wrn/coreip -DCPU=$$upper($$VXWORKS_ARCH) -DVX_CPU_FAMILY=$$VXWORKS_ARCH -DTOOL_FAMILY=gnu -DTOOL=gnu -D_WRS_KERNEL -D_VSB_CONFIG_FILE=\'<../lib/h/config/vsbConfig.h>\' +QMAKE_CFLAGS_SHLIB = # remove -fPIC +QMAKE_CFLAGS_STATIC_LIB = # remove -fPIC +QMAKE_CXX = c++$$VXWORKS_ARCH_MUNCH +QMAKE_CXXFLAGS = $$QMAKE_CFLAGS +QMAKE_CXXFLAGS_SHLIB= # remove -fPIC +QMAKE_CXXFLAGS_STATIC_LIB= # remove -fPIC +QMAKE_LINK = $$QMAKE_CXX +QMAKE_LINK_SHLIB = $$QMAKE_CXX +QMAKE_LFLAGS_SHLIB = -Wl,-Ur -L $(WIND_BASE)/target/lib/$$VXWORKS_ARCH/$$VXWORKS_CPU/common # remove -shared +QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_APP += -Wl,-Ur -L $(WIND_BASE)/target/lib/$$VXWORKS_ARCH/$$VXWORKS_CPU/common +# QMAKE_LIBS_NETWORK = # -lnetwrap # only needed if kernel is missing gethostbyname() and friends +QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_THREAD = + +load(qt_config) + diff --git a/mkspecs/unsupported/vxworks-ppc-g++/qplatformdefs.h b/mkspecs/unsupported/vxworks-ppc-g++/qplatformdefs.h new file mode 100644 index 0000000..4b0c24c --- /dev/null +++ b/mkspecs/unsupported/vxworks-ppc-g++/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../vxworks-simpentium-g++/qplatformdefs.h" diff --git a/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf b/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf new file mode 100644 index 0000000..6228a6b --- /dev/null +++ b/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf @@ -0,0 +1,110 @@ +# +# qmake configuration for vxworks-simpentium-dcc +# + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl vxworks +QT += core gui network +QMAKE_INCREMENTAL_STYLE = sublib + +VXWORKS_ARCH = simlinux +VXWORKS_CPU = SIMLINUX +VXWORKS_DIAB_SPEC = -tX86LH:vxworks66 +VXWORKS_ARCH_MUNCH = pentium + +QMAKE_CC = dcc +QMAKE_CFLAGS += $$VXWORKS_DIAB_SPEC -Xkeywords=0x0 -Xcode-absolute-far -Xansi -Xforce-declarations -I$(WIND_BASE)/target/h -I$(WIND_BASE)/target/h/wrn/coreip -DCPU=$$upper($$VXWORKS_ARCH) -DVX_CPU_FAMILY=$$VXWORKS_ARCH -DTOOL_FAMILY=diab -DTOOL=diab -D_WRS_KERNEL -DVXWORKS -D_VSB_CONFIG_FILE=\'<../lib/h/config/vsbConfig.h>\' +QMAKE_CFLAGS_DEPS += +QMAKE_CFLAGS_WARN_ON += +QMAKE_CFLAGS_WARN_OFF += -Xsuppress-warnings +QMAKE_CFLAGS_RELEASE += +QMAKE_CFLAGS_DEBUG += -g +QMAKE_CFLAGS_SHLIB += +QMAKE_CFLAGS_STATIC_LIB += +QMAKE_CFLAGS_YACC += +QMAKE_CFLAGS_HIDESYMS += +QMAKE_CFLAGS_PRECOMPILE += +QMAKE_CFLAGS_USE_PRECOMPILE += + +QMAKE_CXX = dcc +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS +QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS +QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON +QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE +QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG +QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB +QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB +QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC +QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS +QMAKE_CXXFLAGS_PRECOMPILE += +QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE + +QMAKE_LINK = dld +QMAKE_LINK_SHLIB = dld +QMAKE_LFLAGS += $$VXWORKS_DIAB_SPEC -L $(WIND_BASE)/target/lib/$$VXWORKS_ARCH/$$VXWORKS_CPU/common +QMAKE_LFLAGS_RELEASE += +QMAKE_LFLAGS_DEBUG += +QMAKE_LFLAGS_APP += -r5 +QMAKE_LFLAGS_SHLIB += +QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_SONAME += +QMAKE_LFLAGS_THREAD += +QMAKE_LFLAGS_NOUNDEF += +QMAKE_RPATH = + +QMAKE_PCH_OUTPUT_EXT = .gch + +# -Bsymbolic-functions (ld) support +QMAKE_LFLAGS_BSYMBOLIC_FUNC = +QMAKE_LFLAGS_DYNAMIC_LIST = + +QMAKE_CFLAGS_THREAD += -D_REENTRANT +QMAKE_CXXFLAGS_THREAD += $$QMAKE_CFLAGS_THREAD + +QMAKE_INCDIR = +QMAKE_LIBDIR = +QMAKE_INCDIR_X11 = $(WIND_HOME)/GSS/include +QMAKE_LIBDIR_X11 = $(WIND_HOME)/GSS/lib +QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] +QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] +QMAKE_INCDIR_OPENGL = $$QMAKE_INCDIR_X11 +QMAKE_LIBDIR_OPENGL = $$QMAKE_LIBDIR_X11 + +QMAKE_LIBS = +QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_X11 = -lXext -lX11 +QMAKE_LIBS_X11SM = -lSM -lICE +QMAKE_LIBS_NIS = -lnsl +QMAKE_LIBS_OPENGL = -lGLU -lGL +QMAKE_LIBS_OPENGL_QT = -lGL +QMAKE_LIBS_THREAD = +QMAKE_LIBS_NETWORK = # -lnet # only needed if kernel is missing gethostbyname and friends + +QMAKE_MOC = $$[QT_INSTALL_BINS]/moc +QMAKE_UIC = $$[QT_INSTALL_BINS]/uic + +QMAKE_AR = ar cqs +QMAKE_OBJCOPY = objcopy +QMAKE_RANLIB = + +QMAKE_TAR = tar -cf +QMAKE_GZIP = gzip -9f + +QMAKE_COPY = cp -f +QMAKE_COPY_FILE = $(COPY) +QMAKE_COPY_DIR = $(COPY) -r +QMAKE_MOVE = mv -f +QMAKE_DEL_FILE = rm -f +QMAKE_DEL_DIR = rmdir +QMAKE_STRIP = strip +QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +QMAKE_INSTALL_FILE = install -m 644 -p +QMAKE_INSTALL_PROGRAM = install -m 755 -p + +include(../../common/unix.conf) +load(qt_config) + diff --git a/mkspecs/unsupported/vxworks-simpentium-dcc/qplatformdefs.h b/mkspecs/unsupported/vxworks-simpentium-dcc/qplatformdefs.h new file mode 100644 index 0000000..4b0c24c --- /dev/null +++ b/mkspecs/unsupported/vxworks-simpentium-dcc/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../vxworks-simpentium-g++/qplatformdefs.h" diff --git a/mkspecs/unsupported/vxworks-simpentium-g++/qmake.conf b/mkspecs/unsupported/vxworks-simpentium-g++/qmake.conf new file mode 100644 index 0000000..29e9c70 --- /dev/null +++ b/mkspecs/unsupported/vxworks-simpentium-g++/qmake.conf @@ -0,0 +1,37 @@ +# +# qmake configuration for vxworks-simpentium-g++ +# + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl vxworks +QT += core gui network +QMAKE_INCREMENTAL_STYLE = sublib +DEFINES += VXWORKS + +VXWORKS_ARCH = simlinux +VXWORKS_CPU = SIMLINUX +VXWORKS_ARCH_MUNCH = pentium + +include(../../common/g++.conf) +include(../../common/linux.conf) + +QMAKE_CC = cc$$VXWORKS_ARCH_MUNCH +QMAKE_CFLAGS = -fno-builtin -I$(WIND_BASE)/target/h -I$(WIND_BASE)/target/h/wrn/coreip -DCPU=$$upper($$VXWORKS_ARCH) -DVX_CPU_FAMILY=$$VXWORKS_ARCH -DTOOL_FAMILY=gnu -DTOOL=gnu -D_WRS_KERNEL -D_VSB_CONFIG_FILE=\'<../lib/h/config/vsbConfig.h>\' +QMAKE_CFLAGS_SHLIB = # remove -fPIC +QMAKE_CFLAGS_STATIC_LIB = # remove -fPIC +QMAKE_CXX = c++$$VXWORKS_ARCH_MUNCH +QMAKE_CXXFLAGS = $$QMAKE_CFLAGS +QMAKE_CXXFLAGS_SHLIB= # remove -fPIC +QMAKE_CXXFLAGS_STATIC_LIB= # remove -fPIC +QMAKE_LINK = $$QMAKE_CXX +QMAKE_LINK_SHLIB = $$QMAKE_CXX +QMAKE_LFLAGS_SHLIB = -Wl,-Ur -L $(WIND_BASE)/target/lib/$$VXWORKS_ARCH/$$VXWORKS_CPU/common # remove -shared +QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_APP += -Wl,-Ur -L $(WIND_BASE)/target/lib/$$VXWORKS_ARCH/$$VXWORKS_CPU/common +QMAKE_LIBS_NETWORK = # -lnetwrap # only needed if kernel is missing gethostbyname() and friends +QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_THREAD = + +load(qt_config) + diff --git a/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h b/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h new file mode 100644 index 0000000..90eb955 --- /dev/null +++ b/mkspecs/unsupported/vxworks-simpentium-g++/qplatformdefs.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMDEFS_H +#define QPLATFORMDEFS_H + +// Get Qt defines/settings + +#include "qglobal.h" +#include "qfunctions_vxworks.h" + + +#ifdef QT_LARGEFILE_SUPPORT +#define QT_STATBUF struct stat64 +#define QT_STATBUF4TSTAT struct stat64 +#define QT_STAT ::stat64 +#define QT_FSTAT ::fstat64 +#define QT_LSTAT ::stat64 +#define QT_OPEN ::open64 +#define QT_TRUNCATE ::truncate64 +#define QT_FTRUNCATE ::ftruncate64 +#define QT_LSEEK ::lseek64 +#else +#define QT_STATBUF struct stat +#define QT_STATBUF4TSTAT struct stat +#define QT_STAT ::stat +#define QT_FSTAT ::fstat +#define QT_LSTAT ::stat +#define QT_OPEN ::open +#define QT_TRUNCATE ::truncate +#define QT_FTRUNCATE ::ftruncate +#define QT_LSEEK ::lseek +#endif + +#ifdef QT_LARGEFILE_SUPPORT +#define QT_FOPEN ::fopen64 +#define QT_FSEEK ::fseeko64 +#define QT_FTELL ::ftello64 +#define QT_FGETPOS ::fgetpos64 +#define QT_FSETPOS ::fsetpos64 +#define QT_FPOS_T fpos64_t +#define QT_OFF_T off64_t +#else +#define QT_FOPEN ::fopen +#define QT_FSEEK ::fseek +#define QT_FTELL ::ftell +#define QT_FGETPOS ::fgetpos +#define QT_FSETPOS ::fsetpos +#define QT_FPOS_T fpos_t +#define QT_OFF_T long +#endif + +#define QT_STAT_REG S_IFREG +#define QT_STAT_DIR S_IFDIR +#define QT_STAT_MASK S_IFMT +#define QT_STAT_LNK S_IFLNK +#define QT_SOCKET_CONNECT(sd, to, tolen) \ + ::connect(sd, (struct sockaddr *) to, tolen) +#define QT_SOCKET_BIND ::bind +#define QT_FILENO fileno +#define QT_CLOSE ::close +#define QT_READ(fd, buf, len) ::read(fd, (char*) buf, len) +#define QT_WRITE(fd, buf, len) ::write(fd, (char*) buf, len) +#define QT_ACCESS ::access +#define QT_GETCWD ::getcwd +#define QT_CHDIR ::chdir +#define QT_MKDIR(dir, perm) ::mkdir(dir) +#define QT_RMDIR ::rmdir +#define QT_OPEN_LARGEFILE O_LARGEFILE +#define QT_OPEN_RDONLY O_RDONLY +#define QT_OPEN_WRONLY O_WRONLY +#define QT_OPEN_RDWR O_RDWR +#define QT_OPEN_CREAT O_CREAT +#define QT_OPEN_TRUNC O_TRUNC +#define QT_OPEN_APPEND O_APPEND + +#define QT_SIGNAL_RETTYPE void +#define QT_SIGNAL_ARGS int +#define QT_SIGNAL_IGNORE SIG_IGN + +// there IS a socklen_t in sys/socket.h (unsigned int), +// but sockLib.h uses int in all function declaration... +//#define QT_SOCKLEN_T socklen_t +#define QT_SOCKLEN_T int + +#define QT_SNPRINTF ::snprintf +#define QT_VSNPRINTF ::vsnprintf + + +#endif // QPLATFORMDEFS_H diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 6658213..36b6c00 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2112,8 +2112,6 @@ QString MakefileGenerator::buildArgs(const QString &outdir) ret += " -unix"; else if(Option::target_mode == Option::TARG_WIN_MODE) ret += " -win32"; - else if(Option::target_mode == Option::TARG_QNX6_MODE) - ret += " -qnx6"; //configs for(QStringList::Iterator it = Option::user_configs.begin(); diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 1dafd98..68d9d88 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -49,9 +49,9 @@ QT_BEGIN_NAMESPACE // XML Tags --------------------------------------------------------- const char _Configuration[] = "Configuration"; const char _Configurations[] = "Configurations"; -const char _File[] = "File"; +const char q_File[] = "File"; const char _FileConfiguration[] = "FileConfiguration"; -const char _Files[] = "Files"; +const char q_Files[] = "Files"; const char _Filter[] = "Filter"; const char _Globals[] = "Globals"; const char _Platform[] = "Platform"; @@ -2381,11 +2381,11 @@ XmlOutput &operator<<(XmlOutput &xml, VCFilter &tool) } for (int i = 0; i < tool.Files.count(); ++i) { const VCFilterFile &info = tool.Files.at(i); - xml << tag(_File) + xml << tag(q_File) << attrS(_RelativePath, Option::fixPathToLocalOS(info.file)) << data(); // In case no custom builds, to avoid "/>" endings tool.outputFileConfig(xml, tool.Files.at(i).file); - xml << closetag(_File); + xml << closetag(q_File); } if (!tool.Name.isEmpty()) xml << closetag(_Filter); @@ -2421,7 +2421,7 @@ XmlOutput &operator<<(XmlOutput &xml, const VCProjectSingleConfig &tool) << tag(_Configurations) << tool.Configuration; xml << closetag(_Configurations) - << tag(_Files); + << tag(q_Files); // Add this configuration into a multi-config project, since that's where we have the flat/tree // XML output functionality VCProject tempProj; @@ -2437,7 +2437,7 @@ XmlOutput &operator<<(XmlOutput &xml, const VCProjectSingleConfig &tool) tempProj.outputFilter(xml, tempProj.ExtraCompilers.at(x)); } tempProj.outputFilter(xml, "RootFiles"); - xml << closetag(_Files) + xml << closetag(q_Files) << tag(_Globals) << data(); // No "/>" end tag return xml; @@ -2492,7 +2492,7 @@ void VCProject::outputFileConfigs(XmlOutput &xml, const VCFilterFile &info, const QString &filtername) { - xml << tag(_File) + xml << tag(q_File) << attrS(_RelativePath, Option::fixPathToLocalOS(info.file)); for (int i = 0; i < SingleProjects.count(); ++i) { VCFilter filter; @@ -2520,7 +2520,7 @@ void VCProject::outputFileConfigs(XmlOutput &xml, if (filter.Config) // only if the filter is not empty filter.outputFileConfig(xml, info.file); } - xml << closetag(_File); + xml << closetag(q_File); } // outputs a given filter for all existing configurations of a project @@ -2615,7 +2615,7 @@ XmlOutput &operator<<(XmlOutput &xml, VCProject &tool) for (int i = 0; i < tool.SingleProjects.count(); ++i) xml << tool.SingleProjects.at(i).Configuration; xml << closetag(_Configurations) - << tag(_Files); + << tag(q_Files); tool.outputFilter(xml, "Sources"); tool.outputFilter(xml, "Headers"); tool.outputFilter(xml, "GeneratedFiles"); @@ -2627,7 +2627,7 @@ XmlOutput &operator<<(XmlOutput &xml, VCProject &tool) tool.outputFilter(xml, tool.ExtraCompilers.at(x)); } tool.outputFilter(xml, "RootFiles"); - xml << closetag(_Files) + xml << closetag(q_Files) << tag(_Globals) << data(); // No "/>" end tag return xml; diff --git a/qmake/option.cpp b/qmake/option.cpp index 5f8c4f4..2308017 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -99,8 +99,6 @@ QStringList Option::shellPath; Option::TARG_MODE Option::target_mode = Option::TARG_WIN_MODE; #elif defined(Q_OS_MAC) Option::TARG_MODE Option::target_mode = Option::TARG_MACX_MODE; -#elif defined(Q_OS_QNX6) -Option::TARG_MODE Option::target_mode = Option::TARG_QNX6_MODE; #else Option::TARG_MODE Option::target_mode = Option::TARG_UNIX_MODE; #endif diff --git a/qmake/option.h b/qmake/option.h index 4205b03..df2c940 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -149,7 +149,7 @@ struct Option static int warn_level; static bool recursive; static QStringList before_user_vars, after_user_vars, user_configs, after_user_configs; - enum TARG_MODE { TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE, TARG_MAC9_MODE, TARG_QNX6_MODE }; + enum TARG_MODE { TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE, TARG_MAC9_MODE }; static TARG_MODE target_mode; static QString user_template, user_template_prefix; static QStringList shellPath; diff --git a/qmake/project.cpp b/qmake/project.cpp index 704d8a6..4fefbab 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -623,10 +623,6 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0) concat << base_concat + QDir::separator() + "mac"; concat << base_concat + QDir::separator() + "mac9"; break; - case Option::TARG_QNX6_MODE: //also a unix - concat << base_concat + QDir::separator() + "qnx6"; - concat << base_concat + QDir::separator() + "unix"; - break; } concat << base_concat; } @@ -1610,13 +1606,11 @@ QMakeProject::isActiveConfig(const QString &x, bool regex, QMap<QString, QString return false; //mkspecs - if((Option::target_mode == Option::TARG_MACX_MODE || Option::target_mode == Option::TARG_QNX6_MODE || + if((Option::target_mode == Option::TARG_MACX_MODE || Option::target_mode == Option::TARG_UNIX_MODE) && x == "unix") return true; else if(Option::target_mode == Option::TARG_MACX_MODE && x == "macx") return true; - else if(Option::target_mode == Option::TARG_QNX6_MODE && x == "qnx6") - return true; else if(Option::target_mode == Option::TARG_MAC9_MODE && x == "mac9") return true; else if((Option::target_mode == Option::TARG_MAC9_MODE || Option::target_mode == Option::TARG_MACX_MODE) && diff --git a/src/3rdparty/freetype/builds/unix/ftsystem.c b/src/3rdparty/freetype/builds/unix/ftsystem.c index 3a740fd..40fa8d0 100644 --- a/src/3rdparty/freetype/builds/unix/ftsystem.c +++ b/src/3rdparty/freetype/builds/unix/ftsystem.c @@ -69,6 +69,9 @@ #include <string.h> #include <errno.h> +#ifdef VXWORKS +#include <ioLib.h> +#endif /*************************************************************************/ /* */ @@ -238,7 +241,7 @@ return FT_Err_Invalid_Stream_Handle; /* open the file */ - file = open( filepathname, O_RDONLY ); + file = open( filepathname, O_RDONLY, 0); if ( file < 0 ) { FT_ERROR(( "FT_Stream_Open:" )); @@ -317,7 +320,11 @@ read_count = read( file, +#ifndef VXWORKS stream->base + total_read_count, +#else + (char *) stream->base + total_read_count, +#endif stream->size - total_read_count ); if ( read_count <= 0 ) diff --git a/src/3rdparty/libjpeg/jmorecfg.h b/src/3rdparty/libjpeg/jmorecfg.h index 54a7d1c..b0b5870 100644 --- a/src/3rdparty/libjpeg/jmorecfg.h +++ b/src/3rdparty/libjpeg/jmorecfg.h @@ -157,7 +157,7 @@ typedef short INT16; /* INT32 must hold at least signed 32-bit values. */ -#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +#if !defined(XMD_H) && !defined(VXWORKS) /* X11/xmd.h correctly defines INT32 */ typedef long INT32; #endif @@ -183,6 +183,9 @@ typedef unsigned int JDIMENSION; /* a function called through method pointers: */ #define METHODDEF(type) static type /* a function used only in its module: */ +#if defined(VXWORKS) && defined(LOCAL) +# undef LOCAL +#endif #define LOCAL(type) static type /* a function referenced thru EXTERNs: */ #define GLOBAL(type) type diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index 19e4732..8eb7d35 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -344,7 +344,7 @@ # endif /* __linux__ */ #endif /* PNG_SETJMP_SUPPORTED */ -#ifdef BSD +#if defined(BSD) && !defined(VXWORKS) # include <strings.h> #else # include <string.h> diff --git a/src/3rdparty/libtiff/libtiff/tif_config.h b/src/3rdparty/libtiff/libtiff/tif_config.h index e95f7a4..689421c 100644 --- a/src/3rdparty/libtiff/libtiff/tif_config.h +++ b/src/3rdparty/libtiff/libtiff/tif_config.h @@ -104,7 +104,7 @@ /* #undef HAVE_PTHREAD */ /* Define to 1 if you have the <search.h> header file. */ -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_VXWORKS) #define HAVE_SEARCH_H 1 #endif diff --git a/src/3rdparty/patches/freetype-2.3.6-vxworks.patch b/src/3rdparty/patches/freetype-2.3.6-vxworks.patch new file mode 100644 index 0000000..21e884c --- /dev/null +++ b/src/3rdparty/patches/freetype-2.3.6-vxworks.patch @@ -0,0 +1,35 @@ +diff --git builds/unix/ftsystem.c builds/unix/ftsystem.c +index 3a740fd..40fa8d0 100644 +--- builds/unix/ftsystem.c ++++ builds/unix/ftsystem.c +@@ -69,6 +69,9 @@ + #include <string.h> + #include <errno.h> + ++#ifdef VXWORKS ++#include <ioLib.h> ++#endif + + /*************************************************************************/ + /* */ +@@ -238,7 +241,7 @@ + return FT_Err_Invalid_Stream_Handle; + + /* open the file */ +- file = open( filepathname, O_RDONLY ); ++ file = open( filepathname, O_RDONLY, 0); + if ( file < 0 ) + { + FT_ERROR(( "FT_Stream_Open:" )); +@@ -317,7 +320,11 @@ + + + read_count = read( file, ++#ifndef VXWORKS + stream->base + total_read_count, ++#else ++ (char *) stream->base + total_read_count, ++#endif + stream->size - total_read_count ); + + if ( read_count <= 0 ) diff --git a/src/3rdparty/patches/libjpeg-6b-vxworks.patch b/src/3rdparty/patches/libjpeg-6b-vxworks.patch new file mode 100644 index 0000000..263c8d0 --- /dev/null +++ b/src/3rdparty/patches/libjpeg-6b-vxworks.patch @@ -0,0 +1,23 @@ +diff --git jmorecfg.h jmorecfg.h +index 54a7d1c..b0b5870 100644 +--- jmorecfg.h ++++ jmorecfg.h +@@ -157,7 +157,7 @@ typedef short INT16; + + /* INT32 must hold at least signed 32-bit values. */ + +-#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ ++#if !defined(XMD_H) && !defined(VXWORKS) /* X11/xmd.h correctly defines INT32 */ + typedef long INT32; + #endif + +@@ -183,6 +183,9 @@ typedef unsigned int JDIMENSION; + /* a function called through method pointers: */ + #define METHODDEF(type) static type + /* a function used only in its module: */ ++#if defined(VXWORKS) && defined(LOCAL) ++# undef LOCAL ++#endif + #define LOCAL(type) static type + /* a function referenced thru EXTERNs: */ + #define GLOBAL(type) type diff --git a/src/3rdparty/patches/libpng-1.2.20-vxworks.patch b/src/3rdparty/patches/libpng-1.2.20-vxworks.patch new file mode 100644 index 0000000..4c49b3f --- /dev/null +++ b/src/3rdparty/patches/libpng-1.2.20-vxworks.patch @@ -0,0 +1,13 @@ +diff --git pngconf.h pngconf.h +index 19e4732..8eb7d35 100644 +--- pngconf.h ++++ pngconf.h +@@ -344,7 +344,7 @@ + # endif /* __linux__ */ + #endif /* PNG_SETJMP_SUPPORTED */ + +-#ifdef BSD ++#if defined(BSD) && !defined(VXWORKS) + # include <strings.h> + #else + # include <string.h> diff --git a/src/3rdparty/patches/libtiff-3.8.2-vxworks.patch b/src/3rdparty/patches/libtiff-3.8.2-vxworks.patch new file mode 100644 index 0000000..b1b725e --- /dev/null +++ b/src/3rdparty/patches/libtiff-3.8.2-vxworks.patch @@ -0,0 +1,11 @@ +--- libtiff/tif_config.h.orig ++++ libtiff/tif_config.h +@@ -104,7 +104,7 @@ + /* #undef HAVE_PTHREAD */ + + /* Define to 1 if you have the <search.h> header file. */ +-#if !defined(Q_OS_WINCE) ++#if !defined(Q_OS_WINCE) && !defined(Q_OS_VXWORKS) + #define HAVE_SEARCH_H 1 + #endif + diff --git a/src/3rdparty/patches/sqlite-3.5.6-vxworks.patch b/src/3rdparty/patches/sqlite-3.5.6-vxworks.patch new file mode 100644 index 0000000..6ae65fd --- /dev/null +++ b/src/3rdparty/patches/sqlite-3.5.6-vxworks.patch @@ -0,0 +1,68 @@ +--- sqlite3.c.orig ++++ sqlite3.c +@@ -383,7 +383,7 @@ SQLITE_PRIVATE void sqlite3Coverage(int); + ** + ** See also ticket #2741. + */ +-#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE ++#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE && !defined(VXWORKS) + # define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ + #endif + +@@ -440,6 +440,13 @@ SQLITE_PRIVATE void sqlite3Coverage(int); + */ + #ifndef _SQLITE3_H_ + #define _SQLITE3_H_ ++ ++#ifdef VXWORKS ++# define SQLITE_HOMEGROWN_RECURSIVE_MUTEX ++# define NO_GETTOD ++# include <ioLib.h> ++#endif ++ + #include <stdarg.h> /* Needed for the definition of va_list */ + + /* +@@ -18792,7 +18799,11 @@ SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void){ + #include <sys/stat.h> + #include <fcntl.h> + #include <unistd.h> +-#include <sys/time.h> ++#ifdef VXWORKS ++# include <sys/times.h> ++#else ++# include <sys/time.h> ++#endif + #include <errno.h> + #ifdef SQLITE_ENABLE_LOCKING_STYLE + #include <sys/ioctl.h> +@@ -19728,7 +19739,11 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ + if( newOffset!=offset ){ + return -1; + } ++# ifndef VXWORKS + got = write(id->h, pBuf, cnt); ++# else ++ got = write(id->h, (char *)pBuf, cnt); ++# endif + #endif + TIMER_END; + OSTRACE5("WRITE %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED); +@@ -21554,12 +21569,16 @@ static int unixRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + #if !defined(SQLITE_TEST) + { + int pid, fd; +- fd = open("/dev/urandom", O_RDONLY); ++ fd = open("/dev/urandom", O_RDONLY, 0); + if( fd<0 ){ + time_t t; + time(&t); + memcpy(zBuf, &t, sizeof(t)); ++#ifndef VXWORKS + pid = getpid(); ++#else ++ pid = (int)taskIdCurrent(); ++#endif + memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid)); + }else{ + read(fd, zBuf, nBuf); diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 91ce30f..7e604cb 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -383,7 +383,7 @@ SQLITE_PRIVATE void sqlite3Coverage(int); ** ** See also ticket #2741. */ -#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE +#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE && !defined(VXWORKS) # define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ #endif @@ -440,6 +440,13 @@ SQLITE_PRIVATE void sqlite3Coverage(int); */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ + +#ifdef VXWORKS +# define SQLITE_HOMEGROWN_RECURSIVE_MUTEX +# define NO_GETTOD +# include <ioLib.h> +#endif + #include <stdarg.h> /* Needed for the definition of va_list */ /* @@ -18792,7 +18799,11 @@ SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void){ #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> -#include <sys/time.h> +#ifdef VXWORKS +# include <sys/times.h> +#else +# include <sys/time.h> +#endif #include <errno.h> #ifdef SQLITE_ENABLE_LOCKING_STYLE #include <sys/ioctl.h> @@ -19728,7 +19739,11 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ if( newOffset!=offset ){ return -1; } +# ifndef VXWORKS got = write(id->h, pBuf, cnt); +# else + got = write(id->h, (char *)pBuf, cnt); +# endif #endif TIMER_END; OSTRACE5("WRITE %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED); @@ -21554,12 +21569,16 @@ static int unixRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ #if !defined(SQLITE_TEST) { int pid, fd; - fd = open("/dev/urandom", O_RDONLY); + fd = open("/dev/urandom", O_RDONLY, 0); if( fd<0 ){ time_t t; time(&t); memcpy(zBuf, &t, sizeof(t)); +#ifndef VXWORKS pid = getpid(); +#else + pid = (int)taskIdCurrent(); +#endif memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid)); }else{ read(fd, zBuf, nBuf); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp index e1b7bd4..dddd83d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp @@ -89,6 +89,13 @@ extern int *__libc_stack_end; #include <pthread_np.h> #endif +#if PLATFORM(QNX) +#include <fcntl.h> +#include <sys/procfs.h> +#include <stdio.h> +#include <errno.h> +#endif + #endif #define DEBUG_COLLECTOR 0 @@ -580,6 +587,24 @@ static inline void* currentThreadStackBase() static pthread_t stackThread; pthread_t thread = pthread_self(); if (stackBase == 0 || thread != stackThread) { +#if PLATFORM(QNX) + int fd; + struct _debug_thread_info tinfo; + memset(&tinfo, 0, sizeof(tinfo)); + tinfo.tid = pthread_self(); + fd = open("/proc/self", O_RDONLY); + if (fd == -1) { +#ifndef NDEBUG + perror("Unable to open /proc/self:"); +#endif + return 0; + } + devctl(fd, DCMD_PROC_TIDSTATUS, &tinfo, sizeof(tinfo), NULL); + close(fd); + stackBase = (void*)tinfo.stkbase; + stackSize = tinfo.stksize; + ASSERT(stackBase); +#else #if defined(QT_LINUXBASE) // LinuxBase is missing pthread_getattr_np - resolve it once at runtime instead // see http://bugs.linuxbase.org/show_bug.cgi?id=2364 @@ -604,6 +629,7 @@ static inline void* currentThreadStackBase() (void)rc; // FIXME: Deal with error code somehow? Seems fatal. ASSERT(stackBase); pthread_attr_destroy(&sattr); +#endif stackThread = thread; } return static_cast<char*>(stackBase) + stackSize; diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/DateMath.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/DateMath.cpp index 648dc70..0b76649 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/DateMath.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/DateMath.cpp @@ -841,7 +841,7 @@ double parseDateFromNullTerminatedCharacters(const char* dateString) return NaN; int sgn = (o < 0) ? -1 : 1; - o = abs(o); + o = labs(o); if (*dateString != ':') { offset = ((o / 100) * 60 + (o % 100)) * sgn; } else { // GMT+05:00 diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h index 5b43d17..c7a5be9 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h @@ -109,6 +109,13 @@ #define WTF_PLATFORM_NETBSD 1 #endif +/* PLATFORM(QNX) */ +/* Operating system level dependencies for QNX that should be used */ +/* regardless of operating environment */ +#if defined(__QNXNTO__) +#define WTF_PLATFORM_QNX 1 +#endif + /* PLATFORM(UNIX) */ /* Operating system level dependencies for Unix-like systems that */ /* should be used regardless of operating environment */ @@ -119,7 +126,8 @@ || defined(unix) \ || defined(__unix) \ || defined(__unix__) \ - || defined(_AIX) + || defined(_AIX) \ + || defined(__QNXNTO__) #define WTF_PLATFORM_UNIX 1 #endif @@ -431,7 +439,8 @@ #define HAVE_SIGNAL_H 1 #endif -#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !PLATFORM(SYMBIAN) && !COMPILER(RVCT) +#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !PLATFORM(QNX) \ + && !PLATFORM(SYMBIAN) && !COMPILER(RVCT) #define HAVE_TM_GMTOFF 1 #define HAVE_TM_ZONE 1 #define HAVE_TIMEGM 1 @@ -481,6 +490,15 @@ #define HAVE_SYS_PARAM_H 1 #endif +#elif PLATFORM(QNX) + +#define HAVE_ERRNO_H 1 +#define HAVE_MMAP 1 +#define HAVE_SBRK 1 +#define HAVE_STRINGS_H 1 +#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYS_TIME_H 1 + #else /* FIXME: is this actually used or do other platforms generate their own config.h? */ diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 89c70d1..6834134 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -4,7 +4,7 @@ This is a snapshot of the Qt port of WebKit from The commit imported was from the - origin/qtwebkit-4.6-staging branch/tag + qtwebkit-4.6-snapshot-29072009 branch/tag and has the sha1 checksum diff --git a/src/3rdparty/webkit/WebCore/bridge/npapi.h b/src/3rdparty/webkit/WebCore/bridge/npapi.h index 003e67a..07fed86 100644 --- a/src/3rdparty/webkit/WebCore/bridge/npapi.h +++ b/src/3rdparty/webkit/WebCore/bridge/npapi.h @@ -114,6 +114,14 @@ /* Definition of Basic Types */ /*----------------------------------------------------------------------*/ +/* QNX sets the _INT16 and friends defines, but does not typedef the types */ +#ifdef __QNXNTO__ +#undef _UINT16 +#undef _INT16 +#undef _UINT32 +#undef _INT32 +#endif + #ifndef _UINT16 #define _UINT16 typedef unsigned short uint16; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp index 35d873a..e1a0c98 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp @@ -86,7 +86,7 @@ public: \image qwebview-url.png A web site can be loaded onto QWebView with the load() function. Like all - Qt Widgets, the show() function must be invoked in order to display + Qt widgets, the show() function must be invoked in order to display QWebView. The snippet below illustrates this: \snippet webkitsnippets/simple/main.cpp Using QWebView @@ -146,7 +146,8 @@ public: if you do not require QWidget attributes. Nevertheless, QtWebKit depends on QtGui, so you should use a QApplication instead of QCoreApplication. - \sa {Previewer Example}, {Browser}, {Form Extractor}, {Google Chat}, {Fancy Browser} + \sa {Previewer Example}, {Web Browser}, {Form Extractor Example}, + {Google Chat Example}, {Fancy Browser Example} */ /*! diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 20b9227..dd3141a 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -4,6 +4,8 @@ win32:HEADERS += arch/qatomic_windows.h \ mac:HEADERS += arch/qatomic_macosx.h \ arch/qatomic_generic.h +vxworks:HEADERS += arch/qatomic_vxworks.h + !wince*:!win32:!mac:HEADERS += arch/qatomic_alpha.h \ arch/qatomic_avr32.h \ arch/qatomic_ia64.h \ diff --git a/src/corelib/arch/qatomic_arch.h b/src/corelib/arch/qatomic_arch.h index 724cf7e..17e4630 100644 --- a/src/corelib/arch/qatomic_arch.h +++ b/src/corelib/arch/qatomic_arch.h @@ -46,7 +46,9 @@ QT_BEGIN_HEADER #include "QtCore/qglobal.h" -#if defined(QT_ARCH_ALPHA) +#if defined(QT_ARCH_VXWORKS) +# include "QtCore/qatomic_vxworks.h" +#elif defined(QT_ARCH_ALPHA) # include "QtCore/qatomic_alpha.h" #elif defined(QT_ARCH_ARM) # include "QtCore/qatomic_arm.h" diff --git a/src/corelib/arch/qatomic_vxworks.h b/src/corelib/arch/qatomic_vxworks.h new file mode 100644 index 0000000..573a44d --- /dev/null +++ b/src/corelib/arch/qatomic_vxworks.h @@ -0,0 +1,318 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QATOMIC_VXWORKS_H +#define QATOMIC_VXWORKS_H + +QT_BEGIN_HEADER + +#if defined(__ppc) +# include <QtCore/qatomic_powerpc.h> +#else // generic implementation with taskLock() + +#if 0 +// we don't want to include the system header here for two function prototypes, +// because it pulls in a _lot_ of stuff that pollutes the global namespace +# include <vxWorksCommon.h> +# include <taskLib.h> +#else +extern "C" int taskLock(); +extern "C" int taskUnlock(); +#endif + + + +QT_BEGIN_NAMESPACE + +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE + +inline bool QBasicAtomicInt::isReferenceCountingNative() +{ return false; } +inline bool QBasicAtomicInt::isReferenceCountingWaitFree() +{ return false; } + +#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE + +inline bool QBasicAtomicInt::isTestAndSetNative() +{ return false; } +inline bool QBasicAtomicInt::isTestAndSetWaitFree() +{ return false; } + +#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE + +inline bool QBasicAtomicInt::isFetchAndStoreNative() +{ return false; } +inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() +{ return false; } + +#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE + +inline bool QBasicAtomicInt::isFetchAndAddNative() +{ return false; } +inline bool QBasicAtomicInt::isFetchAndAddWaitFree() +{ return false; } + +#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE + +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() +{ return false; } +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() +{ return false; } + +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE + +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() +{ return false; } +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() +{ return false; } + +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE + +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() +{ return false; } +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() +{ return false; } + +// Reference counting + +inline bool QBasicAtomicInt::ref() +{ + taskLock(); + bool ret = (++_q_value != 0); + taskUnlock(); + return ret; +} + +inline bool QBasicAtomicInt::deref() +{ + taskLock(); + bool ret = (--_q_value != 0); + taskUnlock(); + return ret; +} + +// Test-and-set for integers + +inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) +{ + taskLock(); + if (_q_value == expectedValue) { + _q_value = newValue; + taskUnlock(); + return true; + } + taskUnlock(); + return false; +} + +inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +// Fetch-and-store for integers + +inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +{ + taskLock(); + int returnValue = _q_value; + _q_value = newValue; + taskUnlock(); + return returnValue; +} + +inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +// Fetch-and-add for integers + +inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) +{ + taskLock(); + int originalValue = _q_value; + _q_value += valueToAdd; + taskUnlock(); + return originalValue; +} + +inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +// Test and set for pointers + +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) +{ + taskLock(); + if (_q_value == expectedValue) { + _q_value = newValue; + taskUnlock(); + return true; + } + taskUnlock(); + return false; +} + +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +template <typename T> +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +// Fetch and store for pointers + +template <typename T> +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) +{ + taskLock(); + T *returnValue = (_q_value); + _q_value = newValue; + taskUnlock(); + return returnValue; +} + +template <typename T> +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +template <typename T> +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +template <typename T> +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +// Fetch and add for pointers + +template <typename T> +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) +{ + taskLock(); + T *returnValue = (_q_value); + _q_value += valueToAdd; + taskUnlock(); + return returnValue; +} + +template <typename T> +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +template <typename T> +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +template <typename T> +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +QT_END_NAMESPACE + +#endif // generic implementation with taskLock() + +QT_END_HEADER + +#endif // QATOMIC_VXWORKS_H diff --git a/src/corelib/arch/vxworks/arch.pri b/src/corelib/arch/vxworks/arch.pri new file mode 100644 index 0000000..a768618 --- /dev/null +++ b/src/corelib/arch/vxworks/arch.pri @@ -0,0 +1,6 @@ +# +# VxWorks generic +# +*-ppc-* { + SOURCES += qatomic_ppc.s +} diff --git a/src/corelib/arch/vxworks/qatomic_ppc.s b/src/corelib/arch/vxworks/qatomic_ppc.s new file mode 100644 index 0000000..03971e8 --- /dev/null +++ b/src/corelib/arch/vxworks/qatomic_ppc.s @@ -0,0 +1,415 @@ + + .align 2 + .globl q_atomic_test_and_set_int + .globl .q_atomic_test_and_set_int +q_atomic_test_and_set_int: +.q_atomic_test_and_set_int: + lwarx 6,0,3 + xor. 6,6,4 + bne $+12 + stwcx. 5,0,3 + bne- $-16 + subfic 3,6,0 + adde 3,3,6 + blr +LT..q_atomic_test_and_set_int: + .long 0 + .byte 0,9,32,64,0,0,3,0 + .long 0 + .long LT..q_atomic_test_and_set_int-.q_atomic_test_and_set_int + .short 25 + .byte "q_atomic_test_and_set_int" + .align 2 + + .align 2 + .globl q_atomic_test_and_set_acquire_int + .globl .q_atomic_test_and_set_acquire_int +q_atomic_test_and_set_acquire_int: +.q_atomic_test_and_set_acquire_int: + lwarx 6,0,3 + xor. 6,6,4 + bne $+16 + stwcx. 5,0,3 + bne- $-16 + isync + subfic 3,6,0 + adde 3,3,6 + blr +LT..q_atomic_test_and_set_acquire_int: + .long 0 + .byte 0,9,32,64,0,0,3,0 + .long 0 + .long LT..q_atomic_test_and_set_acquire_int-.q_atomic_test_and_set_acquire_int + .short 33 + .byte "q_atomic_test_and_set_acquire_int" + .align 2 + + .align 2 + .globl q_atomic_test_and_set_release_int + .globl .q_atomic_test_and_set_release_int +q_atomic_test_and_set_release_int: +.q_atomic_test_and_set_release_int: + lwarx 6,0,3 + xor. 6,6,4 + bne $+12 + stwcx. 5,0,3 + bne- $-16 + subfic 3,6,0 + adde 3,3,6 + blr +LT..q_atomic_test_and_set_release_int: + .long 0 + .byte 0,9,32,64,0,0,3,0 + .long 0 + .long LT..q_atomic_test_and_set_release_int-.q_atomic_test_and_set_release_int + .short 33 + .byte "q_atomic_test_and_set_release_int" + .align 2 + + .align 2 + .globl q_atomic_test_and_set_ptr + .globl .q_atomic_test_and_set_ptr +q_atomic_test_and_set_ptr: +.q_atomic_test_and_set_ptr: + lwarx 6,0,3 + xor. 6,6,4 + bne $+12 + stwcx. 5,0,3 + bne- $-16 + subfic 3,6,0 + adde 3,3,6 + blr +LT..q_atomic_test_and_set_ptr: + .long 0 + .byte 0,9,32,64,0,0,3,0 + .long 0 + .long LT..q_atomic_test_and_set_ptr-.q_atomic_test_and_set_ptr + .short 25 + .byte "q_atomic_test_and_set_ptr" + .align 2 + + .align 2 + .globl q_atomic_test_and_set_acquire_ptr + .globl .q_atomic_test_and_set_acquire_ptr +q_atomic_test_and_set_acquire_ptr: +.q_atomic_test_and_set_acquire_ptr: + lwarx 6,0,3 + xor. 6,6,4 + bne $+16 + stwcx. 5,0,3 + bne- $-16 + isync + subfic 3,6,0 + adde 3,3,6 + blr +LT..q_atomic_test_and_set_acquire_ptr: + .long 0 + .byte 0,9,32,64,0,0,3,0 + .long 0 + .long LT..q_atomic_test_and_set_acquire_ptr-.q_atomic_test_and_set_acquire_ptr + .short 25 + .byte "q_atomic_test_and_set_acquire_ptr" + .align 2 + + .align 2 + .globl q_atomic_test_and_set_release_ptr + .globl .q_atomic_test_and_set_release_ptr +q_atomic_test_and_set_release_ptr: +.q_atomic_test_and_set_release_ptr: + lwarx 6,0,3 + xor. 6,6,4 + bne $+12 + stwcx. 5,0,3 + bne- $-16 + subfic 3,6,0 + adde 3,3,6 + blr +LT..q_atomic_test_and_set_release_ptr: + .long 0 + .byte 0,9,32,64,0,0,3,0 + .long 0 + .long LT..q_atomic_test_and_set_release_ptr-.q_atomic_test_and_set_release_ptr + .short 33 + .byte "q_atomic_test_and_set_release_ptr" + .align 2 + + .align 2 + .globl q_atomic_increment + .globl .q_atomic_increment +q_atomic_increment: +.q_atomic_increment: + lwarx 4,0,3 + addi 4,4,1 + stwcx. 4,0,3 + bne- $-12 + mr 3,4 + blr +LT..q_atomic_increment: + .long 0 + .byte 0,9,32,64,0,0,1,0 + .long 0 + .long LT..q_atomic_increment-.q_atomic_increment + .short 18 + .byte "q_atomic_increment" + .align 2 + + .align 2 + .globl q_atomic_decrement + .globl .q_atomic_decrement +q_atomic_decrement: +.q_atomic_decrement: + lwarx 4,0,3 + subi 4,4,1 + stwcx. 4,0,3 + bne- $-12 + mr 3,4 + blr +LT..q_atomic_decrement: + .long 0 + .byte 0,9,32,64,0,0,1,0 + .long 0 + .long LT..q_atomic_decrement-.q_atomic_decrement + .short 18 + .byte "q_atomic_decrement" + .align 2 + + .align 2 + .globl q_atomic_set_int + .globl .q_atomic_set_int +q_atomic_set_int: +.q_atomic_set_int: + lwarx 5,0,3 + stwcx. 4,0,3 + bne- $-8 + mr 3,5 + blr +LT..q_atomic_set_int: + .long 0 + .byte 0,9,32,64,0,0,2,0 + .long 0 + .long LT..q_atomic_set_int-.q_atomic_set_int + .short 16 + .byte "q_atomic_set_int" + .align 2 + + .align 2 + .globl q_atomic_fetch_and_store_acquire_int + .globl .q_atomic_fetch_and_store_acquire_int +q_atomic_fetch_and_store_acquire_int: +.q_atomic_fetch_and_store_acquire_int: + lwarx 5,0,3 + stwcx. 4,0,3 + bne- $-8 + isync + mr 3,5 + blr +LT..q_atomic_fetch_and_store_acquire_int: + .long 0 + .byte 0,9,32,64,0,0,2,0 + .long 0 + .long LT..q_atomic_fetch_and_store_acquire_int-.q_atomic_fetch_and_store_acquire_int + .short 16 + .byte "q_atomic_fetch_and_store_acquire_int" + .align 2 + + .align 2 + .globl q_atomic_fetch_and_store_release_int + .globl .q_atomic_fetch_and_store_release_int +q_atomic_fetch_and_store_release_int: +.q_atomic_fetch_and_store_release_int: + lwarx 5,0,3 + stwcx. 4,0,3 + bne- $-8 + mr 3,5 + blr +LT..q_atomic_fetch_and_store_release_int: + .long 0 + .byte 0,9,32,64,0,0,2,0 + .long 0 + .long LT..q_atomic_fetch_and_store_release_int-.q_atomic_fetch_and_store_release_int + .short 16 + .byte "q_atomic_fetch_and_store_release_int" + .align 2 + + .align 2 + .globl q_atomic_set_ptr + .globl .q_atomic_set_ptr +q_atomic_set_ptr: +.q_atomic_set_ptr: + lwarx 5,0,3 + stwcx. 4,0,3 + bne- $-8 + mr 3,5 + blr +LT..q_atomic_set_ptr: + .long 0 + .byte 0,9,32,64,0,0,2,0 + .long 0 + .long LT..q_atomic_set_ptr-.q_atomic_set_ptr + .short 16 + .byte "q_atomic_set_ptr" + .align 2 + + .align 2 + .globl q_atomic_fetch_and_store_acquire_ptr + .globl .q_atomic_fetch_and_store_acquire_ptr +q_atomic_fetch_and_store_acquire_ptr: +.q_atomic_fetch_and_store_acquire_ptr: + lwarx 5,0,3 + stwcx. 4,0,3 + bne- $-8 + isync + mr 3,5 + blr +LT..q_atomic_fetch_and_store_acquire_ptr: + .long 0 + .byte 0,9,32,64,0,0,2,0 + .long 0 + .long LT..q_atomic_fetch_and_store_acquire_ptr-.q_atomic_fetch_and_store_acquire_ptr + .short 16 + .byte "q_atomic_fetch_and_store_acquire_ptr" + .align 2 + + .align 2 + .globl q_atomic_fetch_and_store_release_ptr + .globl .q_atomic_fetch_and_store_release_ptr +q_atomic_fetch_and_store_release_ptr: +.q_atomic_fetch_and_store_release_ptr: + lwarx 5,0,3 + stwcx. 4,0,3 + bne- $-8 + mr 3,5 + blr +LT..q_atomic_fetch_and_store_release_ptr: + .long 0 + .byte 0,9,32,64,0,0,2,0 + .long 0 + .long LT..q_atomic_fetch_and_store_release_ptr-.q_atomic_fetch_and_store_release_ptr + .short 16 + .byte "q_atomic_fetch_and_store_release_ptr" + .align 2 + + .align 2 + .globl q_atomic_fetch_and_add_int + .globl .q_atomic_fetch_and_add_int +q_atomic_fetch_and_add_int: +.q_atomic_fetch_and_add_int: + lwarx 5,0,3 + add 6,4,5 + stwcx. 6,0,3 + bne- $-12 + mr 3,5 + blr +LT..q_atomic_fetch_and_add_int: + .long 0 + .byte 0,9,32,64,0,0,1,0 + .long 0 + .long LT..q_atomic_fetch_and_add_int-.q_atomic_fetch_and_add_int + .short 18 + .byte "q_atomic_fetch_and_add_int" + .align 2 + + .align 2 + .globl q_atomic_fetch_and_add_acquire_int + .globl .q_atomic_fetch_and_add_acquire_int +q_atomic_fetch_and_add_acquire_int: +.q_atomic_fetch_and_add_acquire_int: + lwarx 5,0,3 + add 6,4,5 + stwcx. 6,0,3 + bne- $-12 + isync + mr 3,5 + blr +LT..q_atomic_fetch_and_add_acquire_int: + .long 0 + .byte 0,9,32,64,0,0,1,0 + .long 0 + .long LT..q_atomic_fetch_and_add_acquire_int-.q_atomic_fetch_and_add_acquire_int + .short 18 + .byte "q_atomic_fetch_and_add_acquire_int" + .align 2 + + .align 2 + .globl q_atomic_fetch_and_add_release_int + .globl .q_atomic_fetch_and_add_release_int +q_atomic_fetch_and_add_release_int: +.q_atomic_fetch_and_add_release_int: + lwarx 5,0,3 + add 6,4,5 + stwcx. 6,0,3 + bne- $-12 + mr 3,5 + blr +LT..q_atomic_fetch_and_add_release_int: + .long 0 + .byte 0,9,32,64,0,0,1,0 + .long 0 + .long LT..q_atomic_fetch_and_add_release_int-.q_atomic_fetch_and_add_release_int + .short 34 + .byte "q_atomic_fetch_and_add_release_int" + .align 2 + + .align 2 + .globl q_atomic_fetch_and_add_ptr + .globl .q_atomic_fetch_and_add_ptr +q_atomic_fetch_and_add_ptr: +.q_atomic_fetch_and_add_ptr: + lwarx 5,0,3 + add 6,4,5 + stwcx. 6,0,3 + bne- $-12 + mr 3,5 + blr +LT..q_atomic_fetch_and_add_ptr: + .long 0 + .byte 0,9,32,64,0,0,1,0 + .long 0 + .long LT..q_atomic_fetch_and_add_ptr-.q_atomic_fetch_and_add_ptr + .short 26 + .byte "q_atomic_fetch_and_add_ptr" + .align 2 + + .align 2 + .globl q_atomic_fetch_and_add_acquire_ptr + .globl .q_atomic_fetch_and_add_acquire_ptr +q_atomic_fetch_and_add_acquire_ptr: +.q_atomic_fetch_and_add_acquire_ptr: + lwarx 5,0,3 + add 6,4,5 + stwcx. 6,0,3 + bne- $-12 + isync + mr 3,5 + blr +LT..q_atomic_fetch_and_add_acquire_ptr: + .long 0 + .byte 0,9,32,64,0,0,1,0 + .long 0 + .long LT..q_atomic_fetch_and_add_acquire_ptr-.q_atomic_fetch_and_add_acquire_ptr + .short 34 + .byte "q_atomic_fetch_and_add_acquire_ptr" + .align 2 + + .align 2 + .globl q_atomic_fetch_and_add_release_ptr + .globl .q_atomic_fetch_and_add_release_ptr +q_atomic_fetch_and_add_release_ptr: +.q_atomic_fetch_and_add_release_ptr: + lwarx 5,0,3 + add 6,4,5 + stwcx. 6,0,3 + bne- $-12 + mr 3,5 + blr +LT..q_atomic_fetch_and_add_release_ptr: + .long 0 + .byte 0,9,32,64,0,0,1,0 + .long 0 + .long LT..q_atomic_fetch_and_add_release_ptr-.q_atomic_fetch_and_add_release_ptr + .short 34 + .byte "q_atomic_fetch_and_add_release_ptr" + .align 2 + +_section_.text: + .long _section_.text diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp index 188ac8c..7f89a8f 100644 --- a/src/corelib/codecs/qiconvcodec.cpp +++ b/src/corelib/codecs/qiconvcodec.cpp @@ -52,7 +52,7 @@ // unistd.h is needed for the _XOPEN_UNIX macro #include <unistd.h> -#if defined(_XOPEN_UNIX) && !defined(Q_OS_QNX6) && !defined(Q_OS_OSF) +#if defined(_XOPEN_UNIX) && !defined(Q_OS_QNX) && !defined(Q_OS_OSF) # include <langinfo.h> #endif @@ -455,7 +455,7 @@ iconv_t QIconvCodec::createIconv_t(const char *to, const char *from) char *codeset = 0; #endif -#if defined(_XOPEN_UNIX) && !defined(Q_OS_QNX6) && !defined(Q_OS_OSF) +#if defined(_XOPEN_UNIX) && !defined(Q_OS_QNX) && !defined(Q_OS_OSF) if (cd == (iconv_t) -1) { codeset = nl_langinfo(CODESET); if (codeset) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index f49e34a..4b774d7 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -84,7 +84,7 @@ #include <stdlib.h> #include <ctype.h> #include <locale.h> -#if defined (_XOPEN_UNIX) && !defined(Q_OS_QNX6) && !defined(Q_OS_OSF) +#if defined (_XOPEN_UNIX) && !defined(Q_OS_QNX) && !defined(Q_OS_OSF) #include <langinfo.h> #endif @@ -532,7 +532,7 @@ static void setupLocaleMapper() localeMapper = QTextCodec::codecForName("System"); #endif -#if defined (_XOPEN_UNIX) && !defined(Q_OS_QNX6) && !defined(Q_OS_OSF) +#if defined (_XOPEN_UNIX) && !defined(Q_OS_QNX) && !defined(Q_OS_OSF) if (!localeMapper) { char *charset = nl_langinfo (CODESET); if (charset) diff --git a/src/corelib/concurrent/qtconcurrentiteratekernel.cpp b/src/corelib/concurrent/qtconcurrentiteratekernel.cpp index ee1ed3a..d0a37de 100644 --- a/src/corelib/concurrent/qtconcurrentiteratekernel.cpp +++ b/src/corelib/concurrent/qtconcurrentiteratekernel.cpp @@ -52,6 +52,8 @@ #include <qt_windows.h> #endif +#include "private/qfunctions_p.h" + #ifndef QT_NO_CONCURRENT diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index f7d6514..776a740 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -62,6 +62,10 @@ # endif #endif +#if defined(Q_OS_VXWORKS) +# include <envLib.h> +#endif + #ifdef Q_CC_MWERKS #include <CoreServices/CoreServices.h> #endif @@ -1344,14 +1348,7 @@ bool qSharedBuild() \macro Q_OS_QNX \relates <QtGlobal> - Defined on QNX. -*/ - -/*! - \macro Q_OS_QNX6 - \relates <QtGlobal> - - Defined on QNX RTP 6.1. + Defined on QNX Neutrino. */ /*! @@ -1914,7 +1911,7 @@ QString qt_error_string(int errorCode) if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND) ret = QString::fromLatin1("The specified module could not be found."); -#elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) +#elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) QByteArray buf(1024, '\0'); strerror_r(errorCode, buf.data(), buf.size()); diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 4ceabee..8263bae 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -238,8 +238,6 @@ namespace QT_NAMESPACE {} #elif defined(__DGUX__) # define Q_OS_DGUX #elif defined(__QNXNTO__) -# define Q_OS_QNX6 -#elif defined(__QNX__) # define Q_OS_QNX #elif defined(_SEQUENT_) # define Q_OS_DYNIX @@ -251,6 +249,8 @@ namespace QT_NAMESPACE {} # define Q_OS_UNIXWARE #elif defined(__INTEGRITY) # define Q_OS_INTEGRITY +#elif defined(VXWORKS) /* there is no "real" VxWorks define - this has to be set in the mkspec! */ +# define Q_OS_VXWORKS #elif defined(__MAKEDEPEND__) #else # error "Qt has not been ported to this OS - talk to qt-bugs@trolltech.com" @@ -425,25 +425,6 @@ namespace QT_NAMESPACE {} #elif defined(__WATCOMC__) # define Q_CC_WAT -# if defined(Q_OS_QNX4) -/* compiler flags */ -# define Q_TYPENAME -# define Q_NO_BOOL_TYPE -# define Q_CANNOT_DELETE_CONSTANT -# define mutable -/* ??? */ -# define Q_BROKEN_TEMPLATE_SPECIALIZATION -/* no template classes in QVariant */ -# define QT_NO_TEMPLATE_VARIANT -/* Wcc does not fill in functions needed by valuelists, maps, and - valuestacks implicitly */ -# define Q_FULL_TEMPLATE_INSTANTIATION -/* can we just compare the structures? */ -# define Q_FULL_TEMPLATE_INSTANTIATION_MEMCMP -/* these are not useful to our customers */ -# define QT_NO_QWS_MULTIPROCESS -# define QT_NO_QWS_CURSOR -# endif #elif defined(__CC_ARM) # define Q_CC_RVCT @@ -611,6 +592,13 @@ namespace QT_NAMESPACE {} # elif defined(__ghs) # define Q_CC_GHS +# elif defined(__DCC__) +# define Q_CC_DIAB +# undef Q_NO_BOOL_TYPE +# if !defined(__bool) +# define Q_NO_BOOL_TYPE +# endif + /* The UnixWare 7 UDK compiler is based on EDG and does define __EDG__ */ # elif defined(__USLC__) && defined(__SCO_VERSION__) # define Q_CC_USLC @@ -642,6 +630,11 @@ namespace QT_NAMESPACE {} # endif # endif +/* VxWorks' DIAB toolchain has an additional EDG type C++ compiler + (see __DCC__ above). This one is for C mode files (__EDG is not defined) */ +#elif defined(_DIAB_TOOL) +# define Q_CC_DIAB + /* Never tested! */ #elif defined(__HIGHC__) # define Q_CC_HIGHC @@ -1110,6 +1103,15 @@ class QDataStream; # define QT_NO_COP #endif +#if defined(Q_OS_VXWORKS) +# define QT_NO_CRASHHANDLER // no popen +# define QT_NO_PROCESS // no exec*, no fork +# define QT_NO_LPR +# define QT_NO_SHAREDMEMORY // only POSIX, no SysV and in the end... +# define QT_NO_SYSTEMSEMAPHORE // not needed at all in a flat address space +# define QT_NO_QWS_MULTIPROCESS // no processes +#endif + # include <QtCore/qfeatures.h> #define QT_SUPPORTS(FEATURE) (!defined(QT_NO_##FEATURE)) @@ -1552,7 +1554,7 @@ Q_CORE_EXPORT void qt_check_pointer(const char *, int); # define Q_CHECK_PTR(p) #endif -#if (defined(Q_CC_GNU) && !defined(Q_OS_SOLARIS)) || defined(Q_CC_HPACC) +#if (defined(Q_CC_GNU) && !defined(Q_OS_SOLARIS)) || defined(Q_CC_HPACC) || defined(Q_CC_DIAB) # define Q_FUNC_INFO __PRETTY_FUNCTION__ #elif defined(_MSC_VER) /* MSVC 2002 doesn't have __FUNCSIG__ nor can it handle QT_STRINGIFY. */ @@ -2142,6 +2144,17 @@ inline const QForeachContainer<T> *qForeachContainer(const QForeachContainerBase qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->brk; \ --qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->brk) +#elif defined(Q_CC_DIAB) +// VxWorks DIAB generates unresolvable symbols, if container is a function call +# define Q_FOREACH(variable,container) \ + if(0){}else \ + for (const QForeachContainerBase &_container_ = qForeachContainerNew(container); \ + qForeachContainer(&_container_, (__typeof__(container) *) 0)->condition(); \ + ++qForeachContainer(&_container_, (__typeof__(container) *) 0)->i) \ + for (variable = *qForeachContainer(&_container_, (__typeof__(container) *) 0)->i; \ + qForeachContainer(&_container_, (__typeof__(container) *) 0)->brk; \ + --qForeachContainer(&_container_, (__typeof__(container) *) 0)->brk) + #else # define Q_FOREACH(variable, container) \ for (const QForeachContainerBase &_container_ = qForeachContainerNew(container); \ @@ -2418,6 +2431,17 @@ QT_LICENSED_MODULE(DBus) # define QT_NO_CONCURRENT_FILTER #endif +#ifdef Q_OS_QNX +// QNX doesn't have SYSV style shared memory. Multiprocess QWS apps, +// shared fonts and QSystemSemaphore + QSharedMemory are not available +# define QT_NO_QWS_MULTIPROCESS +# define QT_NO_QWS_SHARE_FONTS +# define QT_NO_SYSTEMSEMAPHORE +# define QT_NO_SHAREDMEMORY +// QNX currently doesn't support forking in a thread, so disable QProcess +# define QT_NO_PROCESS +#endif + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 47e3db0..c0b6820 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -413,7 +413,7 @@ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) con if (QT_STAT(chunk, &st) != -1) { if ((st.st_mode & S_IFMT) != S_IFDIR) return false; - } else if (::mkdir(chunk, 0777) != 0) { + } else if (QT_MKDIR(chunk, 0777) != 0) { return false; } } @@ -424,7 +424,7 @@ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) con if (dirName[dirName.length() - 1] == QLatin1Char('/')) dirName = dirName.left(dirName.length() - 1); #endif - return (::mkdir(QFile::encodeName(dirName), 0777) == 0); + return (QT_MKDIR(QFile::encodeName(dirName), 0777) == 0); } bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 16927ea..42c57a4 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -62,6 +62,15 @@ //#define DEBUG_RESOURCE_MATCH +#if defined(Q_OS_VXWORKS) +# if defined(m_data) +# undef m_data +# endif +# if defined(m_len) +# undef m_len +# endif +#endif + QT_BEGIN_NAMESPACE diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 7de5030..2a483bc 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -74,6 +74,10 @@ #endif // Q_OS_WIN #endif // QT_NO_QOBJECT +#ifdef Q_OS_VXWORKS +# include <ioLib.h> +#endif + #include <stdlib.h> #ifndef CSIDL_COMMON_APPDATA @@ -167,7 +171,7 @@ static bool isLikelyToBeNfs(int handle) } #elif defined(Q_OS_SOLARIS) || defined(Q_OS_IRIX) || defined(Q_OS_AIX) || defined(Q_OS_HPUX) \ - || defined(Q_OS_OSF) || defined(Q_OS_QNX) || defined(Q_OS_QNX6) || defined(Q_OS_SCO) \ + || defined(Q_OS_OSF) || defined(Q_OS_QNX) || defined(Q_OS_SCO) \ || defined(Q_OS_UNIXWARE) || defined(Q_OS_RELIANT) || defined(Q_OS_NETBSD) QT_BEGIN_INCLUDE_NAMESPACE # include <sys/statvfs.h> diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index b520bee..e92e729 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -73,7 +73,10 @@ #if defined(Q_OS_WINCE) # include <types.h> -# include "qfunctions_wince.h" +#endif + +#if defined(Q_OS_VXWORKS) +# include <taskLib.h> #endif QT_BEGIN_NAMESPACE @@ -133,6 +136,8 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) } #if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400 pid = _getpid(); +#elif defined(Q_OS_VXWORKS) + pid = (pid_t) taskIdCurrent; #else pid = getpid(); #endif @@ -234,7 +239,7 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) #ifdef Q_OS_WIN if (QT_MKDIR(path) == 0) #else - if (mkdir(path, 0700) == 0) + if (QT_MKDIR(path, 0700) == 0) #endif return 1; if (errno != EEXIST) diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 8759578..7177293 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -112,3 +112,10 @@ unix { contains(QT_CONFIG, clock-gettime):include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri) } +vxworks { + SOURCES += \ + kernel/qfunctions_vxworks.cpp + HEADERS += \ + kernel/qfunctions_vxworks.h +} + diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index 28c1d9c..b57d385 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -41,11 +41,14 @@ #include "qcore_unix_p.h" -#include <sys/select.h> -#include <sys/time.h> -#include <stdlib.h> +#ifndef Q_OS_VXWORKS +# include <sys/select.h> +# include <sys/time.h> +#else +# include <selectLib.h> +#endif -#include "qeventdispatcher_unix_p.h" // for the timeval operators +#include <stdlib.h> #ifdef Q_OS_MAC #include <mach/mach_time.h> diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index bffd670..dceb73a 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -67,6 +67,10 @@ #include <errno.h> #include <fcntl.h> +#if defined(Q_OS_VXWORKS) +# include <ioLib.h> +#endif + struct sockaddr; #if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 @@ -110,6 +114,51 @@ using namespace QT_PREPEND_NAMESPACE(QtLibcSupplement); QT_BEGIN_NAMESPACE +// Internal operator functions for timevals +inline timeval &normalizedTimeval(timeval &t) +{ + while (t.tv_usec > 1000000l) { + ++t.tv_sec; + t.tv_usec -= 1000000l; + } + while (t.tv_usec < 0l) { + --t.tv_sec; + t.tv_usec += 1000000l; + } + return t; +} +inline bool operator<(const timeval &t1, const timeval &t2) +{ return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); } +inline bool operator==(const timeval &t1, const timeval &t2) +{ return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec; } +inline timeval &operator+=(timeval &t1, const timeval &t2) +{ + t1.tv_sec += t2.tv_sec; + t1.tv_usec += t2.tv_usec; + return normalizedTimeval(t1); +} +inline timeval operator+(const timeval &t1, const timeval &t2) +{ + timeval tmp; + tmp.tv_sec = t1.tv_sec + t2.tv_sec; + tmp.tv_usec = t1.tv_usec + t2.tv_usec; + return normalizedTimeval(tmp); +} +inline timeval operator-(const timeval &t1, const timeval &t2) +{ + timeval tmp; + tmp.tv_sec = t1.tv_sec - (t2.tv_sec - 1); + tmp.tv_usec = t1.tv_usec - (t2.tv_usec + 1000000); + return normalizedTimeval(tmp); +} +inline timeval operator*(const timeval &t1, int mul) +{ + timeval tmp; + tmp.tv_sec = t1.tv_sec * mul; + tmp.tv_usec = t1.tv_usec * mul; + return normalizedTimeval(tmp); +} + // don't call QT_OPEN or ::open // call qt_safe_open static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 0777) @@ -129,6 +178,7 @@ static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 07 #undef QT_OPEN #define QT_OPEN qt_safe_open +#ifndef Q_OS_VXWORKS // no POSIX pipes in VxWorks // don't call ::pipe // call qt_safe_pipe static inline int qt_safe_pipe(int pipefd[2], int flags = 0) @@ -164,6 +214,8 @@ static inline int qt_safe_pipe(int pipefd[2], int flags = 0) return 0; } +#endif // Q_OS_VXWORKS + // don't call dup or fcntl(F_DUPFD) static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC) { @@ -238,6 +290,8 @@ static inline int qt_safe_close(int fd) #undef QT_CLOSE #define QT_CLOSE qt_safe_close +#ifndef Q_OS_VXWORKS // no processes in VxWorks + static inline int qt_safe_execve(const char *filename, char *const argv[], char *const envp[]) { @@ -267,6 +321,8 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options) return ret; } +#endif // Q_OS_VXWORKS + bool qt_gettime_is_monotonic(); timeval qt_gettime(); Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 706dc54..d0a4943 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -61,6 +61,7 @@ #include <private/qthread_p.h> #include <qlibraryinfo.h> #include <private/qfactoryloader_p.h> +#include <private/qfunctions_p.h> #ifdef Q_OS_UNIX # if !defined(QT_NO_GLIB) @@ -83,6 +84,10 @@ # include <locale.h> #endif +#ifdef Q_OS_VXWORKS +# include <taskLib.h> +#endif + QT_BEGIN_NAMESPACE #if defined(Q_WS_WIN) || defined(Q_WS_MAC) @@ -1821,8 +1826,9 @@ qint64 QCoreApplication::applicationPid() { #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) return GetCurrentProcessId(); +#elif defined(Q_OS_VXWORKS) + return (pid_t) taskIdCurrent; #else - // UNIX return getpid(); #endif } diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 2943c6d..7982d4c 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -55,6 +55,16 @@ #include <stdio.h> #include <stdlib.h> +// VxWorks doesn't correctly set the _POSIX_... options +#if defined(Q_OS_VXWORKS) +# if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK <= 0) +# undef _POSIX_MONOTONIC_CLOCK +# define _POSIX_MONOTONIC_CLOCK 1 +# endif +# include <pipeDrv.h> +# include <selectLib.h> +#endif + #if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED) # include <sys/times.h> #endif @@ -77,7 +87,7 @@ static void signalHandler(int sig) } -#ifdef Q_OS_INTEGRITY +#if defined(Q_OS_INTEGRITY) || defined(Q_OS_VXWORKS) static void initThreadPipeFD(int fd) { int ret = fcntl(fd, F_SETFD, FD_CLOEXEC); @@ -98,20 +108,47 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() { extern Qt::HANDLE qt_application_thread_id; mainThread = (QThread::currentThreadId() == qt_application_thread_id); + bool pipefail = false; // initialize the common parts of the event loop -#ifdef Q_OS_INTEGRITY +#if defined(Q_OS_INTEGRITY) // INTEGRITY doesn't like a "select" on pipes, so use socketpair instead - if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1) + if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1) { perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair"); - - initThreadPipeFD(thread_pipe[0]); - initThreadPipeFD(thread_pipe[1]); + pipefail = true; + } else { + initThreadPipeFD(thread_pipe[0]); + initThreadPipeFD(thread_pipe[1]); + } +#elif defined(Q_OS_VXWORKS) + char name[20]; + qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent)); + + // make sure there is no pipe with this name + pipeDevDelete(name, true); + // create the pipe + if (pipeDevCreate(name, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) { + perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe device"); + pipefail = true; + } else { + if ((thread_pipe[0] = open(name, O_RDWR, 0)) < 0) { + perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe"); + pipefail = true; + } else { + initThreadPipeFD(thread_pipe[0]); + thread_pipe[1] = thread_pipe[0]; + } + } #else - if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1) + if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1) { perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe"); + pipefail = true; + } #endif + if (pipefail) + qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe"); + sn_highest = -1; interrupt = false; @@ -119,9 +156,18 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate() { +#if defined(Q_OS_VXWORKS) + close(thread_pipe[0]); + + char name[20]; + qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent)); + + pipeDevDelete(name, true); +#else // cleanup the common parts of the event loop close(thread_pipe[0]); close(thread_pipe[1]); +#endif // cleanup timers qDeleteAll(timerList); @@ -226,9 +272,15 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, // select doesn't immediately return next time int nevents = 0; if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) { +#if defined(Q_OS_VXWORKS) + char c[16]; + ::read(thread_pipe[0], c, sizeof(c)); + ::ioctl(thread_pipe[0], FIOFLUSH, 0); +#else char c[16]; while (::read(thread_pipe[0], c, sizeof(c)) > 0) ; +#endif if (!wakeUps.testAndSetRelease(1, 0)) { // hopefully, this is dead code qWarning("QEventDispatcherUNIX: internal error, wakeUps.testAndSetRelease(1, 0) failed!"); @@ -313,7 +365,7 @@ timeval qAbs(const timeval &t) */ bool QTimerInfoList::timeChanged(timeval *delta) { - tms unused; + struct tms unused; clock_t currentTicks = times(&unused); clock_t elapsedTicks = currentTicks - previousTicks; diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index 61d94c9..9c67c70 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -56,65 +56,23 @@ #include "QtCore/qabstracteventdispatcher.h" #include "QtCore/qlist.h" #include "private/qabstracteventdispatcher_p.h" +#include "private/qcore_unix_p.h" #include "private/qpodlist_p.h" -#include <sys/types.h> -#include <sys/time.h> -#if !defined(Q_OS_HPUX) || defined(__ia64) -#include <sys/select.h> +#if defined(Q_OS_VXWORKS) +# include <sys/times.h> +#else +# include <sys/time.h> +# if !defined(Q_OS_HPUX) || defined(__ia64) +# include <sys/select.h> +# endif #endif -#include <unistd.h> QT_BEGIN_NAMESPACE #if !defined(_POSIX_MONOTONIC_CLOCK) # define _POSIX_MONOTONIC_CLOCK -1 #endif -// Internal operator functions for timevals -inline timeval &normalizedTimeval(timeval &t) -{ - while (t.tv_usec > 1000000l) { - ++t.tv_sec; - t.tv_usec -= 1000000l; - } - while (t.tv_usec < 0l) { - --t.tv_sec; - t.tv_usec += 1000000l; - } - return t; -} -inline bool operator<(const timeval &t1, const timeval &t2) -{ return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); } -inline bool operator==(const timeval &t1, const timeval &t2) -{ return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec; } -inline timeval &operator+=(timeval &t1, const timeval &t2) -{ - t1.tv_sec += t2.tv_sec; - t1.tv_usec += t2.tv_usec; - return normalizedTimeval(t1); -} -inline timeval operator+(const timeval &t1, const timeval &t2) -{ - timeval tmp; - tmp.tv_sec = t1.tv_sec + t2.tv_sec; - tmp.tv_usec = t1.tv_usec + t2.tv_usec; - return normalizedTimeval(tmp); -} -inline timeval operator-(const timeval &t1, const timeval &t2) -{ - timeval tmp; - tmp.tv_sec = t1.tv_sec - (t2.tv_sec - 1); - tmp.tv_usec = t1.tv_usec - (t2.tv_usec + 1000000); - return normalizedTimeval(tmp); -} -inline timeval operator*(const timeval &t1, int mul) -{ - timeval tmp; - tmp.tv_sec = t1.tv_sec * mul; - tmp.tv_usec = t1.tv_usec * mul; - return normalizedTimeval(tmp); -} - // internal timer info struct QTimerInfo { int id; // - timer identifier diff --git a/src/corelib/kernel/qfunctions_p.h b/src/corelib/kernel/qfunctions_p.h index a7f2f9d..ad44a15 100644 --- a/src/corelib/kernel/qfunctions_p.h +++ b/src/corelib/kernel/qfunctions_p.h @@ -57,6 +57,8 @@ #if defined(Q_OS_WINCE) # include "QtCore/qfunctions_wince.h" +#elif defined(Q_OS_VXWORKS) +# include "QtCore/qfunctions_vxworks.h" #endif #ifdef Q_CC_RVCT diff --git a/src/corelib/kernel/qfunctions_vxworks.cpp b/src/corelib/kernel/qfunctions_vxworks.cpp new file mode 100644 index 0000000..6d5e7cc --- /dev/null +++ b/src/corelib/kernel/qfunctions_vxworks.cpp @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qglobal.h" + +#ifdef Q_OS_VXWORKS + +#include "qplatformdefs.h" +#include "qfunctions_vxworks.h" + +#include <vmLib.h> +#include <selectLib.h> +#include <ioLib.h> + +QT_USE_NAMESPACE + +#ifdef __cplusplus +extern "C" { +#endif + +// no lfind() - used by the TIF image format +void *lfind(const void* key, const void* base, size_t* elements, size_t size, + int (*compare)(const void*, const void*)) +{ + const char* current = (char*) base; + const char* const end = (char*) (current + (*elements) * size); + while (current != end) { + if (compare(current, key) == 0) + return (void*)current; + current += size; + } + return 0; +} + + +// no rand_r(), but rand() +// NOTE: this implementation is wrong for multi threaded applications, +// but there is no way to get it right on VxWorks (in kernel mode) +int rand_r(unsigned int * /*seedp*/) +{ + return rand(); +} + +// no usleep() support +int usleep(unsigned int usec) +{ + div_t dt = div(usec, 1000000); + struct timespec ts = { dt.quot, dt.rem * 1000 }; + + return nanosleep(&ts, 0); +} + + +// gettimeofday() is declared, but is missing from the library +// It IS however defined in the Curtis-Wright X11 libraries, so +// we have to make the symbol 'weak' +#if defined(Q_CC_DIAB) +# pragma weak gettimeofday +#endif +int gettimeofday(struct timeval *tv, void /*struct timezone*/ *) +{ + // the compiler will optimize this and will only use one code path + if (sizeof(struct timeval) == sizeof(struct timespec)) { + int res = clock_gettime(CLOCK_REALTIME, (struct timespec *) tv); + if (!res) + tv->tv_usec /= 1000; + return res; + } else { + struct timespec ts; + + int res = clock_gettime(CLOCK_REALTIME, &ts); + if (!res) { + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + } + return res; + } +} + +// neither getpagesize() or sysconf(_SC_PAGESIZE) are available +int getpagesize() +{ + return vmPageSizeGet(); +} + +// symlinks are not supported (lstat is now just a call to stat - see qplatformdefs.h) +int symlink(const char *, const char *) +{ + errno = EIO; + return -1; +} + +ssize_t readlink(const char *, char *, size_t) +{ + errno = EIO; + return -1; +} + +// there's no truncate(), but ftruncate() support... +int truncate(const char *path, off_t length) +{ + int fd = open(path, O_WRONLY, 00777); + if (fd >= 0) { + int res = ftruncate(fd, length); + int en = errno; + close(fd); + errno = en; + return res; + } + // errno is already set by open + return -1; +} + + + +// VxWorks doesn't know about passwd & friends. +// in order to avoid patching the unix fs path everywhere +// we introduce some dummy functions that simulate a single +// 'root' user on the system. + +uid_t getuid() +{ + return 0; +} + +gid_t getgid() +{ + return 0; +} + +uid_t geteuid() +{ + return 0; +} + +struct passwd *getpwuid(uid_t uid) +{ + static struct passwd pwbuf = { "root", 0, 0, 0, 0, 0, 0 }; + + if (uid == 0) { + return &pwbuf; + } else { + errno = ENOENT; + return 0; + } +} + +struct group *getgrgid(gid_t gid) +{ + static struct group grbuf = { "root", 0, 0, 0 }; + + if (gid == 0) { + return &grbuf; + } else { + errno = ENOENT; + return 0; + } +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // Q_OS_VXWORKS diff --git a/src/corelib/kernel/qfunctions_vxworks.h b/src/corelib/kernel/qfunctions_vxworks.h new file mode 100644 index 0000000..cc98948 --- /dev/null +++ b/src/corelib/kernel/qfunctions_vxworks.h @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFUNCTIONS_VXWORKS_H +#define QFUNCTIONS_VXWORKS_H +#ifdef Q_OS_VXWORKS + +#include <unistd.h> +#include <pthread.h> +#include <dirent.h> +#include <signal.h> +#include <string.h> +#include <strings.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/times.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <netinet/in.h> +#ifndef QT_NO_IPV6IFNAME +#include <net/if.h> +#endif + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +#ifdef QT_BUILD_CORE_LIB +QT_MODULE(Core) +#endif + +QT_END_NAMESPACE +QT_END_HEADER + + +#ifndef RTLD_LOCAL +#define RTLD_LOCAL 0 +#endif + +#ifndef NSIG +#define NSIG _NSIGS +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// isascii is missing (sometimes!!) +#ifndef isascii +inline int isascii(int c) { return (c & 0x7f); } +#endif + +// no lfind() - used by the TIF image format +void *lfind(const void* key, const void* base, size_t* elements, size_t size, + int (*compare)(const void*, const void*)); + +// no rand_r(), but rand() +// NOTE: this implementation is wrong for multi threaded applications, +// but there is no way to get it right on VxWorks (in kernel mode) +int rand_r(unsigned int * /*seedp*/); + +// no usleep() support +int usleep(unsigned int); + +// gettimeofday() is declared, but is missing from the library. +// It IS however defined in the Curtis-Wright X11 libraries, so +// we have to make the symbol 'weak' +int gettimeofday(struct timeval *tv, void /*struct timezone*/ *) __attribute__((weak)); + +// neither getpagesize() or sysconf(_SC_PAGESIZE) are available +int getpagesize(); + +// symlinks are not supported (lstat is now just a call to stat - see qplatformdefs.h) +int symlink(const char *, const char *); +ssize_t readlink(const char *, char *, size_t); + +// there's no truncate(), but ftruncate() support... +int truncate(const char *path, off_t length); + +// VxWorks doesn't know about passwd & friends. +// in order to avoid patching the unix fs path everywhere +// we introduce some dummy functions that simulate a single +// 'root' user on the system. + +uid_t getuid(); +gid_t getgid(); +uid_t geteuid(); + +struct passwd { + char *pw_name; /* user name */ + char *pw_passwd; /* user password */ + uid_t pw_uid; /* user ID */ + gid_t pw_gid; /* group ID */ + char *pw_gecos; /* real name */ + char *pw_dir; /* home directory */ + char *pw_shell; /* shell program */ +}; + +struct group { + char *gr_name; /* group name */ + char *gr_passwd; /* group password */ + gid_t gr_gid; /* group ID */ + char **gr_mem; /* group members */ +}; + +struct passwd *getpwuid(uid_t uid); +struct group *getgrgid(gid_t gid); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // Q_OS_VXWORKS +#endif // QFUNCTIONS_VXWORKS_H diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 8f364ba..309bfb8 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -667,12 +667,15 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) #endif } + // Qt 4.5 compatibility: stl doesn't affect binary compatibility + key.replace(" no-stl", ""); + +#ifndef QT_NO_SETTINGS QStringList queried; queried << QString::number(qt_version,16) << QString::number((int)debug) << QLatin1String(key) << lastModified; -#ifndef QT_NO_SETTINGS settings->setValue(regkey, queried); #endif } diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp index 6b9e1ad..cc70589 100644 --- a/src/corelib/plugin/qlibrary_unix.cpp +++ b/src/corelib/plugin/qlibrary_unix.cpp @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE -#if !defined(QT_HPUX_LD) +#if !defined(QT_HPUX_LD) && !defined(Q_OS_VXWORKS) QT_BEGIN_INCLUDE_NAMESPACE #include <dlfcn.h> QT_END_INCLUDE_NAMESPACE @@ -66,7 +66,9 @@ QT_END_INCLUDE_NAMESPACE static QString qdlerror() { -#if !defined(QT_HPUX_LD) +#if defined(Q_OS_VXWORKS) + const char *err = "VxWorks does not support dynamic libraries."; +#elif !defined(QT_HPUX_LD) const char *err = dlerror(); #else const char *err = strerror(errno); @@ -76,6 +78,8 @@ static QString qdlerror() bool QLibraryPrivate::load_sys() { + QString attempt; +#if !defined(Q_OS_VXWORKS) QFileInfo fi(fileName); QString path = fi.path(); QString name = fi.fileName(); @@ -163,7 +167,6 @@ bool QLibraryPrivate::load_sys() } #endif #endif // QT_HPUX_LD - QString attempt; bool retry = true; for(int prefix = 0; retry && !pHnd && prefix < prefixes.size(); prefix++) { for(int suffix = 0; retry && !pHnd && suffix < suffixes.size(); suffix++) { @@ -204,7 +207,8 @@ bool QLibraryPrivate::load_sys() attempt = str; } } -# endif +#endif +#endif // Q_OS_VXWORKS if (!pHnd) { errorString = QLibrary::tr("Cannot load library %1: %2").arg(fileName).arg(qdlerror()); } @@ -217,14 +221,16 @@ bool QLibraryPrivate::load_sys() bool QLibraryPrivate::unload_sys() { -#if defined(QT_HPUX_LD) +#if !defined(Q_OS_VXWORKS) +# if defined(QT_HPUX_LD) if (shl_unload((shl_t)pHnd)) { -#else +# else if (dlclose(pHnd)) { -#endif +# endif errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName).arg(qdlerror()); return false; } +#endif errorString.clear(); return true; } @@ -249,6 +255,8 @@ void* QLibraryPrivate::resolve_sys(const char* symbol) void* address = 0; if (shl_findsym((shl_t*)&pHnd, symbol, TYPE_UNDEFINED, &address) < 0) address = 0; +#elif defined(Q_OS_VXWORKS) + void *address = 0; #else void* address = dlsym(pHnd, symbol); #endif diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp index 43ba668..02c7c6f 100644 --- a/src/corelib/thread/qmutex_unix.cpp +++ b/src/corelib/thread/qmutex_unix.cpp @@ -49,6 +49,10 @@ #include <errno.h> +#if defined(Q_OS_VXWORKS) && defined(wakeup) +#undef wakeup +#endif + QT_BEGIN_NAMESPACE static void report_error(int code, const char *where, const char *what) diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 19b5104..efe37ad 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -61,6 +61,13 @@ #ifdef Q_OS_BSD4 #include <sys/sysctl.h> #endif +#ifdef Q_OS_VXWORKS +# if (_WRS_VXWORKS_MAJOR > 6) || ((_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR >= 6)) +# include <vxCpuLib.h> +# include <cpuset.h> +# define QT_VXWORKS_HAS_CPUSET +# endif +#endif #if defined(Q_OS_MAC) # ifdef qDebug @@ -85,6 +92,13 @@ static pthread_key_t current_thread_data_key; static void destroy_current_thread_data(void *p) { +#if defined(Q_OS_VXWORKS) + // Calling setspecific(..., 0) sets the value to 0 for ALL threads. + // The 'set to 1' workaround adds a bit of an overhead though, + // since this function is called twice now. + if (p == (void *)1) + return; +#endif // POSIX says the value in our key is set to zero before calling // this destructor function, so we need to set it back to the // right value... @@ -93,7 +107,12 @@ static void destroy_current_thread_data(void *p) // ... but we must reset it to zero before returning so we aren't // called again (POSIX allows implementations to call destructor // functions repeatedly until all values are zero) - pthread_setspecific(current_thread_data_key, 0); + pthread_setspecific(current_thread_data_key, +#if defined(Q_OS_VXWORKS) + (void *)1); +#else + 0); +#endif } static void create_current_thread_data_key() @@ -267,7 +286,25 @@ int QThread::idealThreadCount() // IRIX cores = (int)sysconf(_SC_NPROC_ONLN); #elif defined(Q_OS_INTEGRITY) - // ### TODO - how to get the amound of CPUs on INTEGRITY? + // as of aug 2008 Integrity only supports one single core CPU + cores = 1; +#elif defined(Q_OS_VXWORKS) + // VxWorks +# if defined(QT_VXWORKS_HAS_CPUSET) + cpuset_t cpus = vxCpuEnabledGet(); + cores = 0; + + // 128 cores should be enough for everyone ;) + for (int i = 0; i < 128 && !CPUSET_ISZERO(cpus); ++i) { + if (CPUSET_ISSET(cpus, i)) { + CPUSET_CLR(cpus, i); + cores++; + } + } +# else + // as of aug 2008 VxWorks < 6.6 only supports one single core CPU + cores = 1; +# endif #else // the rest: Linux, Solaris, AIX, Tru64 cores = (int)sysconf(_SC_NPROCESSORS_ONLN); diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 85e49c7..8608fe4 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -2640,6 +2640,8 @@ static QString timeZone() # else return QString::fromLocal8Bit(_tzname[1]); # endif +#elif defined(Q_OS_VXWORKS) + return QString(); #else tzset(); return QString::fromLocal8Bit(tzname[1]); @@ -4938,6 +4940,9 @@ static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c) #define Bletch 0x10 #define Bndry_mask 0xfffff #define Bndry_mask1 0xfffff +#if defined(LSB) && defined(Q_OS_VXWORKS) +#undef LSB +#endif #define LSB 1 #define Sign_bit 0x80000000 #define Log2P 1 diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index 804ce20..7817381 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -688,6 +688,10 @@ int qFindString(const QChar *haystack, int haystackLen, int from, {tools/regexp}{Regular Expression Example} */ +#if defined(Q_OS_VXWORKS) && defined(EOS) +# undef EOS +#endif + const int NumBadChars = 64; #define BadChar(ch) ((ch).unicode() % NumBadChars) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 51a6709..dcd87b7 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -252,11 +252,7 @@ public: typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; -#ifndef QT_NO_STL typedef ptrdiff_t difference_type; -#else - typedef int difference_type; -#endif typedef iterator Iterator; typedef const_iterator ConstIterator; typedef int size_type; diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 08c94ac..44fbb62 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -109,4 +109,4 @@ SOURCES += ../3rdparty/harfbuzz/src/harfbuzz-buffer.c \ tools/qharfbuzz.cpp HEADERS += tools/qharfbuzz_p.h -!macx-icc:unix:LIBS += -lm +!macx-icc:!vxworks:unix:LIBS += -lm diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h index f1614ea..7a4d2a8 100644 --- a/src/corelib/xml/qxmlstream_p.h +++ b/src/corelib/xml/qxmlstream_p.h @@ -54,6 +54,10 @@ #ifndef QXMLSTREAM_P_H #define QXMLSTREAM_P_H +#if defined(Q_OS_VXWORKS) && defined(ERROR) +# undef ERROR +#endif + class QXmlStreamReader_Table { public: diff --git a/src/gui/dialogs/qfileinfogatherer.cpp b/src/gui/dialogs/qfileinfogatherer.cpp index 887eb71..467822c 100644 --- a/src/gui/dialogs/qfileinfogatherer.cpp +++ b/src/gui/dialogs/qfileinfogatherer.cpp @@ -44,8 +44,11 @@ #include <qfsfileengine.h> #include <qdiriterator.h> #ifndef Q_OS_WIN -#include <unistd.h> -#include <sys/types.h> +# include <unistd.h> +# include <sys/types.h> +#endif +#if defined(Q_OS_VXWORKS) +# include "qplatformdefs.h" #endif QT_BEGIN_NAMESPACE diff --git a/src/gui/embedded/embedded.pri b/src/gui/embedded/embedded.pri index 53a2512..e8eb959 100644 --- a/src/gui/embedded/embedded.pri +++ b/src/gui/embedded/embedded.pri @@ -114,11 +114,18 @@ embedded { SOURCES += embedded/qscreenlinuxfb_qws.cpp } + contains( gfx-drivers, qnx ) { + HEADERS += embedded/qscreenqnx_qws.h + SOURCES += embedded/qscreenqnx_qws.cpp + LIBS += -lgf + } + contains( gfx-drivers, qvfb ) { HEADERS += embedded/qscreenvfb_qws.h SOURCES += embedded/qscreenvfb_qws.cpp } + contains( gfx-drivers, vnc ) { VNCDIR = $$QT_SOURCE_TREE/src/plugins/gfxdrivers/vnc INCLUDEPATH += $$VNCDIR @@ -158,6 +165,11 @@ embedded { SOURCES +=embedded/qkbdum_qws.cpp } + contains( kbd-drivers, qnx ) { + HEADERS += embedded/qkbdqnx_qws.h + SOURCES += embedded/qkbdqnx_qws.cpp + } + # # Mouse drivers # @@ -185,5 +197,10 @@ embedded { contains( mouse-drivers, linuxinput ) { HEADERS +=embedded/qmouselinuxinput_qws.h SOURCES +=embedded/qmouselinuxinput_qws.cpp - } + } + + contains( mouse-drivers, qnx ) { + HEADERS += embedded/qmouseqnx_qws.h + SOURCES += embedded/qmouseqnx_qws.cpp + } } diff --git a/src/gui/embedded/qkbddriverfactory_qws.cpp b/src/gui/embedded/qkbddriverfactory_qws.cpp index b77eb72..fb10030 100644 --- a/src/gui/embedded/qkbddriverfactory_qws.cpp +++ b/src/gui/embedded/qkbddriverfactory_qws.cpp @@ -48,6 +48,7 @@ #include "qkbdlinuxinput_qws.h" #include "qkbdum_qws.h" #include "qkbdvfb_qws.h" +#include "qkbdqnx_qws.h" #include <stdlib.h> #include "private/qfactoryloader_p.h" #include "qkbddriverplugin_qws.h" @@ -101,6 +102,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, QWSKeyboardHandler *QKbdDriverFactory::create(const QString& key, const QString& device) { QString driver = key.toLower(); +#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_KBD_QNX) + if (driver == QLatin1String("qnx") || driver.isEmpty()) + return new QWSQnxKeyboardHandler(device); +#endif #ifndef QT_NO_QWS_KEYBOARD # ifndef QT_NO_QWS_KBD_TTY if (driver == QLatin1String("tty") || driver.isEmpty()) @@ -143,6 +148,9 @@ QStringList QKbdDriverFactory::keys() { QStringList list; +#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_KBD_QNX) + list << QLatin1String("QNX"); +#endif #ifndef QT_NO_QWS_KBD_TTY list << QLatin1String("TTY"); #endif diff --git a/src/gui/embedded/qkbdqnx_qws.cpp b/src/gui/embedded/qkbdqnx_qws.cpp new file mode 100644 index 0000000..06163c7 --- /dev/null +++ b/src/gui/embedded/qkbdqnx_qws.cpp @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qkbdqnx_qws.h" +#include "QtCore/qsocketnotifier.h" +#include "QtCore/qdebug.h" + +#include <sys/dcmd_input.h> +#include <photon/keycodes.h> + +#include "qplatformdefs.h" +#include <errno.h> + +/*! + \class QWSQnxKeyboardHandler + \preliminary + \ingroup qws + \since 4.6 + \internal + + \brief The QWSQnxKeyboardHandler class implements a keyboard driver + for the QNX \c{devi-hid} input manager. + + To be able to compile this mouse handler, \l{Qt for Embedded Linux} + must be configured with the \c -qt-kbd-qnx option, see the + \l{Qt for Embedded Linux Character Input} documentation for details. + + In order to use this keyboard handler, the \c{devi-hid} input manager + must be set up and run with the resource manager interface (option \c{-r}). + Also, Photon must not be running. + + Example invocation from command line: \c{/usr/photon/bin/devi-hid -Pr kbd mouse} + Note that after running \c{devi-hid}, you will not be able to use the local + shell anymore. It is suggested to run the command in a shell scrip, that launches + a Qt application after invocation of \c{devi-hid}. + + To make \l{Qt for Embedded Linux} explicitly choose the qnx keyboard + handler, set the QWS_KEYBOARD environment variable to \c{qnx}. By default, + the first keyboard device (\c{/dev/devi/keyboard0}) is used. To override, pass a device + name as the first and only parameter, for example + \c{QWS_KEYBOARD=qnx:/dev/devi/keyboard1; export QWS_KEYBOARD}. + + \sa {Qt for Embedded Linux Character Input}, {Qt for Embedded Linux} +*/ + +/*! + Constructs a keyboard handler for the specified \a device, defaulting to + \c{/dev/devi/keyboard0}. + + Note that you should never instanciate this class, instead let QKbdDriverFactory + handle the keyboard handlers. + + \sa QKbdDriverFactory + */ +QWSQnxKeyboardHandler::QWSQnxKeyboardHandler(const QString &device) +{ + // open the keyboard device + keyboardFD = QT_OPEN(device.isEmpty() ? "/dev/devi/keyboard0" : device.toLatin1().constData(), + QT_OPEN_RDONLY); + if (keyboardFD == -1) { + qErrnoWarning(errno, "QWSQnxKeyboardHandler: Unable to open device"); + return; + } + + // create a socket notifier so we'll wake up whenever keyboard input is detected. + QSocketNotifier *notifier = new QSocketNotifier(keyboardFD, QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), SLOT(socketActivated())); + + qDebug() << "QWSQnxKeyboardHandler: connected."; + +} + +/*! + Destroys this keyboard handler and closes the connection to the keyboard device. + */ +QWSQnxKeyboardHandler::~QWSQnxKeyboardHandler() +{ + QT_CLOSE(keyboardFD); +} + +/*! \internal + Translates the QNX keyboard events to Qt keyboard events + */ +void QWSQnxKeyboardHandler::socketActivated() +{ + _keyboard_packet packet; + + // read one keyboard event + int bytesRead = QT_READ(keyboardFD, &packet, sizeof(_keyboard_packet)); + if (bytesRead == -1) { + qErrnoWarning(errno, "QWSQnxKeyboardHandler::socketActivated(): Unable to read data."); + return; + } + + // the bytes read must be the size of a keyboard packet + Q_ASSERT(bytesRead == sizeof(_keyboard_packet)); + +#if 0 + qDebug() << "keyboard got scancode" + << hex << packet.data.modifiers + << packet.data.flags + << packet.data.key_cap + << packet.data.key_sym + << packet.data.key_scan; +#endif + + // QNX is nice enough to translate the raw keyboard data into a QNX data structure + // Now we just have to translate it into a format Qt understands. + + // figure out whether it's a press + bool isPress = packet.data.key_cap & KEY_DOWN; + // figure out wheter the key is still pressed and the key event is repeated + bool isRepeat = packet.data.key_cap & KEY_REPEAT; + + Qt::Key key = Qt::Key_unknown; + int unicode = 0xffff; + + // TODO - this switch is not complete! + switch (packet.data.key_scan) { + case KEYCODE_SPACE: key = Qt::Key_Space; unicode = 0x20; break; + case KEYCODE_F1: key = Qt::Key_F1; break; + case KEYCODE_F2: key = Qt::Key_F2; break; + case KEYCODE_F3: key = Qt::Key_F3; break; + case KEYCODE_F4: key = Qt::Key_F4; break; + case KEYCODE_F5: key = Qt::Key_F5; break; + case KEYCODE_F6: key = Qt::Key_F6; break; + case KEYCODE_F7: key = Qt::Key_F7; break; + case KEYCODE_F8: key = Qt::Key_F8; break; + case KEYCODE_F9: key = Qt::Key_F9; break; + case KEYCODE_F10: key = Qt::Key_F10; break; + case KEYCODE_F11: key = Qt::Key_F11; break; + case KEYCODE_F12: key = Qt::Key_F12; break; + case KEYCODE_BACKSPACE: key = Qt::Key_Backspace; break; + case KEYCODE_TAB: key = Qt::Key_Tab; break; + case KEYCODE_RETURN: key = Qt::Key_Return; break; + case KEYCODE_KP_ENTER: key = Qt::Key_Enter; break; + case KEYCODE_UP: + case KEYCODE_KP_UP: + key = Qt::Key_Up; break; + case KEYCODE_DOWN: + case KEYCODE_KP_DOWN: + key = Qt::Key_Down; break; + case KEYCODE_LEFT: + case KEYCODE_KP_LEFT: + key = Qt::Key_Left; break; + case KEYCODE_RIGHT: + case KEYCODE_KP_RIGHT: + key = Qt::Key_Right; break; + case KEYCODE_HOME: + case KEYCODE_KP_HOME: + key = Qt::Key_Home; break; + case KEYCODE_END: + case KEYCODE_KP_END: + key = Qt::Key_End; break; + case KEYCODE_PG_UP: + case KEYCODE_KP_PG_UP: + key = Qt::Key_PageUp; break; + case KEYCODE_PG_DOWN: + case KEYCODE_KP_PG_DOWN: + key = Qt::Key_PageDown; break; + case KEYCODE_INSERT: + case KEYCODE_KP_INSERT: + key = Qt::Key_Insert; break; + case KEYCODE_DELETE: + case KEYCODE_KP_DELETE: + key = Qt::Key_Delete; break; + case KEYCODE_ESCAPE: + key = Qt::Key_Escape; break; + default: // none of the above, try the key_scan directly + unicode = packet.data.key_scan; + break; + } + + // figure out the modifiers that are currently pressed + Qt::KeyboardModifiers modifiers = Qt::NoModifier; + if (packet.data.flags & KEYMOD_SHIFT) + modifiers |= Qt::ShiftModifier; + if (packet.data.flags & KEYMOD_CTRL) + modifiers |= Qt::ControlModifier; + if (packet.data.flags & KEYMOD_ALT) + modifiers |= Qt::AltModifier; + + // if the unicode value is not ascii, we ignore it. + // TODO - do a complete mapping between all QNX scan codes and Qt codes + if (unicode != 0xffff && !isascii(unicode)) + return; // unprintable character + + // call processKeyEvent. This is where all the magic happens to insert a + // key event into Qt's event loop. + // Note that for repeated key events, isPress must be true + // (on QNX, isPress is not set when the key event is repeated). + processKeyEvent(unicode, key, modifiers, isPress || isRepeat, isRepeat); +} diff --git a/src/gui/embedded/qkbdqnx_qws.h b/src/gui/embedded/qkbdqnx_qws.h new file mode 100644 index 0000000..c046c8d --- /dev/null +++ b/src/gui/embedded/qkbdqnx_qws.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QKBDQNX_QWS_H +#define QKBDQNX_QWS_H + +#include <QtGui/qapplication.h> +#include <QtGui/qkbd_qws.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_QNX) + +class Q_GUI_EXPORT QWSQnxKeyboardHandler : public QObject, public QWSKeyboardHandler +{ + Q_OBJECT +public: + QWSQnxKeyboardHandler(const QString &device); + ~QWSQnxKeyboardHandler(); + +private Q_SLOTS: + void socketActivated(); + +private: + int keyboardFD; +}; + +#endif // QT_NO_QWS_KEYBOARD + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QKBDQNX_QWS_H diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp index 305832c..9592a4d 100644 --- a/src/gui/embedded/qlock.cpp +++ b/src/gui/embedded/qlock.cpp @@ -41,9 +41,46 @@ #include "qlock_p.h" -#ifndef QT_NO_QWS_MULTIPROCESS +QT_BEGIN_NAMESPACE + +#ifdef QT_NO_QWS_MULTIPROCESS + +/* no multiprocess - use a dummy */ + +QLock::QLock(const QString & /*filename*/, char /*id*/, bool /*create*/) + : type(Read), data(0) +{ +} + +QLock::~QLock() +{ +} + +bool QLock::isValid() const +{ + return true; +} + +void QLock::lock(Type t) +{ + data = (QLockData *)-1; + type = t; +} + +void QLock::unlock() +{ + data = 0; +} + +bool QLock::locked() const +{ + return data; +} + +#else // QT_NO_QWS_MULTIPROCESS #include "qwssignalhandler_p.h" + #include <unistd.h> #include <sys/types.h> #if defined(Q_OS_DARWIN) @@ -71,16 +108,10 @@ union semun { #include <qdebug.h> #include <signal.h> -#endif // QT_NO_QWS_MULTIPROCESS - #include <private/qcore_unix_p.h> // overrides QT_OPEN #define MAX_LOCKS 200 // maximum simultaneous read locks -QT_BEGIN_NAMESPACE - - -#ifndef QT_NO_QWS_MULTIPROCESS class QLockData { public: @@ -91,7 +122,6 @@ public: int count; bool owned; }; -#endif // QT_NO_QWS_MULTIPROCESS /*! \class QLock @@ -126,11 +156,6 @@ public: QLock::QLock(const QString &filename, char id, bool create) { -#ifdef QT_NO_QWS_MULTIPROCESS - Q_UNUSED(filename); - Q_UNUSED(id); - Q_UNUSED(create); -#else data = new QLockData; data->count = 0; #ifdef Q_NO_SEMAPHORE @@ -163,7 +188,6 @@ QLock::QLock(const QString &filename, char id, bool create) qPrintable(filename), id); qDebug() << "Error" << eno << strerror(eno); } -#endif } /*! @@ -174,7 +198,6 @@ QLock::QLock(const QString &filename, char id, bool create) QLock::~QLock() { -#ifndef QT_NO_QWS_MULTIPROCESS if (locked()) unlock(); #ifdef Q_NO_SEMAPHORE @@ -188,7 +211,6 @@ QLock::~QLock() QWSSignalHandler::instance()->removeSemaphore(data->id); #endif delete data; -#endif } /*! @@ -200,11 +222,7 @@ QLock::~QLock() bool QLock::isValid() const { -#ifndef QT_NO_QWS_MULTIPROCESS return (data->id != -1); -#else - return true; -#endif } /*! @@ -221,9 +239,6 @@ bool QLock::isValid() const void QLock::lock(Type t) { -#ifdef QT_NO_QWS_MULTIPROCESS - Q_UNUSED(t); -#else if (!data->count) { #ifdef Q_NO_SEMAPHORE int op = LOCK_SH; @@ -256,7 +271,6 @@ void QLock::lock(Type t) #endif } data->count++; -#endif } /*! @@ -269,7 +283,6 @@ void QLock::lock(Type t) void QLock::unlock() { -#ifndef QT_NO_QWS_MULTIPROCESS if(data->count) { data->count--; if(!data->count) { @@ -298,7 +311,6 @@ void QLock::unlock() } else { qDebug("Unlock without corresponding lock"); } -#endif } /*! @@ -310,11 +322,9 @@ void QLock::unlock() bool QLock::locked() const { -#ifndef QT_NO_QWS_MULTIPROCESS return (data->count > 0); -#else - return false; -#endif } +#endif // QT_NO_QWS_MULTIPROCESS + QT_END_NAMESPACE diff --git a/src/gui/embedded/qmousedriverfactory_qws.cpp b/src/gui/embedded/qmousedriverfactory_qws.cpp index 46898ae..6d71750 100644 --- a/src/gui/embedded/qmousedriverfactory_qws.cpp +++ b/src/gui/embedded/qmousedriverfactory_qws.cpp @@ -47,6 +47,7 @@ #include "qmouselinuxinput_qws.h" #include "qmousevfb_qws.h" #include "qmousetslib_qws.h" +#include "qmouseqnx_qws.h" #include <stdlib.h> #include "private/qfactoryloader_p.h" #include "qmousedriverplugin_qws.h" @@ -102,6 +103,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, QWSMouseHandler *QMouseDriverFactory::create(const QString& key, const QString &device) { QString driver = key.toLower(); +#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_MOUSE_QNX) + if (driver == QLatin1String("qnx") || driver.isEmpty()) + return new QQnxMouseHandler(key, device); +#endif #ifndef QT_NO_QWS_MOUSE_LINUXTP if (driver == QLatin1String("linuxtp") || driver.isEmpty()) return new QWSLinuxTPMouseHandler(key, device); @@ -149,6 +154,9 @@ QStringList QMouseDriverFactory::keys() { QStringList list; +#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_MOUSE_QNX) + list << QLatin1String("QNX"); +#endif #ifndef QT_NO_QWS_MOUSE_LINUXTP list << QLatin1String("LinuxTP"); #endif diff --git a/src/gui/embedded/qmousepc_qws.cpp b/src/gui/embedded/qmousepc_qws.cpp index 317bb8a..2d62772 100644 --- a/src/gui/embedded/qmousepc_qws.cpp +++ b/src/gui/embedded/qmousepc_qws.cpp @@ -332,7 +332,7 @@ protected: tty.c_oflag = 0; tty.c_lflag = 0; tty.c_cflag = f | CREAD | CLOCAL | HUPCL; -#if !defined(Q_OS_DARWIN) && !defined(Q_OS_SOLARIS) && !defined(Q_OS_INTEGRITY) +#ifdef Q_OS_LINUX tty.c_line = 0; #endif tty.c_cc[VTIME] = 0; diff --git a/src/gui/embedded/qmouseqnx_qws.cpp b/src/gui/embedded/qmouseqnx_qws.cpp new file mode 100644 index 0000000..98f8f06 --- /dev/null +++ b/src/gui/embedded/qmouseqnx_qws.cpp @@ -0,0 +1,190 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qplatformdefs.h" +#include "qmouseqnx_qws.h" + +#include "qsocketnotifier.h" +#include "qdebug.h" + +#include <sys/dcmd_input.h> + +#include <errno.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QQnxMouseHandler + \preliminary + \ingroup qws + \internal + \since 4.6 + + \brief The QQnxMouseHandler class implements a mouse driver + for the QNX \c{devi-hid} input manager. + + To be able to compile this mouse handler, \l{Qt for Embedded Linux} + must be configured with the \c -qt-mouse-qnx option, see the + \l{Qt for Embedded Linux Pointer Handling}{Pointer Handling} documentation for details. + + In order to use this mouse handler, the \c{devi-hid} input manager + must be set up and run with the resource manager interface (option \c{-r}). + Also, Photon must not be running. + + Example invocation from command line: \c{/usr/photon/bin/devi-hid -Pr kbd mouse} + Note that after running \c{devi-hid}, you will not be able to use the local + shell anymore. It is suggested to run the command in a shell scrip, that launches + a Qt application after invocation of \c{devi-hid}. + + To make \l{Qt for Embedded Linux} explicitly choose the qnx mouse + handler, set the QWS_MOUSE_PROTO environment variable to \c{qnx}. By default, + the first mouse device (\c{/dev/devi/mouse0}) is used. To override, pass a device + name as the first and only parameter, for example + \c{QWS_MOUSE_PROTO=qnx:/dev/devi/mouse1; export QWS_MOUSE_PROTO}. + + \sa {Qt for Embedded Linux Pointer Handling}{Pointer Handling}, {Qt for Embedded Linux} +*/ + +/*! + Constructs a mouse handler for the specified \a device, defaulting to \c{/dev/devi/mouse0}. + The \a driver parameter must be \c{"qnx"}. + + Note that you should never instanciate this class, instead let QMouseDriverFactory + handle the mouse handlers. + + \sa QMouseDriverFactory + */ +QQnxMouseHandler::QQnxMouseHandler(const QString & /*driver*/, const QString &device) +{ + // open the mouse device with O_NONBLOCK so reading won't block when there's no data + mouseFD = QT_OPEN(device.isEmpty() ? "/dev/devi/mouse0" : device.toLatin1().constData(), + QT_OPEN_RDONLY | O_NONBLOCK); + if (mouseFD == -1) { + qErrnoWarning(errno, "QQnxMouseHandler: Unable to open mouse device"); + return; + } + + // register a socket notifier on the file descriptor so we'll wake up whenever + // there's a mouse move waiting for us. + mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this); + connect(mouseNotifier, SIGNAL(activated(int)), SLOT(socketActivated())); + + qDebug() << "QQnxMouseHandler: connected."; +} + +/*! + Destroys this mouse handler and closes the connection to the mouse device. + */ +QQnxMouseHandler::~QQnxMouseHandler() +{ + QT_CLOSE(mouseFD); +} + +/*! \reimp */ +void QQnxMouseHandler::resume() +{ + if (mouseNotifier) + mouseNotifier->setEnabled(true); +} + +/*! \reimp */ +void QQnxMouseHandler::suspend() +{ + if (mouseNotifier) + mouseNotifier->setEnabled(false); +} + +/*! \internal + + This function is called whenever there is activity on the mouse device. + By default, it reads up to 10 mouse move packets and calls mouseChanged() + for each of them. +*/ +void QQnxMouseHandler::socketActivated() +{ + // _mouse_packet is a QNX structure. devi-hid is nice enough to translate + // the raw byte data from mouse devices into generic format for us. + _mouse_packet packet; + + int iteration = 0; + + // read mouse events in batches of 10. Since we're getting quite a lot + // of mouse events, it's better to do them in batches than to return to the + // event loop every time. + do { + int bytesRead = QT_READ(mouseFD, &packet, sizeof(packet)); + if (bytesRead == -1) { + // EAGAIN means that there are no more mouse events to read + if (errno != EAGAIN) + qErrnoWarning(errno, "QQnxMouseHandler: Unable to read from socket"); + return; + } + + // bytes read should always be equal to the size of a packet. + Q_ASSERT(bytesRead == sizeof(packet)); + + // translate the coordinates from the QNX data structure to Qt coordinates + // note the swapped y axis + QPoint pos = mousePos; + pos += QPoint(packet.dx, -packet.dy); + + // QNX only tells us relative mouse movements, not absolute ones, so limit the + // cursor position manually to the screen + limitToScreen(pos); + + // translate the QNX mouse button bitmask to Qt buttons + int buttons = Qt::NoButton; + + if (packet.hdr.buttons & _POINTER_BUTTON_LEFT) + buttons |= Qt::LeftButton; + if (packet.hdr.buttons & _POINTER_BUTTON_MIDDLE) + buttons |= Qt::MidButton; + if (packet.hdr.buttons & _POINTER_BUTTON_RIGHT) + buttons |= Qt::RightButton; + + // call mouseChanged() - this does all the magic to actually move the on-screen + // mouse cursor. + mouseChanged(pos, buttons, 0); + } while (++iteration < 11); +} + +QT_END_NAMESPACE + diff --git a/src/gui/embedded/qmouseqnx_qws.h b/src/gui/embedded/qmouseqnx_qws.h new file mode 100644 index 0000000..a61562e --- /dev/null +++ b/src/gui/embedded/qmouseqnx_qws.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMOUSE_QNX_H +#define QMOUSE_QNX_H + +#include <QtCore/qobject.h> +#include <QtGui/qmouse_qws.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QSocketNotifier; + +class Q_GUI_EXPORT QQnxMouseHandler : public QObject, public QWSMouseHandler +{ + Q_OBJECT +public: + explicit QQnxMouseHandler(const QString &driver = QString(), + const QString &device = QString()); + ~QQnxMouseHandler(); + + void resume(); + void suspend(); + +private Q_SLOTS: + void socketActivated(); + +private: + QSocketNotifier *mouseNotifier; + int mouseFD; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMOUSE_QWS_H diff --git a/src/gui/embedded/qscreendriverfactory_qws.cpp b/src/gui/embedded/qscreendriverfactory_qws.cpp index 2290627..b531798 100644 --- a/src/gui/embedded/qscreendriverfactory_qws.cpp +++ b/src/gui/embedded/qscreendriverfactory_qws.cpp @@ -47,6 +47,7 @@ #include "qscreentransformed_qws.h" #include "qscreenvfb_qws.h" #include "qscreenmulti_qws_p.h" +#include "qscreenqnx_qws.h" #include <stdlib.h> #include "private/qfactoryloader_p.h" #include "qscreendriverplugin_qws.h" @@ -105,6 +106,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, QScreen *QScreenDriverFactory::create(const QString& key, int displayId) { QString driver = key.toLower(); +#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_QNX) + if (driver == QLatin1String("qnx") || driver.isEmpty()) + return new QQnxScreen(displayId); +#endif #ifndef QT_NO_QWS_QVFB if (driver == QLatin1String("qvfb") || driver.isEmpty()) return new QVFbScreen(displayId); @@ -146,6 +151,9 @@ QStringList QScreenDriverFactory::keys() { QStringList list; +#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_QNX) + list << QLatin1String("QNX"); +#endif #ifndef QT_NO_QWS_QVFB list << QLatin1String("QVFb"); #endif diff --git a/src/gui/embedded/qscreenqnx_qws.cpp b/src/gui/embedded/qscreenqnx_qws.cpp new file mode 100644 index 0000000..7101bc7 --- /dev/null +++ b/src/gui/embedded/qscreenqnx_qws.cpp @@ -0,0 +1,447 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscreenqnx_qws.h" +#include "qdebug.h" + +#include <gf/gf.h> + +// This struct holds all the pointers to QNX's internals +struct QQnxScreenContext +{ + inline QQnxScreenContext() + : device(0), display(0), layer(0), hwSurface(0), memSurface(0), context(0) + {} + + gf_dev_t device; + gf_dev_info_t deviceInfo; + gf_display_t display; + gf_display_info_t displayInfo; + gf_layer_t layer; + gf_surface_t hwSurface; + gf_surface_t memSurface; + gf_surface_info_t memSurfaceInfo; + gf_context_t context; +}; + +/*! + \class QQnxScreen + \preliminary + \ingroup qws + \since 4.6 + \internal + + \brief The QQnxScreen class implements a screen driver + for QNX io-display based devices. + + Note - you never have to instanciate this class, the QScreenDriverFactory + does that for us based on the \c{QWS_DISPLAY} environment variable. + + To activate this driver, set \c{QWS_DISPLAY} to \c{qnx}. + + Example: + \c{QWS_DISPLAY=qnx; export QWS_DISPLAY} + + By default, the main layer of the first display of the first device is used. + If you have multiple graphic cards, multiple displays or multiple layers and + don't want to connect to the default, you can override that with setting + the corresponding options \c{device}, \c{display} or \c{layer} in the \c{QWS_DISPLAY} variable: + + \c{QWS_DISPLAY=qnx:device=3:display=4:layer=5} + + In addition, it is suggested to set the physical width and height of the display. + QQnxScreen will use that information to compute the dots per inch (DPI) in order to render + fonts correctly. If this informaiton is omitted, QQnxScreen defaults to 72 dpi. + + \c{QWS_DISPLAY=qnx:mmWidth=120:mmHeight=80} + + \c{mmWidth} and \c{mmHeight} are the physical width/height of the screen in millimeters. + + \sa QScreen, QScreenDriverPlugin, {Running Qt for Embedded Linux Applications}{Running Applications} +*/ + +/*! + Constructs a QQnxScreen object. The \a display_id argument + identifies the Qt for Embedded Linux server to connect to. +*/ +QQnxScreen::QQnxScreen(int display_id) + : QScreen(display_id), d(new QQnxScreenContext) +{ +} + +/*! + Destroys this QQnxScreen object. +*/ +QQnxScreen::~QQnxScreen() +{ + delete d; +} + +/*! \reimp +*/ +bool QQnxScreen::initDevice() +{ + // implement this if you have multiple processes that want to access the display + // (not required if QT_NO_QWS_MULTIPROCESS is set) + return true; +} + +/*! \internal + Attaches to the named device \a name. +*/ +static bool attachDevice(QQnxScreenContext * const d, const char *name) +{ + int ret = gf_dev_attach(&d->device, name, &d->deviceInfo); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_dev_attach(%s) failed with error code %d", name, ret); + return false; + } + return true; +} + +/*! \internal + Attaches to the display at index \a displayIndex. + */ +static bool attachDisplay(QQnxScreenContext * const d, int displayIndex) +{ + int ret = gf_display_attach(&d->display, d->device, displayIndex, &d->displayInfo); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_display_attach(%d) failed with error code %d", + displayIndex, ret); + return false; + } + return true; +} + +/*! \internal + Attaches to the layer \a layerIndex. + */ +static bool attachLayer(QQnxScreenContext * const d, int layerIndex) +{ + int ret = gf_layer_attach(&d->layer, d->display, layerIndex, 0); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_layer_attach(%d) failed with error code %d", layerIndex, + ret); + return false; + } + gf_layer_enable(d->layer); + + return true; +} + +/*! \internal + Creates a new hardware surface (usually on the Gfx card memory) with the dimensions \a w * \a h. + */ +static bool createHwSurface(QQnxScreenContext * const d, int w, int h) +{ + int ret = gf_surface_create_layer(&d->hwSurface, &d->layer, 1, 0, + w, h, GF_FORMAT_ARGB8888, 0, 0); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_surface_create_layer(%dx%d) failed with error code %d", + w, h, ret); + return false; + } + + gf_layer_set_surfaces(d->layer, &d->hwSurface, 1); + + ret = gf_layer_update(d->layer, 0); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_layer_update() failed with error code %d\n", ret); + return false; + } + + return true; +} + +/*! \internal + Creates an in-memory, linear accessible surface of dimensions \a w * \a h. + This is the main surface that QWS blits to. + */ +static bool createMemSurface(QQnxScreenContext * const d, int w, int h) +{ + // Note: gf_surface_attach() could also be used, so we'll create the buffer + // and let the surface point to it. Here, we use surface_create instead. + + int ret = gf_surface_create(&d->memSurface, d->device, w, h, + GF_FORMAT_ARGB8888, 0, + GF_SURFACE_CREATE_CPU_FAST_ACCESS | GF_SURFACE_CREATE_CPU_LINEAR_ACCESSIBLE + | GF_SURFACE_PHYS_CONTIG); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_surface_create(%dx%d) failed with error code %d", + w, h, ret); + return false; + } + + gf_surface_get_info(d->memSurface, &d->memSurfaceInfo); + + if (d->memSurfaceInfo.sid == unsigned(GF_SID_INVALID)) { + qWarning("QQnxScreen: gf_surface_get_info() failed."); + return false; + } + + return true; +} + +/* \internal + Creates a QNX gf context and sets our memory surface on it. + */ +static bool createContext(QQnxScreenContext * const d) +{ + int ret = gf_context_create(&d->context); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_context_create() failed with error code %d", ret); + return false; + } + + ret = gf_context_set_surface(d->context, d->memSurface); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_context_set_surface() failed with error code %d", ret); + return false; + } + + return true; +} + +/*! \reimp + Connects to QNX's io-display based device based on the \a displaySpec parameters + from the \c{QWS_DISPLAY} environment variable. See the QQnxScreen class documentation + for possible parameters. + + \sa QQnxScreen + */ +bool QQnxScreen::connect(const QString &displaySpec) +{ + const QStringList params = displaySpec.split(QLatin1Char(':'), QString::SkipEmptyParts); + + bool isOk = false; + QRegExp deviceRegExp(QLatin1String("^device=(.+)$")); + if (params.indexOf(deviceRegExp) != -1) { + isOk = attachDevice(d, deviceRegExp.cap(1).toLocal8Bit().constData()); + } else { + // no device specified - attach to device 0 (the default) + isOk = attachDevice(d, GF_DEVICE_INDEX(0)); + } + + if (!isOk) + return false; + + qDebug("QQnxScreen: Attached to Device, number of displays: %d", d->deviceInfo.ndisplays); + + // default to display 0 + int displayIndex = 0; + QRegExp displayRegexp(QLatin1String("^display=(\\d+)$")); + if (params.indexOf(displayRegexp) != -1) { + displayIndex = displayRegexp.cap(1).toInt(); + } + + if (!attachDisplay(d, displayIndex)) + return false; + + qDebug("QQnxScreen: Attached to Display %d, resolution %dx%d, refresh %d Hz", + displayIndex, d->displayInfo.xres, d->displayInfo.yres, + d->displayInfo.refresh); + + + // default to main_layer_index from the displayInfo struct + int layerIndex = 0; + QRegExp layerRegexp(QLatin1String("^layer=(\\d+)$")); + if (params.indexOf(layerRegexp) != -1) { + layerIndex = layerRegexp.cap(1).toInt(); + } else { + layerIndex = d->displayInfo.main_layer_index; + } + + if (!attachLayer(d, layerIndex)) + return false; + + // tell QWSDisplay the width and height of the display + w = dw = d->displayInfo.xres; + h = dh = d->displayInfo.yres; + + // we only support 32 bit displays for now. + QScreen::d = 32; + + // assume 72 dpi as default, to calculate the physical dimensions if not specified + const int defaultDpi = 72; + + // Handle display physical size spec. + QRegExp mmWidthRegexp(QLatin1String("^mmWidth=(\\d+)$")); + if (params.indexOf(mmWidthRegexp) == -1) { + physWidth = qRound(dw * 25.4 / defaultDpi); + } else { + physWidth = mmWidthRegexp.cap(1).toInt(); + } + + QRegExp mmHeightRegexp(QLatin1String("^mmHeight=(\\d+)$")); + if (params.indexOf(mmHeightRegexp) == -1) { + physHeight = qRound(dh * 25.4 / defaultDpi); + } else { + physHeight = mmHeightRegexp.cap(1).toInt(); + } + + // create a hardware surface with our dimensions. In the old days, it was possible + // to get a pointer directly to the hw surface, so we could blit directly. Now, we + // have to use one indirection more, because it's not guaranteed that the hw surface + // is mappable into our process. + if (!createHwSurface(d, w, h)) + return false; + + // create an in-memory linear surface that is used by QWS. QWS will blit directly in here. + if (!createMemSurface(d, w, h)) + return false; + + // set the address of the in-memory buffer that QWS is blitting to + data = d->memSurfaceInfo.vaddr; + // set the line stepping + lstep = d->memSurfaceInfo.stride; + + // the overall size of the in-memory buffer is linestep * height + size = mapsize = lstep * h; + + // create a QNX drawing context + if (!createContext(d)) + return false; + + // we're always using a software cursor for now. Initialize it here. + QScreenCursor::initSoftwareCursor(); + + // done, the driver should be connected to the display now. + return true; +} + +/*! \reimp + */ +void QQnxScreen::disconnect() +{ + if (d->context) + gf_context_free(d->context); + + if (d->memSurface) + gf_surface_free(d->memSurface); + + if (d->hwSurface) + gf_surface_free(d->hwSurface); + + if (d->layer) + gf_layer_detach(d->layer); + + if (d->display) + gf_display_detach(d->display); + + if (d->device) + gf_dev_detach(d->device); + + d->memSurface = 0; + d->hwSurface = 0; + d->context = 0; + d->layer = 0; + d->display = 0; + d->device = 0; +} + +/*! \reimp + */ +void QQnxScreen::shutdownDevice() +{ +} + + +/*! \reimp + QQnxScreen doesn't support setting the mode, use io-display instead. + */ +void QQnxScreen::setMode(int,int,int) +{ + qWarning("QQnxScreen: Unable to change mode, use io-display instead."); +} + +/*! \reimp + */ +bool QQnxScreen::supportsDepth(int depth) const +{ + // only 32-bit for the moment + return depth == 32; +} + +/*! \reimp + */ +void QQnxScreen::exposeRegion(QRegion r, int changing) +{ + // here is where the actual magic happens. QWS will call exposeRegion whenever + // a region on the screen is dirty and needs to be updated on the actual screen. + + // first, call the parent implementation. The parent implementation will update + // the region on our in-memory surface + QScreen::exposeRegion(r, changing); + + // now our in-memory surface should be up to date with the latest changes. + // the code below copies the region from the in-memory surface to the hardware. + + // just get the bounding rectangle of the region. Most screen updates are rectangular + // anyways. Code could be optimized to blit each and every member of the region + // individually, but in real life, the speed-up is neglectable + const QRect br = r.boundingRect(); + if (br.isEmpty()) + return; // ignore empty regions because gf_draw_blit2 doesn't like 0x0 dimensions + + // start drawing. + int ret = gf_draw_begin(d->context); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_draw_begin() failed with error code %d", ret); + return; + } + + // blit the changed region from the memory surface to the hardware surface + ret = gf_draw_blit2(d->context, d->memSurface, d->hwSurface, + br.x(), br.y(), br.right(), br.bottom(), br.x(), br.y()); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_draw_blit2() failed with error code %d", ret); + } + + // flush all drawing commands (in our case, a single blit) + ret = gf_draw_flush(d->context); + if (ret != GF_ERR_OK) { + qWarning("QQnxScreen: gf_draw_flush() failed with error code %d", ret); + } + + // tell QNX that we're done drawing. + gf_draw_end(d->context); +} + diff --git a/src/gui/embedded/qscreenqnx_qws.h b/src/gui/embedded/qscreenqnx_qws.h new file mode 100644 index 0000000..837c061 --- /dev/null +++ b/src/gui/embedded/qscreenqnx_qws.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCREENQNX_QWS_H +#define QSCREENQNX_QWS_H + +#include <QtGui/qscreen_qws.h> + +#ifndef QT_NO_QWS_QNX + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +struct QQnxScreenContext; + +class QQnxScreen : public QScreen +{ +public: + explicit QQnxScreen(int display_id); + ~QQnxScreen(); + + bool initDevice(); + bool connect(const QString &displaySpec); + void disconnect(); + void shutdownDevice(); + void setMode(int,int,int); + bool supportsDepth(int) const; + + void exposeRegion(QRegion r, int changing); + +private: + QQnxScreenContext * const d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QT_NO_QWS_QNX + +#endif diff --git a/src/gui/embedded/qwindowsystem_qws.cpp b/src/gui/embedded/qwindowsystem_qws.cpp index 0580198..624ba84 100644 --- a/src/gui/embedded/qwindowsystem_qws.cpp +++ b/src/gui/embedded/qwindowsystem_qws.cpp @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include "qplatformdefs.h" + #include "qwindowsystem_qws.h" #include "qwsevent_qws.h" #include "qwscommand_qws_p.h" @@ -71,24 +73,26 @@ #include <qdebug.h> -#include <unistd.h> +#include "qkbddriverfactory_qws.h" +#include "qmousedriverfactory_qws.h" + +#include <qbuffer.h> +#include <qdir.h> + +#include <private/qwindowsurface_qws_p.h> +#include <private/qfontengine_qpf_p.h> + +#include "qwindowsystem_p.h" + + #include <stdlib.h> #include <stdio.h> #include <errno.h> #ifndef QT_NO_QWS_MULTIPROCESS -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/ipc.h> -#include <sys/shm.h> -#ifndef Q_OS_DARWIN -# include <sys/sem.h> -#endif #include <sys/param.h> #include <sys/mount.h> #endif -#include <signal.h> -#include <fcntl.h> #if !defined(QT_NO_SOUND) && !defined(Q_OS_DARWIN) #ifdef QT_USE_OLD_QWS_SOUND @@ -101,17 +105,6 @@ #endif #endif -#include "qkbddriverfactory_qws.h" -#include "qmousedriverfactory_qws.h" - -#include <qbuffer.h> -#include <qdir.h> - -#include <private/qwindowsurface_qws_p.h> -#include <private/qfontengine_qpf_p.h> - -#include "qwindowsystem_p.h" - //#define QWS_DEBUG_FONTCLEANUP QT_BEGIN_NAMESPACE @@ -1400,7 +1393,7 @@ void QWSServerPrivate::initServer(int flags) #ifndef QT_NO_QWS_MULTIPROCESS if (!geteuid()) { -#if !defined(Q_OS_FREEBSD) && !defined(Q_OS_SOLARIS) && !defined(Q_OS_DARWIN) && !defined(QT_LINUXBASE) +#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE) if(mount(0,"/var/shm", "shm", 0, 0)) { /* This just confuses people with 2.2 kernels if (errno != EBUSY) diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 0c0747e..9d232e4 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -16,12 +16,13 @@ HEADERS += graphicsview/qgraphicsgridlayout.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicssceneindex_p.h \ graphicsview/qgraphicsscenelinearindex_p.h \ + graphicsview/qgraphicstransform.h \ + graphicsview/qgraphicstransform_p.h \ graphicsview/qgraphicsview.h \ graphicsview/qgraphicsview_p.h \ graphicsview/qgraphicswidget.h \ graphicsview/qgraphicswidget_p.h \ graphicsview/qgridlayoutengine_p.h - SOURCES += graphicsview/qgraphicsgridlayout.cpp \ graphicsview/qgraphicsitem.cpp \ graphicsview/qgraphicsitemanimation.cpp \ @@ -36,6 +37,7 @@ SOURCES += graphicsview/qgraphicsgridlayout.cpp \ graphicsview/qgraphicssceneevent.cpp \ graphicsview/qgraphicssceneindex.cpp \ graphicsview/qgraphicsscenelinearindex.cpp \ + graphicsview/qgraphicstransform.cpp \ graphicsview/qgraphicsview.cpp \ graphicsview/qgraphicswidget.cpp \ graphicsview/qgraphicswidget_p.cpp \ diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index c8e55e3..5aae93e 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -303,11 +303,12 @@ drop shadow effects and for decoration objects that follow the parent item's geometry without drawing on top of it. - \value ItemUsesExtendedStyleOption The item makes use of either - QStyleOptionGraphicsItem::exposedRect or QStyleOptionGraphicsItem::matrix. + \value ItemUsesExtendedStyleOption The item makes use of either the + exposedRect or matrix member of the QStyleOptionGraphicsItem. Implementers + of QGraphicsItem subclasses should set that flag if this data is required. By default, the exposedRect is initialized to the item's boundingRect and the matrix is untransformed. Enable this flag for more fine-grained values. - Use QStyleOptionGraphicsItem::levelOfDetailFromTransform for a more + Use QStyleOptionGraphicsItem::levelOfDetailFromTransform() for a more fine-grained value. \value ItemHasNoContents The item does not paint anything (i.e., calling @@ -1196,6 +1197,13 @@ QGraphicsItem::~QGraphicsItem() else d_ptr->setParentItemHelper(0); + if (d_ptr->transformData) { + for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) { + QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i); + static_cast<QGraphicsTransformPrivate *>(t->d_ptr)->item = 0; + delete t; + } + } delete d_ptr->transformData; delete d_ptr; @@ -2979,94 +2987,19 @@ QTransform QGraphicsItem::transform() const /*! \since 4.6 - Returns the rotation around the X axis. - - The default is 0 - - \warning The value doesn't take in account any rotation set with - the setTransform() method. - - \sa setXRotation(), {Transformations} -*/ -qreal QGraphicsItem::xRotation() const -{ - if (!d_ptr->transformData) - return 0; - return d_ptr->transformData->xRotation; -} - -/*! - \since 4.6 - - Sets the rotation around the X axis to \a angle degrees. - - \warning The value doesn't take in account any rotation set with the setTransform() method. - - \sa xRotation(), setTransformOrigin(), {Transformations} -*/ -void QGraphicsItem::setXRotation(qreal angle) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->xRotation = angle; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; -} - -/*! - \since 4.6 - - Returns the rotation around the Y axis. - - The default is 0 - - \warning The value doesn't take in account any rotation set with the setTransform() method. - - \sa setYRotation(), {Transformations} -*/ -qreal QGraphicsItem::yRotation() const -{ - if (!d_ptr->transformData) - return 0; - return d_ptr->transformData->yRotation; -} - -/*! - \since 4.6 - - Sets the rotation around the Y axis to \a angle degrees. - - \warning The value doesn't take in account any rotation set with the setTransform() method. - - \sa yRotation(), setTransformOrigin() {Transformations} -*/ -void QGraphicsItem::setYRotation(qreal angle) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->yRotation = angle; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; -} - -/*! - \since 4.6 - Returns the rotation around the Z axis. The default is 0 \warning The value doesn't take in account any rotation set with the setTransform() method. - \sa setZRotation(), {Transformations} + \sa setRotation(), {Transformations} */ -qreal QGraphicsItem::zRotation() const +qreal QGraphicsItem::rotation() const { if (!d_ptr->transformData) return 0; - return d_ptr->transformData->zRotation; + return d_ptr->transformData->rotation; } /*! @@ -3076,224 +3009,107 @@ qreal QGraphicsItem::zRotation() const \warning The value doesn't take in account any rotation set with the setTransform() method. - \sa zRotation(), setTransformOrigin(), {Transformations} + \sa rotation(), setTransformOriginPoint(), {Transformations} */ -void QGraphicsItem::setZRotation(qreal angle) +void QGraphicsItem::setRotation(qreal angle) { prepareGeometryChange(); if (!d_ptr->transformData) d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->zRotation = angle; + d_ptr->transformData->rotation = angle; d_ptr->transformData->onlyTransform = false; d_ptr->dirtySceneTransform = 1; -} - -/*! - \since 4.6 - - This convenience function set the rotation angles around the 3 axes - to \a x, \a y and \a z. - \sa setXRotation(), setYRotation(), setZRotation(), {Transformations} -*/ -void QGraphicsItem::setRotation(qreal x, qreal y, qreal z) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->xRotation = x; - d_ptr->transformData->yRotation = y; - d_ptr->transformData->zRotation = z; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; + if (d_ptr->isObject) + emit static_cast<QGraphicsObject *>(this)->rotationChanged(); } /*! \since 4.6 - Returns the scale factor on the X axis. + Returns the scale factor of the item. The default is 1 \warning The value doesn't take in account any scaling set with the setTransform() method. - \sa setXScale(), {Transformations} + \sa setScale(), {Transformations} */ -qreal QGraphicsItem::xScale() const +qreal QGraphicsItem::scale() const { if (!d_ptr->transformData) - return 1; - return d_ptr->transformData->xScale; + return 1.; + return d_ptr->transformData->scale; } /*! \since 4.6 - Sets the scale factor on the X axis to \a factor. + Sets the scale factor of the item to \a factor. \warning The value doesn't take in account any scaling set with the setTransform() method. - \sa xScale(), setTransformOrigin(), {Transformations} + \sa scale(), setTransformOriginPoint(), {Transformations} */ -void QGraphicsItem::setXScale(qreal factor) +void QGraphicsItem::setScale(qreal factor) { prepareGeometryChange(); if (!d_ptr->transformData) d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->xScale = factor; + d_ptr->transformData->scale = factor; d_ptr->transformData->onlyTransform = false; d_ptr->dirtySceneTransform = 1; -} - -/*! - \since 4.6 - - Returns the scale factor on the Y axis. - - The default is 1 - - \warning The value doesn't take in account any scaling set with the setTransform() method. - - \sa setYScale(), {Transformations} -*/ -qreal QGraphicsItem::yScale() const -{ - if (!d_ptr->transformData) - return 1; - return d_ptr->transformData->yScale; -} - -/*! - \since 4.6 - - Sets the scale factor on the Y axis to \a factor. - - \warning The value doesn't take in account any scaling set with the setTransform() method. - \sa yScale(), setTransformOrigin(), {Transformations} -*/ -void QGraphicsItem::setYScale(qreal factor) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->yScale = factor; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; + if (d_ptr->isObject) + emit static_cast<QGraphicsObject *>(this)->scaleChanged(); } -/*! - \since 4.6 - - This convenience function set the scaling factors on X and Y axis to \a sx and \a sy. - - \warning The value doesn't take in account any scaling set with the setTransform() method. - - \sa setXScale(), setYScale(), {Transformations} -*/ -void QGraphicsItem::setScale(qreal sx, qreal sy) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->xScale = sx; - d_ptr->transformData->yScale = sy; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; -} /*! \since 4.6 - Returns the horizontal shear. - - The default is 0 - - \warning The value doesn't take in account any shearing set with the setTransform() method. + returns list of graphics transformations on the item. - \sa setHorizontalShear(), {Transformations} + \sa scale(), setTransformOriginPoint(), {Transformations} */ -qreal QGraphicsItem::horizontalShear() const +QList<QGraphicsTransform *> QGraphicsItem::transformations() const { if (!d_ptr->transformData) - return 0; - return d_ptr->transformData->horizontalShear; + return QList<QGraphicsTransform *>(); + return d_ptr->transformData->graphicsTransforms; } /*! \since 4.6 - Sets the horizontal shear to \a shear. + Sets a list of graphics transformations on the item to \a transformations. - \warning The value doesn't take in account any shearing set with the setTransform() method. - - \sa horizontalShear(), {Transformations} + \sa scale(), setTransformOriginPoint(), {Transformations} */ -void QGraphicsItem::setHorizontalShear(qreal shear) +void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transformations) { prepareGeometryChange(); if (!d_ptr->transformData) d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->horizontalShear = shear; + d_ptr->transformData->graphicsTransforms = transformations; + for (int i = 0; i < transformations.size(); ++i) + transformations.at(i)->d_func()->setItem(this); d_ptr->transformData->onlyTransform = false; d_ptr->dirtySceneTransform = 1; } -/*! - \since 4.6 - - Returns the vertical shear. - - The default is 0 - - \warning The value doesn't take in account any shearing set with the setTransform() method. - \sa setHorizontalShear(), {Transformations} -*/ -qreal QGraphicsItem::verticalShear() const +void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t) { - if (!d_ptr->transformData) - return 0; - return d_ptr->transformData->verticalShear; -} - -/*! - \since 4.6 - - Sets the vertical shear to \a shear. - - \warning The value doesn't take in account any shearing set with the setTransform() method. - - \sa verticalShear(), {Transformations} -*/ -void QGraphicsItem::setVerticalShear(qreal shear) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->verticalShear = shear; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; -} - -/*! - \since 4.6 - - This convenience function sets the horizontal shear to \a sh and the vertical shear to \a sv. + if (!transformData) + transformData = new QGraphicsItemPrivate::TransformData; + if (!transformData->graphicsTransforms.contains(t)) + transformData->graphicsTransforms.append(t); - \warning The value doesn't take in account any shearing set with the setTransform() method. - - \sa setHorizontalShear(), setVerticalShear() -*/ -void QGraphicsItem::setShear(qreal sh, qreal sv) -{ - prepareGeometryChange(); - if (!d_ptr->transformData) - d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->horizontalShear = sh; - d_ptr->transformData->verticalShear = sv; - d_ptr->transformData->onlyTransform = false; - d_ptr->dirtySceneTransform = 1; + Q_Q(QGraphicsItem); + t->d_func()->setItem(q); + transformData->onlyTransform = false; + dirtySceneTransform = 1; } /*! @@ -3303,9 +3119,9 @@ void QGraphicsItem::setShear(qreal sh, qreal sv) The default is QPointF(0,0). - \sa setTransformOrigin(), {Transformations} + \sa setTransformOriginPoint(), {Transformations} */ -QPointF QGraphicsItem::transformOrigin() const +QPointF QGraphicsItem::transformOriginPoint() const { if (!d_ptr->transformData) return QPointF(0,0); @@ -3317,9 +3133,9 @@ QPointF QGraphicsItem::transformOrigin() const Sets the \a origin point for the transformation in item coordinates. - \sa transformOrigin(), {Transformations} + \sa transformOriginPoint(), {Transformations} */ -void QGraphicsItem::setTransformOrigin(const QPointF &origin) +void QGraphicsItem::setTransformOriginPoint(const QPointF &origin) { prepareGeometryChange(); if (!d_ptr->transformData) @@ -3331,15 +3147,15 @@ void QGraphicsItem::setTransformOrigin(const QPointF &origin) } /*! - \fn void QGraphicsItem::setTransformOrigin(qreal x, qreal y) + \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y) \since 4.6 \overload Sets the origin point for the transformation in item coordinates. - This is equivalent to calling setTransformOrigin(QPointF(\a x, \a y)). + This is equivalent to calling setTransformOriginPoint(QPointF(\a x, \a y)). - \sa setTransformOrigin(), {Transformations} + \sa setTransformOriginPoint(), {Transformations} */ @@ -3618,7 +3434,7 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine) \warning using this function doesnt affect the value of the transformation properties - \sa transform(), setRotation(), setScale(), setShear(), setTransformOrigin(), {The Graphics View Coordinate System}, {Transformations} + \sa transform(), setRotation(), setScale(), setTransformOriginPoint(), {The Graphics View Coordinate System}, {Transformations} */ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine) { @@ -3732,7 +3548,7 @@ void QGraphicsItem::shear(qreal sh, qreal sv) /*! \obsolete - Use setPos() or setTransformOrigin() instead. + Use setPos() or setTransformOriginPoint() instead. Translates the current item transformation by (\a dx, \a dy). @@ -6856,6 +6672,41 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent \sa pos() */ +/*! + \property QGraphicsObject::rotation + This property holds the rotation of the item in degrees. + + This specifies how many degrees to rotate the item around its transformOrigin. + The default rotation is 0 degrees (i.e. not rotated at all). +*/ + +/*! + \fn QGraphicsObject::rotationChanged() + + This signal gets emitted whenever the roation of the item changes. +*/ + +/*! + \property QGraphicsObject::scale + This property holds the scale of the item. + + A scale of less than 1 means the item will be displayed smaller than + normal, and a scale of greater than 1 means the item will be + displayed larger than normal. A negative scale means the item will + be mirrored. + + By default, items are displayed at a scale of 1 (i.e. at their + normal size). + + Scaling is from the item's transformOrigin. +*/ + +/*! + \fn void QGraphicsObject::scaleChanged() + + This signal is emitted when the scale of the item changes. +*/ + /*! \property QGraphicsObject::enabled @@ -6895,6 +6746,25 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent \sa visible */ +/*! + \fn const QObjectList &QGraphicsObject::children() const + \internal + + This function returns the same value as QObject::children(). It's + provided to differentiate between the obsolete member + QGraphicsItem::children() and QObject::children(). QGraphicsItem now + provides childItems() instead. +*/ + +/*! + \property QGraphicsObject::transformOriginPoint + \brief the transformation origin + + This property sets a specific point in the items coordiante system as the + origin for scale and rotation. + + \sa scale, rotation, QGraphicsItem::transformOriginPoint() +*/ /*! diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 0e21a47..b94fb97 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -71,6 +71,7 @@ class QGraphicsSceneHoverEvent; class QGraphicsSceneMouseEvent; class QGraphicsSceneWheelEvent; class QGraphicsScene; +class QGraphicsTransform; class QGraphicsWidget; class QInputMethodEvent; class QKeyEvent; @@ -268,34 +269,19 @@ public: void shear(qreal sh, qreal sv); // ### obsolete void translate(qreal dx, qreal dy); // ### obsolete - qreal xRotation() const; - void setXRotation(qreal angle); + void setRotation(qreal angle); + qreal rotation() const; - qreal yRotation() const; - void setYRotation(qreal angle); + void setScale(qreal scale); + qreal scale() const; - qreal zRotation() const; - void setZRotation(qreal angle); - void setRotation(qreal x, qreal y, qreal z); + QList<QGraphicsTransform *> transformations() const; + void setTransformations(const QList<QGraphicsTransform *> &transformations); - qreal xScale() const; - void setXScale(qreal factor); - - qreal yScale() const; - void setYScale(qreal factor); - void setScale(qreal sx, qreal sy); - - qreal horizontalShear() const; - void setHorizontalShear(qreal shear); - - qreal verticalShear() const; - void setVerticalShear(qreal shear); - void setShear(qreal sh, qreal sv); - - QPointF transformOrigin() const; - void setTransformOrigin(const QPointF &origin); - inline void setTransformOrigin(qreal x, qreal y) - { setTransformOrigin(QPointF(x,y)); } + QPointF transformOriginPoint() const; + void setTransformOriginPoint(const QPointF &origin); + inline void setTransformOriginPoint(qreal x, qreal y) + { setTransformOriginPoint(QPointF(x,y)); } virtual void advance(int phase); @@ -456,6 +442,7 @@ private: friend class QGraphicsSceneIndexPrivate; friend class QGraphicsSceneBspTreeIndex; friend class QGraphicsSceneBspTreeIndexPrivate; + friend class QGraphicsTransformPrivate; friend class ::tst_QGraphicsItem; friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *); @@ -521,9 +508,19 @@ class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) Q_PROPERTY(qreal z READ zValue WRITE setZValue NOTIFY zChanged) + Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) + Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) + Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint) public: QGraphicsObject(QGraphicsItem *parent = 0); + // ### Qt 5: Disambiguate +#ifdef Q_NO_USING_KEYWORD + const QObjectList &children() const { return QObject::children(); } +#else + using QObject::children; +#endif + Q_SIGNALS: void parentChanged(); void opacityChanged(); @@ -532,6 +529,8 @@ Q_SIGNALS: void xChanged(); void yChanged(); void zChanged(); + void rotationChanged(); + void scaleChanged(); protected: QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index c208b99..b8d98c1 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -57,6 +57,8 @@ #include "qset.h" #include "qpixmapcache.h" #include "qgraphicsview_p.h" +#include "qgraphicstransform.h" +#include "qgraphicstransform_p.h" #include <QtCore/qpoint.h> @@ -192,7 +194,7 @@ public: void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const; void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const; - void updateSceneTransformFromParent(); + virtual void updateSceneTransformFromParent(); // ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4. virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const; @@ -200,6 +202,7 @@ public: void setPosHelper(const QPointF &pos); void setTransformHelper(const QTransform &transform); + void appendGraphicsTransform(QGraphicsTransform *t); void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false, @@ -467,45 +470,35 @@ public: struct QGraphicsItemPrivate::TransformData { QTransform transform; - qreal xScale; - qreal yScale; - qreal xRotation; - qreal yRotation; - qreal zRotation; - qreal horizontalShear; - qreal verticalShear; + qreal scale; + qreal rotation; qreal xOrigin; qreal yOrigin; + QList<QGraphicsTransform *> graphicsTransforms; bool onlyTransform; TransformData() : - xScale(1.0), yScale(1.0), xRotation(0.0), yRotation(0.0), zRotation(0.0), - horizontalShear(0.0), verticalShear(0.0), xOrigin(0.0), yOrigin(0.0), + scale(1.0), rotation(0.0), + xOrigin(0.0), yOrigin(0.0), onlyTransform(true) {} QTransform computedFullTransform(QTransform *postmultiplyTransform = 0) const { if (onlyTransform) { - if (!postmultiplyTransform) - return transform; - if (postmultiplyTransform->isIdentity()) + if (!postmultiplyTransform || postmultiplyTransform->isIdentity()) return transform; if (transform.isIdentity()) return *postmultiplyTransform; - QTransform x(transform); - x *= *postmultiplyTransform; - return x; + return transform * *postmultiplyTransform; } QTransform x(transform); - if (xOrigin != 0 || yOrigin != 0) - x *= QTransform::fromTranslate(xOrigin, yOrigin); - x.rotate(xRotation, Qt::XAxis); - x.rotate(yRotation, Qt::YAxis); - x.rotate(zRotation, Qt::ZAxis); - x.shear(horizontalShear, verticalShear); - x.scale(xScale, yScale); + for (int i = 0; i < graphicsTransforms.size(); ++i) + graphicsTransforms.at(i)->applyTo(&x); + x.translate(xOrigin, yOrigin); + x.rotate(rotation, Qt::ZAxis); + x.scale(scale, scale); x.translate(-xOrigin, -yOrigin); if (postmultiplyTransform) x *= *postmultiplyTransform; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index f223cbe..a846cf6 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -2356,6 +2356,10 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Deliver post-change notification item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant); + // Auto-activate the first inactive window if the scene is active. + if (d->activationRefCount > 0 && !d->activeWindow && item->isWindow()) + setActiveWindow(static_cast<QGraphicsWidget *>(item)); + // Ensure that newly added items that have subfocus set, gain // focus automatically if there isn't a focus item already. if (!d->focusItem && item->focusItem()) @@ -3678,6 +3682,13 @@ void QGraphicsScene::keyReleaseEvent(QKeyEvent *keyEvent) void QGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { Q_D(QGraphicsScene); + if (d->mouseGrabberItems.isEmpty()) { + // Dispatch hover events + QGraphicsSceneHoverEvent hover; + _q_hoverFromMouseEvent(&hover, mouseEvent); + d->dispatchHoverEvent(&hover); + } + d->mousePressEventHandler(mouseEvent); } diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp new file mode 100644 index 0000000..b55d78e --- /dev/null +++ b/src/gui/graphicsview/qgraphicstransform.cpp @@ -0,0 +1,479 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgraphicstransform.h" +#include "qgraphicsitem_p.h" +#include "qgraphicstransform_p.h" +#include <QDebug> + +#include <math.h> +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +QT_BEGIN_NAMESPACE + + +void QGraphicsTransformPrivate::setItem(QGraphicsItem *i) +{ + if (item == i) + return; + + if (item) { + Q_Q(QGraphicsTransform); + QGraphicsItemPrivate *d_ptr = item->d_ptr; + + item->prepareGeometryChange(); + Q_ASSERT(d_ptr->transformData); + d_ptr->transformData->graphicsTransforms.removeAll(q); + d_ptr->dirtySceneTransform = 1; + item = 0; + } + + item = i; +} + +void QGraphicsTransformPrivate::updateItem(QGraphicsItem *item) +{ + item->prepareGeometryChange(); + item->d_ptr->dirtySceneTransform = 1; +} + +void QGraphicsTransform::update() +{ + Q_D(QGraphicsTransform); + if (d->item) + d->updateItem(d->item); +} + +/*! + returns this object as a QTransform. +*/ +QTransform QGraphicsTransform::transform() const +{ + QTransform t; + applyTo(&t); + return t; +} + +/*! + \class QGraphicsTransform + \brief The QGraphicsTransform class is an abstract base class for tranformations on QGraphicsItems. + \since 4.6 + + The classes that inherit QGraphicsTransform express different types of transformations + that can be applied to graphics items. + + A list of these transformations can be applied to any graphics item. These + transformations are then easily modifyable and usable from e.g. within animations. + + QGraphicsTransform is an abstract base class that is implemented by QGraphicsScale, + QGraphicsRotation and QGraphicsRotation3D. Subclasses have to implement the applyTo method. + + \sa QGraphicsItem::transform(), QGraphicsScale, QGraphicsRotation, QGraphicsRotation3D +*/ + +/*! + Constructs a new QGraphicsTransform with \a parent. +*/ +QGraphicsTransform::QGraphicsTransform(QObject *parent) : + QObject(*new QGraphicsTransformPrivate, parent) +{ +} + +/*! + Destructs the graphics transform. +*/ +QGraphicsTransform::~QGraphicsTransform() +{ + Q_D(QGraphicsTransform); + d->setItem(0); +} + +/*! + \internal +*/ +QGraphicsTransform::QGraphicsTransform(QGraphicsTransformPrivate &p, QObject *parent) + : QObject(p, parent) +{ +} + +/*! \fn void QGraphicsTransform::applyTo(QTransform *transform) const + + This pure virtual method has to be reimplemented in derived classes. + + It applies this transformation to \a transform. +*/ + + +/*! + \class QGraphicsScale + \brief The QGraphicsScale class provides a way to scale a graphics item in 2 dimensions. + \since 4.6 + + QGraphicsScale contains an \a origin around which the scaling happens, and two + scale factors, xScale and yScale, the x and one for the y axis. +*/ + +class QGraphicsScalePrivate : public QGraphicsTransformPrivate +{ +public: + QGraphicsScalePrivate() + : xScale(1), yScale(1) {} + QPointF origin; + qreal xScale; + qreal yScale; +}; + +/*! + Constructs a new graphics scale object with \a parent. +*/ +QGraphicsScale::QGraphicsScale(QObject *parent) + : QGraphicsTransform(*new QGraphicsScalePrivate, parent) +{ +} + +/*! + Destroys the object +*/ +QGraphicsScale::~QGraphicsScale() +{ +} + +/*! + \property QGraphicsScale::origin + The origin of the scale. All scaling will be done relative to this point. + + The \a origin is in other words the fixed point for the transformation. +*/ +QPointF QGraphicsScale::origin() const +{ + Q_D(const QGraphicsScale); + return d->origin; +} + +void QGraphicsScale::setOrigin(const QPointF &point) +{ + Q_D(QGraphicsScale); + d->origin = point; + update(); + emit originChanged(); +} + +/*! + \fn QGraphicsScale::originChanged() + + This signal is emitted whenever the origin of the object + changes. +*/ + +/*! + \property QGraphicsScale::xScale + + The scale factor in x direction. The x direction is + in the graphics items logical coordinates. + + \sa yScale +*/ +qreal QGraphicsScale::xScale() const +{ + Q_D(const QGraphicsScale); + return d->xScale; +} + +void QGraphicsScale::setXScale(qreal scale) +{ + Q_D(QGraphicsScale); + if (d->xScale == scale) + return; + d->xScale = scale; + update(); + emit scaleChanged(); +} + +/*! + \property QGraphicsScale::yScale + + The scale factor in y direction. The y direction is + in the graphics items logical coordinates. + + \sa xScale +*/ +qreal QGraphicsScale::yScale() const +{ + Q_D(const QGraphicsScale); + return d->yScale; +} + +void QGraphicsScale::setYScale(qreal scale) +{ + Q_D(QGraphicsScale); + if (d->yScale == scale) + return; + d->yScale = scale; + update(); + emit scaleChanged(); +} + +/*! + \fn QGraphicsScale::scaleChanged() + + This signal is emitted whenever the xScale or yScale of the object + changes. +*/ + +/*! + \reimp +*/ +void QGraphicsScale::applyTo(QTransform *transform) const +{ + Q_D(const QGraphicsScale); + transform->translate(d->origin.x(), d->origin.y()); + transform->scale(d->xScale, d->yScale); + transform->translate(-d->origin.x(), -d->origin.y()); +} + +/*! + \class QGraphicsRotation + \brief The QGraphicsRotation class provides a way to rotate a graphics item in 2 dimensions. + \since 4.6 + + QGraphicsRotation contains an \a origin around which the rotation happens, and one + angle in degrees describing the amount of the rotation. +*/ + +class QGraphicsRotationPrivate : public QGraphicsTransformPrivate +{ +public: + QGraphicsRotationPrivate() + : angle(0) {} + QPointF origin; + qreal originY; + qreal angle; +}; + +/*! + Constructs a new graphics rotation with \a parent. +*/ +QGraphicsRotation::QGraphicsRotation(QObject *parent) + : QGraphicsTransform(*new QGraphicsRotationPrivate, parent) +{ +} + +/*! + \internal +*/ +QGraphicsRotation::QGraphicsRotation(QGraphicsRotationPrivate &p, QObject *parent) + : QGraphicsTransform(p, parent) +{ +} + +/*! + Destructs the object +*/ +QGraphicsRotation::~QGraphicsRotation() +{ +} + +/*! + \property QGraphicsRotation::origin + The origin around which this object will rotate the graphics item. + + The \a origin is in other words the fixed point for the transformation. +*/ +QPointF QGraphicsRotation::origin() const +{ + Q_D(const QGraphicsRotation); + return d->origin; +} + +void QGraphicsRotation::setOrigin(const QPointF &point) +{ + Q_D(QGraphicsRotation); + d->origin = point; + update(); + emit originChanged(); +} + +/*! + \fn QGraphicsRotation::originChanged() + + This signal is emitted whenever the origin of the object + changes. +*/ + +/*! + \property QGraphicsRotation::angle + The angle, in degrees, of the rotation. +*/ +qreal QGraphicsRotation::angle() const +{ + Q_D(const QGraphicsRotation); + return d->angle; +} + +void QGraphicsRotation::setAngle(qreal angle) +{ + Q_D(QGraphicsRotation); + if (d->angle == angle) + return; + d->angle = angle; + update(); + emit angleChanged(); +} + +/*! + \fn void QGraphicsRotation::angleChanged() + + This signal is emitted whenever the angle of the object + changes. +*/ + +/*! + \reimp +*/ +void QGraphicsRotation::applyTo(QTransform *t) const +{ + Q_D(const QGraphicsRotation); + if(d->angle) { + t->translate(d->origin.x(), d->origin.y()); + t->rotate(d->angle); + t->translate(-d->origin.x(), -d->origin.y()); + } +} + + +/*! + \class QGraphicsRotation3D + \brief The QGraphicsRotation3D class provides a way to rotate a graphics item in 3 dimensions. + \since 4.6 + + In addition to the origin and angle of a simple QGraphicsRotation, QGraphicsRotation3D contains + also an axis that describes around which axis in space the rotation is supposed to happen. +*/ + +class QGraphicsRotation3DPrivate : public QGraphicsRotationPrivate +{ +public: + QGraphicsRotation3DPrivate() {} + + QVector3D axis; +}; + +/*! + Constructs a new 3D rotation with \a parent. +*/ +QGraphicsRotation3D::QGraphicsRotation3D(QObject *parent) + : QGraphicsRotation(*new QGraphicsRotation3DPrivate, parent) +{ +} + +/*! + Destroys the object +*/ +QGraphicsRotation3D::~QGraphicsRotation3D() +{ +} + +/*! + \property QGraphicsRotation3D::axis + + A rotation axis is specified by a vector in 3D space. +*/ +QVector3D QGraphicsRotation3D::axis() +{ + Q_D(QGraphicsRotation3D); + return d->axis; +} + +void QGraphicsRotation3D::setAxis(const QVector3D &axis) +{ + Q_D(QGraphicsRotation3D); + d->axis = axis; + update(); +} + +/*! + \fn void QGraphicsRotation3D::axisChanged() + + This signal is emitted whenever the axis of the object + changes. +*/ + +const qreal inv_dist_to_plane = 1. / 1024.; + +/*! + \reimp +*/ +void QGraphicsRotation3D::applyTo(QTransform *t) const +{ + Q_D(const QGraphicsRotation3D); + + if (d->angle == 0. || + (d->axis.z() == 0. && d->axis.y() == 0 && d->axis.x() == 0)) + return; + + qreal rad = d->angle * 2. * M_PI / 360.; + qreal c = ::cos(rad); + qreal s = ::sin(rad); + + qreal x = d->axis.x(); + qreal y = d->axis.y(); + qreal z = d->axis.z(); + + qreal len = x * x + y * y + z * z; + if (len != 1.) { + len = 1./::sqrt(len); + x *= len; + y *= len; + z *= len; + } + + t->translate(d->origin.x(), d->origin.y()); + *t = QTransform(x*x*(1-c)+c, x*y*(1-c)-z*s, x*z*(1-c)+y*s*inv_dist_to_plane, + y*x*(1-c)+z*s, y*y*(1-c)+c, y*z*(1-c)-x*s*inv_dist_to_plane, + 0, 0, 1) * *t; + t->translate(-d->origin.x(), -d->origin.y()); +} + +#include "moc_qgraphicstransform.cpp" + +QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicstransform.h b/src/gui/graphicsview/qgraphicstransform.h new file mode 100644 index 0000000..b5d8d84 --- /dev/null +++ b/src/gui/graphicsview/qgraphicstransform.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSTRANSFORM_H +#define QGRAPHICSTRANSFORM_H + +#include <QtCore/QObject> +#include <QtGui/QTransform> +#include <QtGui/QVector3D> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QGraphicsItem; +class QGraphicsTransformPrivate; + +class Q_GUI_EXPORT QGraphicsTransform : public QObject +{ + Q_OBJECT +public: + QGraphicsTransform(QObject *parent = 0); + ~QGraphicsTransform(); + + QTransform transform() const; + virtual void applyTo(QTransform *transform) const = 0; + +protected Q_SLOTS: + void update(); + +protected: + QGraphicsTransform(QGraphicsTransformPrivate &p, QObject *parent); +private: + friend class QGraphicsItem; + friend class QGraphicsItemPrivate; + Q_DECLARE_PRIVATE(QGraphicsTransform) +}; + +class QGraphicsScalePrivate; + +class Q_GUI_EXPORT QGraphicsScale : public QGraphicsTransform +{ + Q_OBJECT + + Q_PROPERTY(QPointF origin READ origin WRITE setOrigin NOTIFY originChanged) + Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY scaleChanged) + Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY scaleChanged) +public: + QGraphicsScale(QObject *parent = 0); + ~QGraphicsScale(); + + QPointF origin() const; + void setOrigin(const QPointF &point); + + qreal xScale() const; + void setXScale(qreal); + + qreal yScale() const; + void setYScale(qreal); + + void applyTo(QTransform *transform) const; + +Q_SIGNALS: + void originChanged(); + void scaleChanged(); + +private: + Q_DECLARE_PRIVATE(QGraphicsScale) +}; + +class QGraphicsRotationPrivate; + +class Q_GUI_EXPORT QGraphicsRotation : public QGraphicsTransform +{ + Q_OBJECT + + Q_PROPERTY(QPointF origin READ origin WRITE setOrigin NOTIFY originChanged) + Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) +public: + QGraphicsRotation(QObject *parent = 0); + ~QGraphicsRotation(); + + QPointF origin() const; + void setOrigin(const QPointF &point); + + qreal angle() const; + void setAngle(qreal); + + void applyTo(QTransform *transform) const; + +Q_SIGNALS: + void originChanged(); + void angleChanged(); + +protected: + QGraphicsRotation(QGraphicsRotationPrivate &p, QObject *parent); +private: + Q_DECLARE_PRIVATE(QGraphicsRotation) +}; + +class QGraphicsRotation3DPrivate; + +class Q_GUI_EXPORT QGraphicsRotation3D : public QGraphicsRotation +{ + Q_OBJECT + + Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged) +public: + QGraphicsRotation3D(QObject *parent = 0); + ~QGraphicsRotation3D(); + + QVector3D axis(); + void setAxis(const QVector3D &axis); + + void applyTo(QTransform *transform) const; + +Q_SIGNALS: + void axisChanged(); + +private: + Q_DECLARE_PRIVATE(QGraphicsRotation3D) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QFXTRANSFORM_H diff --git a/src/gui/graphicsview/qgraphicstransform_p.h b/src/gui/graphicsview/qgraphicstransform_p.h new file mode 100644 index 0000000..2d36eda --- /dev/null +++ b/src/gui/graphicsview/qgraphicstransform_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSTRANSFORM_P_H +#define QGRAPHICSTRANSFORM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include "private/qobject_p.h" + +class QGraphicsItem; + +class QGraphicsTransformPrivate : public QObjectPrivate { +public: + Q_DECLARE_PUBLIC(QGraphicsTransform) + + QGraphicsTransformPrivate() + : QObjectPrivate(), item(0) {} + + QGraphicsItem *item; + + void setItem(QGraphicsItem *item); + static void updateItem(QGraphicsItem *item); +}; + +#endif // QGRAPHICSTRANSFORM_P_H diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 6937584..3ea80ce 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -1728,39 +1728,6 @@ QGraphicsWidget *QGraphicsWidget::focusWidget() const return 0; } -/*! \property QGraphicsWidget::horizontalShear - \brief This property holds the horizontal shear value for the item. - */ - -/*! \property QGraphicsWidget::transformOrigin - \brief This property holds the origin point used for transformations - in item coordinates. - */ - -/*! \property QGraphicsWidget::verticalShear - \brief This property holds the vertical shear value for the item. - */ - -/*! \property QGraphicsWidget::xRotation - \brief This property holds the value for rotation around the x axis. - */ - -/*! \property QGraphicsWidget::xScale - \brief This property holds the scale factor for the x axis. - */ - -/*! \property QGraphicsWidget::yRotation - \brief This property holds the value for rotation around the y axis. - */ - -/*! \property QGraphicsWidget::yScale - \brief This property holds the scale factor for the y axis. - */ - -/*! \property QGraphicsWidget::zRotation - \brief This property holds the value for rotation around the z axis. - */ - #ifndef QT_NO_SHORTCUT /*! \since 4.5 @@ -2286,6 +2253,7 @@ bool QGraphicsWidget::close() #ifdef Q_NO_USING_KEYWORD /*! \fn const QObjectList &QGraphicsWidget::children() const + \internal This function returns the same value as QObject::children(). It's provided to differentiate between the obsolete member diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index b72ec9f..d03a637 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -77,14 +77,6 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags) Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) - Q_PROPERTY(QPointF transformOrigin READ transformOrigin WRITE setTransformOrigin) - Q_PROPERTY(qreal xRotation READ xRotation WRITE setXRotation) - Q_PROPERTY(qreal yRotation READ yRotation WRITE setYRotation) - Q_PROPERTY(qreal zRotation READ zRotation WRITE setZRotation) - Q_PROPERTY(qreal xScale READ xScale WRITE setXScale) - Q_PROPERTY(qreal yScale READ yScale WRITE setYScale) - Q_PROPERTY(qreal horizontalShear READ horizontalShear WRITE setHorizontalShear) - Q_PROPERTY(qreal verticalShear READ verticalShear WRITE setVerticalShear) public: QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); ~QGraphicsWidget(); diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index dd56765..e8ca7a9 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4628,12 +4628,19 @@ bool QImage::loadFromData(const uchar *data, int len, const char *format) binary \a data. The loader attempts to read the image using the specified \a format. If \a format is not specified (which is the default), the loader probes the file for a header to guess the file format. + binary \a data. The loader attempts to read the image, either using the + optional image \a format specified or by determining the image format from + the data. - If the loading of the image failed, this object is a null image. + If \a format is not specified (which is the default), the loader probes the + file for a header to determine the file format. If \a format is specified, + it must be one of the values returned by QImageReader::supportedImageFormats(). + + If the loading of the image fails, the image returned will be a null image. + + \sa load(), save(), {QImage#Reading and Writing Image Files}{Reading and Writing Image Files} + */ - \sa load(), save(), {QImage#Reading and Writing Image - Files}{Reading and Writing Image Files} -*/ QImage QImage::fromData(const uchar *data, int size, const char *format) { QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(data), size); diff --git a/src/gui/inputmethod/qinputcontextplugin.h b/src/gui/inputmethod/qinputcontextplugin.h index 8ab8f84..c0c127b 100644 --- a/src/gui/inputmethod/qinputcontextplugin.h +++ b/src/gui/inputmethod/qinputcontextplugin.h @@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -#if !defined(QT_NO_IM) && !defined(QT_NO_LIBRARY) +#if !defined(QT_NO_IM) class QInputContext; class QInputContextPluginPrivate; diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp index 9b21163..074b189 100644 --- a/src/gui/inputmethod/qximinputcontext_x11.cpp +++ b/src/gui/inputmethod/qximinputcontext_x11.cpp @@ -53,6 +53,7 @@ ** ****************************************************************************/ +#include "qplatformdefs.h" #include "qdebug.h" #include "qximinputcontext_p.h" diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 3453408..5181689 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qplatformdefs.h" #include "qabstracteventdispatcher.h" #include "qaccessible.h" #include "qapplication.h" diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp index 347afc8..00695fa 100644 --- a/src/gui/kernel/qapplication_qws.cpp +++ b/src/gui/kernel/qapplication_qws.cpp @@ -101,7 +101,11 @@ #include <locale.h> #include <errno.h> #include <fcntl.h> -#include <sys/time.h> +#ifdef Q_OS_VXWORKS +# include <sys/times.h> +#else +# include <sys/time.h> +#endif #include <sys/stat.h> #include <sys/types.h> @@ -194,7 +198,14 @@ QString qws_dataDir() static QString result; if (!result.isEmpty()) return result; - QByteArray dataDir = QString::fromLatin1("/tmp/qtembedded-%1").arg(qws_display_id).toLocal8Bit(); + QByteArray dataDir; +#ifdef QT_QWS_TEMP_DIR + dataDir = QT_QWS_TEMP_DIR; +#else + dataDir = "/tmp"; +#endif + dataDir += "/qtembedded-"; + dataDir += QByteArray::number(qws_display_id); if (QT_MKDIR(dataDir, 0700)) { if (errno != EEXIST) { qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData()); @@ -208,7 +219,7 @@ QString qws_dataDir() if (!S_ISDIR(buf.st_mode)) qFatal("%s is not a directory", dataDir.constData()); -#ifndef Q_OS_INTEGRITY +#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS) if (buf.st_uid != getuid()) qFatal("Qt for Embedded Linux data directory is not owned by user %d", getuid()); diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 1c4177e..3104083 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -1211,7 +1211,10 @@ void qt_mac_menu_collapseSeparators(void */*NSMenu **/ theMenu, bool collapse) if (collapse) { bool previousIsSeparator = true; // setting to true kills all the separators placed at the top. NSMenuItem *previousItem = nil; - for (NSMenuItem *item in [menu itemArray]) { + + NSArray *itemArray = [menu itemArray]; + for (unsigned int i = 0; i < [itemArray count]; ++i) { + NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]); if ([item isSeparatorItem]) { [item setHidden:previousIsSeparator]; } @@ -1226,7 +1229,9 @@ void qt_mac_menu_collapseSeparators(void */*NSMenu **/ theMenu, bool collapse) if (previousItem && previousIsSeparator) [previousItem setHidden:YES]; } else { - for (NSMenuItem *item in [menu itemArray]) { + NSArray *itemArray = [menu itemArray]; + for (unsigned int i = 0; i < [itemArray count]; ++i) { + NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]); if (QAction *action = reinterpret_cast<QAction *>([item tag])) [item setHidden:!action->isVisible()]; } diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index 1c8394b..1ac51e0 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -74,11 +74,19 @@ #include <X11/Xutil.h> #include <X11/Xos.h> #ifdef index -# undef index +# undef index #endif #ifdef rindex -# undef 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 diff --git a/src/gui/kernel/qx11embed_x11.cpp b/src/gui/kernel/qx11embed_x11.cpp index 659331f..359434e 100644 --- a/src/gui/kernel/qx11embed_x11.cpp +++ b/src/gui/kernel/qx11embed_x11.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qplatformdefs.h" #include "qx11embed_x11.h" #include <qapplication.h> #include <qevent.h> diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 34bc578..01c6159 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -39,6 +39,9 @@ ** ****************************************************************************/ + +#include "qplatformdefs.h" + #include "qbackingstore_p.h" #include <QtCore/qglobal.h> diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h index 6dbb94b..13b5eba 100644 --- a/src/gui/painting/qbrush.h +++ b/src/gui/painting/qbrush.h @@ -51,6 +51,15 @@ #include <QtGui/qimage.h> #include <QtGui/qpixmap.h> +#if defined(Q_OS_VXWORKS) +# if defined(m_data) +# undef m_data +# endif +# if defined(m_type) +# undef m_type +# endif +#endif + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h index 275ec13..b568f43 100644 --- a/src/gui/painting/qdatabuffer_p.h +++ b/src/gui/painting/qdatabuffer_p.h @@ -114,6 +114,23 @@ public: qSwap(buffer, other.buffer); } + inline void insertBlank(int pos, int count) { + Q_ASSERT(pos >= 0); + Q_ASSERT(pos < siz); + reserve(siz + count); + for (int i = siz - pos - 1; i >= 0; --i) + buffer[pos + count + i] = buffer[pos + i]; + siz += count; + } + + inline void removeAndShift(int pos, int count) { + Q_ASSERT(pos >= 0); + Q_ASSERT(pos < siz); + for (int i=pos; i<siz-count; ++i) + buffer[i] = buffer[i+count]; + siz -= count; + } + inline QDataBuffer &operator<<(const Type &t) { add(t); return *this; } private: diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index 7a9eda3..c41b040 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -134,7 +134,9 @@ #define ErrRaster_MemoryOverflow -4 - +#if defined(VXWORKS) +# include <vxWorksCommon.h> /* needed for setjmp.h */ +#endif #include <string.h> /* for qt_ft_memcpy() */ #include <setjmp.h> #include <limits.h> diff --git a/src/gui/painting/qoutlinemapper.cpp b/src/gui/painting/qoutlinemapper.cpp index 401fad9..9c073f2 100644 --- a/src/gui/painting/qoutlinemapper.cpp +++ b/src/gui/painting/qoutlinemapper.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qoutlinemapper_p.h" +#include "qbezier_p.h" #include "qmath.h" @@ -199,51 +200,69 @@ void QOutlineMapper::endOutline() } } else { // ## TODO: this case needs to be plain code polygonal paths - QPainterPath path; + QTransform matrix(m_m11, m_m12, m_m13, m_m21, m_m22, m_m23, m_dx, m_dy, m_m33); + if (m_element_types.isEmpty()) { if (!m_elements.isEmpty()) - path.moveTo(m_elements.at(0)); + m_elements_dev << m_elements.at(0) * matrix; for (int i=1; i<m_elements.size(); ++i) - path.lineTo(m_elements.at(i)); + m_elements_dev << m_elements.at(i) * matrix; + } else { - for (int i=0; i<m_elements.size(); ++i) { - switch (m_element_types.at(i)) { + for (int i=0, t=0; i<m_elements.size(); ++i) { + switch (m_element_types.at(t)) { case QPainterPath::MoveToElement: - path.moveTo(m_elements.at(i)); + m_elements_dev << m_elements.at(i) * matrix; + ++t; break; case QPainterPath::LineToElement: - path.lineTo(m_elements.at(i)); + m_elements_dev << m_elements.at(i) * matrix; + ++t; break; - case QPainterPath::CurveToElement: - path.cubicTo(m_elements.at(i), m_elements.at(i+1), m_elements.at(i+2)); + case QPainterPath::CurveToElement: { + QPolygonF segment = QBezier::fromPoints(m_elements.at(i-1), + m_elements.at(i), + m_elements.at(i+1), + m_elements.at(i+2)).toPolygon(); + if (segment.size() > 3) + m_element_types.insertBlank(t, segment.size() - 3); + else if (segment.size() < 3) + m_element_types.removeAndShift(t, 3 - segment.size()); + + for (QPolygonF::const_iterator it = segment.constBegin(); + it < segment.constEnd(); ++it, ++t) { + m_elements_dev << *it * matrix; + m_element_types.at(t) = QPainterPath::LineToElement; + } i += 2; - break; + } break; default: Q_ASSERT(false); break; } } + element_count = m_elements_dev.size(); } - path = QTransform(m_m11, m_m12, m_m13, m_m21, m_m22, m_m23, m_dx, m_dy, m_m33).map(path); - uint old_txop = m_txop; - m_txop = QTransform::TxNone; - if (path.isEmpty()) - m_valid = false; - else - convertPath(path); - m_txop = old_txop; - return; } elements = m_elements_dev.data(); } if (m_round_coords) { // round coordinates to match outlines drawn with drawLine_midpoint_i - for (int i = 0; i < m_elements.size(); ++i) + for (int i = 0; i < element_count; ++i) elements[i] = QPointF(qFloor(elements[i].x() + aliasedCoordinateDelta), qFloor(elements[i].y() + aliasedCoordinateDelta)); } +#ifdef QT_DEBUG_CONVERT + for (int i=0; i<element_count; ++i) { + printf("%d: (%.2f, %.2f)\n", + !m_element_types.isEmpty() ? m_element_types.at(i) : -1, + elements[i].x(), + elements[i].y()); + } +#endif + controlPointRect = boundingRect(elements, element_count); #ifdef QT_DEBUG_CONVERT diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index dfd3e16..69e490a 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1672,34 +1672,6 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount) QPaintEngineEx::drawRects(rects, rectCount); } -void QRasterPaintEnginePrivate::strokeProjective(const QPainterPath &path) -{ - Q_Q(QRasterPaintEngine); - QRasterPaintEngineState *s = q->state(); - - const QPen &pen = s->lastPen; - QPainterPathStroker pathStroker; - pathStroker.setWidth(pen.width() == 0 ? qreal(1) : pen.width()); - pathStroker.setCapStyle(pen.capStyle()); - pathStroker.setJoinStyle(pen.joinStyle()); - pathStroker.setMiterLimit(pen.miterLimit()); - pathStroker.setDashOffset(pen.dashOffset()); - - if (qpen_style(pen) == Qt::CustomDashLine) - pathStroker.setDashPattern(pen.dashPattern()); - else - pathStroker.setDashPattern(qpen_style(pen)); - - outlineMapper->setMatrix(QTransform()); - const QPainterPath stroke = pen.isCosmetic() - ? pathStroker.createStroke(s->matrix.map(path)) - : s->matrix.map(pathStroker.createStroke(path)); - - rasterize(outlineMapper->convertPath(stroke), s->penData.blend, &s->penData, rasterBuffer); - outlinemapper_xform_dirty = true; -} - - /*! \internal @@ -1969,67 +1941,6 @@ void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color) fillRect(r, &d->solid_color_filler); } -/*! - \reimp -*/ -void QRasterPaintEngine::drawPath(const QPainterPath &path) -{ -#ifdef QT_DEBUG_DRAW - QRectF bounds = path.boundingRect(); - qDebug(" - QRasterPaintEngine::drawPath(), [%.2f, %.2f, %.2f, %.2f]", - bounds.x(), bounds.y(), bounds.width(), bounds.height()); -#endif - - if (path.isEmpty()) - return; - - // Filling.., - Q_D(QRasterPaintEngine); - QRasterPaintEngineState *s = state(); - - ensureBrush(); - if (s->brushData.blend) { - ensureOutlineMapper(); - fillPath(path, &s->brushData); - } - - // Stroking... - ensurePen(); - if (!s->penData.blend) - return; - { - if (s->matrix.type() >= QTransform::TxProject) { - d->strokeProjective(path); - } else { - Q_ASSERT(s->stroker); - d->outlineMapper->beginOutline(Qt::WindingFill); - qreal txscale = 1; - if (s->pen.isCosmetic() || (qt_scaleForTransform(s->matrix, &txscale) && txscale != 1)) { - const qreal strokeWidth = d->basicStroker.strokeWidth(); - const QRectF clipRect = d->dashStroker ? d->dashStroker->clipRect() : QRectF(); - if (d->dashStroker) - d->dashStroker->setClipRect(d->deviceRect); - d->basicStroker.setStrokeWidth(strokeWidth * txscale); - d->outlineMapper->setMatrix(QTransform()); - s->stroker->strokePath(path, d->outlineMapper, s->matrix); - d->outlinemapper_xform_dirty = true; - d->basicStroker.setStrokeWidth(strokeWidth); - if (d->dashStroker) - d->dashStroker->setClipRect(clipRect); - } else { - ensureOutlineMapper(); - s->stroker->strokePath(path, d->outlineMapper, QTransform()); - } - d->outlineMapper->endOutline(); - - ProcessSpans blend = d->getPenFunc(d->outlineMapper->controlPointRect, - &s->penData); - d->rasterize(d->outlineMapper->outline(), blend, &s->penData, d->rasterBuffer); - } - } - -} - static inline bool isAbove(const QPointF *a, const QPointF *b) { return a->y() < b->y(); diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 283c442..3dab491 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -165,7 +165,6 @@ public: void updateMatrix(const QTransform &matrix); - void drawPath(const QPainterPath &path); void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode); void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode); void fillPath(const QPainterPath &path, QSpanData *fillData); @@ -327,7 +326,6 @@ public: inline const QClipData *clip() const; - void strokeProjective(const QPainterPath &path); void initializeRasterizer(QSpanData *data); void recalculateFastImages(); diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 797a5ab..8ec881e 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -42,6 +42,7 @@ #include "qpaintengineex_p.h" #include "qpainter_p.h" #include "qstroker_p.h" +#include "qbezier_p.h" #include <private/qpainterpath_p.h> #include <qvarlengtharray.h> @@ -91,6 +92,40 @@ QRectF QVectorPath::controlPointRect() const return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2)); } +QPainterPath QVectorPath::convertToPainterPath() const +{ + QPainterPath path; + + if (m_count == 0) + return path; + + const QPointF *points = (const QPointF *) m_points; + + if (m_elements) { + for (int i=0; i<m_count; ++i) { + switch (m_elements[i]) { + case QPainterPath::MoveToElement: + path.moveTo(points[i]); + break; + case QPainterPath::LineToElement: + path.lineTo(points[i]); + break; + case QPainterPath::CurveToElement: + path.cubicTo(points[i], points[i+1], points[i+2]); + break; + default: + break; + } + } + } else { + path.moveTo(points[0]); + for (int i=1; i<m_count; ++i) + path.lineTo(points[i]); + } + + return path; +} + const QVectorPath &qtVectorPathForPath(const QPainterPath &path) { Q_ASSERT(path.d_func()); @@ -450,13 +485,14 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) QVectorPath strokePath(d->strokeHandler->pts.data(), d->strokeHandler->types.size(), d->strokeHandler->types.data(), - QVectorPath::WindingFill); + flags); fill(strokePath, pen.brush()); } else { const qreal strokeWidth = d->stroker.strokeWidth(); d->stroker.setStrokeWidth(strokeWidth * txscale); // For cosmetic pens we need a bit of trickery... We to process xform the input points if (types) { + bool isProject = state()->matrix.type() >= QTransform::TxProject; while (points < lastPoint) { switch (*types) { case QPainterPath::MoveToElement: { @@ -474,10 +510,30 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) break; } case QPainterPath::CurveToElement: { - QPointF c1 = ((QPointF *) points)[0] * state()->matrix; - QPointF c2 = ((QPointF *) points)[1] * state()->matrix; - QPointF e = ((QPointF *) points)[2] * state()->matrix; - d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); + // Convert projective xformed curves to line + // segments so they can be transformed more + // accurately + if (isProject) { + // -1 access here is safe because there is + // always an element prior to the cubicTo, we + // just need the value.. + QPolygonF segment = + QBezier::fromPoints(*(((QPointF *) points) - 1), + *((QPointF *) points), + *(((QPointF *) points) + 1), + *(((QPointF *) points) + 2)).toPolygon(); + + for (QPolygonF::const_iterator it = segment.constBegin(); + it < segment.constEnd(); ++it) { + const QPointF pt = *it * state()->matrix; + d->activeStroker->lineTo(pt.x(), pt.y()); + } + } else { + QPointF c1 = ((QPointF *) points)[0] * state()->matrix; + QPointF c2 = ((QPointF *) points)[1] * state()->matrix; + QPointF e = ((QPointF *) points)[2] * state()->matrix; + d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); + } points += 6; types += 3; flags |= QVectorPath::CurvedShapeHint; @@ -512,7 +568,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) QVectorPath strokePath(d->strokeHandler->pts.data(), d->strokeHandler->types.size(), d->strokeHandler->types.data(), - QVectorPath::WindingFill); + flags); QTransform xform = state()->matrix; state()->matrix = QTransform(); diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index ea86cf5..09972b0 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -3271,6 +3271,8 @@ void QPainterPath::setDirty(bool dirty) { d_func()->dirtyBounds = dirty; d_func()->dirtyControlBounds = dirty; + delete d_func()->pathConverter; + d_func()->pathConverter = 0; } void QPainterPath::computeBoundingRect() const diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h index 6968f4e..a34c354 100644 --- a/src/gui/painting/qtextureglyphcache_p.h +++ b/src/gui/painting/qtextureglyphcache_p.h @@ -60,6 +60,10 @@ #include <private/qfontengineglyphcache_p.h> +#if defined(Q_OS_VXWORKS) && defined(m_type) +# undef m_type +#endif + struct glyph_metrics_t; typedef unsigned int glyph_t; diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 45939c1..a322fe4 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -101,7 +101,7 @@ QT_BEGIN_NAMESPACE allowing perspective transformations. QTransform's toAffine() method allows casting QTransform to QMatrix. If a perspective transformation has been specified on the matrix, then the - conversion to an affine QMatrix will cause loss of data. + conversion will cause loss of data. QTransform is the recommended transformation class in Qt. @@ -125,11 +125,13 @@ QT_BEGIN_NAMESPACE which returns true if the matrix is non-singular (i.e. AB = BA = I). The inverted() function returns an inverted copy of \e this matrix if it is invertible (otherwise it returns the identity - matrix). In addition, QTransform provides the det() function - returning the matrix's determinant. + matrix), and adjoint() returns the matrix's classical adjoint. + In addition, QTransform provides the determinant() function which + returns the matrix's determinant. - Finally, the QTransform class supports matrix multiplication, and - objects of the class can be streamed as well as compared. + Finally, the QTransform class supports matrix multiplication, addition + and subtraction, and objects of the class can be streamed as well + as compared. \tableofcontents @@ -191,7 +193,7 @@ QT_BEGIN_NAMESPACE The various matrix elements can be set when constructing the matrix, or by using the setMatrix() function later on. They can also be manipulated using the translate(), rotate(), scale() and - shear() convenience functions, The currently set values can be + shear() convenience functions. The currently set values can be retrieved using the m11(), m12(), m13(), m21(), m22(), m23(), m31(), m32(), m33(), dx() and dy() functions. @@ -204,9 +206,9 @@ QT_BEGIN_NAMESPACE to 0) mapping a point to itself. Shearing is controlled by \c m12 and \c m21. Setting these elements to values different from zero will twist the coordinate system. Rotation is achieved by - carefully setting both the shearing factors and the scaling - factors. Perspective transformation is achieved by carefully setting - both the projection factors and the scaling factors. + setting both the shearing factors and the scaling factors. Perspective + transformation is achieved by setting both the projection factors and + the scaling factors. Here's the combined transformations example using basic matrix operations: @@ -958,8 +960,8 @@ QTransform & QTransform::operator=(const QTransform &matrix) /*! Resets the matrix to an identity matrix, i.e. all elements are set - to zero, except \c m11 and \c m22 (specifying the scale) which are - set to 1. + to zero, except \c m11 and \c m22 (specifying the scale) and \c m33 + which are set to 1. \sa QTransform(), isIdentity(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations} @@ -1773,7 +1775,7 @@ bool QTransform::quadToQuad(const QPolygonF &one, Sets the matrix elements to the specified values, \a m11, \a m12, \a m13 \a m21, \a m22, \a m23 \a m31, \a m32 and \a m33. Note that this function replaces the previous values. - QMatrix provides the translate(), rotate(), scale() and shear() + QTransform provides the translate(), rotate(), scale() and shear() convenience functions to manipulate the various matrix elements based on the currently defined coordinate system. @@ -1951,8 +1953,11 @@ void QTransform::map(int x, int y, int *tx, int *ty) const } /*! - Returns the QTransform cast to a QMatrix. - */ + Returns the QTransform as an affine matrix. + + \warning If a perspective transformation has been specified, + then the conversion will cause loss of data. +*/ const QMatrix &QTransform::toAffine() const { return affine; @@ -2030,8 +2035,9 @@ QTransform::operator QVariant() const /*! \fn qreal QTransform::det() const + \obsolete - Returns the matrix's determinant. + Returns the matrix's determinant. Use determinant() instead. */ diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index 291d35c..69d4de2 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -50,6 +50,10 @@ #include <QtCore/qpoint.h> #include <QtCore/qrect.h> +#if defined(Q_OS_VXWORKS) && defined(m_type) +# undef m_type +#endif + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index b6b85fa..9264c9c 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -130,6 +130,8 @@ public: static inline uint polygonFlags(QPaintEngine::PolygonDrawMode mode); + QPainterPath convertToPainterPath() const; + private: Q_DISABLE_COPY(QVectorPath) diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp index c869976..598fe6b 100644 --- a/src/gui/styles/qstyle.cpp +++ b/src/gui/styles/qstyle.cpp @@ -564,7 +564,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, /*! \enum QStyle::PrimitiveElement - This enum describes that various primitive elements. A + This enum describes the various primitive elements. A primitive element is a common GUI element, such as a checkbox indicator or button bevel. diff --git a/src/gui/styles/qstyleoption.cpp b/src/gui/styles/qstyleoption.cpp index 7547dda..0ff7995 100644 --- a/src/gui/styles/qstyleoption.cpp +++ b/src/gui/styles/qstyleoption.cpp @@ -5007,11 +5007,6 @@ QStyleOptionGraphicsItem::QStyleOptionGraphicsItem(int version) of the painter used to draw the item. By default, if no transformations are applied, its value is 1. If zoomed out 1:2, the level of detail will be 0.5, and if zoomed in 2:1, its value is 2. - - For more advanced level-of-detail metrics, use - QStyleOptionGraphicsItem::matrix directly. - - \sa QStyleOptionGraphicsItem::matrix */ qreal QStyleOptionGraphicsItem::levelOfDetailFromTransform(const QTransform &worldTransform) { @@ -5038,20 +5033,32 @@ qreal QStyleOptionGraphicsItem::levelOfDetailFromTransform(const QTransform &wor Make use of this rectangle to speed up item drawing when only parts of the item are exposed. If the whole item is exposed, this rectangle will be the same as QGraphicsItem::boundingRect(). + + This member is only initialized for items that have the + QGraphicsItem::ItemUsesExtendedStyleOption flag set. */ /*! \variable QStyleOptionGraphicsItem::matrix \brief the complete transformation matrix for the item + \obsolete - This matrix is the sum of the item's scene matrix and the matrix of the - painter used for drawing the item. It is provided for convenience, + The QMatrix provided through this member does include information about + any perspective transformations applied to the view or item. To get the + correct transformation matrix, use QPainter::transform() on the painter + passed into the QGraphicsItem::paint() implementation. + + This matrix is the combination of the item's scene matrix and the matrix + of the painter used for drawing the item. It is provided for convenience, allowing anvanced level-of-detail metrics that can be used to speed up item drawing. - To find the dimentions of an item in screen coordinates (i.e., pixels), + To find the dimensions of an item in screen coordinates (i.e., pixels), you can use the mapping functions of QMatrix, such as QMatrix::map(). + This member is only initialized for items that have the + QGraphicsItem::ItemUsesExtendedStyleOption flag set. + \sa QStyleOptionGraphicsItem::levelOfDetailFromTransform() */ @@ -5059,7 +5066,7 @@ qreal QStyleOptionGraphicsItem::levelOfDetailFromTransform(const QTransform &wor \variable QStyleOptionGraphicsItem::levelOfDetail \obsolete - Use QStyleOptionGraphicsItem::levelOfDetailFromTransform + Use QStyleOptionGraphicsItem::levelOfDetailFromTransform() together with QPainter::worldTransform() instead. */ diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index b07acd5..9f046ff 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -67,6 +67,11 @@ #ifndef QT_NO_CSSPARSER +// VxWorks defines NONE as (-1) "for times when NULL won't do" +#if defined(Q_OS_VXWORKS) && defined(NONE) +# undef NONE +#endif + QT_BEGIN_NAMESPACE namespace QCss diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp index d348e1b..34239ff 100644 --- a/src/gui/text/qfontdatabase_qws.cpp +++ b/src/gui/text/qfontdatabase_qws.cpp @@ -360,7 +360,7 @@ static QString qwsFontPath() return fontpath; } -#ifdef QFONTDATABASE_DEBUG +#if defined(QFONTDATABASE_DEBUG) && defined(QT_FONTS_ARE_RESOURCES) class FriendlyResource : public QResource { public: @@ -694,8 +694,12 @@ QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp, QFontDef def = request; def.pixelSize = pixelSize; +#ifdef QT_NO_QWS_SHARE_FONTS + bool shareFonts = false; +#else static bool dontShareFonts = !qgetenv("QWS_NO_SHARE_FONTS").isEmpty(); bool shareFonts = !dontShareFonts; +#endif QFontEngine *engine = 0; diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index b255694..ed8abb8 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -331,16 +331,37 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng #if defined(DEBUG_FONTENGINE) qDebug() << "found existing qpf:" << fileName; #endif - if (::access(encodedName, W_OK | R_OK) == 0) - fd = QT_OPEN(encodedName, O_RDWR, 0); - else if (::access(encodedName, R_OK) == 0) - fd = QT_OPEN(encodedName, O_RDONLY, 0); + if (::access(encodedName, W_OK | R_OK) == 0) { + fd = QT_OPEN(encodedName, O_RDWR); + } + // read-write access failed - try read-only access + if (fd == -1 && ::access(encodedName, R_OK) == 0) { + fd = QT_OPEN(encodedName, O_RDONLY); + if (fd == -1) { +#if defined(DEBUG_FONTENGINE) + qErrnoWarning("QFontEngineQPF: unable to open %s", encodedName.constData()); +#endif + return; + } + } + if (fd == -1) { +#if defined(DEBUG_FONTENGINE) + qWarning("QFontEngineQPF: insufficient access rights to %s", encodedName.constData()); +#endif + return; + } } else { #if defined(DEBUG_FONTENGINE) qDebug() << "creating qpf on the fly:" << fileName; #endif if (::access(QFile::encodeName(qws_fontCacheDir()), W_OK) == 0) { fd = QT_OPEN(encodedName, O_RDWR | O_EXCL | O_CREAT, 0644); + if (fd == -1) { +#if defined(DEBUG_FONTENGINE) + qErrnoWarning(errno, "QFontEngineQPF: open() failed for %s", encodedName.constData()); +#endif + return; + } QBuffer buffer; buffer.open(QIODevice::ReadWrite); @@ -348,7 +369,17 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng generator.generate(); buffer.close(); const QByteArray &data = buffer.data(); - QT_WRITE(fd, data.constData(), data.size()); + if (QT_WRITE(fd, data.constData(), data.size()) == -1) { +#if defined(DEBUG_FONTENGINE) + qErrnoWarning(errno, "QFontEngineQPF: write() failed for %s", encodedName.constData()); +#endif + return; + } + } else { +#if defined(DEBUG_FONTENGINE) + qErrnoWarning(errno, "QFontEngineQPF: access() failed for %s", qPrintable(qws_fontCacheDir())); +#endif + return; } } } @@ -356,7 +387,7 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng QT_STATBUF st; if (QT_FSTAT(fd, &st)) { #if defined(DEBUG_FONTENGINE) - qDebug() << "stat failed!"; + qErrnoWarning(errno, "QFontEngineQPF: fstat failed!"); #endif return; } @@ -486,8 +517,13 @@ QFontEngineQPF::~QFontEngineQPF() qt_fbdpy->sendFontCommand(QWSFontCommand::StoppedUsingFont, QFile::encodeName(fileName)); #endif delete renderingFontEngine; - if (fontData) - munmap((void *)fontData, dataSize); + if (fontData) { + if (munmap((void *)fontData, dataSize) == -1) { +#if defined(DEBUG_FONTENGINE) + qErrnoWarning(errno, "~QFontEngineQPF: Unable to munmap"); +#endif + } + } if (fd != -1) ::close(fd); #if !defined(QT_NO_FREETYPE) diff --git a/src/gui/text/qfontengine_qws.cpp b/src/gui/text/qfontengine_qws.cpp index 70ce8f9..10bee2c 100644 --- a/src/gui/text/qfontengine_qws.cpp +++ b/src/gui/text/qfontengine_qws.cpp @@ -396,7 +396,7 @@ QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn) uchar* data = (uchar*)mmap( 0, // any address st.st_size, // whole file PROT_READ, // read-only memory -#if !defined(Q_OS_SOLARIS) && !defined(Q_OS_QNX4) && !defined(Q_OS_INTEGRITY) +#if !defined(Q_OS_SOLARIS) && !defined(Q_OS_QNX4) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS) MAP_FILE | MAP_PRIVATE, // swap-backed map from file #else MAP_PRIVATE, diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index ea37e04..e66b07c 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -60,6 +60,15 @@ QT_BEGIN_NAMESPACE #define PMDEBUG if(0) qDebug +// The VxWorks DIAB compiler crashes when initializing the anonymouse union with { a7 } +#if !defined(Q_CC_DIAB) +# define QT_INIT_TEXTUNDOCOMMAND(c, a1, a2, a3, a4, a5, a6, a7, a8) \ + QTextUndoCommand c = { a1, a2, a3, a4, a5, a6, { a7 }, a8 } +#else +# define QT_INIT_TEXTUNDOCOMMAND(c, a1, a2, a3, a4, a5, a6, a7, a8) \ + QTextUndoCommand c = { a1, a2, a3, a4, a5, a6 }; c.blockFormat = a7; c.revision = a8 +#endif + /* Structure of a document: @@ -406,9 +415,9 @@ int QTextDocumentPrivate::insertBlock(const QChar &blockSeparator, int b = blocks.findNode(pos); QTextBlockData *B = blocks.fragment(b); - QTextUndoCommand c = { QTextUndoCommand::BlockInserted, editBlock != 0, - op, charFormat, strPos, pos, { blockFormat }, - B->revision }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::BlockInserted, editBlock != 0, + op, charFormat, strPos, pos, blockFormat, + B->revision); appendUndoItem(c); Q_ASSERT(undoState == undoStack.size()); @@ -447,9 +456,9 @@ void QTextDocumentPrivate::insert(int pos, int strPos, int strLength, int format int b = blocks.findNode(pos); QTextBlockData *B = blocks.fragment(b); - QTextUndoCommand c = { QTextUndoCommand::Inserted, editBlock != 0, - QTextUndoCommand::MoveCursor, format, strPos, pos, { strLength }, - B->revision }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::Inserted, editBlock != 0, + QTextUndoCommand::MoveCursor, format, strPos, pos, strLength, + B->revision); appendUndoItem(c); B->revision = undoState; Q_ASSERT(undoState == undoStack.size()); @@ -606,12 +615,12 @@ void QTextDocumentPrivate::move(int pos, int to, int length, QTextUndoCommand::O int blockRevision = B->revision; QTextFragmentData *X = fragments.fragment(x); - QTextUndoCommand c = { QTextUndoCommand::Removed, editBlock != 0, - op, X->format, X->stringPosition, key, { X->size_array[0] }, - blockRevision }; - QTextUndoCommand cInsert = { QTextUndoCommand::Inserted, editBlock != 0, - op, X->format, X->stringPosition, dstKey, { X->size_array[0] }, - blockRevision }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::Removed, editBlock != 0, + op, X->format, X->stringPosition, key, X->size_array[0], + blockRevision); + QT_INIT_TEXTUNDOCOMMAND(cInsert, QTextUndoCommand::Inserted, editBlock != 0, + op, X->format, X->stringPosition, dstKey, X->size_array[0], + blockRevision); if (key+1 != blocks.position(b)) { // qDebug("remove_string from %d length %d", key, X->size_array[0]); @@ -723,8 +732,8 @@ void QTextDocumentPrivate::setCharFormat(int pos, int length, const QTextCharFor fragment->format = newFormatIdx; } - QTextUndoCommand c = { QTextUndoCommand::CharFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat, - 0, pos, { length }, 0 }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::CharFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat, + 0, pos, length, 0); appendUndoItem(c); pos += length; @@ -783,8 +792,8 @@ void QTextDocumentPrivate::setBlockFormat(const QTextBlock &from, const QTextBlo block(it)->invalidate(); - QTextUndoCommand c = { QTextUndoCommand::BlockFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat, - 0, it.position(), { 1 }, 0 }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::BlockFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat, + 0, it.position(), 1, 0); appendUndoItem(c); if (group != oldGroup) { @@ -1298,8 +1307,8 @@ void QTextDocumentPrivate::changeObjectFormat(QTextObject *obj, int format) if (f) documentChange(f->firstPosition(), f->lastPosition() - f->firstPosition()); - QTextUndoCommand c = { QTextUndoCommand::GroupFormatChange, editBlock != 0, QTextUndoCommand::MoveCursor, oldFormatIndex, - 0, 0, { obj->d_func()->objectIndex }, 0 }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::GroupFormatChange, editBlock != 0, QTextUndoCommand::MoveCursor, oldFormatIndex, + 0, 0, obj->d_func()->objectIndex, 0); appendUndoItem(c); endEditBlock(); diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index a940aa4..cb09452 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -54,7 +54,11 @@ QT_BEGIN_NAMESPACE QTextCopyHelper::QTextCopyHelper(const QTextCursor &_source, const QTextCursor &_destination, bool forceCharFormat, const QTextCharFormat &fmt) +#if defined(Q_CC_DIAB) // compiler bug + : formatCollection(*_destination.d->priv->formatCollection()), originalText((const QString)_source.d->priv->buffer()) +#else : formatCollection(*_destination.d->priv->formatCollection()), originalText(_source.d->priv->buffer()) +#endif { src = _source.d->priv; dst = _destination.d->priv; diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 4e43418..a3dd83e 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -89,7 +89,7 @@ QT_BEGIN_NAMESPACE /*! \fn Type QTextLength::type() const - Returns the type of length. + Returns the type of this length object. \sa QTextLength::Type */ @@ -129,9 +129,15 @@ QT_BEGIN_NAMESPACE /*! \enum QTextLength::Type - \value VariableLength - \value FixedLength - \value PercentageLength + This enum describes the different types a length object can + have. + + \value VariableLength The width of the object is variable + \value FixedLength The width of the object is fixed + \value PercentageLength The width of the object is in + percentage of the maximum width + + \sa type() */ /*! @@ -417,7 +423,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) more useful, and describe the formatting that is applied to specific parts of the document. - A format has a \c FormatType which specifies the kinds of thing it + A format has a \c FormatType which specifies the kinds of text item it can format; e.g. a block of text, a list, a table, etc. A format also has various properties (some specific to particular format types), as described by the Property enum. Every property has a @@ -447,24 +453,32 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) /*! \enum QTextFormat::FormatType - \value InvalidFormat - \value BlockFormat - \value CharFormat - \value ListFormat - \value TableFormat - \value FrameFormat + This enum describes the text item a QTextFormat object is formatting. + + \value InvalidFormat An invalid format as created by the default + constructor + \value BlockFormat The object formats a text block + \value CharFormat The object formats a single character + \value ListFormat The object formats a list + \value TableFormat The object formats a table + \value FrameFormat The object formats a frame \value UserFormat + + \sa QTextCharFormat, QTextBlockFormat, QTextListFormat, + QTextTableFormat, type() */ /*! \enum QTextFormat::Property - \value ObjectIndex + This enum describes the different properties a format can have. + + \value ObjectIndex The index of the formatted object. See objectIndex(). Paragraph and character properties - \value CssFloat + \value CssFloat How a frame is located relative to the surrounding text \value LayoutDirection The layout direction of the text in the document (Qt::LayoutDirection). @@ -482,25 +496,25 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \value BlockRightMargin \value TextIndent \value TabPositions Specifies the tab positions. The tab positions are structs of QTextOption::Tab which are stored in - a QList (internally, in a QList<QVariant>). + a QList (internally, in a QList<QVariant>). \value BlockIndent \value BlockNonBreakableLines - \value BlockTrailingHorizontalRulerWidth + \value BlockTrailingHorizontalRulerWidth The width of a horizontal ruler element. Character properties \value FontFamily \value FontPointSize + \value FontPixelSize \value FontSizeAdjustment Specifies the change in size given to the fontsize already set using FontPointSize or FontPixelSize. + \value FontFixedPitch \omitvalue FontSizeIncrement \value FontWeight \value FontItalic \value FontUnderline \e{This property has been deprecated.} Use QTextFormat::TextUnderlineStyle instead. \value FontOverline \value FontStrikeOut - \value FontFixedPitch - \value FontPixelSize \value FontCapitalization Specifies the capitalization type that is to be applied to the text. \value FontLetterSpacing Changes the default spacing between individual letters in the font. The value is specified in percentage, with 100 as the default value. @@ -512,7 +526,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \omitvalue FirstFontProperty \omitvalue LastFontProperty - + \value TextUnderlineColor \value TextVerticalAlignment \value TextOutline @@ -533,7 +547,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \value FrameBorder \value FrameBorderBrush - \value FrameBorderStyle + \value FrameBorderStyle See the \l{QTextFrameFormat::BorderStyle}{BorderStyle} enum. \value FrameBottomMargin \value FrameHeight \value FrameLeftMargin @@ -565,33 +579,46 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) Selection properties - \value FullWidthSelection When set on the characterFormat of a selection, the whole width of the text will be shown selected + \value FullWidthSelection When set on the characterFormat of a selection, + the whole width of the text will be shown selected. Page break properties - \value PageBreakPolicy + \value PageBreakPolicy Specifies how pages are broken. See the PageBreakFlag enum. \value UserProperty + + \sa property(), setProperty() */ /*! \enum QTextFormat::ObjectTypes + This enum describes what kind of QTextObject this format is associated with. + \value NoObject \value ImageObject \value TableObject \value TableCellObject \value UserObject The first object that can be used for application-specific purposes. + + \sa QTextObject, QTextTable, QTextObject::format() */ /*! \enum QTextFormat::PageBreakFlag \since 4.2 + This enum describes how page breaking is performed when printing. It maps to the + corresponding css properties. + \value PageBreak_Auto The page break is determined automatically depending on the available space on the current page \value PageBreak_AlwaysBefore The page is always broken before the paragraph/table \value PageBreak_AlwaysAfter A new page is always started after the paragraph/table + + \sa QTextBlockFormat::pageBreakPolicy(), QTextFrameFormat::pageBreakPolicy(), + PageBreakPolicy */ /*! @@ -971,6 +998,8 @@ QVector<QTextLength> QTextFormat::lengthVectorProperty(int propertyId) const /*! Returns the property specified by the given \a propertyId. + + \sa Property */ QVariant QTextFormat::property(int propertyId) const { @@ -979,6 +1008,8 @@ QVariant QTextFormat::property(int propertyId) const /*! Sets the property specified by the \a propertyId to the given \a value. + + \sa Property */ void QTextFormat::setProperty(int propertyId, const QVariant &value) { @@ -1006,8 +1037,10 @@ void QTextFormat::setProperty(int propertyId, const QVector<QTextLength> &value) } /*! - Clears the value of the property given by \a propertyId - */ + Clears the value of the property given by \a propertyId + + \sa Property +*/ void QTextFormat::clearProperty(int propertyId) { if (!d) @@ -1019,14 +1052,18 @@ void QTextFormat::clearProperty(int propertyId) /*! \fn void QTextFormat::setObjectType(int type) - Sets the text format's object \a type. See \c{ObjectTypes}. + Sets the text format's object type to \a type. + + \sa ObjectTypes, objectType() */ /*! \fn int QTextFormat::objectType() const - Returns the text format's object type. See \c{ObjectTypes}. + Returns the text format's object type. + + \sa ObjectTypes, setObjectType() */ @@ -2116,17 +2153,17 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt) /*! \fn void QTextListFormat::setStyle(Style style) - Sets the list format's \a style. See \c{Style} for the available styles. + Sets the list format's \a style. - \sa style() + \sa style() Style */ /*! \fn Style QTextListFormat::style() const - Returns the list format's style. See \c{Style}. + Returns the list format's style. - \sa setStyle() + \sa setStyle() Style */ @@ -2188,16 +2225,21 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt) /*! \enum QTextFrameFormat::Position + This enum describes how a frame is located relative to the surrounding text. + \value InFlow \value FloatLeft \value FloatRight + \sa position() CssFloat */ /*! \enum QTextFrameFormat::BorderStyle \since 4.3 + This enum describes different border styles for the text frame. + \value BorderStyle_None \value BorderStyle_Dotted \value BorderStyle_Dashed @@ -2210,6 +2252,7 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt) \value BorderStyle_Inset \value BorderStyle_Outset + \sa borderStyle() FrameBorderStyle */ /*! diff --git a/src/gui/util/qdesktopservices_x11.cpp b/src/gui/util/qdesktopservices_x11.cpp index f0202d4..0a3c2d0 100644 --- a/src/gui/util/qdesktopservices_x11.cpp +++ b/src/gui/util/qdesktopservices_x11.cpp @@ -56,7 +56,11 @@ QT_BEGIN_NAMESPACE inline static bool launch(const QUrl &url, const QString &client) { +#if !defined(QT_NO_PROCESS) return (QProcess::startDetached(client + QLatin1Char(' ') + QString::fromLatin1(url.toEncoded().constData()))); +#else + return (::system((client + QLatin1Char(' ') + QString::fromLatin1(url.toEncoded().constData())).toLocal8Bit().constData()) != -1); +#endif } static bool openDocument(const QUrl &url) diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index 433406c..7fa26ae 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -976,7 +976,7 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event) #endif case Qt::Key_Enter: case Qt::Key_Return: - d->edit->d_func()->modifiedState = d->edit->d_func()->undoState = 0; + d->edit->d_func()->control->clearUndo(); d->interpret(d->keyboardTracking ? AlwaysEmit : EmitIfChanged); selectAll(); event->ignore(); diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp new file mode 100644 index 0000000..106d8f2 --- /dev/null +++ b/src/gui/widgets/qlinecontrol.cpp @@ -0,0 +1,1749 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qlinecontrol_p.h" + +#ifndef QT_NO_LINEEDIT + +#include "qabstractitemview.h" +#include "qclipboard.h" +#ifndef QT_NO_ACCESSIBILITY +#include "qaccessible.h" +#endif +#ifndef QT_NO_IM +#include "qinputcontext.h" +#include "qlist.h" +#endif +#include "qapplication.h" +#ifndef QT_NO_GRAPHICSVIEW +#include "qgraphicssceneevent.h" +#endif + +QT_BEGIN_NAMESPACE + +/*! + \internal + + Updates the display text based of the current edit text + If the text has changed will emit displayTextChanged() +*/ +void QLineControl::updateDisplayText() +{ + QString orig = m_textLayout.text(); + QString str; + if (m_echoMode == QLineEdit::NoEcho) + str = QString::fromLatin1(""); + else + str = m_text; + + if (m_echoMode == QLineEdit::Password || (m_echoMode == QLineEdit::PasswordEchoOnEdit + && !m_passwordEchoEditing)) + str.fill(m_passwordCharacter); + + // replace certain non-printable characters with spaces (to avoid + // drawing boxes when using fonts that don't have glyphs for such + // characters) + QChar* uc = str.data(); + for (int i = 0; i < (int)str.length(); ++i) { + if ((uc[i] < 0x20 && uc[i] != 0x09) + || uc[i] == QChar::LineSeparator + || uc[i] == QChar::ParagraphSeparator + || uc[i] == QChar::ObjectReplacementCharacter) + uc[i] = QChar(0x0020); + } + + m_textLayout.setText(str); + + QTextOption option; + option.setTextDirection(m_layoutDirection); + option.setFlags(QTextOption::IncludeTrailingSpaces); + m_textLayout.setTextOption(option); + + m_textLayout.beginLayout(); + QTextLine l = m_textLayout.createLine(); + m_textLayout.endLayout(); + m_ascent = qRound(l.ascent()); + + if (str != orig) + emit displayTextChanged(str); +} + +#ifndef QT_NO_CLIPBOARD +/*! + \internal + + Copies the currently selected text into the clipboard using the given + \a mode. + + \note If the echo mode is set to a mode other than Normal then copy + will not work. This is to prevent using copy as a method of bypassing + password features of the line control. +*/ +void QLineControl::copy(QClipboard::Mode mode) const +{ + QString t = selectedText(); + if (!t.isEmpty() && m_echoMode == QLineEdit::Normal) { + disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), this, 0); + QApplication::clipboard()->setText(t, mode); + connect(QApplication::clipboard(), SIGNAL(selectionChanged()), + this, SLOT(_q_clipboardChanged())); + } +} + +/*! + \internal + + Inserts the text stored in the application clipboard into the line + control. + + \sa insert() +*/ +void QLineControl::paste() +{ + insert(QApplication::clipboard()->text(QClipboard::Clipboard)); +} + +#endif // !QT_NO_CLIPBOARD + +/*! + \internal + + Handles the behavior for the backspace key or function. + Removes the current selection if there is a selection, otherwise + removes the character prior to the cursor position. + + \sa del() +*/ +void QLineControl::backspace() +{ + int priorState = m_undoState; + if (hasSelectedText()) { + removeSelectedText(); + } else if (m_cursor) { + --m_cursor; + if (m_maskData) + m_cursor = prevMaskBlank(m_cursor); + QChar uc = m_text.at(m_cursor); + if (m_cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { + // second half of a surrogate, check if we have the first half as well, + // if yes delete both at once + uc = m_text.at(m_cursor - 1); + if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) { + internalDelete(true); + --m_cursor; + } + } + internalDelete(true); + } + finishChange(priorState); +} + +/*! + \internal + + Handles the behavior for the delete key or function. + Removes the current selection if there is a selection, otherwise + removes the character after the cursor position. + + \sa del() +*/ +void QLineControl::del() +{ + int priorState = m_undoState; + if (hasSelectedText()) { + removeSelectedText(); + } else { + int n = m_textLayout.nextCursorPosition(m_cursor) - m_cursor; + while (n--) + internalDelete(); + } + finishChange(priorState); +} + +/*! + \internal + + Inserts the given \a newText at the current cursor position. + If there is any selected text it is removed prior to insertion of + the new text. +*/ +void QLineControl::insert(const QString &newText) +{ + int priorState = m_undoState; + removeSelectedText(); + internalInsert(newText); + finishChange(priorState); +} + +/*! + \internal + + Clears the line control text. +*/ +void QLineControl::clear() +{ + int priorState = m_undoState; + m_selstart = 0; + m_selend = m_text.length(); + removeSelectedText(); + separate(); + finishChange(priorState, /*update*/false, /*edited*/false); +} + +/*! + \internal + + Sets \a length characters from the given \a start position as selected. + The given \a start position must be within the current text for + the line control. If \a length characters cannot be selected, then + the selection will extend to the end of the current text. +*/ +void QLineControl::setSelection(int start, int length) +{ + if(start < 0 || start > (int)m_text.length()){ + qWarning("QLineControl::setSelection: Invalid start position"); + return; + } + + if (length > 0) { + if (start == m_selstart && start + length == m_selend) + return; + m_selstart = start; + m_selend = qMin(start + length, (int)m_text.length()); + m_cursor = m_selend; + } else { + if (start == m_selend && start + length == m_selstart) + return; + m_selstart = qMax(start + length, 0); + m_selend = start; + m_cursor = m_selstart; + } + emit selectionChanged(); +} + +void QLineControl::_q_clipboardChanged() +{ +} + +void QLineControl::_q_deleteSelected() +{ + if (!hasSelectedText()) + return; + + int priorState = m_undoState; + emit resetInputContext(); + removeSelectedText(); + separate(); + finishChange(priorState); +} + +/*! + \internal + + Initializes the line control with a starting text value of \a txt. +*/ +void QLineControl::init(const QString &txt) +{ + m_text = txt; + updateDisplayText(); + m_cursor = m_text.length(); +} + +/*! + \internal + + Sets the password echo editing to \a editing. If password echo editing + is true, then the text of the password is displayed even if the echo + mode is set to QLineEdit::PasswordEchoOnEdit. Password echoing editing + does not affect other echo modes. +*/ +void QLineControl::updatePasswordEchoEditing(bool editing) +{ + m_passwordEchoEditing = editing; + updateDisplayText(); +} + +/*! + \internal + + Returns the cursor position of the given \a x pixel value in relation + to the displayed text. The given \a betweenOrOn specified what kind + of cursor position is requested. +*/ +int QLineControl::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const +{ + return m_textLayout.lineAt(0).xToCursor(x, betweenOrOn); +} + +/*! + \internal + + Returns the bounds of the current cursor, as defined as a + between characters cursor. +*/ +QRect QLineControl::cursorRect() const +{ + QTextLine l = m_textLayout.lineAt(0); + int c = m_cursor; + if (m_preeditCursor != -1) + c += m_preeditCursor; + int cix = qRound(l.cursorToX(c)); + int w = m_cursorWidth; + int ch = l.height() + 1; + + return QRect(cix-5, 0, w+9, ch); +} + +/*! + \internal + + Fixes the current text so that it is valid given any set validators. + + Returns true if the text was changed. Otherwise returns false. +*/ +bool QLineControl::fixup() // this function assumes that validate currently returns != Acceptable +{ +#ifndef QT_NO_VALIDATOR + if (m_validator) { + QString textCopy = m_text; + int cursorCopy = m_cursor; + m_validator->fixup(textCopy); + if (m_validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) { + if (textCopy != m_text || cursorCopy != m_cursor) + internalSetText(textCopy, cursorCopy); + return true; + } + } +#endif + return false; +} + +/*! + \internal + + Moves the cursor to the given position \a pos. If \a mark is true will + adjust the currently selected text. +*/ +void QLineControl::moveCursor(int pos, bool mark) +{ + if (pos != m_cursor) { + separate(); + if (m_maskData) + pos = pos > m_cursor ? nextMaskBlank(pos) : prevMaskBlank(pos); + } + if (mark) { + int anchor; + if (m_selend > m_selstart && m_cursor == m_selstart) + anchor = m_selend; + else if (m_selend > m_selstart && m_cursor == m_selend) + anchor = m_selstart; + else + anchor = m_cursor; + m_selstart = qMin(anchor, pos); + m_selend = qMax(anchor, pos); + updateDisplayText(); + } else { + internalDeselect(); + } + m_cursor = pos; + if (mark || m_selDirty) { + m_selDirty = false; + emit selectionChanged(); + } + emitCursorPositionChanged(); +} + +/*! + \internal + + Applies the given input method event \a event to the text of the line + control +*/ +void QLineControl::processInputMethodEvent(QInputMethodEvent *event) +{ + int priorState = m_undoState; + removeSelectedText(); + + int c = m_cursor; // cursor position after insertion of commit string + if (event->replacementStart() <= 0) + c += event->commitString().length() + qMin(-event->replacementStart(), event->replacementLength()); + + m_cursor += event->replacementStart(); + + // insert commit string + if (event->replacementLength()) { + m_selstart = m_cursor; + m_selend = m_selstart + event->replacementLength(); + removeSelectedText(); + } + if (!event->commitString().isEmpty()) + insert(event->commitString()); + + m_cursor = qMin(c, m_text.length()); + + setPreeditArea(m_cursor, event->preeditString()); + m_preeditCursor = event->preeditString().length(); + m_hideCursor = false; + QList<QTextLayout::FormatRange> formats; + for (int i = 0; i < event->attributes().size(); ++i) { + const QInputMethodEvent::Attribute &a = event->attributes().at(i); + if (a.type == QInputMethodEvent::Cursor) { + m_preeditCursor = a.start; + m_hideCursor = !a.length; + } else if (a.type == QInputMethodEvent::TextFormat) { + QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat(); + if (f.isValid()) { + QTextLayout::FormatRange o; + o.start = a.start + m_cursor; + o.length = a.length; + o.format = f; + formats.append(o); + } + } + } + m_textLayout.setAdditionalFormats(formats); + updateDisplayText(); + if (!event->commitString().isEmpty()) + emitCursorPositionChanged(); + finishChange(priorState); +} + +/*! + \internal + + Draws the display text for the line control using the given + \a painter, \a clip, and \a offset. Which aspects of the display text + are drawn is specified by the given \a flags. + + If the flags contain DrawSelections, then the selection or input mask + backgrounds and foregrounds will be applied before drawing the text. + + If the flags contain DrawCursor a cursor of the current cursorWidth() + will be drawn after drawing the text. + + The display text will only be drawn if the flags contain DrawText +*/ +void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &clip, int flags) +{ + QVector<QTextLayout::FormatRange> selections; + if (flags & DrawSelections) { + QTextLayout::FormatRange o; + if (m_selstart < m_selend) { + o.start = m_selstart; + o.length = m_selend - m_selstart; + o.format.setBackground(m_palette.brush(QPalette::Highlight)); + o.format.setForeground(m_palette.brush(QPalette::HighlightedText)); + } else { + // mask selection + o.start = m_cursor; + o.length = 1; + o.format.setBackground(m_palette.brush(QPalette::Text)); + o.format.setForeground(m_palette.brush(QPalette::Window)); + } + selections.append(o); + } + + if (flags & DrawText) + m_textLayout.draw(painter, offset, selections, clip); + + if (flags & DrawCursor){ + if(!m_blinkPeriod || m_blinkStatus) + m_textLayout.drawCursor(painter, offset, m_cursor, m_cursorWidth); + } +} + +/*! + \internal + + Sets the selection to cover the word at the given cursor position. + The word boundries is defined by the behavior of QTextLayout::SkipWords + cursor mode. +*/ +void QLineControl::selectWordAtPos(int cursor) +{ + int c = m_textLayout.previousCursorPosition(cursor, QTextLayout::SkipWords); + moveCursor(c, false); + // ## text layout should support end of words. + int end = m_textLayout.nextCursorPosition(cursor, QTextLayout::SkipWords); + while (end > cursor && m_text[end-1].isSpace()) + --end; + moveCursor(end, true); +} + +/*! + \internal + + Completes a change to the line control text. If the change is not valid + will undo the line control state back to the given \a validateFromState. + + If \a edited is true and the change is valid, will emit textEdited() in + addition to textChanged(). Otherwise only emits textChanged() on a valid + change. + + The \a update value is currently unused. +*/ +bool QLineControl::finishChange(int validateFromState, bool update, bool edited) +{ + Q_UNUSED(update) + bool lineDirty = m_selDirty; + if (m_textDirty) { + // do validation + bool wasValidInput = m_validInput; + m_validInput = true; +#ifndef QT_NO_VALIDATOR + if (m_validator) { + m_validInput = false; + QString textCopy = m_text; + int cursorCopy = m_cursor; + m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid); + if (m_validInput) { + if (m_text != textCopy) { + internalSetText(textCopy, cursorCopy); + return true; + } + m_cursor = cursorCopy; + } + } +#endif + if (validateFromState >= 0 && wasValidInput && !m_validInput) { + if (m_transactions.count()) + return false; + internalUndo(validateFromState); + m_history.resize(m_undoState); + if (m_modifiedState > m_undoState) + m_modifiedState = -1; + m_validInput = true; + m_textDirty = false; + } + updateDisplayText(); + lineDirty |= m_textDirty; + if (m_textDirty) { + m_textDirty = false; + QString actualText = text(); + if (edited) + emit textEdited(actualText); + emit textChanged(actualText); + } + } + if (m_selDirty) { + m_selDirty = false; + emit selectionChanged(); + } + emitCursorPositionChanged(); + return true; +} + +/*! + \internal + + An internal function for setting the text of the line control. +*/ +void QLineControl::internalSetText(const QString &txt, int pos, bool edited) +{ + internalDeselect(); + emit resetInputContext(); + QString oldText = m_text; + if (m_maskData) { + m_text = maskString(0, txt, true); + m_text += clearString(m_text.length(), m_maxLength - m_text.length()); + } else { + m_text = txt.isEmpty() ? txt : txt.left(m_maxLength); + } + m_history.clear(); + m_modifiedState = m_undoState = 0; + m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos; + m_textDirty = (oldText != m_text); + finishChange(-1, true, edited); +} + + +/*! + \internal + + Adds the given \a command to the undo history + of the line control. Does not apply the command. +*/ +void QLineControl::addCommand(const Command &cmd) +{ + if (m_separator && m_undoState && m_history[m_undoState - 1].type != Separator) { + m_history.resize(m_undoState + 2); + m_history[m_undoState++] = Command(Separator, m_cursor, 0, m_selstart, m_selend); + } else { + m_history.resize(m_undoState + 1); + } + m_separator = false; + m_history[m_undoState++] = cmd; +} + +/*! + \internal + + Inserts the given string \a s into the line + control. + + Also adds the appropriate commands into the undo history. + This function does not call finishChange(), and may leave the text + in an invalid state. +*/ +void QLineControl::internalInsert(const QString &s) +{ + if (hasSelectedText()) + addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); + if (m_maskData) { + QString ms = maskString(m_cursor, s); + for (int i = 0; i < (int) ms.length(); ++i) { + addCommand (Command(DeleteSelection, m_cursor + i, m_text.at(m_cursor + i), -1, -1)); + addCommand(Command(Insert, m_cursor + i, ms.at(i), -1, -1)); + } + m_text.replace(m_cursor, ms.length(), ms); + m_cursor += ms.length(); + m_cursor = nextMaskBlank(m_cursor); + m_textDirty = true; + } else { + int remaining = m_maxLength - m_text.length(); + if (remaining != 0) { + m_text.insert(m_cursor, s.left(remaining)); + for (int i = 0; i < (int) s.left(remaining).length(); ++i) + addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1)); + m_textDirty = true; + } + } +} + +/*! + \internal + + deletes a single character from the current text. If \a wasBackspace, + the character prior to the cursor is removed. Otherwise the character + after the cursor is removed. + + Also adds the appropriate commands into the undo history. + This function does not call finishChange(), and may leave the text + in an invalid state. +*/ +void QLineControl::internalDelete(bool wasBackspace) +{ + if (m_cursor < (int) m_text.length()) { + if (hasSelectedText()) + addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); + addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)), + m_cursor, m_text.at(m_cursor), -1, -1)); + if (m_maskData) { + m_text.replace(m_cursor, 1, clearString(m_cursor, 1)); + addCommand(Command(Insert, m_cursor, m_text.at(m_cursor), -1, -1)); + } else { + m_text.remove(m_cursor, 1); + } + m_textDirty = true; + } +} + +/*! + \internal + + removes the currently selected text from the line control. + + Also adds the appropriate commands into the undo history. + This function does not call finishChange(), and may leave the text + in an invalid state. +*/ +void QLineControl::removeSelectedText() +{ + if (m_selstart < m_selend && m_selend <= (int) m_text.length()) { + separate(); + int i ; + addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); + if (m_selstart <= m_cursor && m_cursor < m_selend) { + // cursor is within the selection. Split up the commands + // to be able to restore the correct cursor position + for (i = m_cursor; i >= m_selstart; --i) + addCommand (Command(DeleteSelection, i, m_text.at(i), -1, 1)); + for (i = m_selend - 1; i > m_cursor; --i) + addCommand (Command(DeleteSelection, i - m_cursor + m_selstart - 1, m_text.at(i), -1, -1)); + } else { + for (i = m_selend-1; i >= m_selstart; --i) + addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1)); + } + if (m_maskData) { + m_text.replace(m_selstart, m_selend - m_selstart, clearString(m_selstart, m_selend - m_selstart)); + for (int i = 0; i < m_selend - m_selstart; ++i) + addCommand(Command(Insert, m_selstart + i, m_text.at(m_selstart + i), -1, -1)); + } else { + m_text.remove(m_selstart, m_selend - m_selstart); + } + if (m_cursor > m_selstart) + m_cursor -= qMin(m_cursor, m_selend) - m_selstart; + internalDeselect(); + m_textDirty = true; + } +} + +/*! + \internal + + Parses the input mask specified by \a maskFields to generate + the mask data used to handle input masks. +*/ +void QLineControl::parseInputMask(const QString &maskFields) +{ + int delimiter = maskFields.indexOf(QLatin1Char(';')); + if (maskFields.isEmpty() || delimiter == 0) { + if (m_maskData) { + delete [] m_maskData; + m_maskData = 0; + m_maxLength = 32767; + internalSetText(QString()); + } + return; + } + + if (delimiter == -1) { + m_blank = QLatin1Char(' '); + m_inputMask = maskFields; + } else { + m_inputMask = maskFields.left(delimiter); + m_blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' '); + } + + // calculate m_maxLength / m_maskData length + m_maxLength = 0; + QChar c = 0; + for (int i=0; i<m_inputMask.length(); i++) { + c = m_inputMask.at(i); + if (i > 0 && m_inputMask.at(i-1) == QLatin1Char('\\')) { + m_maxLength++; + continue; + } + if (c != QLatin1Char('\\') && c != QLatin1Char('!') && + c != QLatin1Char('<') && c != QLatin1Char('>') && + c != QLatin1Char('{') && c != QLatin1Char('}') && + c != QLatin1Char('[') && c != QLatin1Char(']')) + m_maxLength++; + } + + delete [] m_maskData; + m_maskData = new MaskInputData[m_maxLength]; + + MaskInputData::Casemode m = MaskInputData::NoCaseMode; + c = 0; + bool s; + bool escape = false; + int index = 0; + for (int i = 0; i < m_inputMask.length(); i++) { + c = m_inputMask.at(i); + if (escape) { + s = true; + m_maskData[index].maskChar = c; + m_maskData[index].separator = s; + m_maskData[index].caseMode = m; + index++; + escape = false; + } else if (c == QLatin1Char('<')) { + m = MaskInputData::Lower; + } else if (c == QLatin1Char('>')) { + m = MaskInputData::Upper; + } else if (c == QLatin1Char('!')) { + m = MaskInputData::NoCaseMode; + } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) { + switch (c.unicode()) { + case 'A': + case 'a': + case 'N': + case 'n': + case 'X': + case 'x': + case '9': + case '0': + case 'D': + case 'd': + case '#': + case 'H': + case 'h': + case 'B': + case 'b': + s = false; + break; + case '\\': + escape = true; + default: + s = true; + break; + } + + if (!escape) { + m_maskData[index].maskChar = c; + m_maskData[index].separator = s; + m_maskData[index].caseMode = m; + index++; + } + } + } + internalSetText(m_text); +} + + +/*! + \internal + + checks if the key is valid compared to the inputMask +*/ +bool QLineControl::isValidInput(QChar key, QChar mask) const +{ + switch (mask.unicode()) { + case 'A': + if (key.isLetter()) + return true; + break; + case 'a': + if (key.isLetter() || key == m_blank) + return true; + break; + case 'N': + if (key.isLetterOrNumber()) + return true; + break; + case 'n': + if (key.isLetterOrNumber() || key == m_blank) + return true; + break; + case 'X': + if (key.isPrint()) + return true; + break; + case 'x': + if (key.isPrint() || key == m_blank) + return true; + break; + case '9': + if (key.isNumber()) + return true; + break; + case '0': + if (key.isNumber() || key == m_blank) + return true; + break; + case 'D': + if (key.isNumber() && key.digitValue() > 0) + return true; + break; + case 'd': + if ((key.isNumber() && key.digitValue() > 0) || key == m_blank) + return true; + break; + case '#': + if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == m_blank) + return true; + break; + case 'B': + if (key == QLatin1Char('0') || key == QLatin1Char('1')) + return true; + break; + case 'b': + if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == m_blank) + return true; + break; + case 'H': + if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F'))) + return true; + break; + case 'h': + if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == m_blank) + return true; + break; + default: + break; + } + return false; +} + +/*! + \internal + + Returns true if the given text \a str is valid for any + validator or input mask set for the line control. + + Otherwise returns false +*/ +bool QLineControl::hasAcceptableInput(const QString &str) const +{ +#ifndef QT_NO_VALIDATOR + QString textCopy = str; + int cursorCopy = m_cursor; + if (m_validator && m_validator->validate(textCopy, cursorCopy) + != QValidator::Acceptable) + return false; +#endif + + if (!m_maskData) + return true; + + if (str.length() != m_maxLength) + return false; + + for (int i=0; i < m_maxLength; ++i) { + if (m_maskData[i].separator) { + if (str.at(i) != m_maskData[i].maskChar) + return false; + } else { + if (!isValidInput(str.at(i), m_maskData[i].maskChar)) + return false; + } + } + return true; +} + +/*! + \internal + + Applies the inputMask on \a str starting from position \a pos in the mask. \a clear + specifies from where characters should be gotten when a separator is met in \a str - true means + that blanks will be used, false that previous input is used. + Calling this when no inputMask is set is undefined. +*/ +QString QLineControl::maskString(uint pos, const QString &str, bool clear) const +{ + if (pos >= (uint)m_maxLength) + return QString::fromLatin1(""); + + QString fill; + fill = clear ? clearString(0, m_maxLength) : m_text; + + int strIndex = 0; + QString s = QString::fromLatin1(""); + int i = pos; + while (i < m_maxLength) { + if (strIndex < str.length()) { + if (m_maskData[i].separator) { + s += m_maskData[i].maskChar; + if (str[(int)strIndex] == m_maskData[i].maskChar) + strIndex++; + ++i; + } else { + if (isValidInput(str[(int)strIndex], m_maskData[i].maskChar)) { + switch (m_maskData[i].caseMode) { + case MaskInputData::Upper: + s += str[(int)strIndex].toUpper(); + break; + case MaskInputData::Lower: + s += str[(int)strIndex].toLower(); + break; + default: + s += str[(int)strIndex]; + } + ++i; + } else { + // search for separator first + int n = findInMask(i, true, true, str[(int)strIndex]); + if (n != -1) { + if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[(int)strIndex]))) { + s += fill.mid(i, n-i+1); + i = n + 1; // update i to find + 1 + } + } else { + // search for valid m_blank if not + n = findInMask(i, true, false, str[(int)strIndex]); + if (n != -1) { + s += fill.mid(i, n-i); + switch (m_maskData[n].caseMode) { + case MaskInputData::Upper: + s += str[(int)strIndex].toUpper(); + break; + case MaskInputData::Lower: + s += str[(int)strIndex].toLower(); + break; + default: + s += str[(int)strIndex]; + } + i = n + 1; // updates i to find + 1 + } + } + } + ++strIndex; + } + } else + break; + } + + return s; +} + + + +/*! + \internal + + Returns a "cleared" string with only separators and blank chars. + Calling this when no inputMask is set is undefined. +*/ +QString QLineControl::clearString(uint pos, uint len) const +{ + if (pos >= (uint)m_maxLength) + return QString(); + + QString s; + int end = qMin((uint)m_maxLength, pos + len); + for (int i = pos; i < end; ++i) + if (m_maskData[i].separator) + s += m_maskData[i].maskChar; + else + s += m_blank; + + return s; +} + +/*! + \internal + + Strips blank parts of the input in a QLineControl when an inputMask is set, + separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1". +*/ +QString QLineControl::stripString(const QString &str) const +{ + if (!m_maskData) + return str; + + QString s; + int end = qMin(m_maxLength, (int)str.length()); + for (int i = 0; i < end; ++i) + if (m_maskData[i].separator) + s += m_maskData[i].maskChar; + else + if (str[i] != m_blank) + s += str[i]; + + return s; +} + +/*! + \internal + searches forward/backward in m_maskData for either a separator or a m_blank +*/ +int QLineControl::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const +{ + if (pos >= m_maxLength || pos < 0) + return -1; + + int end = forward ? m_maxLength : -1; + int step = forward ? 1 : -1; + int i = pos; + + while (i != end) { + if (findSeparator) { + if (m_maskData[i].separator && m_maskData[i].maskChar == searchChar) + return i; + } else { + if (!m_maskData[i].separator) { + if (searchChar.isNull()) + return i; + else if (isValidInput(searchChar, m_maskData[i].maskChar)) + return i; + } + } + i += step; + } + return -1; +} + +void QLineControl::internalUndo(int until) +{ + if (!isUndoAvailable()) + return; + internalDeselect(); + while (m_undoState && m_undoState > until) { + Command& cmd = m_history[--m_undoState]; + switch (cmd.type) { + case Insert: + m_text.remove(cmd.pos, 1); + m_cursor = cmd.pos; + break; + case SetSelection: + m_selstart = cmd.selStart; + m_selend = cmd.selEnd; + m_cursor = cmd.pos; + break; + case Remove: + case RemoveSelection: + m_text.insert(cmd.pos, cmd.uc); + m_cursor = cmd.pos + 1; + break; + case Delete: + case DeleteSelection: + m_text.insert(cmd.pos, cmd.uc); + m_cursor = cmd.pos; + break; + case Separator: + continue; + } + if (until < 0 && m_undoState) { + Command& next = m_history[m_undoState-1]; + if (next.type != cmd.type && next.type < RemoveSelection + && (cmd.type < RemoveSelection || next.type == Separator)) + break; + } + } + m_textDirty = true; + emitCursorPositionChanged(); +} + +void QLineControl::internalRedo() +{ + if (!isRedoAvailable()) + return; + internalDeselect(); + while (m_undoState < (int)m_history.size()) { + Command& cmd = m_history[m_undoState++]; + switch (cmd.type) { + case Insert: + m_text.insert(cmd.pos, cmd.uc); + m_cursor = cmd.pos + 1; + break; + case SetSelection: + m_selstart = cmd.selStart; + m_selend = cmd.selEnd; + m_cursor = cmd.pos; + break; + case Remove: + case Delete: + case RemoveSelection: + case DeleteSelection: + m_text.remove(cmd.pos, 1); + m_selstart = cmd.selStart; + m_selend = cmd.selEnd; + m_cursor = cmd.pos; + break; + case Separator: + m_selstart = cmd.selStart; + m_selend = cmd.selEnd; + m_cursor = cmd.pos; + break; + } + if (m_undoState < (int)m_history.size()) { + Command& next = m_history[m_undoState]; + if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator + && (next.type < RemoveSelection || cmd.type == Separator)) + break; + } + } + m_textDirty = true; + emitCursorPositionChanged(); +} + +/*! + \internal + + If the current cursor position differs from the last emited cursor + position, emits cursorPositionChanged(). +*/ +void QLineControl::emitCursorPositionChanged() +{ + if (m_cursor != m_lastCursorPos) { + const int oldLast = m_lastCursorPos; + m_lastCursorPos = m_cursor; + cursorPositionChanged(oldLast, m_cursor); + } +} + +#ifndef QT_NO_COMPLETER +// iterating forward(dir=1)/backward(dir=-1) from the +// current row based. dir=0 indicates a new completion prefix was set. +bool QLineControl::advanceToEnabledItem(int dir) +{ + int start = m_completer->currentRow(); + if (start == -1) + return false; + int i = start + dir; + if (dir == 0) dir = 1; + do { + if (!m_completer->setCurrentRow(i)) { + if (!m_completer->wrapAround()) + break; + i = i > 0 ? 0 : m_completer->completionCount() - 1; + } else { + QModelIndex currentIndex = m_completer->currentIndex(); + if (m_completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled) + return true; + i += dir; + } + } while (i != start); + + m_completer->setCurrentRow(start); // restore + return false; +} + +void QLineControl::complete(int key) +{ + if (!m_completer || isReadOnly() || echoMode() != QLineEdit::Normal) + return; + + QString text = this->text(); + if (m_completer->completionMode() == QCompleter::InlineCompletion) { + if (key == Qt::Key_Backspace) + return; + int n = 0; + if (key == Qt::Key_Up || key == Qt::Key_Down) { + if (textAfterSelection().length()) + return; + QString prefix = hasSelectedText() ? textBeforeSelection() + : text; + if (text.compare(m_completer->currentCompletion(), m_completer->caseSensitivity()) != 0 + || prefix.compare(m_completer->completionPrefix(), m_completer->caseSensitivity()) != 0) { + m_completer->setCompletionPrefix(prefix); + } else { + n = (key == Qt::Key_Up) ? -1 : +1; + } + } else { + m_completer->setCompletionPrefix(text); + } + if (!advanceToEnabledItem(n)) + return; + } else { +#ifndef QT_KEYPAD_NAVIGATION + if (text.isEmpty()) { + m_completer->popup()->hide(); + return; + } +#endif + m_completer->setCompletionPrefix(text); + } + + m_completer->complete(); +} +#endif + +void QLineControl::setCursorBlinkPeriod(int msec) +{ + if (msec == m_blinkPeriod) + return; + if (m_blinkTimer) { + killTimer(m_blinkTimer); + } + if (msec) { + m_blinkTimer = startTimer(msec / 2); + m_blinkStatus = 1; + } else { + m_blinkTimer = 0; + if (m_blinkStatus == 0) + emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect()); + } + m_blinkPeriod = msec; +} + +void QLineControl::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == m_blinkTimer) { + m_blinkStatus = !m_blinkStatus; + emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect()); + } else if (event->timerId() == m_deleteAllTimer) { + killTimer(m_deleteAllTimer); + m_deleteAllTimer = 0; + clear(); + } else if (event->timerId() == m_tripleClickTimer) { + killTimer(m_tripleClickTimer); + m_tripleClickTimer = 0; + } +} + +bool QLineControl::processEvent(QEvent* ev) +{ +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::keypadNavigationEnabled()) { + if ((ev->type() == QEvent::KeyPress) || (ev->type() == QEvent::KeyRelease)) { + QKeyEvent *ke = (QKeyEvent *)ev; + if (ke->key() == Qt::Key_Back) { + if (ke->isAutoRepeat()) { + // Swallow it. We don't want back keys running amok. + ke->accept(); + return true; + } + if ((ev->type() == QEvent::KeyRelease) + && !isReadOnly() + && deleteAllTimer) { + killTimer(m_deleteAllTimer); + m_deleteAllTimer = 0; + backspace(); + ke->accept(); + return true; + } + } + } + } +#endif + switch(ev->type()){ +#ifndef QT_NO_GRAPHICSVIEW + case QEvent::GraphicsSceneMouseMove: + case QEvent::GraphicsSceneMouseRelease: + case QEvent::GraphicsSceneMousePress:{ + QGraphicsSceneMouseEvent *gvEv = static_cast<QGraphicsSceneMouseEvent*>(ev); + QMouseEvent* mouse = new QMouseEvent(ev->type(), + gvEv->pos().toPoint(), gvEv->button(), gvEv->buttons(), gvEv->modifiers()); + processMouseEvent(mouse); break; + } +#endif + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + processMouseEvent(static_cast<QMouseEvent*>(ev)); break; + case QEvent::KeyPress: + case QEvent::KeyRelease: + processKeyEvent(static_cast<QKeyEvent*>(ev)); break; + case QEvent::InputMethod: + processInputMethodEvent(static_cast<QInputMethodEvent*>(ev)); break; +#ifndef QT_NO_SHORTCUT + case QEvent::ShortcutOverride:{ + QKeyEvent* ke = static_cast<QKeyEvent*>(ev); + if (ke == QKeySequence::Copy + || ke == QKeySequence::Paste + || ke == QKeySequence::Cut + || ke == QKeySequence::Redo + || ke == QKeySequence::Undo + || ke == QKeySequence::MoveToNextWord + || ke == QKeySequence::MoveToPreviousWord + || ke == QKeySequence::MoveToStartOfDocument + || ke == QKeySequence::MoveToEndOfDocument + || ke == QKeySequence::SelectNextWord + || ke == QKeySequence::SelectPreviousWord + || ke == QKeySequence::SelectStartOfLine + || ke == QKeySequence::SelectEndOfLine + || ke == QKeySequence::SelectStartOfBlock + || ke == QKeySequence::SelectEndOfBlock + || ke == QKeySequence::SelectStartOfDocument + || ke == QKeySequence::SelectAll + || ke == QKeySequence::SelectEndOfDocument) { + ke->accept(); + } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier + || ke->modifiers() == Qt::KeypadModifier) { + if (ke->key() < Qt::Key_Escape) { + ke->accept(); + } else { + switch (ke->key()) { + case Qt::Key_Delete: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_Backspace: + case Qt::Key_Left: + case Qt::Key_Right: + ke->accept(); + default: + break; + } + } + } + } +#endif + default: + return false; + } + return true; +} + +void QLineControl::processMouseEvent(QMouseEvent* ev) +{ + + switch (ev->type()) { + case QEvent::GraphicsSceneMousePress: + case QEvent::MouseButtonPress:{ + if (m_tripleClickTimer + && (ev->pos() - m_tripleClick).manhattanLength() + < QApplication::startDragDistance()) { + selectAll(); + return; + } + if (ev->button() == Qt::RightButton) + return; + + bool mark = ev->modifiers() & Qt::ShiftModifier; + int cursor = xToPos(ev->pos().x()); + moveCursor(cursor, mark); + break; + } + case QEvent::MouseButtonDblClick: + if (ev->button() == Qt::LeftButton) { + selectWordAtPos(xToPos(ev->pos().x())); + if (m_tripleClickTimer) + killTimer(m_tripleClickTimer); + m_tripleClickTimer = startTimer(QApplication::doubleClickInterval()); + m_tripleClick = ev->pos(); + } + break; + case QEvent::GraphicsSceneMouseRelease: + case QEvent::MouseButtonRelease: +#ifndef QT_NO_CLIPBOARD + if (QApplication::clipboard()->supportsSelection()) { + if (ev->button() == Qt::LeftButton) { + copy(QClipboard::Selection); + } else if (!isReadOnly() && ev->button() == Qt::MidButton) { + deselect(); + insert(QApplication::clipboard()->text(QClipboard::Selection)); + } + } +#endif + break; + case QEvent::GraphicsSceneMouseMove: + case QEvent::MouseMove: + if (ev->buttons() & Qt::LeftButton) { + moveCursor(xToPos(ev->pos().x()), true); + } + break; + default: + break; + } +} + +void QLineControl::processKeyEvent(QKeyEvent* event) +{ + bool inlineCompletionAccepted = false; + +#ifndef QT_NO_COMPLETER + if (m_completer) { + QCompleter::CompletionMode completionMode = m_completer->completionMode(); + if ((completionMode == QCompleter::PopupCompletion + || completionMode == QCompleter::UnfilteredPopupCompletion) + && m_completer->popup() + && m_completer->popup()->isVisible()) { + // The following keys are forwarded by the completer to the widget + // Ignoring the events lets the completer provide suitable default behavior + switch (event->key()) { + case Qt::Key_Escape: + event->ignore(); + return; + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_F4: +#ifdef QT_KEYPAD_NAVIGATION + case Qt::Key_Select: + if (!QApplication::keypadNavigationEnabled()) + break; +#endif + m_completer->popup()->hide(); // just hide. will end up propagating to parent + default: + break; // normal key processing + } + } else if (completionMode == QCompleter::InlineCompletion) { + switch (event->key()) { + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_F4: +#ifdef QT_KEYPAD_NAVIGATION + case Qt::Key_Select: + if (!QApplication::keypadNavigationEnabled()) + break; +#endif + if (!m_completer->currentCompletion().isEmpty() && hasSelectedText() + && textAfterSelection().isEmpty()) { + setText(m_completer->currentCompletion()); + inlineCompletionAccepted = true; + } + default: + break; // normal key processing + } + } + } +#endif // QT_NO_COMPLETER + + if (echoMode() == QLineEdit::PasswordEchoOnEdit + && !passwordEchoEditing() + && !isReadOnly() + && !event->text().isEmpty() +#ifdef QT_KEYPAD_NAVIGATION + && event->key() != Qt::Key_Select + && event->key() != Qt::Key_Up + && event->key() != Qt::Key_Down + && event->key() != Qt::Key_Back +#endif + && !(event->modifiers() & Qt::ControlModifier)) { + // Clear the edit and reset to normal echo mode while editing; the + // echo mode switches back when the edit loses focus + // ### resets current content. dubious code; you can + // navigate with keys up, down, back, and select(?), but if you press + // "left" or "right" it clears? + updatePasswordEchoEditing(true); + clear(); + } + + if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { + if (hasAcceptableInput() || fixup()) { + emit accepted(); + emit editingFinished(); + } + if (inlineCompletionAccepted) + event->accept(); + else + event->ignore(); + return; + } + bool unknown = false; + + if (false) { + } +#ifndef QT_NO_SHORTCUT + else if (event == QKeySequence::Undo) { + if (!isReadOnly()) + undo(); + } + else if (event == QKeySequence::Redo) { + if (!isReadOnly()) + redo(); + } + else if (event == QKeySequence::SelectAll) { + selectAll(); + } +#ifndef QT_NO_CLIPBOARD + else if (event == QKeySequence::Copy) { + copy(); + } + else if (event == QKeySequence::Paste) { + if (!isReadOnly()) + paste(); + } + else if (event == QKeySequence::Cut) { + if (!isReadOnly()) { + copy(); + del(); + } + } + else if (event == QKeySequence::DeleteEndOfLine) { + if (!isReadOnly()) { + setSelection(cursor(), end()); + copy(); + del(); + } + } +#endif //QT_NO_CLIPBOARD + else if (event == QKeySequence::MoveToStartOfLine) { + home(0); + } + else if (event == QKeySequence::MoveToEndOfLine) { + end(0); + } + else if (event == QKeySequence::SelectStartOfLine) { + home(1); + } + else if (event == QKeySequence::SelectEndOfLine) { + end(1); + } + else if (event == QKeySequence::MoveToNextChar) { +#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER) + if (hasSelectedText()) { +#else + if (hasSelectedText() && m_completer + && m_completer->completionMode() == QCompleter::InlineCompletion) { +#endif + moveCursor(selectionEnd(), false); + } else { + cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1); + } + } + else if (event == QKeySequence::SelectNextChar) { + cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1); + } + else if (event == QKeySequence::MoveToPreviousChar) { +#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER) + if (hasSelectedText()) { +#else + if (hasSelectedText() && m_completer + && m_completer->completionMode() == QCompleter::InlineCompletion) { +#endif + moveCursor(selectionStart(), false); + } else { + cursorForward(0, layoutDirection() == Qt::LeftToRight ? -1 : 1); + } + } + else if (event == QKeySequence::SelectPreviousChar) { + cursorForward(1, layoutDirection() == Qt::LeftToRight ? -1 : 1); + } + else if (event == QKeySequence::MoveToNextWord) { + if (echoMode() == QLineEdit::Normal) + layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0); + else + layoutDirection() == Qt::LeftToRight ? end(0) : home(0); + } + else if (event == QKeySequence::MoveToPreviousWord) { + if (echoMode() == QLineEdit::Normal) + layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0); + else if (!isReadOnly()) { + layoutDirection() == Qt::LeftToRight ? home(0) : end(0); + } + } + else if (event == QKeySequence::SelectNextWord) { + if (echoMode() == QLineEdit::Normal) + layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1); + else + layoutDirection() == Qt::LeftToRight ? end(1) : home(1); + } + else if (event == QKeySequence::SelectPreviousWord) { + if (echoMode() == QLineEdit::Normal) + layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1); + else + layoutDirection() == Qt::LeftToRight ? home(1) : end(1); + } + else if (event == QKeySequence::Delete) { + if (!isReadOnly()) + del(); + } + else if (event == QKeySequence::DeleteEndOfWord) { + if (!isReadOnly()) { + cursorWordForward(true); + del(); + } + } + else if (event == QKeySequence::DeleteStartOfWord) { + if (!isReadOnly()) { + cursorWordBackward(true); + del(); + } + } +#endif // QT_NO_SHORTCUT + else { +#ifdef Q_WS_MAC + if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) { + Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier); + if (myModifiers & Qt::ShiftModifier) { + if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier) + || myModifiers == (Qt::AltModifier|Qt::ShiftModifier) + || myModifiers == Qt::ShiftModifier) { + + event->key() == Qt::Key_Up ? home(1) : end(1); + } + } else { + if ((myModifiers == Qt::ControlModifier + || myModifiers == Qt::AltModifier + || myModifiers == Qt::NoModifier)) { + event->key() == Qt::Key_Up ? home(0) : end(0); + } + } + } +#endif + if (event->modifiers() & Qt::ControlModifier) { + switch (event->key()) { + case Qt::Key_Backspace: + if (!isReadOnly()) { + cursorWordBackward(true); + del(); + } + break; +#ifndef QT_NO_COMPLETER + case Qt::Key_Up: + case Qt::Key_Down: + complete(event->key()); + break; +#endif +#if defined(Q_WS_X11) + case Qt::Key_E: + end(0); + break; + + case Qt::Key_U: + if (!isReadOnly()) { + setSelection(0, text().size()); +#ifndef QT_NO_CLIPBOARD + copy(); +#endif + del(); + } + break; +#endif + default: + unknown = true; + } + } else { // ### check for *no* modifier + switch (event->key()) { + case Qt::Key_Backspace: + if (!isReadOnly()) { + backspace(); +#ifndef QT_NO_COMPLETER + complete(Qt::Key_Backspace); +#endif + } + break; +#ifdef QT_KEYPAD_NAVIGATION + case Qt::Key_Back: + if (QApplication::keypadNavigationEnabled() && !event->isAutoRepeat() + && !isReadOnly()) { + if (text().length() == 0) { + setText(m_cancelText); + + if (passwordEchoEditing) + updatePasswordEchoEditing(false); + + setEditFocus(false); + } else if (!deleteAllTimer) { + deleteAllTimer = startTimer(750); + } + } else { + unknown = true; + } + break; +#endif + + default: + unknown = true; + } + } + } + + if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) { + setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft); + unknown = false; + } + + if (unknown && !isReadOnly()) { + QString t = event->text(); + if (!t.isEmpty() && t.at(0).isPrint()) { + insert(t); +#ifndef QT_NO_COMPLETER + complete(event->key()); +#endif + event->accept(); + return; + } + } + + if (unknown) + event->ignore(); + else + event->accept(); +} + + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h new file mode 100644 index 0000000..9cad857 --- /dev/null +++ b/src/gui/widgets/qlinecontrol_p.h @@ -0,0 +1,741 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QLINECONTROL_P_H +#define QLINECONTROL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "QtCore/qglobal.h" + +#ifndef QT_NO_LINEEDIT +#include "private/qwidget_p.h" +#include "QtGui/qlineedit.h" +#include "QtGui/qtextlayout.h" +#include "QtGui/qstyleoption.h" +#include "QtCore/qpointer.h" +#include "QtGui/qlineedit.h" +#include "QtGui/qclipboard.h" +#include "QtCore/qpoint.h" +#include "QtGui/qcompleter.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class Q_GUI_EXPORT QLineControl : public QObject +{ + Q_OBJECT + +public: + QLineControl(const QString &txt = QString()) + : m_cursor(0), m_preeditCursor(0), m_layoutDirection(Qt::LeftToRight), + m_hideCursor(false), m_separator(0), m_readOnly(0), + m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0), + m_validInput(1), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0), + m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1), + m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0), + m_selstart(0), m_selend(0), m_passwordEchoEditing(false) + { + init(txt); + } + + ~QLineControl() + { + delete [] m_maskData; + } + + int nextMaskBlank(int pos); + int prevMaskBlank(int pos); + + bool isUndoAvailable() const; + bool isRedoAvailable() const; + void clearUndo(); + bool isModified() const; + void setModified(bool modified); + + bool allSelected() const; + bool hasSelectedText() const; + + int width() const; + int height() const; + int ascent() const; + + void setSelection(int start, int length); + + QString selectedText() const; + QString textBeforeSelection() const; + QString textAfterSelection() const; + + int selectionStart() const; + int selectionEnd() const; + bool inSelection(int x) const; + + void removeSelection(); + + int start() const; + int end() const; + +#ifndef QT_NO_CLIPBOARD + void copy(QClipboard::Mode mode = QClipboard::Clipboard) const; + void paste(); +#endif + + int cursor() const; + int preeditCursor() const; + + int cursorWidth() const; + void setCursorWidth(int value); + + void moveCursor(int pos, bool mark = false); + void cursorForward(bool mark, int steps); + void cursorWordForward(bool mark); + void cursorWordBackward(bool mark); + void home(bool mark); + void end(bool mark); + + int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const; + QRect cursorRect() const; + + qreal cursorToX(int cursor) const; + qreal cursorToX() const; + + bool isReadOnly() const; + void setReadOnly(bool enable); + + QString text() const; + void setText(const QString &txt); + + QString displayText() const; + + void backspace(); + void del(); + void deselect(); + void selectAll(); + void insert(const QString &); + void clear(); + void undo(); + void redo(); + void selectWordAtPos(int); + + uint echoMode() const; + void setEchoMode(uint mode); + + void setMaxLength(int maxLength); + int maxLength() const; + + const QValidator *validator() const; + void setValidator(const QValidator *); + +#ifndef QT_NO_COMPLETER + QCompleter *completer() const; + void setCompleter(const QCompleter*); + void complete(int key); +#endif + + void setCursorPosition(int pos); + int cursorPosition() const; + + bool hasAcceptableInput() const; + bool fixup(); + + QString inputMask() const; + void setInputMask(const QString &mask); + + // input methods +#ifndef QT_NO_IM + bool composeMode() const; + void setPreeditArea(int cursor, const QString &text); +#endif + + QString preeditAreaText() const; + + void updatePasswordEchoEditing(bool editing); + bool passwordEchoEditing() const; + + QChar passwordCharacter() const; + void setPasswordCharacter(const QChar &character); + + Qt::LayoutDirection layoutDirection() const; + void setLayoutDirection(Qt::LayoutDirection direction); + void setFont(const QFont &font); + + void processInputMethodEvent(QInputMethodEvent *event); + void processMouseEvent(QMouseEvent* ev); + void processKeyEvent(QKeyEvent* ev); + + int cursorBlinkPeriod() const; + void setCursorBlinkPeriod(int msec); + + QString cancelText() const; + void setCancelText(const QString &text); + + enum DrawFlags { + DrawText = 0x01, + DrawSelections = 0x02, + DrawCursor = 0x04, + DrawAll = DrawText | DrawSelections | DrawCursor + }; + void draw(QPainter *, const QPoint &, const QRect &, int flags = DrawAll); + + bool processEvent(QEvent *ev); + +private: + void init(const QString &txt); + void removeSelectedText(); + void internalSetText(const QString &txt, int pos = -1, bool edited = true); + void updateDisplayText(); + + void internalInsert(const QString &s); + void internalDelete(bool wasBackspace = false); + void internalRemove(int pos); + + inline void internalDeselect() + { + m_selDirty |= (m_selend > m_selstart); + m_selstart = m_selend = 0; + } + + void internalUndo(int until = -1); + void internalRedo(); + + QString m_text; + QPalette m_palette; + int m_cursor; + int m_preeditCursor; + int m_cursorWidth; + Qt::LayoutDirection m_layoutDirection; + uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas + uint m_separator : 1; + uint m_readOnly : 1; + uint m_dragEnabled : 1; + uint m_echoMode : 2; + uint m_textDirty : 1; + uint m_selDirty : 1; + uint m_validInput : 1; + int m_blinkPeriod; // 0 for non-blinking cursor + int m_blinkTimer; + int m_deleteAllTimer; + int m_blinkStatus; + int m_ascent; + int m_maxLength; + int m_lastCursorPos; + QList<int> m_transactions; + QPoint m_tripleClick; + int m_tripleClickTimer; + QString m_cancelText; + + void emitCursorPositionChanged(); + + bool finishChange(int validateFromState = -1, bool update = false, bool edited = true); + + QPointer<QValidator> m_validator; + QPointer<QCompleter> m_completer; +#ifndef QT_NO_COMPLETER + bool advanceToEnabledItem(int dir); +#endif + + struct MaskInputData { + enum Casemode { NoCaseMode, Upper, Lower }; + QChar maskChar; // either the separator char or the inputmask + bool separator; + Casemode caseMode; + }; + QString m_inputMask; + QChar m_blank; + MaskInputData *m_maskData; + + // undo/redo handling + enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection }; + struct Command { + inline Command() {} + inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {} + uint type : 4; + QChar uc; + int pos, selStart, selEnd; + }; + int m_modifiedState; + int m_undoState; + QVector<Command> m_history; + void addCommand(const Command& cmd); + + inline void separate() { m_separator = true; } + + // selection + int m_selstart; + int m_selend; + + // masking + void parseInputMask(const QString &maskFields); + bool isValidInput(QChar key, QChar mask) const; + bool hasAcceptableInput(const QString &text) const; + QString maskString(uint pos, const QString &str, bool clear = false) const; + QString clearString(uint pos, uint len) const; + QString stripString(const QString &str) const; + int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const; + + // complex text layout + QTextLayout m_textLayout; + + bool m_passwordEchoEditing; + QChar m_passwordCharacter; + +Q_SIGNALS: + void cursorPositionChanged(int, int); + void selectionChanged(); + + void displayTextChanged(const QString &); + void textChanged(const QString &); + void textEdited(const QString &); + + void resetInputContext(); + + void accepted(); + void editingFinished(); + void updateNeeded(const QRect &); + +protected: + virtual void timerEvent(QTimerEvent *event); + +private slots: + void _q_clipboardChanged(); + void _q_deleteSelected(); + +}; + +inline int QLineControl::nextMaskBlank(int pos) +{ + int c = findInMask(pos, true, false); + m_separator |= (c != pos); + return (c != -1 ? c : m_maxLength); +} + +inline int QLineControl::prevMaskBlank(int pos) +{ + int c = findInMask(pos, false, false); + m_separator |= (c != pos); + return (c != -1 ? c : 0); +} + +inline bool QLineControl::isUndoAvailable() const +{ + return !m_readOnly && m_undoState; +} + +inline bool QLineControl::isRedoAvailable() const +{ + return !m_readOnly && m_undoState < (int)m_history.size(); +} + +inline void QLineControl::clearUndo() +{ + m_history.clear(); + m_modifiedState = m_undoState = 0; +} + +inline bool QLineControl::isModified() const +{ + return m_modifiedState != m_undoState; +} + +inline void QLineControl::setModified(bool modified) +{ + m_modifiedState = modified ? -1 : m_undoState; +} + +inline bool QLineControl::allSelected() const +{ + return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); +} + +inline bool QLineControl::hasSelectedText() const +{ + return !m_text.isEmpty() && m_selend > m_selstart; +} + +inline int QLineControl::width() const +{ + return qRound(m_textLayout.lineAt(0).width()) + 1; +} + +inline int QLineControl::height() const +{ + return qRound(m_textLayout.lineAt(0).height()) + 1; +} + +inline int QLineControl::ascent() const +{ + return m_ascent; +} + +inline QString QLineControl::selectedText() const +{ + if (hasSelectedText()) + return m_text.mid(m_selstart, m_selend - m_selstart); + return QString(); +} + +inline QString QLineControl::textBeforeSelection() const +{ + if (hasSelectedText()) + return m_text.left(m_selstart); + return QString(); +} + +inline QString QLineControl::textAfterSelection() const +{ + if (hasSelectedText()) + return m_text.mid(m_selend); + return QString(); +} + +inline int QLineControl::selectionStart() const +{ + return hasSelectedText() ? m_selstart : -1; +} + +inline int QLineControl::selectionEnd() const +{ + return hasSelectedText() ? m_selend : -1; +} + +inline int QLineControl::start() const +{ + return 0; +} + +inline int QLineControl::end() const +{ + return m_text.length(); +} + +inline void QLineControl::removeSelection() +{ + int priorState = m_undoState; + removeSelectedText(); + finishChange(priorState); +} + +inline bool QLineControl::inSelection(int x) const +{ + if (m_selstart >= m_selend) + return false; + int pos = xToPos(x, QTextLine::CursorOnCharacter); + return pos >= m_selstart && pos < m_selend; +} + +inline int QLineControl::cursor() const +{ + return m_cursor; +} + +inline int QLineControl::preeditCursor() const +{ + return m_preeditCursor; +} + +inline int QLineControl::cursorWidth() const +{ + return m_cursorWidth; +} + +inline void QLineControl::setCursorWidth(int value) +{ + m_cursorWidth = value; +} + +inline void QLineControl::cursorForward(bool mark, int steps) +{ + int c = m_cursor; + if (steps > 0) { + while (steps--) + c = m_textLayout.nextCursorPosition(c); + } else if (steps < 0) { + while (steps++) + c = m_textLayout.previousCursorPosition(c); + } + moveCursor(c, mark); +} + +inline void QLineControl::cursorWordForward(bool mark) +{ + moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); +} + +inline void QLineControl::home(bool mark) +{ + moveCursor(0, mark); +} + +inline void QLineControl::end(bool mark) +{ + moveCursor(text().length(), mark); +} + +inline void QLineControl::cursorWordBackward(bool mark) +{ + moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); +} + +inline qreal QLineControl::cursorToX(int cursor) const +{ + return m_textLayout.lineAt(0).cursorToX(cursor); +} + +inline qreal QLineControl::cursorToX() const +{ + return cursorToX(m_cursor); +} + +inline bool QLineControl::isReadOnly() const +{ + return m_readOnly; +} + +inline void QLineControl::setReadOnly(bool enable) +{ + m_readOnly = enable; +} + +inline QString QLineControl::text() const +{ + QString res = m_maskData ? stripString(m_text) : m_text; + return (res.isNull() ? QString::fromLatin1("") : res); +} + +inline void QLineControl::setText(const QString &txt) +{ + internalSetText(txt, -1, false); +} + +inline QString QLineControl::displayText() const +{ + return m_textLayout.text(); +} + +inline void QLineControl::deselect() +{ + internalDeselect(); + finishChange(); +} + +inline void QLineControl::selectAll() +{ + m_selstart = m_selend = m_cursor = 0; + moveCursor(m_text.length(), true); +} + +inline void QLineControl::undo() +{ + internalUndo(); + finishChange(-1, true); +} + +inline void QLineControl::redo() +{ + internalRedo(); + finishChange(); +} + +inline uint QLineControl::echoMode() const +{ + return m_echoMode; +} + +inline void QLineControl::setEchoMode(uint mode) +{ + m_echoMode = mode; + m_passwordEchoEditing = false; + updateDisplayText(); +} + +inline void QLineControl::setMaxLength(int maxLength) +{ + if (m_maskData) + return; + m_maxLength = maxLength; + setText(m_text); +} + +inline int QLineControl::maxLength() const +{ + return m_maxLength; +} + +inline const QValidator *QLineControl::validator() const +{ + return m_validator; +} + +inline void QLineControl::setValidator(const QValidator *v) +{ + m_validator = const_cast<QValidator*>(v); +} + +#ifndef QT_NO_COMPLETER +inline QCompleter *QLineControl::completer() const +{ + return m_completer; +} + +/* Note that you must set the widget for the completer seperately */ +inline void QLineControl::setCompleter(const QCompleter* c) +{ + m_completer = const_cast<QCompleter*>(c); +} +#endif + +inline void QLineControl::setCursorPosition(int pos) +{ + if (pos < 0) + pos = 0; + if (pos < m_text.length()) + moveCursor(pos); +} + +inline int QLineControl::cursorPosition() const +{ + return m_cursor; +} + +inline bool QLineControl::hasAcceptableInput() const +{ + return hasAcceptableInput(m_text); +} + +inline QString QLineControl::inputMask() const +{ + return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); +} + +inline void QLineControl::setInputMask(const QString &mask) +{ + parseInputMask(mask); + if (m_maskData) + moveCursor(nextMaskBlank(0)); +} + +// input methods +#ifndef QT_NO_IM +inline bool QLineControl::composeMode() const +{ + return !m_textLayout.preeditAreaText().isEmpty(); +} + +inline void QLineControl::setPreeditArea(int cursor, const QString &text) +{ + m_textLayout.setPreeditArea(cursor, text); +} +#endif + +inline QString QLineControl::preeditAreaText() const +{ + return m_textLayout.preeditAreaText(); +} + +inline bool QLineControl::passwordEchoEditing() const +{ + return m_passwordEchoEditing; +} + +inline QChar QLineControl::passwordCharacter() const +{ + return m_passwordCharacter; +} + +inline void QLineControl::setPasswordCharacter(const QChar &character) +{ + m_passwordCharacter = character; + updateDisplayText(); +} + +inline Qt::LayoutDirection QLineControl::layoutDirection() const +{ + return m_layoutDirection; +} + +inline void QLineControl::setLayoutDirection(Qt::LayoutDirection direction) +{ + if (direction != m_layoutDirection) { + m_layoutDirection = direction; + updateDisplayText(); + } +} + +inline void QLineControl::setFont(const QFont &font) +{ + m_textLayout.setFont(font); + updateDisplayText(); +} + +inline int QLineControl::cursorBlinkPeriod() const +{ + return m_blinkPeriod; +} + +inline QString QLineControl::cancelText() const +{ + return m_cancelText; +} + +inline void QLineControl::setCancelText(const QString &text) +{ + m_cancelText = text; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QT_NO_LINEEDIT + +#endif // QLINECONTROL_P_H diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index c7f3e97..e0f5bc9 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -86,21 +86,12 @@ #include <limits.h> -#define verticalMargin 1 -#define horizontalMargin 2 - QT_BEGIN_NAMESPACE #ifdef Q_WS_MAC extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp #endif -static inline bool shouldEnableInputMethod(QLineEdit *lineedit) -{ - const QLineEdit::EchoMode mode = lineedit->echoMode(); - return !lineedit->isReadOnly() && (mode == QLineEdit::Normal || mode == QLineEdit::PasswordEchoOnEdit); -} - /*! Initialize \a option with the values from this QLineEdit. This method is useful for subclasses when they need a QStyleOptionFrame or QStyleOptionFrameV2, but don't want @@ -122,7 +113,7 @@ void QLineEdit::initStyleOption(QStyleOptionFrame *option) const : 0; option->midLineWidth = 0; option->state |= QStyle::State_Sunken; - if (d->readOnly) + if (d->control->isReadOnly()) option->state |= QStyle::State_ReadOnly; #ifdef QT_KEYPAD_NAVIGATION if (hasEditFocus()) @@ -350,14 +341,9 @@ QLineEdit::QLineEdit(const QString& contents, const QString &inputMask, QWidget* { Q_D(QLineEdit); setObjectName(QString::fromAscii(name)); - d->parseInputMask(inputMask); - if (d->maskData) { - QString ms = d->maskString(0, contents); - d->init(ms + d->clearString(ms.length(), d->maxLength - ms.length())); - d->cursor = d->nextMaskBlank(ms.length()); - } else { - d->init(contents); - } + d->init(contents); + d->control->setInputMask(inputMask); + d->control->moveCursor(d->control->nextMaskBlank(contents.length())); } #endif @@ -388,19 +374,13 @@ QLineEdit::~QLineEdit() QString QLineEdit::text() const { Q_D(const QLineEdit); - QString res = d->text; - if (d->maskData) - res = d->stripString(d->text); - return (res.isNull() ? QString::fromLatin1("") : res); + return d->control->text(); } void QLineEdit::setText(const QString& text) { Q_D(QLineEdit); - d->setText(text, -1, false); -#ifdef QT_KEYPAD_NAVIGATION - d->origText = d->text; -#endif + d->control->setText(text); } @@ -421,17 +401,7 @@ void QLineEdit::setText(const QString& text) QString QLineEdit::displayText() const { Q_D(const QLineEdit); - if (d->echoMode == NoEcho) - return QString::fromLatin1(""); - QString res = d->text; - - if (d->echoMode == Password || (d->echoMode == PasswordEchoOnEdit - && !d->passwordEchoEditing)) { - QStyleOptionFrameV2 opt; - initStyleOption(&opt); - res.fill(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this)); - } - return (res.isNull() ? QString::fromLatin1("") : res); + return d->control->displayText(); } @@ -456,20 +426,15 @@ QString QLineEdit::displayText() const int QLineEdit::maxLength() const { Q_D(const QLineEdit); - return d->maxLength; + return d->control->maxLength(); } void QLineEdit::setMaxLength(int maxLength) { Q_D(QLineEdit); - if (d->maskData) - return; - d->maxLength = maxLength; - setText(d->text); + d->control->setMaxLength(maxLength); } - - /*! \property QLineEdit::frame \brief whether the line edit draws itself with a frame @@ -536,22 +501,20 @@ void QLineEdit::setFrame(bool enable) QLineEdit::EchoMode QLineEdit::echoMode() const { Q_D(const QLineEdit); - return (EchoMode) d->echoMode; + return (EchoMode) d->control->echoMode(); } void QLineEdit::setEchoMode(EchoMode mode) { Q_D(QLineEdit); - if (mode == (EchoMode)d->echoMode) + if (mode == (EchoMode)d->control->echoMode()) return; - setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this)); - d->echoMode = mode; - d->passwordEchoEditing = false; - d->updateTextLayout(); + setAttribute(Qt::WA_InputMethodEnabled, d->shouldEnableInputMethod()); + d->control->setEchoMode(mode); update(); #ifdef Q_WS_MAC if (hasFocus()) - qt_mac_secure_keyboard(d->echoMode == Password || d->echoMode == NoEcho); + qt_mac_secure_keyboard(mode == Password || mode == NoEcho); #endif } @@ -567,7 +530,7 @@ void QLineEdit::setEchoMode(EchoMode mode) const QValidator * QLineEdit::validator() const { Q_D(const QLineEdit); - return d->validator; + return d->control->validator(); } /*! @@ -585,7 +548,7 @@ const QValidator * QLineEdit::validator() const void QLineEdit::setValidator(const QValidator *v) { Q_D(QLineEdit); - d->validator = const_cast<QValidator*>(v); + d->control->setValidator(v); } #endif // QT_NO_VALIDATOR @@ -609,23 +572,23 @@ void QLineEdit::setValidator(const QValidator *v) void QLineEdit::setCompleter(QCompleter *c) { Q_D(QLineEdit); - if (c == d->completer) + if (c == d->control->completer()) return; - if (d->completer) { - disconnect(d->completer, 0, this, 0); - d->completer->setWidget(0); - if (d->completer->parent() == this) - delete d->completer; + if (d->control->completer()) { + disconnect(d->control->completer(), 0, this, 0); + d->control->completer()->setWidget(0); + if (d->control->completer()->parent() == this) + delete d->control->completer(); } - d->completer = c; + d->control->setCompleter(c); if (!c) return; if (c->widget() == 0) c->setWidget(this); if (hasFocus()) { - QObject::connect(d->completer, SIGNAL(activated(QString)), + QObject::connect(d->control->completer(), SIGNAL(activated(QString)), this, SLOT(setText(QString))); - QObject::connect(d->completer, SIGNAL(highlighted(QString)), + QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)), this, SLOT(_q_completionHighlighted(QString))); } } @@ -638,83 +601,9 @@ void QLineEdit::setCompleter(QCompleter *c) QCompleter *QLineEdit::completer() const { Q_D(const QLineEdit); - return d->completer; -} - -// looks for an enabled item iterating forward(dir=1)/backward(dir=-1) from the -// current row based. dir=0 indicates a new completion prefix was set. -bool QLineEditPrivate::advanceToEnabledItem(int dir) -{ - int start = completer->currentRow(); - if (start == -1) - return false; - int i = start + dir; - if (dir == 0) dir = 1; - do { - if (!completer->setCurrentRow(i)) { - if (!completer->wrapAround()) - break; - i = i > 0 ? 0 : completer->completionCount() - 1; - } else { - QModelIndex currentIndex = completer->currentIndex(); - if (completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled) - return true; - i += dir; - } - } while (i != start); - - completer->setCurrentRow(start); // restore - return false; -} - -void QLineEditPrivate::complete(int key) -{ - if (!completer || readOnly || echoMode != QLineEdit::Normal) - return; - - if (completer->completionMode() == QCompleter::InlineCompletion) { - if (key == Qt::Key_Backspace) - return; - int n = 0; - if (key == Qt::Key_Up || key == Qt::Key_Down) { - if (selend != 0 && selend != text.length()) - return; - QString prefix = hasSelectedText() ? text.left(selstart) : text; - if (text.compare(completer->currentCompletion(), completer->caseSensitivity()) != 0 - || prefix.compare(completer->completionPrefix(), completer->caseSensitivity()) != 0) { - completer->setCompletionPrefix(prefix); - } else { - n = (key == Qt::Key_Up) ? -1 : +1; - } - } else { - completer->setCompletionPrefix(text); - } - if (!advanceToEnabledItem(n)) - return; - } else { -#ifndef QT_KEYPAD_NAVIGATION - if (text.isEmpty()) { - completer->popup()->hide(); - return; - } -#endif - completer->setCompletionPrefix(text); - } - - completer->complete(); + return d->control->completer(); } -void QLineEditPrivate::_q_completionHighlighted(QString newText) -{ - Q_Q(QLineEdit); - if (completer->completionMode() != QCompleter::InlineCompletion) - q->setText(newText); - else { - int c = cursor; - q->setText(text.left(c) + newText.mid(c)); - q->setSelection(text.length(), c - newText.length()); - } -} #endif // QT_NO_COMPLETER /*! @@ -729,10 +618,10 @@ QSize QLineEdit::sizeHint() const Q_D(const QLineEdit); ensurePolished(); QFontMetrics fm(font()); - int h = qMax(fm.lineSpacing(), 14) + 2*verticalMargin + int h = qMax(fm.lineSpacing(), 14) + 2*d->verticalMargin + d->topTextMargin + d->bottomTextMargin + d->topmargin + d->bottommargin; - int w = fm.width(QLatin1Char('x')) * 17 + 2*horizontalMargin + int w = fm.width(QLatin1Char('x')) * 17 + 2*d->horizontalMargin + d->leftTextMargin + d->rightTextMargin + d->leftmargin + d->rightmargin; // "some" QStyleOptionFrameV2 opt; @@ -753,7 +642,7 @@ QSize QLineEdit::minimumSizeHint() const Q_D(const QLineEdit); ensurePolished(); QFontMetrics fm = fontMetrics(); - int h = fm.height() + qMax(2*verticalMargin, fm.leading()) + int h = fm.height() + qMax(2*d->verticalMargin, fm.leading()) + d->topmargin + d->bottommargin; int w = fm.maxWidth() + d->leftmargin + d->rightmargin; QStyleOptionFrameV2 opt; @@ -775,17 +664,13 @@ QSize QLineEdit::minimumSizeHint() const int QLineEdit::cursorPosition() const { Q_D(const QLineEdit); - return d->cursor; + return d->control->cursorPosition(); } void QLineEdit::setCursorPosition(int pos) { Q_D(QLineEdit); - if (pos < 0) - pos = 0; - - if (pos <= d->text.length()) - d->moveCursor(pos); + d->control->setCursorPosition(pos); } /*! @@ -807,22 +692,17 @@ int QLineEdit::cursorPositionAt(const QPoint &pos) bool QLineEdit::validateAndSet(const QString &newText, int newPos, int newMarkAnchor, int newMarkDrag) { - Q_D(QLineEdit); - int priorState = d->undoState; - d->selstart = 0; - d->selend = d->text.length(); - d->removeSelectedText(); - d->insert(newText); - d->finishChange(priorState); - if (d->undoState > priorState) { - d->cursor = newPos; - d->selstart = qMin(newMarkAnchor, newMarkDrag); - d->selend = qMax(newMarkAnchor, newMarkDrag); - update(); - d->emitCursorPositionChanged(); - return true; + // The suggested functions above in the docs don't seem to validate, + // below code tries to mimic previous behaviour. + QString oldText = text(); + setText(newText); + if(!hasAcceptableInput()){ + setText(oldText); + return false; } - return false; + setCursorPosition(newPos); + setSelection(qMin(newMarkAnchor, newMarkDrag), qAbs(newMarkAnchor - newMarkDrag)); + return true; } #endif //QT3_SUPPORT @@ -863,15 +743,7 @@ void QLineEdit::setAlignment(Qt::Alignment alignment) void QLineEdit::cursorForward(bool mark, int steps) { Q_D(QLineEdit); - int cursor = d->cursor; - if (steps > 0) { - while(steps--) - cursor = d->textLayout.nextCursorPosition(cursor); - } else if (steps < 0) { - while (steps++) - cursor = d->textLayout.previousCursorPosition(cursor); - } - d->moveCursor(cursor, mark); + d->control->cursorForward(mark, steps); } @@ -896,7 +768,7 @@ void QLineEdit::cursorBackward(bool mark, int steps) void QLineEdit::cursorWordForward(bool mark) { Q_D(QLineEdit); - d->moveCursor(d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords), mark); + d->control->cursorWordForward(mark); } /*! @@ -909,7 +781,7 @@ void QLineEdit::cursorWordForward(bool mark) void QLineEdit::cursorWordBackward(bool mark) { Q_D(QLineEdit); - d->moveCursor(d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords), mark); + d->control->cursorWordBackward(mark); } @@ -924,26 +796,7 @@ void QLineEdit::cursorWordBackward(bool mark) void QLineEdit::backspace() { Q_D(QLineEdit); - int priorState = d->undoState; - if (d->hasSelectedText()) { - d->removeSelectedText(); - } else if (d->cursor) { - --d->cursor; - if (d->maskData) - d->cursor = d->prevMaskBlank(d->cursor); - QChar uc = d->text.at(d->cursor); - if (d->cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { - // second half of a surrogate, check if we have the first half as well, - // if yes delete both at once - uc = d->text.at(d->cursor - 1); - if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) { - d->del(true); - --d->cursor; - } - } - d->del(true); - } - d->finishChange(priorState); + d->control->backspace(); } /*! @@ -957,15 +810,7 @@ void QLineEdit::backspace() void QLineEdit::del() { Q_D(QLineEdit); - int priorState = d->undoState; - if (d->hasSelectedText()) { - d->removeSelectedText(); - } else { - int n = d->textLayout.nextCursorPosition(d->cursor) - d->cursor; - while (n--) - d->del(); - } - d->finishChange(priorState); + d->control->del(); } /*! @@ -980,7 +825,7 @@ void QLineEdit::del() void QLineEdit::home(bool mark) { Q_D(QLineEdit); - d->moveCursor(0, mark); + d->control->home(mark); } /*! @@ -995,7 +840,7 @@ void QLineEdit::home(bool mark) void QLineEdit::end(bool mark) { Q_D(QLineEdit); - d->moveCursor(d->text.length(), mark); + d->control->end(mark); } @@ -1020,16 +865,13 @@ void QLineEdit::end(bool mark) bool QLineEdit::isModified() const { Q_D(const QLineEdit); - return d->modifiedState != d->undoState; + return d->control->isModified(); } void QLineEdit::setModified(bool modified) { Q_D(QLineEdit); - if (modified) - d->modifiedState = -1; - else - d->modifiedState = d->undoState; + d->control->setModified(modified); } @@ -1057,7 +899,7 @@ Use setModified(false) instead. bool QLineEdit::hasSelectedText() const { Q_D(const QLineEdit); - return d->hasSelectedText(); + return d->control->hasSelectedText(); } /*! @@ -1075,9 +917,7 @@ bool QLineEdit::hasSelectedText() const QString QLineEdit::selectedText() const { Q_D(const QLineEdit); - if (d->hasSelectedText()) - return d->text.mid(d->selstart, d->selend - d->selstart); - return QString(); + return d->control->selectedText(); } /*! @@ -1090,7 +930,7 @@ QString QLineEdit::selectedText() const int QLineEdit::selectionStart() const { Q_D(const QLineEdit); - return d->hasSelectedText() ? d->selstart : -1; + return d->control->selectionStart(); } @@ -1120,9 +960,10 @@ void QLineEdit::setEdited(bool on) { setModified(on); } int QLineEdit::characterAt(int xpos, QChar *chr) const { Q_D(const QLineEdit); - int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + horizontalMargin); - if (chr && pos < (int) d->text.length()) - *chr = d->text.at(pos); + int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + d->horizontalMargin); + QString txt = d->control->text(); + if (chr && pos < (int) txt.length()) + *chr = txt.at(pos); return pos; } @@ -1133,9 +974,9 @@ int QLineEdit::characterAt(int xpos, QChar *chr) const bool QLineEdit::getSelection(int *start, int *end) { Q_D(QLineEdit); - if (d->hasSelectedText() && start && end) { - *start = d->selstart; - *end = d->selend; + if (d->control->hasSelectedText() && start && end) { + *start = selectionStart(); + *end = *start + selectedText().length(); return true; } return false; @@ -1153,30 +994,19 @@ bool QLineEdit::getSelection(int *start, int *end) void QLineEdit::setSelection(int start, int length) { Q_D(QLineEdit); - if (start < 0 || start > (int)d->text.length()) { + if (start < 0 || start > (int)d->control->text().length()) { qWarning("QLineEdit::setSelection: Invalid start position (%d)", start); return; - } else { - if (length > 0) { - d->selstart = start; - d->selend = qMin(start + length, (int)d->text.length()); - d->cursor = d->selend; - } else { - d->selstart = qMax(start + length, 0); - d->selend = start; - d->cursor = d->selstart; - } } - if (d->hasSelectedText()){ + d->control->setSelection(start, length); + + if (d->control->hasSelectedText()){ QStyleOptionFrameV2 opt; initStyleOption(&opt); if (!style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this)) d->setCursorVisible(false); } - - update(); - d->emitCursorPositionChanged(); } @@ -1192,7 +1022,7 @@ void QLineEdit::setSelection(int start, int length) bool QLineEdit::isUndoAvailable() const { Q_D(const QLineEdit); - return d->isUndoAvailable(); + return d->control->isUndoAvailable(); } /*! @@ -1208,7 +1038,7 @@ bool QLineEdit::isUndoAvailable() const bool QLineEdit::isRedoAvailable() const { Q_D(const QLineEdit); - return d->isRedoAvailable(); + return d->control->isRedoAvailable(); } /*! @@ -1244,7 +1074,7 @@ void QLineEdit::setDragEnabled(bool b) bool QLineEdit::hasAcceptableInput() const { Q_D(const QLineEdit); - return d->hasAcceptableInput(d->text); + return d->control->hasAcceptableInput(); } /*! @@ -1350,15 +1180,13 @@ void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) con QString QLineEdit::inputMask() const { Q_D(const QLineEdit); - return (d->maskData ? d->inputMask + QLatin1Char(';') + d->blank : QString()); + return d->control->inputMask(); } void QLineEdit::setInputMask(const QString &inputMask) { Q_D(QLineEdit); - d->parseInputMask(inputMask); - if (d->maskData) - d->moveCursor(d->nextMaskBlank(0)); + d->control->setInputMask(inputMask); } /*! @@ -1373,8 +1201,7 @@ void QLineEdit::setInputMask(const QString &inputMask) void QLineEdit::selectAll() { Q_D(QLineEdit); - d->selstart = d->selend = d->cursor = 0; - d->moveCursor(d->text.length(), true); + d->control->selectAll(); } /*! @@ -1386,8 +1213,7 @@ void QLineEdit::selectAll() void QLineEdit::deselect() { Q_D(QLineEdit); - d->deselect(); - d->finishChange(); + d->control->deselect(); } @@ -1402,10 +1228,7 @@ void QLineEdit::insert(const QString &newText) { // q->resetInputContext(); //#### FIX ME IN QT Q_D(QLineEdit); - int priorState = d->undoState; - d->removeSelectedText(); - d->insert(newText); - d->finishChange(priorState); + d->control->insert(newText); } /*! @@ -1416,13 +1239,8 @@ void QLineEdit::insert(const QString &newText) void QLineEdit::clear() { Q_D(QLineEdit); - int priorState = d->undoState; resetInputContext(); - d->selstart = 0; - d->selend = d->text.length(); - d->removeSelectedText(); - d->separate(); - d->finishChange(priorState, /*update*/false, /*edited*/false); + d->control->clear(); } /*! @@ -1435,8 +1253,7 @@ void QLineEdit::undo() { Q_D(QLineEdit); resetInputContext(); - d->undo(); - d->finishChange(-1, true); + d->control->undo(); } /*! @@ -1447,8 +1264,7 @@ void QLineEdit::redo() { Q_D(QLineEdit); resetInputContext(); - d->redo(); - d->finishChange(); + d->control->redo(); } @@ -1470,16 +1286,16 @@ void QLineEdit::redo() bool QLineEdit::isReadOnly() const { Q_D(const QLineEdit); - return d->readOnly; + return d->control->isReadOnly(); } void QLineEdit::setReadOnly(bool enable) { Q_D(QLineEdit); - if (d->readOnly != enable) { - d->readOnly = enable; - setAttribute(Qt::WA_MacShowFocusRect, !d->readOnly); - setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this)); + if (d->control->isReadOnly() != enable) { + d->control->setReadOnly(enable); + setAttribute(Qt::WA_MacShowFocusRect, !enable); + setAttribute(Qt::WA_InputMethodEnabled, d->shouldEnableInputMethod()); #ifndef QT_NO_CURSOR setCursor(enable ? Qt::ArrowCursor : Qt::IBeamCursor); #endif @@ -1518,7 +1334,7 @@ void QLineEdit::cut() void QLineEdit::copy() const { Q_D(const QLineEdit); - d->copy(); + d->control->copy(); } /*! @@ -1535,23 +1351,7 @@ void QLineEdit::copy() const void QLineEdit::paste() { Q_D(QLineEdit); - if (echoMode() == PasswordEchoOnEdit && !d->passwordEchoEditing) { - // Clear the edit and reset to normal echo mode when pasting; the echo - // mode switches back when the edit loses focus. ### changes a public - // property, resets current content - d->updatePasswordEchoEditing(true); - clear(); - } - insert(QApplication::clipboard()->text(QClipboard::Clipboard)); -} - -void QLineEditPrivate::copy(bool clipboard) const -{ - Q_Q(const QLineEdit); - QString t = q->selectedText(); - if (!t.isEmpty() && echoMode == QLineEdit::Normal) { - QApplication::clipboard()->setText(t, clipboard ? QClipboard::Clipboard : QClipboard::Selection); - } + d->control->paste(); } #endif // !QT_NO_CLIPBOARD @@ -1561,57 +1361,10 @@ void QLineEditPrivate::copy(bool clipboard) const bool QLineEdit::event(QEvent * e) { Q_D(QLineEdit); -#ifndef QT_NO_SHORTCUT - if (e->type() == QEvent::ShortcutOverride && !d->readOnly) { - QKeyEvent* ke = (QKeyEvent*) e; - if (ke == QKeySequence::Copy - || ke == QKeySequence::Paste - || ke == QKeySequence::Cut - || ke == QKeySequence::Redo - || ke == QKeySequence::Undo - || ke == QKeySequence::MoveToNextWord - || ke == QKeySequence::MoveToPreviousWord - || ke == QKeySequence::MoveToStartOfDocument - || ke == QKeySequence::MoveToEndOfDocument - || ke == QKeySequence::SelectNextWord - || ke == QKeySequence::SelectPreviousWord - || ke == QKeySequence::SelectStartOfLine - || ke == QKeySequence::SelectEndOfLine - || ke == QKeySequence::SelectStartOfBlock - || ke == QKeySequence::SelectEndOfBlock - || ke == QKeySequence::SelectStartOfDocument - || ke == QKeySequence::SelectAll - || ke == QKeySequence::SelectEndOfDocument) { - ke->accept(); - } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier - || ke->modifiers() == Qt::KeypadModifier) { - if (ke->key() < Qt::Key_Escape) { - ke->accept(); - } else { - switch (ke->key()) { - case Qt::Key_Delete: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_Backspace: - case Qt::Key_Left: - case Qt::Key_Right: - ke->accept(); - default: - break; - } - } - } - } else -#endif - if (e->type() == QEvent::Timer) { + if (e->type() == QEvent::Timer) { // should be timerEvent, is here for binary compatibility int timerId = ((QTimerEvent*)e)->timerId(); - if (timerId == d->cursorTimer) { - QStyleOptionFrameV2 opt; - initStyleOption(&opt); - if(!hasSelectedText() - || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this)) - d->setCursorVisible(!d->cursorVisible); + if (false) { #ifndef QT_NO_DRAGANDDROP } else if (timerId == d->dndTimer.timerId()) { d->drag(); @@ -1619,60 +1372,31 @@ bool QLineEdit::event(QEvent * e) } else if (timerId == d->tripleClickTimer.timerId()) d->tripleClickTimer.stop(); -#ifdef QT_KEYPAD_NAVIGATION - else if (timerId == d->deleteAllTimer.timerId()) { - d->deleteAllTimer.stop(); - clear(); - } -#endif } else if (e->type() == QEvent::ContextMenu) { #ifndef QT_NO_IM - if (d->composeMode()) + if (d->control->composeMode()) return true; #endif - d->separate(); + //d->separate(); } else if (e->type() == QEvent::WindowActivate) { QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate())); + }else if(e->type() == QEvent::ShortcutOverride){ + d->control->processEvent(e); } + #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled()) { - if ((e->type() == QEvent::KeyPress) || (e->type() == QEvent::KeyRelease)) { - QKeyEvent *ke = (QKeyEvent *)e; - if (ke->key() == Qt::Key_Back) { - if (ke->isAutoRepeat()) { - // Swallow it. We don't want back keys running amok. - ke->accept(); - return true; - } - if ((e->type() == QEvent::KeyRelease) - && !isReadOnly() - && d->deleteAllTimer.isActive()) { - d->deleteAllTimer.stop(); - backspace(); - ke->accept(); - return true; - } - } - } else if (e->type() == QEvent::EnterEditFocus) { + if (e->type() == QEvent::EnterEditFocus) { end(false); - if (!d->cursorTimer) { - int cft = QApplication::cursorFlashTime(); - d->cursorTimer = cft ? startTimer(cft/2) : -1; - } + int cft = QApplication::cursorFlashTime(); + d->control->setCursorBlinkPeriod(cft/2); } else if (e->type() == QEvent::LeaveEditFocus) { d->setCursorVisible(false); - if (d->cursorTimer > 0) - killTimer(d->cursorTimer); - d->cursorTimer = 0; - - if (!d->emitingEditingFinished) { - if (hasAcceptableInput() || d->fixup()) { - d->emitingEditingFinished = true; - emit editingFinished(); - d->emitingEditingFinished = false; - } - } + d->control->setCursorBlinkPeriod(0); + if (d->control->hasAcceptableInput() || d->control->fixup()) + emit editingFinished(); } + return true; } #endif return QWidget::event(e); @@ -1684,15 +1408,15 @@ void QLineEdit::mousePressEvent(QMouseEvent* e) { Q_D(QLineEdit); if (d->sendMouseEventToInputContext(e)) - return; + return; if (e->button() == Qt::RightButton) return; #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { setEditFocus(true); // Get the completion list to pop up. - if (d->completer) - d->completer->complete(); + if (d->control->completer()) + d->control->completer()->complete(); } #endif if (d->tripleClickTimer.isActive() && (e->pos() - d->tripleClick).manhattanLength() < @@ -1703,18 +1427,16 @@ void QLineEdit::mousePressEvent(QMouseEvent* e) bool mark = e->modifiers() & Qt::ShiftModifier; int cursor = d->xToPos(e->pos().x()); #ifndef QT_NO_DRAGANDDROP - if (!mark && d->dragEnabled && d->echoMode == Normal && - e->button() == Qt::LeftButton && d->inSelection(e->pos().x())) { - d->cursor = cursor; - update(); + if (!mark && d->dragEnabled && d->control->echoMode() == Normal && + e->button() == Qt::LeftButton && d->control->inSelection(e->pos().x())) { + d->control->moveCursor(cursor); d->dndPos = e->pos(); if (!d->dndTimer.isActive()) d->dndTimer.start(QApplication::startDragTime(), this); - d->emitCursorPositionChanged(); } else #endif { - d->moveCursor(cursor, mark); + d->control->moveCursor(cursor, mark); } } @@ -1724,7 +1446,7 @@ void QLineEdit::mouseMoveEvent(QMouseEvent * e) { Q_D(QLineEdit); if (d->sendMouseEventToInputContext(e)) - return; + return; if (e->buttons() & Qt::LeftButton) { #ifndef QT_NO_DRAGANDDROP @@ -1734,7 +1456,7 @@ void QLineEdit::mouseMoveEvent(QMouseEvent * e) } else #endif { - d->moveCursor(d->xToPos(e->pos().x()), true); + d->control->moveCursor(d->xToPos(e->pos().x()), true); } } } @@ -1745,7 +1467,7 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e) { Q_D(QLineEdit); if (d->sendMouseEventToInputContext(e)) - return; + return; #ifndef QT_NO_DRAGANDDROP if (e->button() == Qt::LeftButton) { if (d->dndTimer.isActive()) { @@ -1758,9 +1480,9 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e) #ifndef QT_NO_CLIPBOARD if (QApplication::clipboard()->supportsSelection()) { if (e->button() == Qt::LeftButton) { - d->copy(false); - } else if (!d->readOnly && e->button() == Qt::MidButton) { - d->deselect(); + d->control->copy(QClipboard::Selection); + } else if (!d->control->isReadOnly() && e->button() == Qt::MidButton) { + deselect(); insert(QApplication::clipboard()->text(QClipboard::Selection)); } } @@ -1773,16 +1495,9 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e) { Q_D(QLineEdit); if (d->sendMouseEventToInputContext(e)) - return; + return; if (e->button() == Qt::LeftButton) { - deselect(); - d->cursor = d->xToPos(e->pos().x()); - d->cursor = d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords); - // ## text layout should support end of words. - int end = d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords); - while (end > d->cursor && d->text[end-1].isSpace()) - --end; - d->moveCursor(end, true); + d->control->selectWordAtPos(d->xToPos(e->pos().x())); d->tripleClickTimer.start(QApplication::doubleClickInterval(), this); d->tripleClick = e->pos(); } @@ -1822,65 +1537,15 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e) void QLineEdit::keyPressEvent(QKeyEvent *event) { Q_D(QLineEdit); - - bool inlineCompletionAccepted = false; - -#ifndef QT_NO_COMPLETER - if (d->completer) { - QCompleter::CompletionMode completionMode = d->completer->completionMode(); - if ((completionMode == QCompleter::PopupCompletion - || completionMode == QCompleter::UnfilteredPopupCompletion) - &&d->completer->popup() - && d->completer->popup()->isVisible()) { - // The following keys are forwarded by the completer to the widget - // Ignoring the events lets the completer provide suitable default behavior - switch (event->key()) { - case Qt::Key_Escape: - event->ignore(); - return; - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_F4: -#ifdef QT_KEYPAD_NAVIGATION - case Qt::Key_Select: - if (!QApplication::keypadNavigationEnabled()) - break; -#endif - d->completer->popup()->hide(); // just hide. will end up propagating to parent - default: - break; // normal key processing - } - } else if (completionMode == QCompleter::InlineCompletion) { - switch (event->key()) { - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_F4: -#ifdef QT_KEYPAD_NAVIGATION - case Qt::Key_Select: - if (!QApplication::keypadNavigationEnabled()) - break; -#endif - if (!d->completer->currentCompletion().isEmpty() && d->selend > d->selstart - && d->selend == d->text.length()) { - setText(d->completer->currentCompletion()); - inlineCompletionAccepted = true; - } - default: - break; // normal key processing - } - } - } -#endif // QT_NO_COMPLETER - -#ifdef QT_KEYPAD_NAVIGATION + #ifdef QT_KEYPAD_NAVIGATION bool select = false; switch (event->key()) { case Qt::Key_Select: if (QApplication::keypadNavigationEnabled()) { if (hasEditFocus()) { setEditFocus(false); - if (d->completer && d->completer->popup()->isVisible()) - d->completer->popup()->hide(); + if (d->control->completer() && d->control->completer()->popup()->isVisible()) + d->control->completer()->popup()->hide(); select = true; } } @@ -1916,273 +1581,7 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) return; // Just start. No action. } #endif - - if (echoMode() == PasswordEchoOnEdit - && !d->passwordEchoEditing - && !isReadOnly() - && !event->text().isEmpty() -#ifdef QT_KEYPAD_NAVIGATION - && event->key() != Qt::Key_Select - && event->key() != Qt::Key_Up - && event->key() != Qt::Key_Down - && event->key() != Qt::Key_Back -#endif - && !(event->modifiers() & Qt::ControlModifier)) { - // Clear the edit and reset to normal echo mode while editing; the - // echo mode switches back when the edit loses focus. ### changes a - // public property, resets current content. dubious code; you can - // navigate with keys up, down, back, and select(?), but if you press - // "left" or "right" it clears? - d->updatePasswordEchoEditing(true); - clear(); - } - - d->setCursorVisible(true); - if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { - if (hasAcceptableInput() || d->fixup()) { - emit returnPressed(); - d->emitingEditingFinished = true; - emit editingFinished(); - d->emitingEditingFinished = false; - } - if (inlineCompletionAccepted) - event->accept(); - else - event->ignore(); - return; - } - bool unknown = false; - - if (false) { - } -#ifndef QT_NO_SHORTCUT - else if (event == QKeySequence::Undo) { - if (!d->readOnly) - undo(); - } - else if (event == QKeySequence::Redo) { - if (!d->readOnly) - redo(); - } - else if (event == QKeySequence::SelectAll) { - selectAll(); - } -#ifndef QT_NO_CLIPBOARD - else if (event == QKeySequence::Copy) { - copy(); - } - else if (event == QKeySequence::Paste) { - if (!d->readOnly) - paste(); - } - else if (event == QKeySequence::Cut) { - if (!d->readOnly) { - cut(); - } - } - else if (event == QKeySequence::DeleteEndOfLine) { - if (!d->readOnly) { - setSelection(d->cursor, d->text.size()); - copy(); - del(); - } - } -#endif //QT_NO_CLIPBOARD - else if (event == QKeySequence::MoveToStartOfLine) { - home(0); - } - else if (event == QKeySequence::MoveToEndOfLine) { - end(0); - } - else if (event == QKeySequence::SelectStartOfLine) { - home(1); - } - else if (event == QKeySequence::SelectEndOfLine) { - end(1); - } - else if (event == QKeySequence::MoveToNextChar) { -#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER) - if (d->hasSelectedText()) { -#else - if (d->hasSelectedText() && d->completer - && d->completer->completionMode() == QCompleter::InlineCompletion) { -#endif - d->moveCursor(d->selend, false); - } else { - cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1); - } - } - else if (event == QKeySequence::SelectNextChar) { - cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1); - } - else if (event == QKeySequence::MoveToPreviousChar) { -#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER) - if (d->hasSelectedText()) { -#else - if (d->hasSelectedText() && d->completer - && d->completer->completionMode() == QCompleter::InlineCompletion) { -#endif - d->moveCursor(d->selstart, false); - } else { - cursorBackward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1); - } - } - else if (event == QKeySequence::SelectPreviousChar) { - cursorBackward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1); - } - else if (event == QKeySequence::MoveToNextWord) { - if (echoMode() == Normal) - layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0); - else - layoutDirection() == Qt::LeftToRight ? end(0) : home(0); - } - else if (event == QKeySequence::MoveToPreviousWord) { - if (echoMode() == Normal) - layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0); - else if (!d->readOnly) { - layoutDirection() == Qt::LeftToRight ? home(0) : end(0); - } - } - else if (event == QKeySequence::SelectNextWord) { - if (echoMode() == Normal) - layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1); - else - layoutDirection() == Qt::LeftToRight ? end(1) : home(1); - } - else if (event == QKeySequence::SelectPreviousWord) { - if (echoMode() == Normal) - layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1); - else - layoutDirection() == Qt::LeftToRight ? home(1) : end(1); - } - else if (event == QKeySequence::Delete) { - if (!d->readOnly) - del(); - } - else if (event == QKeySequence::DeleteEndOfWord) { - if (!d->readOnly) { - cursorWordForward(true); - del(); - } - } - else if (event == QKeySequence::DeleteStartOfWord) { - if (!d->readOnly) { - cursorWordBackward(true); - del(); - } - } -#endif // QT_NO_SHORTCUT - else { -#ifdef Q_WS_MAC - if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) { - Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier); - if (myModifiers & Qt::ShiftModifier) { - if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier) - || myModifiers == (Qt::AltModifier|Qt::ShiftModifier) - || myModifiers == Qt::ShiftModifier) { - - event->key() == Qt::Key_Up ? home(1) : end(1); - } - } else { - if ((myModifiers == Qt::ControlModifier - || myModifiers == Qt::AltModifier - || myModifiers == Qt::NoModifier)) { - event->key() == Qt::Key_Up ? home(0) : end(0); - } - } - } -#endif - if (event->modifiers() & Qt::ControlModifier) { - switch (event->key()) { - case Qt::Key_Backspace: - if (!d->readOnly) { - cursorWordBackward(true); - del(); - } - break; -#ifndef QT_NO_COMPLETER - case Qt::Key_Up: - case Qt::Key_Down: - d->complete(event->key()); - break; -#endif -#if defined(Q_WS_X11) - case Qt::Key_E: - end(0); - break; - - case Qt::Key_U: - if (!d->readOnly) { - setSelection(0, d->text.size()); -#ifndef QT_NO_CLIPBOARD - copy(); -#endif - del(); - } - break; -#endif - default: - unknown = true; - } - } else { // ### check for *no* modifier - switch (event->key()) { - case Qt::Key_Backspace: - if (!d->readOnly) { - backspace(); -#ifndef QT_NO_COMPLETER - d->complete(Qt::Key_Backspace); -#endif - } - break; -#ifdef QT_KEYPAD_NAVIGATION - case Qt::Key_Back: - if (QApplication::keypadNavigationEnabled() && !event->isAutoRepeat() - && !isReadOnly()) { - if (text().length() == 0) { - setText(d->origText); - - if (d->passwordEchoEditing) - d->updatePasswordEchoEditing(false); - - setEditFocus(false); - } else if (!d->deleteAllTimer.isActive()) { - d->deleteAllTimer.start(750, this); - } - } else { - unknown = true; - } - break; -#endif - - default: - unknown = true; - } - } - } - - if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) { - setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft); - d->updateTextLayout(); - update(); - unknown = false; - } - - if (unknown && !d->readOnly) { - QString t = event->text(); - if (!t.isEmpty() && t.at(0).isPrint()) { - insert(t); -#ifndef QT_NO_COMPLETER - d->complete(event->key()); -#endif - event->accept(); - return; - } - } - - if (unknown) - event->ignore(); - else - event->accept(); + d->control->processKeyEvent(event); } /*! @@ -2196,50 +1595,17 @@ QRect QLineEdit::cursorRect() const return d->cursorRect(); } -/*! - This function is not intended as polymorphic usage. Just a shared code - fragment that calls QInputContext::mouseHandler for this - class. -*/ -bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e ) -{ -#if !defined QT_NO_IM - Q_Q(QLineEdit); - if ( composeMode() ) { - int tmp_cursor = xToPos(e->pos().x()); - int mousePos = tmp_cursor - cursor; - if ( mousePos < 0 || mousePos > textLayout.preeditAreaText().length() ) { - mousePos = -1; - // don't send move events outside the preedit area - if ( e->type() == QEvent::MouseMove ) - return true; - } - - QInputContext *qic = q->inputContext(); - if ( qic ) - // may be causing reset() in some input methods - qic->mouseHandler(mousePos, e); - if (!textLayout.preeditAreaText().isEmpty()) - return true; - } -#else - Q_UNUSED(e); -#endif - - return false; -} - /*! \reimp */ void QLineEdit::inputMethodEvent(QInputMethodEvent *e) { Q_D(QLineEdit); - if (d->readOnly) { + if (d->control->isReadOnly()) { e->ignore(); return; } - if (echoMode() == PasswordEchoOnEdit && !d->passwordEchoEditing) { + if (echoMode() == PasswordEchoOnEdit && !d->control->passwordEchoEditing()) { // Clear the edit and reset to normal echo mode while entering input // method data; the echo mode switches back when the edit loses focus. // ### changes a public property, resets current content. @@ -2259,55 +1625,11 @@ void QLineEdit::inputMethodEvent(QInputMethodEvent *e) } #endif - int priorState = d->undoState; - d->removeSelectedText(); - - int c = d->cursor; // cursor position after insertion of commit string - if (e->replacementStart() <= 0) - c += e->commitString().length() + qMin(-e->replacementStart(), e->replacementLength()); - - d->cursor += e->replacementStart(); + d->control->processInputMethodEvent(e); - // insert commit string - if (e->replacementLength()) { - d->selstart = d->cursor; - d->selend = d->selstart + e->replacementLength(); - d->removeSelectedText(); - } - if (!e->commitString().isEmpty()) - d->insert(e->commitString()); - - d->cursor = qMin(c, d->text.length()); - - d->textLayout.setPreeditArea(d->cursor, e->preeditString()); - d->preeditCursor = e->preeditString().length(); - d->hideCursor = false; - QList<QTextLayout::FormatRange> formats; - for (int i = 0; i < e->attributes().size(); ++i) { - const QInputMethodEvent::Attribute &a = e->attributes().at(i); - if (a.type == QInputMethodEvent::Cursor) { - d->preeditCursor = a.start; - d->hideCursor = !a.length; - } else if (a.type == QInputMethodEvent::TextFormat) { - QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat(); - if (f.isValid()) { - QTextLayout::FormatRange o; - o.start = a.start + d->cursor; - o.length = a.length; - o.format = f; - formats.append(o); - } - } - } - d->textLayout.setAdditionalFormats(formats); - d->updateTextLayout(); - update(); - if (!e->commitString().isEmpty()) - d->emitCursorPositionChanged(); - d->finishChange(priorState); #ifndef QT_NO_COMPLETER if (!e->commitString().isEmpty()) - d->complete(Qt::Key_unknown); + d->control->complete(Qt::Key_unknown); #endif } @@ -2322,9 +1644,9 @@ QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const case Qt::ImFont: return font(); case Qt::ImCursorPosition: - return QVariant((d->selend - d->selstart == 0) ? d->cursor : d->selend); + return QVariant(d->control->hasSelectedText() ? d->control->selectionEnd() : d->control->cursor()); case Qt::ImSurroundingText: - return QVariant(d->text); + return QVariant(text()); case Qt::ImCurrentSelection: return QVariant(selectedText()); default: @@ -2341,36 +1663,34 @@ void QLineEdit::focusInEvent(QFocusEvent *e) if (e->reason() == Qt::TabFocusReason || e->reason() == Qt::BacktabFocusReason || e->reason() == Qt::ShortcutFocusReason) { - if (d->maskData) - d->moveCursor(d->nextMaskBlank(0)); - else if (!d->hasSelectedText()) + if (!d->control->inputMask().isEmpty()) + d->control->moveCursor(d->control->nextMaskBlank(0)); + else if (!d->control->hasSelectedText()) selectAll(); } #ifdef QT_KEYPAD_NAVIGATION if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && e->reason() == Qt::PopupFocusReason)) #endif - if (!d->cursorTimer) { - int cft = QApplication::cursorFlashTime(); - d->cursorTimer = cft ? startTimer(cft/2) : -1; - } + int cft = QApplication::cursorFlashTime(); + d->control->setCursorBlinkPeriod(cft/2); QStyleOptionFrameV2 opt; initStyleOption(&opt); - if((!hasSelectedText() && d->textLayout.preeditAreaText().isEmpty()) + if((!hasSelectedText() && d->control->preeditAreaText().isEmpty()) || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this)) d->setCursorVisible(true); #ifdef Q_WS_MAC - if (d->echoMode == Password || d->echoMode == NoEcho) + if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho) qt_mac_secure_keyboard(true); #endif #ifdef QT_KEYPAD_NAVIGATION - d->origText = d->text; + d->control->setCancelText(d->text); #endif #ifndef QT_NO_COMPLETER - if (d->completer) { - d->completer->setWidget(this); - QObject::connect(d->completer, SIGNAL(activated(QString)), + if (d->control->completer()) { + d->control->completer()->setWidget(this); + QObject::connect(d->control->completer(), SIGNAL(activated(QString)), this, SLOT(setText(QString))); - QObject::connect(d->completer, SIGNAL(highlighted(QString)), + QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)), this, SLOT(_q_completionHighlighted(QString))); } #endif @@ -2383,7 +1703,7 @@ void QLineEdit::focusInEvent(QFocusEvent *e) void QLineEdit::focusOutEvent(QFocusEvent *e) { Q_D(QLineEdit); - if (d->passwordEchoEditing) { + if (d->control->passwordEchoEditing()) { // Reset the echomode back to PasswordEchoOnEdit when the widget loses // focus. d->updatePasswordEchoEditing(false); @@ -2395,37 +1715,29 @@ void QLineEdit::focusOutEvent(QFocusEvent *e) deselect(); d->setCursorVisible(false); - if (d->cursorTimer > 0) - killTimer(d->cursorTimer); - d->cursorTimer = 0; - + d->control->setCursorBlinkPeriod(0); #ifdef QT_KEYPAD_NAVIGATION // editingFinished() is already emitted on LeaveEditFocus if (!QApplication::keypadNavigationEnabled()) #endif if (reason != Qt::PopupFocusReason || !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) { - if (!d->emitingEditingFinished) { - if (hasAcceptableInput() || d->fixup()) { - d->emitingEditingFinished = true; + if (hasAcceptableInput() || d->control->fixup()) emit editingFinished(); - d->emitingEditingFinished = false; - } - } #ifdef QT3_SUPPORT emit lostFocus(); #endif } #ifdef Q_WS_MAC - if (d->echoMode == Password || d->echoMode == NoEcho) + if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho) qt_mac_secure_keyboard(false); #endif #ifdef QT_KEYPAD_NAVIGATION - d->origText = QString(); + d->control->setCancelText(QString()); #endif #ifndef QT_NO_COMPLETER - if (d->completer) { - QObject::disconnect(d->completer, 0, this, 0); + if (d->control->completer()) { + QObject::disconnect(d->control->completer(), 0, this, 0); } #endif update(); @@ -2455,24 +1767,19 @@ void QLineEdit::paintEvent(QPaintEvent *) Qt::Alignment va = QStyle::visualAlignment(layoutDirection(), QFlag(d->alignment)); switch (va & Qt::AlignVertical_Mask) { case Qt::AlignBottom: - d->vscroll = r.y() + r.height() - fm.height() - verticalMargin; + d->vscroll = r.y() + r.height() - fm.height() - d->verticalMargin; break; case Qt::AlignTop: - d->vscroll = r.y() + verticalMargin; + d->vscroll = r.y() + d->verticalMargin; break; default: //center d->vscroll = r.y() + (r.height() - fm.height() + 1) / 2; break; } - QRect lineRect(r.x() + horizontalMargin, d->vscroll, r.width() - 2*horizontalMargin, fm.height()); - QTextLine line = d->textLayout.lineAt(0); + QRect lineRect(r.x() + d->horizontalMargin, d->vscroll, r.width() - 2*d->horizontalMargin, fm.height()); - int cursor = d->cursor; - if (d->preeditCursor != -1) - cursor += d->preeditCursor; - // locate cursor position - int cix = qRound(line.cursorToX(cursor)); + int cix = qRound(d->control->cursorToX()); // horizontal scrolling. d->hscroll is the left indent from the beginning // of the text line to the left edge of lineRect. we update this value @@ -2482,7 +1789,7 @@ void QLineEdit::paintEvent(QPaintEvent *) // (cix). int minLB = qMax(0, -fm.minLeftBearing()); int minRB = qMax(0, -fm.minRightBearing()); - int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB; + int widthUsed = d->control->width() + minRB; if ((minLB + widthUsed) <= lineRect.width()) { // text fits in lineRect; use hscroll for alignment switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) { @@ -2510,7 +1817,7 @@ void QLineEdit::paintEvent(QPaintEvent *) d->hscroll = widthUsed - lineRect.width() + 1; } // the y offset is there to keep the baseline constant in case we have script changes in the text. - QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->ascent - fm.ascent()); + QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent()); // draw text, selections and cursors #ifndef QT_NO_STYLE_STYLESHEET @@ -2520,33 +1827,23 @@ void QLineEdit::paintEvent(QPaintEvent *) #endif p.setPen(pal.text().color()); - QVector<QTextLayout::FormatRange> selections; + int flags = QLineControl::DrawText; + #ifdef QT_KEYPAD_NAVIGATION if (!QApplication::keypadNavigationEnabled() || hasEditFocus()) #endif - if (d->selstart < d->selend || (d->cursorVisible && d->maskData && !d->readOnly)) { - QTextLayout::FormatRange o; - if (d->selstart < d->selend) { - o.start = d->selstart; - o.length = d->selend - d->selstart; - o.format.setBackground(pal.brush(QPalette::Highlight)); - o.format.setForeground(pal.brush(QPalette::HighlightedText)); - } else { - // mask selection - o.start = d->cursor; - o.length = 1; - o.format.setBackground(pal.brush(QPalette::Text)); - o.format.setForeground(pal.brush(QPalette::Window)); - } - selections.append(o); - } + if (d->control->hasSelectedText() || (d->cursorVisible && !d->control->inputMask().isEmpty() && !d->control->isReadOnly())) + flags |= QLineControl::DrawSelections; // Asian users see an IM selection text as cursor on candidate // selection phase of input method, so the ordinary cursor should be // invisible if we have a preedit string. - d->textLayout.draw(&p, topLeft, selections, r); - if (d->cursorVisible && !d->readOnly && !d->hideCursor) - d->textLayout.drawCursor(&p, topLeft, cursor, style()->pixelMetric(QStyle::PM_TextCursorWidth)); + if (d->cursorVisible && !d->control->isReadOnly()) + flags |= QLineControl::DrawCursor; + + d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth)); + d->control->draw(&p, topLeft, r, flags); + } @@ -2556,12 +1853,11 @@ void QLineEdit::paintEvent(QPaintEvent *) void QLineEdit::dragMoveEvent(QDragMoveEvent *e) { Q_D(QLineEdit); - if (!d->readOnly && e->mimeData()->hasFormat(QLatin1String("text/plain"))) { + if (!d->control->isReadOnly() && e->mimeData()->hasFormat(QLatin1String("text/plain"))) { e->acceptProposedAction(); - d->cursor = d->xToPos(e->pos().x()); + d->control->moveCursor(d->xToPos(e->pos().x()), false); d->cursorVisible = true; update(); - d->emitCursorPositionChanged(); } } @@ -2587,13 +1883,14 @@ void QLineEdit::dropEvent(QDropEvent* e) Q_D(QLineEdit); QString str = e->mimeData()->text(); - if (!str.isNull() && !d->readOnly) { + if (!str.isNull() && !d->control->isReadOnly()) { if (e->source() == this && e->dropAction() == Qt::CopyAction) deselect(); - d->cursor =d->xToPos(e->pos().x()); - int selStart = d->cursor; - int oldSelStart = d->selstart; - int oldSelEnd = d->selend; + int cursorPos = d->xToPos(e->pos().x()); + int selStart = cursorPos; + int oldSelStart = d->control->selectionStart(); + int oldSelEnd = d->control->selectionEnd(); + d->control->moveCursor(cursorPos, false); d->cursorVisible = false; e->acceptProposedAction(); insert(str); @@ -2615,22 +1912,6 @@ void QLineEdit::dropEvent(QDropEvent* e) } } -void QLineEditPrivate::drag() -{ - Q_Q(QLineEdit); - dndTimer.stop(); - QMimeData *data = new QMimeData; - data->setText(q->selectedText()); - QDrag *drag = new QDrag(q); - drag->setMimeData(data); - Qt::DropAction action = drag->start(); - if (action == Qt::MoveAction && !readOnly && drag->target() != q) { - int priorState = undoState; - removeSelectedText(); - finishChange(priorState); - } -} - #endif // QT_NO_DRAGANDDROP #ifndef QT_NO_CONTEXTMENU @@ -2675,37 +1956,39 @@ QMenu *QLineEdit::createStandardContextMenu() popup->setObjectName(QLatin1String("qt_edit_menu")); QAction *action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo)); - action->setEnabled(d->isUndoAvailable()); + action->setEnabled(d->control->isUndoAvailable()); connect(action, SIGNAL(triggered()), SLOT(undo())); action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo)); - action->setEnabled(d->isRedoAvailable()); + action->setEnabled(d->control->isRedoAvailable()); connect(action, SIGNAL(triggered()), SLOT(redo())); popup->addSeparator(); #ifndef QT_NO_CLIPBOARD action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut)); - action->setEnabled(!d->readOnly && d->hasSelectedText() && d->echoMode == QLineEdit::Normal); + action->setEnabled(!d->control->isReadOnly() && d->control->hasSelectedText() + && d->control->echoMode() == QLineEdit::Normal); connect(action, SIGNAL(triggered()), SLOT(cut())); action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy)); - action->setEnabled(d->hasSelectedText() && d->echoMode == QLineEdit::Normal); + action->setEnabled(d->control->hasSelectedText() + && d->control->echoMode() == QLineEdit::Normal); connect(action, SIGNAL(triggered()), SLOT(copy())); action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste)); - action->setEnabled(!d->readOnly && !QApplication::clipboard()->text().isEmpty()); + action->setEnabled(!d->control->isReadOnly() && !QApplication::clipboard()->text().isEmpty()); connect(action, SIGNAL(triggered()), SLOT(paste())); #endif action = popup->addAction(QLineEdit::tr("Delete")); - action->setEnabled(!d->readOnly && !d->text.isEmpty() && d->hasSelectedText()); + action->setEnabled(!d->control->isReadOnly() && !d->control->text().isEmpty() && d->control->hasSelectedText()); connect(action, SIGNAL(triggered()), SLOT(_q_deleteSelected())); popup->addSeparator(); action = popup->addAction(QLineEdit::tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll)); - action->setEnabled(!d->text.isEmpty() && !d->allSelected()); + action->setEnabled(!d->control->text().isEmpty() && !d->control->allSelected()); d->selectAllAction = action; connect(action, SIGNAL(triggered()), SLOT(selectAll())); @@ -2719,9 +2002,9 @@ QMenu *QLineEdit::createStandardContextMenu() #endif #if defined(Q_WS_WIN) - if (!d->readOnly && qt_use_rtl_extensions) { + if (!d->control->isReadOnly() && qt_use_rtl_extensions) { #else - if (!d->readOnly) { + if (!d->control->isReadOnly()) { #endif popup->addSeparator(); QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, popup); @@ -2735,806 +2018,26 @@ QMenu *QLineEdit::createStandardContextMenu() void QLineEdit::changeEvent(QEvent *ev) { Q_D(QLineEdit); - if(ev->type() == QEvent::ActivationChange) { + switch(ev->type()) + { + case QEvent::ActivationChange: if (!palette().isEqual(QPalette::Active, QPalette::Inactive)) update(); - } else if (ev->type() == QEvent::FontChange - || ev->type() == QEvent::StyleChange - || ev->type() == QEvent::LayoutDirectionChange) { - d->updateTextLayout(); - } - QWidget::changeEvent(ev); -} - -void QLineEditPrivate::_q_handleWindowActivate() -{ - Q_Q(QLineEdit); - if (!q->hasFocus() && q->hasSelectedText()) - q->deselect(); -} - -void QLineEditPrivate::_q_deleteSelected() -{ - Q_Q(QLineEdit); - if (!hasSelectedText()) - return; - - int priorState = undoState; - q->resetInputContext(); - removeSelectedText(); - separate(); - finishChange(priorState); -} - -void QLineEditPrivate::init(const QString& txt) -{ - Q_Q(QLineEdit); -#ifndef QT_NO_CURSOR - q->setCursor(Qt::IBeamCursor); -#endif - q->setFocusPolicy(Qt::StrongFocus); - q->setAttribute(Qt::WA_InputMethodEnabled); - // Specifies that this widget can use more, but is able to survive on - // less, horizontal space; and is fixed vertically. - q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::LineEdit)); - q->setBackgroundRole(QPalette::Base); - q->setAttribute(Qt::WA_KeyCompression); - q->setMouseTracking(true); - q->setAcceptDrops(true); - text = txt; - updateTextLayout(); - cursor = text.length(); - - q->setAttribute(Qt::WA_MacShowFocusRect); -} - -void QLineEditPrivate::updatePasswordEchoEditing(bool editing) -{ - Q_Q(QLineEdit); - passwordEchoEditing = editing; - q->setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(q)); - updateTextLayout(); - q->update(); -} - -void QLineEditPrivate::updateTextLayout() -{ - // replace certain non-printable characters with spaces (to avoid - // drawing boxes when using fonts that don't have glyphs for such - // characters) - Q_Q(QLineEdit); - QString str = q->displayText(); - QChar* uc = str.data(); - for (int i = 0; i < (int)str.length(); ++i) { - if ((uc[i] < 0x20 && uc[i] != 0x09) - || uc[i] == QChar::LineSeparator - || uc[i] == QChar::ParagraphSeparator - || uc[i] == QChar::ObjectReplacementCharacter) - uc[i] = QChar(0x0020); - } - textLayout.setFont(q->font()); - textLayout.setText(str); - QTextOption option; - option.setTextDirection(q->layoutDirection()); - option.setFlags(QTextOption::IncludeTrailingSpaces); - textLayout.setTextOption(option); - - textLayout.beginLayout(); - QTextLine l = textLayout.createLine(); - textLayout.endLayout(); - ascent = qRound(l.ascent()); -} - -int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const -{ - QRect cr = adjustedContentsRect(); - x-= cr.x() - hscroll + horizontalMargin; - QTextLine l = textLayout.lineAt(0); - return l.xToCursor(x, betweenOrOn); -} - -QRect QLineEditPrivate::cursorRect() const -{ - Q_Q(const QLineEdit); - QRect cr = adjustedContentsRect(); - int cix = cr.x() - hscroll + horizontalMargin; - QTextLine l = textLayout.lineAt(0); - int c = cursor; - if (preeditCursor != -1) - c += preeditCursor; - cix += qRound(l.cursorToX(c)); - int ch = qMin(cr.height(), q->fontMetrics().height() + 1); - int w = q->style()->pixelMetric(QStyle::PM_TextCursorWidth); - return QRect(cix-5, vscroll, w + 9, ch); -} - -QRect QLineEditPrivate::adjustedContentsRect() const -{ - Q_Q(const QLineEdit); - QStyleOptionFrameV2 opt; - q->initStyleOption(&opt); - QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q); - r.setX(r.x() + leftTextMargin); - r.setY(r.y() + topTextMargin); - r.setRight(r.right() - rightTextMargin); - r.setBottom(r.bottom() - bottomTextMargin); - return r; -} - -bool QLineEditPrivate::fixup() // this function assumes that validate currently returns != Acceptable -{ -#ifndef QT_NO_VALIDATOR - if (validator) { - QString textCopy = text; - int cursorCopy = cursor; - validator->fixup(textCopy); - if (validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) { - if (textCopy != text || cursorCopy != cursor) - setText(textCopy, cursorCopy); - return true; - } - } -#endif - return false; -} - -void QLineEditPrivate::moveCursor(int pos, bool mark) -{ - Q_Q(QLineEdit); - if (pos != cursor) { - separate(); - if (maskData) - pos = pos > cursor ? nextMaskBlank(pos) : prevMaskBlank(pos); - } - bool fullUpdate = mark || hasSelectedText(); - if (mark) { - int anchor; - if (selend > selstart && cursor == selstart) - anchor = selend; - else if (selend > selstart && cursor == selend) - anchor = selstart; - else - anchor = cursor; - selstart = qMin(anchor, pos); - selend = qMax(anchor, pos); - updateTextLayout(); - } else { - deselect(); - } - if (fullUpdate) { - cursor = pos; - q->update(); - } else { - setCursorVisible(false); - cursor = pos; - setCursorVisible(true); - if (!adjustedContentsRect().contains(cursorRect())) - q->update(); - } - QStyleOptionFrameV2 opt; - q->initStyleOption(&opt); - if (mark && !q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q)) - setCursorVisible(false); - if (mark || selDirty) { - selDirty = false; - emit q->selectionChanged(); - } - emitCursorPositionChanged(); -} - -void QLineEditPrivate::finishChange(int validateFromState, bool update, bool edited) -{ - Q_Q(QLineEdit); - bool lineDirty = selDirty; - if (textDirty) { - // do validation - bool wasValidInput = validInput; - validInput = true; -#ifndef QT_NO_VALIDATOR - if (validator) { - validInput = false; - QString textCopy = text; - int cursorCopy = cursor; - validInput = (validator->validate(textCopy, cursorCopy) != QValidator::Invalid); - if (validInput) { - if (text != textCopy) { - setText(textCopy, cursorCopy); - return; - } - cursor = cursorCopy; - } - } -#endif - if (validateFromState >= 0 && wasValidInput && !validInput) { - undo(validateFromState); - history.resize(undoState); - if (modifiedState > undoState) - modifiedState = -1; - validInput = true; - textDirty = false; - } - updateTextLayout(); - lineDirty |= textDirty; - if (textDirty) { - textDirty = false; - QString actualText = maskData ? stripString(text) : text; - if (edited) - emit q->textEdited(actualText); - q->updateMicroFocus(); -#ifndef QT_NO_COMPLETER - if (edited && completer && completer->completionMode() != QCompleter::InlineCompletion) - complete(-1); // update the popup on cut/paste/del -#endif - emit q->textChanged(actualText); - } -#ifndef QT_NO_ACCESSIBILITY - QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged); -#endif - } - if (selDirty) { - selDirty = false; - emit q->selectionChanged(); - } - if (lineDirty || update) - q->update(); - emitCursorPositionChanged(); -} - -void QLineEditPrivate::emitCursorPositionChanged() -{ - Q_Q(QLineEdit); - if (cursor != lastCursorPos) { - const int oldLast = lastCursorPos; - lastCursorPos = cursor; - emit q->cursorPositionChanged(oldLast, cursor); - } -} - -void QLineEditPrivate::setText(const QString& txt, int pos, bool edited) -{ - Q_Q(QLineEdit); - q->resetInputContext(); - deselect(); - QString oldText = text; - if (maskData) { - text = maskString(0, txt, true); - text += clearString(text.length(), maxLength - text.length()); - } else { - text = txt.isEmpty() ? txt : txt.left(maxLength); - } - history.clear(); - modifiedState = undoState = 0; - cursor = (pos < 0 || pos > text.length()) ? text.length() : pos; - textDirty = (oldText != text); - finishChange(-1, true, edited); -} - - -void QLineEditPrivate::setCursorVisible(bool visible) -{ - Q_Q(QLineEdit); - if ((bool)cursorVisible == visible) - return; - if (cursorTimer) - cursorVisible = visible; - QRect r = cursorRect(); - if (maskData) - q->update(); - else - q->update(r); -} - -void QLineEditPrivate::addCommand(const Command& cmd) -{ - if (separator && undoState && history[undoState-1].type != Separator) { - history.resize(undoState + 2); - history[undoState++] = Command(Separator, cursor, 0, selstart, selend); - } else { - history.resize(undoState + 1); - } - separator = false; - history[undoState++] = cmd; -} - -void QLineEditPrivate::insert(const QString& s) -{ - if (hasSelectedText()) - addCommand(Command(SetSelection, cursor, 0, selstart, selend)); - if (maskData) { - QString ms = maskString(cursor, s); - for (int i = 0; i < (int) ms.length(); ++i) { - addCommand (Command(DeleteSelection, cursor+i, text.at(cursor+i), -1, -1)); - addCommand(Command(Insert, cursor+i, ms.at(i), -1, -1)); - } - text.replace(cursor, ms.length(), ms); - cursor += ms.length(); - cursor = nextMaskBlank(cursor); - textDirty = true; - } else { - int remaining = maxLength - text.length(); - if (remaining != 0) { - text.insert(cursor, s.left(remaining)); - for (int i = 0; i < (int) s.left(remaining).length(); ++i) - addCommand(Command(Insert, cursor++, s.at(i), -1, -1)); - textDirty = true; - } - } -} - -void QLineEditPrivate::del(bool wasBackspace) -{ - if (cursor < (int) text.length()) { - if (hasSelectedText()) - addCommand(Command(SetSelection, cursor, 0, selstart, selend)); - addCommand (Command((CommandType)((maskData?2:0)+(wasBackspace?Remove:Delete)), cursor, text.at(cursor), -1, -1)); - if (maskData) { - text.replace(cursor, 1, clearString(cursor, 1)); - addCommand(Command(Insert, cursor, text.at(cursor), -1, -1)); - } else { - text.remove(cursor, 1); - } - textDirty = true; - } -} - -void QLineEditPrivate::removeSelectedText() -{ - if (selstart < selend && selend <= (int) text.length()) { - separate(); - int i ; - addCommand(Command(SetSelection, cursor, 0, selstart, selend)); - if (selstart <= cursor && cursor < selend) { - // cursor is within the selection. Split up the commands - // to be able to restore the correct cursor position - for (i = cursor; i >= selstart; --i) - addCommand (Command(DeleteSelection, i, text.at(i), -1, 1)); - for (i = selend - 1; i > cursor; --i) - addCommand (Command(DeleteSelection, i - cursor + selstart - 1, text.at(i), -1, -1)); - } else { - for (i = selend-1; i >= selstart; --i) - addCommand (Command(RemoveSelection, i, text.at(i), -1, -1)); - } - if (maskData) { - text.replace(selstart, selend - selstart, clearString(selstart, selend - selstart)); - for (int i = 0; i < selend - selstart; ++i) - addCommand(Command(Insert, selstart + i, text.at(selstart + i), -1, -1)); - } else { - text.remove(selstart, selend - selstart); - } - if (cursor > selstart) - cursor -= qMin(cursor, selend) - selstart; - deselect(); - textDirty = true; - - // adjust hscroll to avoid gap - const int minRB = qMax(0, -q_func()->fontMetrics().minRightBearing()); - updateTextLayout(); - const QTextLine line = textLayout.lineAt(0); - const int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB; - hscroll = qMin(hscroll, widthUsed); - } -} - -void QLineEditPrivate::parseInputMask(const QString &maskFields) -{ - int delimiter = maskFields.indexOf(QLatin1Char(';')); - if (maskFields.isEmpty() || delimiter == 0) { - if (maskData) { - delete [] maskData; - maskData = 0; - maxLength = 32767; - setText(QString()); - } - return; - } - - if (delimiter == -1) { - blank = QLatin1Char(' '); - inputMask = maskFields; - } else { - inputMask = maskFields.left(delimiter); - blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' '); - } - - // calculate maxLength / maskData length - maxLength = 0; - QChar c = 0; - for (int i=0; i<inputMask.length(); i++) { - c = inputMask.at(i); - if (i > 0 && inputMask.at(i-1) == QLatin1Char('\\')) { - maxLength++; - continue; - } - if (c != QLatin1Char('\\') && c != QLatin1Char('!') && - c != QLatin1Char('<') && c != QLatin1Char('>') && - c != QLatin1Char('{') && c != QLatin1Char('}') && - c != QLatin1Char('[') && c != QLatin1Char(']')) - maxLength++; - } - - delete [] maskData; - maskData = new MaskInputData[maxLength]; - - MaskInputData::Casemode m = MaskInputData::NoCaseMode; - c = 0; - bool s; - bool escape = false; - int index = 0; - for (int i = 0; i < inputMask.length(); i++) { - c = inputMask.at(i); - if (escape) { - s = true; - maskData[index].maskChar = c; - maskData[index].separator = s; - maskData[index].caseMode = m; - index++; - escape = false; - } else if (c == QLatin1Char('<')) { - m = MaskInputData::Lower; - } else if (c == QLatin1Char('>')) { - m = MaskInputData::Upper; - } else if (c == QLatin1Char('!')) { - m = MaskInputData::NoCaseMode; - } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) { - switch (c.unicode()) { - case 'A': - case 'a': - case 'N': - case 'n': - case 'X': - case 'x': - case '9': - case '0': - case 'D': - case 'd': - case '#': - case 'H': - case 'h': - case 'B': - case 'b': - s = false; - break; - case '\\': - escape = true; - default: - s = true; - break; - } - - if (!escape) { - maskData[index].maskChar = c; - maskData[index].separator = s; - maskData[index].caseMode = m; - index++; - } - } - } - setText(text); -} - - -/* checks if the key is valid compared to the inputMask */ -bool QLineEditPrivate::isValidInput(QChar key, QChar mask) const -{ - switch (mask.unicode()) { - case 'A': - if (key.isLetter()) - return true; break; - case 'a': - if (key.isLetter() || key == blank) - return true; + case QEvent::FontChange: + d->control->setFont(font()); break; - case 'N': - if (key.isLetterOrNumber()) - return true; - break; - case 'n': - if (key.isLetterOrNumber() || key == blank) - return true; - break; - case 'X': - if (key.isPrint()) - return true; - break; - case 'x': - if (key.isPrint() || key == blank) - return true; - break; - case '9': - if (key.isNumber()) - return true; - break; - case '0': - if (key.isNumber() || key == blank) - return true; - break; - case 'D': - if (key.isNumber() && key.digitValue() > 0) - return true; - break; - case 'd': - if ((key.isNumber() && key.digitValue() > 0) || key == blank) - return true; - break; - case '#': - if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == blank) - return true; - break; - case 'B': - if (key == QLatin1Char('0') || key == QLatin1Char('1')) - return true; - break; - case 'b': - if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == blank) - return true; - break; - case 'H': - if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F'))) - return true; + case QEvent::StyleChange: + d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter)); + update(); break; - case 'h': - if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == blank) - return true; + case QEvent::LayoutDirectionChange: + d->control->setLayoutDirection(layoutDirection()); break; default: break; } - return false; -} - -bool QLineEditPrivate::hasAcceptableInput(const QString &str) const -{ -#ifndef QT_NO_VALIDATOR - QString textCopy = str; - int cursorCopy = cursor; - if (validator && validator->validate(textCopy, cursorCopy) - != QValidator::Acceptable) - return false; -#endif - - if (!maskData) - return true; - - if (str.length() != maxLength) - return false; - - for (int i=0; i < maxLength; ++i) { - if (maskData[i].separator) { - if (str.at(i) != maskData[i].maskChar) - return false; - } else { - if (!isValidInput(str.at(i), maskData[i].maskChar)) - return false; - } - } - return true; -} - -/* - Applies the inputMask on \a str starting from position \a pos in the mask. \a clear - specifies from where characters should be gotten when a separator is met in \a str - true means - that blanks will be used, false that previous input is used. - Calling this when no inputMask is set is undefined. -*/ -QString QLineEditPrivate::maskString(uint pos, const QString &str, bool clear) const -{ - if (pos >= (uint)maxLength) - return QString::fromLatin1(""); - - QString fill; - fill = clear ? clearString(0, maxLength) : text; - - int strIndex = 0; - QString s = QString::fromLatin1(""); - int i = pos; - while (i < maxLength) { - if (strIndex < str.length()) { - if (maskData[i].separator) { - s += maskData[i].maskChar; - if (str[(int)strIndex] == maskData[i].maskChar) - strIndex++; - ++i; - } else { - if (isValidInput(str[(int)strIndex], maskData[i].maskChar)) { - switch (maskData[i].caseMode) { - case MaskInputData::Upper: - s += str[(int)strIndex].toUpper(); - break; - case MaskInputData::Lower: - s += str[(int)strIndex].toLower(); - break; - default: - s += str[(int)strIndex]; - } - ++i; - } else { - // search for separator first - int n = findInMask(i, true, true, str[(int)strIndex]); - if (n != -1) { - if (str.length() != 1 || i == 0 || (i > 0 && (!maskData[i-1].separator || maskData[i-1].maskChar != str[(int)strIndex]))) { - s += fill.mid(i, n-i+1); - i = n + 1; // update i to find + 1 - } - } else { - // search for valid blank if not - n = findInMask(i, true, false, str[(int)strIndex]); - if (n != -1) { - s += fill.mid(i, n-i); - switch (maskData[n].caseMode) { - case MaskInputData::Upper: - s += str[(int)strIndex].toUpper(); - break; - case MaskInputData::Lower: - s += str[(int)strIndex].toLower(); - break; - default: - s += str[(int)strIndex]; - } - i = n + 1; // updates i to find + 1 - } - } - } - strIndex++; - } - } else - break; - } - - return s; -} - - - -/* - Returns a "cleared" string with only separators and blank chars. - Calling this when no inputMask is set is undefined. -*/ -QString QLineEditPrivate::clearString(uint pos, uint len) const -{ - if (pos >= (uint)maxLength) - return QString(); - - QString s; - int end = qMin((uint)maxLength, pos + len); - for (int i=pos; i<end; i++) - if (maskData[i].separator) - s += maskData[i].maskChar; - else - s += blank; - - return s; -} - -/* - Strips blank parts of the input in a QLineEdit when an inputMask is set, - separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1". -*/ -QString QLineEditPrivate::stripString(const QString &str) const -{ - if (!maskData) - return str; - - QString s; - int end = qMin(maxLength, (int)str.length()); - for (int i=0; i < end; i++) - if (maskData[i].separator) - s += maskData[i].maskChar; - else - if (str[i] != blank) - s += str[i]; - - return s; -} - -/* searches forward/backward in maskData for either a separator or a blank */ -int QLineEditPrivate::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const -{ - if (pos >= maxLength || pos < 0) - return -1; - - int end = forward ? maxLength : -1; - int step = forward ? 1 : -1; - int i = pos; - - while (i != end) { - if (findSeparator) { - if (maskData[i].separator && maskData[i].maskChar == searchChar) - return i; - } else { - if (!maskData[i].separator) { - if (searchChar.isNull()) - return i; - else if (isValidInput(searchChar, maskData[i].maskChar)) - return i; - } - } - i += step; - } - return -1; -} - -void QLineEditPrivate::undo(int until) -{ - if (!isUndoAvailable()) - return; - deselect(); - while (undoState && undoState > until) { - Command& cmd = history[--undoState]; - switch (cmd.type) { - case Insert: - text.remove(cmd.pos, 1); - cursor = cmd.pos; - break; - case SetSelection: - selstart = cmd.selStart; - selend = cmd.selEnd; - cursor = cmd.pos; - break; - case Remove: - case RemoveSelection: - text.insert(cmd.pos, cmd.uc); - cursor = cmd.pos + 1; - break; - case Delete: - case DeleteSelection: - text.insert(cmd.pos, cmd.uc); - cursor = cmd.pos; - break; - case Separator: - continue; - } - if (until < 0 && undoState) { - Command& next = history[undoState-1]; - if (next.type != cmd.type && next.type < RemoveSelection - && (cmd.type < RemoveSelection || next.type == Separator)) - break; - } - } - textDirty = true; - emitCursorPositionChanged(); -} - -void QLineEditPrivate::redo() { - if (!isRedoAvailable()) - return; - deselect(); - while (undoState < (int)history.size()) { - Command& cmd = history[undoState++]; - switch (cmd.type) { - case Insert: - text.insert(cmd.pos, cmd.uc); - cursor = cmd.pos + 1; - break; - case SetSelection: - selstart = cmd.selStart; - selend = cmd.selEnd; - cursor = cmd.pos; - break; - case Remove: - case Delete: - case RemoveSelection: - case DeleteSelection: - text.remove(cmd.pos, 1); - selstart = cmd.selStart; - selend = cmd.selEnd; - cursor = cmd.pos; - break; - case Separator: - selstart = cmd.selStart; - selend = cmd.selEnd; - cursor = cmd.pos; - break; - } - if (undoState < (int)history.size()) { - Command& next = history[undoState]; - if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator - && (next.type < RemoveSelection || cmd.type == Separator)) - break; - } - } - textDirty = true; - emitCursorPositionChanged(); + QWidget::changeEvent(ev); } /*! diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index a97dc9a..daac6a7 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -268,6 +268,8 @@ private: Q_DECLARE_PRIVATE(QLineEdit) Q_PRIVATE_SLOT(d_func(), void _q_handleWindowActivate()) Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected()) + Q_PRIVATE_SLOT(d_func(), void _q_textEdited(const QString &)) + Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged(int, int)) #ifndef QT_NO_COMPLETER Q_PRIVATE_SLOT(d_func(), void _q_completionHighlighted(QString)) #endif diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp new file mode 100644 index 0000000..0e39304 --- /dev/null +++ b/src/gui/widgets/qlineedit_p.cpp @@ -0,0 +1,253 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qlineedit.h" +#include "qlineedit_p.h" + +#ifndef QT_NO_LINEEDIT + +#include "qabstractitemview.h" +#include "qclipboard.h" +#ifndef QT_NO_ACCESSIBILITY +#include "qaccessible.h" +#endif +#ifndef QT_NO_IM +#include "qinputcontext.h" +#include "qlist.h" +#endif + +QT_BEGIN_NAMESPACE + +const int QLineEditPrivate::verticalMargin(1); +const int QLineEditPrivate::horizontalMargin(2); + +int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const +{ + QRect cr = adjustedContentsRect(); + x-= cr.x() - hscroll + horizontalMargin; + return control->xToPos(x, betweenOrOn); +} + +QRect QLineEditPrivate::cursorRect() const +{ + QRect cr = adjustedContentsRect(); + int cix = cr.x() - hscroll + horizontalMargin; + QRect crect = control->cursorRect(); + crect.moveTo(crect.topLeft() + QPoint(cix, vscroll)); + return crect; +} + +#ifndef QT_NO_COMPLETER + +void QLineEditPrivate::_q_completionHighlighted(QString newText) +{ + Q_Q(QLineEdit); + if (control->completer()->completionMode() != QCompleter::InlineCompletion) { + q->setText(newText); + } else { + int c = control->cursor(); + QString text = control->text(); + q->setText(text.left(c) + newText.mid(c)); + control->moveCursor(control->end(), false); + control->moveCursor(c, true); + } +} + +#endif // QT_NO_COMPLETER + +void QLineEditPrivate::_q_clipboardChanged() +{ +} + +void QLineEditPrivate::_q_handleWindowActivate() +{ + Q_Q(QLineEdit); + if (!q->hasFocus() && control->hasSelectedText()) + control->deselect(); +} + +void QLineEditPrivate::_q_deleteSelected() +{ +} + +void QLineEditPrivate::_q_textEdited(const QString &text) +{ + Q_Q(QLineEdit); +#ifndef QT_NO_COMPLETER + if (control->completer() && + control->completer()->completionMode() != QCompleter::InlineCompletion) + control->complete(-1); // update the popup on cut/paste/del +#endif + emit q->textEdited(text); +} + +void QLineEditPrivate::_q_cursorPositionChanged(int from, int to) +{ + Q_Q(QLineEdit); + q->update(); + emit q->cursorPositionChanged(from, to); +} + +void QLineEditPrivate::init(const QString& txt) +{ + Q_Q(QLineEdit); + control = new QLineControl(txt); + QObject::connect(control, SIGNAL(textChanged(const QString &)), + q, SIGNAL(textChanged(const QString &))); + QObject::connect(control, SIGNAL(textEdited(const QString &)), + q, SLOT(_q_textEdited(const QString &))); + QObject::connect(control, SIGNAL(cursorPositionChanged(int, int)), + q, SLOT(_q_cursorPositionChanged(int, int))); + QObject::connect(control, SIGNAL(selectionChanged()), + q, SIGNAL(selectionChanged())); + QObject::connect(control, SIGNAL(accepted()), + q, SIGNAL(returnPressed())); + QObject::connect(control, SIGNAL(editingFinished()), + q, SIGNAL(editingFinished())); + + // for now, going completely overboard with updates. + QObject::connect(control, SIGNAL(selectionChanged()), + q, SLOT(update())); + + QObject::connect(control, SIGNAL(displayTextChanged(const QString &)), + q, SLOT(update())); + control->setPasswordCharacter(q->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter)); +#ifndef QT_NO_CURSOR + q->setCursor(Qt::IBeamCursor); +#endif + q->setFocusPolicy(Qt::StrongFocus); + q->setAttribute(Qt::WA_InputMethodEnabled); + // Specifies that this widget can use more, but is able to survive on + // less, horizontal space; and is fixed vertically. + q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::LineEdit)); + q->setBackgroundRole(QPalette::Base); + q->setAttribute(Qt::WA_KeyCompression); + q->setMouseTracking(true); + q->setAcceptDrops(true); + + q->setAttribute(Qt::WA_MacShowFocusRect); +} + +QRect QLineEditPrivate::adjustedContentsRect() const +{ + Q_Q(const QLineEdit); + QStyleOptionFrameV2 opt; + q->initStyleOption(&opt); + QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q); + r.setX(r.x() + leftTextMargin); + r.setY(r.y() + topTextMargin); + r.setRight(r.right() - rightTextMargin); + r.setBottom(r.bottom() - bottomTextMargin); + return r; +} + +void QLineEditPrivate::setCursorVisible(bool visible) +{ + Q_Q(QLineEdit); + if ((bool)cursorVisible == visible) + return; + cursorVisible = visible; + QRect r = cursorRect(); + if (control->inputMask().isEmpty()) + q->update(r); + else + q->update(); +} + +void QLineEditPrivate::updatePasswordEchoEditing(bool editing) +{ + Q_Q(QLineEdit); + control->updatePasswordEchoEditing(editing); + q->setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod()); +} + +/*! + This function is not intended as polymorphic usage. Just a shared code + fragment that calls QInputContext::mouseHandler for this + class. +*/ +bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e ) +{ +#if !defined QT_NO_IM + Q_Q(QLineEdit); + if ( control->composeMode() ) { + int tmp_cursor = xToPos(e->pos().x()); + int mousePos = tmp_cursor - control->cursor(); + if ( mousePos < 0 || mousePos > control->preeditAreaText().length() ) { + mousePos = -1; + // don't send move events outside the preedit area + if ( e->type() == QEvent::MouseMove ) + return true; + } + + QInputContext *qic = q->inputContext(); + if ( qic ) + // may be causing reset() in some input methods + qic->mouseHandler(mousePos, e); + if (!control->preeditAreaText().isEmpty()) + return true; + } +#else + Q_UNUSED(e); +#endif + + return false; +} + +#ifndef QT_NO_DRAGANDDROP +void QLineEditPrivate::drag() +{ + Q_Q(QLineEdit); + dndTimer.stop(); + QMimeData *data = new QMimeData; + data->setText(control->selectedText()); + QDrag *drag = new QDrag(q); + drag->setMimeData(data); + Qt::DropAction action = drag->start(); + if (action == Qt::MoveAction && !control->isReadOnly() && drag->target() != q) + control->removeSelection(); +} + +#endif // QT_NO_DRAGANDDROP + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h index 7a4ff26..230023d 100644 --- a/src/gui/widgets/qlineedit_p.h +++ b/src/gui/widgets/qlineedit_p.h @@ -65,6 +65,8 @@ #include "QtCore/qpointer.h" #include "QtGui/qlineedit.h" +#include "private/qlinecontrol_p.h" + QT_BEGIN_NAMESPACE class QLineEditPrivate : public QWidgetPrivate @@ -73,167 +75,64 @@ class QLineEditPrivate : public QWidgetPrivate public: QLineEditPrivate() - : cursor(0), preeditCursor(0), cursorTimer(0), frame(1), - cursorVisible(0), hideCursor(false), separator(0), readOnly(0), - dragEnabled(0), contextMenuEnabled(1), echoMode(0), textDirty(0), - selDirty(0), validInput(1), alignment(Qt::AlignLeading | Qt::AlignVCenter), ascent(0), - maxLength(32767), hscroll(0), vscroll(0), lastCursorPos(-1), maskData(0), - modifiedState(0), undoState(0), selstart(0), selend(0), userInput(false), - emitingEditingFinished(false), passwordEchoEditing(false) -#ifndef QT_NO_COMPLETER - , completer(0) -#endif - , leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0) - { - } + : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0), + dragEnabled(0), hscroll(0), vscroll(0), + alignment(Qt::AlignLeading | Qt::AlignVCenter), + leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0) + { + } ~QLineEditPrivate() { - delete [] maskData; } + + QLineControl *control; + +#ifndef QT_NO_CONTEXTMENU + QPointer<QAction> selectAllAction; +#endif void init(const QString&); - QString text; - int cursor; - int preeditCursor; - int cursorTimer; // -1 for non blinking cursor. + int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const; + QRect cursorRect() const; + void setCursorVisible(bool visible); + + void updatePasswordEchoEditing(bool); + + inline bool shouldEnableInputMethod() const + { + return !control->isReadOnly() && (control->echoMode() == QLineEdit::Normal || control->echoMode() == QLineEdit::PasswordEchoOnEdit); + } + QPoint tripleClick; QBasicTimer tripleClickTimer; uint frame : 1; + uint contextMenuEnabled : 1; uint cursorVisible : 1; - uint hideCursor : 1; // used to hide the cursor inside preedit areas - uint separator : 1; - uint readOnly : 1; uint dragEnabled : 1; - uint contextMenuEnabled : 1; - uint echoMode : 2; - uint textDirty : 1; - uint selDirty : 1; - uint validInput : 1; - uint alignment; - int ascent; - int maxLength; int hscroll; int vscroll; - int lastCursorPos; - -#ifndef QT_NO_CONTEXTMENU - QPointer<QAction> selectAllAction; -#endif + uint alignment; + static const int verticalMargin; + static const int horizontalMargin; - inline void emitCursorPositionChanged(); bool sendMouseEventToInputContext(QMouseEvent *e); - void finishChange(int validateFromState = -1, bool update = false, bool edited = true); - - QPointer<QValidator> validator; - struct MaskInputData { - enum Casemode { NoCaseMode, Upper, Lower }; - QChar maskChar; // either the separator char or the inputmask - bool separator; - Casemode caseMode; - }; - QString inputMask; - QChar blank; - MaskInputData *maskData; - inline int nextMaskBlank(int pos) { - int c = findInMask(pos, true, false); - separator |= (c != pos); - return (c != -1 ? c : maxLength); - } - inline int prevMaskBlank(int pos) { - int c = findInMask(pos, false, false); - separator |= (c != pos); - return (c != -1 ? c : 0); - } - - void setCursorVisible(bool visible); - - - // undo/redo handling - enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection }; - struct Command { - inline Command() {} - inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {} - uint type : 4; - QChar uc; - int pos, selStart, selEnd; - }; - int modifiedState; - int undoState; - QVector<Command> history; - void addCommand(const Command& cmd); - void insert(const QString& s); - void del(bool wasBackspace = false); - void remove(int pos); - - inline void separate() { separator = true; } - void undo(int until = -1); - void redo(); - inline bool isUndoAvailable() const { return !readOnly && undoState; } - inline bool isRedoAvailable() const { return !readOnly && undoState < (int)history.size(); } - - // selection - int selstart, selend; - inline bool allSelected() const { return !text.isEmpty() && selstart == 0 && selend == (int)text.length(); } - inline bool hasSelectedText() const { return !text.isEmpty() && selend > selstart; } - inline void deselect() { selDirty |= (selend > selstart); selstart = selend = 0; } - void removeSelectedText(); -#ifndef QT_NO_CLIPBOARD - void copy(bool clipboard = true) const; -#endif - inline bool inSelection(int x) const - { if (selstart >= selend) return false; - int pos = xToPos(x, QTextLine::CursorOnCharacter); return pos >= selstart && pos < selend; } - - // masking - void parseInputMask(const QString &maskFields); - bool isValidInput(QChar key, QChar mask) const; - bool hasAcceptableInput(const QString &text) const; - QString maskString(uint pos, const QString &str, bool clear = false) const; - QString clearString(uint pos, uint len) const; - QString stripString(const QString &str) const; - int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const; - - // input methods - bool composeMode() const { return !textLayout.preeditAreaText().isEmpty(); } - - // complex text layout - QTextLayout textLayout; - void updateTextLayout(); - void moveCursor(int pos, bool mark = false); - void setText(const QString& txt, int pos = -1, bool edited = true); - int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const; - QRect cursorRect() const; - bool fixup(); - QRect adjustedContentsRect() const; -#ifndef QT_NO_DRAGANDDROP - // drag and drop - QPoint dndPos; - QBasicTimer dndTimer; - void drag(); -#endif - + void _q_clipboardChanged(); void _q_handleWindowActivate(); void _q_deleteSelected(); - bool userInput; - bool emitingEditingFinished; - -#ifdef QT_KEYPAD_NAVIGATION - QBasicTimer deleteAllTimer; // keypad navigation - QString origText; -#endif - - bool passwordEchoEditing; - void updatePasswordEchoEditing(bool editing); + void _q_textEdited(const QString &); + void _q_cursorPositionChanged(int, int); #ifndef QT_NO_COMPLETER - QPointer<QCompleter> completer; - void complete(int key = -1); void _q_completionHighlighted(QString); - bool advanceToEnabledItem(int n); +#endif +#ifndef QT_NO_DRAGANDDROP + QPoint dndPos; + QBasicTimer dndTimer; + void drag(); #endif int leftTextMargin; diff --git a/src/gui/widgets/qvalidator.h b/src/gui/widgets/qvalidator.h index ce78959..5c27d1d 100644 --- a/src/gui/widgets/qvalidator.h +++ b/src/gui/widgets/qvalidator.h @@ -61,7 +61,7 @@ class Q_GUI_EXPORT QValidator : public QObject { Q_OBJECT public: - explicit QValidator(QObject * parent); + explicit QValidator(QObject * parent=0); ~QValidator(); enum State { @@ -100,7 +100,7 @@ class Q_GUI_EXPORT QIntValidator : public QValidator Q_PROPERTY(int top READ top WRITE setTop) public: - explicit QIntValidator(QObject * parent); + explicit QIntValidator(QObject * parent=0); QIntValidator(int bottom, int top, QObject * parent); ~QIntValidator(); diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri index 2d809a1..8f24fac 100644 --- a/src/gui/widgets/widgets.pri +++ b/src/gui/widgets/widgets.pri @@ -30,6 +30,7 @@ HEADERS += \ widgets/qlcdnumber.h \ widgets/qlineedit.h \ widgets/qlineedit_p.h \ + widgets/qlinecontrol_p.h \ widgets/qmainwindow.h \ widgets/qmainwindowlayout_p.h \ widgets/qmdiarea.h \ @@ -101,7 +102,9 @@ SOURCES += \ widgets/qgroupbox.cpp \ widgets/qlabel.cpp \ widgets/qlcdnumber.cpp \ + widgets/qlineedit_p.cpp \ widgets/qlineedit.cpp \ + widgets/qlinecontrol.cpp \ widgets/qmainwindow.cpp \ widgets/qmainwindowlayout.cpp \ widgets/qmdiarea.cpp \ diff --git a/src/network/access/access.pri b/src/network/access/access.pri index 3269b2e..ab7b3a7 100644 --- a/src/network/access/access.pri +++ b/src/network/access/access.pri @@ -6,6 +6,7 @@ HEADERS += access/qftp.h \ access/qhttpnetworkrequest_p.h \ access/qhttpnetworkreply_p.h \ access/qhttpnetworkconnection_p.h \ + access/qhttpnetworkconnectionchannel_p.h \ access/qnetworkaccessmanager.h \ access/qnetworkaccessmanager_p.h \ access/qnetworkaccesscache_p.h \ @@ -18,6 +19,8 @@ HEADERS += access/qftp.h \ access/qnetworkaccessftpbackend_p.h \ access/qnetworkcookie.h \ access/qnetworkcookie_p.h \ + access/qnetworkcookiejar.h \ + access/qnetworkcookiejar_p.h \ access/qnetworkrequest.h \ access/qnetworkrequest_p.h \ access/qnetworkreply.h \ @@ -34,6 +37,7 @@ SOURCES += access/qftp.cpp \ access/qhttpnetworkrequest.cpp \ access/qhttpnetworkreply.cpp \ access/qhttpnetworkconnection.cpp \ + access/qhttpnetworkconnectionchannel.cpp \ access/qnetworkaccessmanager.cpp \ access/qnetworkaccesscache.cpp \ access/qnetworkaccessbackend.cpp \ @@ -44,6 +48,7 @@ SOURCES += access/qftp.cpp \ access/qnetworkaccessftpbackend.cpp \ access/qnetworkaccesshttpbackend.cpp \ access/qnetworkcookie.cpp \ + access/qnetworkcookiejar.cpp \ access/qnetworkrequest.cpp \ access/qnetworkreply.cpp \ access/qnetworkreplyimpl.cpp \ diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 66aeb22..75ab837 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qhttpnetworkconnection_p.h" +#include "qhttpnetworkconnectionchannel_p.h" #include "private/qnoncontiguousbytedevice_p.h" #include <private/qnetworkrequest_p.h> #include <private/qobject_p.h> @@ -74,7 +75,7 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host #endif { - channels = new Channel[channelCount]; + channels = new QHttpNetworkConnectionChannel[channelCount]; } QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate() @@ -154,25 +155,25 @@ int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const bool QHttpNetworkConnectionPrivate::isSocketBusy(QAbstractSocket *socket) const { int i = indexOf(socket); - return (channels[i].state & BusyState); + return (channels[i].state & QHttpNetworkConnectionChannel::BusyState); } bool QHttpNetworkConnectionPrivate::isSocketWriting(QAbstractSocket *socket) const { int i = indexOf(socket); - return (i != -1 && (channels[i].state & WritingState)); + return (i != -1 && (channels[i].state & QHttpNetworkConnectionChannel::WritingState)); } bool QHttpNetworkConnectionPrivate::isSocketWaiting(QAbstractSocket *socket) const { int i = indexOf(socket); - return (i != -1 && (channels[i].state & WaitingState)); + return (i != -1 && (channels[i].state & QHttpNetworkConnectionChannel::WaitingState)); } bool QHttpNetworkConnectionPrivate::isSocketReading(QAbstractSocket *socket) const { int i = indexOf(socket); - return (i != -1 && (channels[i].state & ReadingState)); + return (i != -1 && (channels[i].state & QHttpNetworkConnectionChannel::ReadingState)); } void QHttpNetworkConnectionPrivate::appendUncompressedData(QHttpNetworkReply &reply, QByteArray &qba) @@ -310,7 +311,7 @@ bool QHttpNetworkConnectionPrivate::ensureConnection(QAbstractSocket *socket) channels[index].resendCurrent = true; return false; } - channels[index].state = ConnectingState; + channels[index].state = QHttpNetworkConnectionChannel::ConnectingState; channels[index].pendingEncrypt = encrypt; // This workaround is needed since we use QAuthenticator for NTLM authentication. The "phase == Done" @@ -361,7 +362,7 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) int i = indexOf(socket); switch (channels[i].state) { - case IdleState: { // write the header + case QHttpNetworkConnectionChannel::IdleState: { // write the header if (!ensureConnection(socket)) { // wait for the connection (and encryption) to be done // sendRequest will be called again from either @@ -375,7 +376,7 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) channels[i].reply->d_func()->connection = q; channels[i].reply->d_func()->autoDecompress = channels[i].request.d->autoDecompress; } - channels[i].state = WritingState; + channels[i].state = QHttpNetworkConnectionChannel::WritingState; channels[i].pendingEncrypt = false; // if the url contains authentication parameters, use the new ones // both channels will use the new authentication parameters @@ -410,20 +411,20 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) channels[i].bytesTotal = channels[i].request.contentLength(); } else { socket->flush(); // ### Remove this when pipelining is implemented. We want less TCP packets! - channels[i].state = WaitingState; + channels[i].state = QHttpNetworkConnectionChannel::WaitingState; break; } // write the initial chunk together with the headers // fall through } - case WritingState: + case QHttpNetworkConnectionChannel::WritingState: { // write the data QNonContiguousByteDevice* uploadByteDevice = channels[i].request.uploadByteDevice(); if (!uploadByteDevice || channels[i].bytesTotal == channels[i].written) { if (uploadByteDevice) emit channels[i].reply->dataSendProgress(channels[i].written, channels[i].bytesTotal); - channels[i].state = WaitingState; // now wait for response + channels[i].state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response sendRequest(socket); break; } @@ -470,7 +471,7 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) if (channels[i].written == channels[i].bytesTotal) { // make sure this function is called once again - channels[i].state = WaitingState; + channels[i].state = QHttpNetworkConnectionChannel::WaitingState; sendRequest(socket); break; } @@ -480,7 +481,7 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) break; } - case WaitingState: + case QHttpNetworkConnectionChannel::WaitingState: { QNonContiguousByteDevice* uploadByteDevice = channels[i].request.uploadByteDevice(); if (uploadByteDevice) { @@ -492,8 +493,8 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) receiveReply(socket, channels[i].reply); break; } - case ReadingState: - case Wait4AuthState: + case QHttpNetworkConnectionChannel::ReadingState: + case QHttpNetworkConnectionChannel::Wait4AuthState: // ignore _q_bytesWritten in these states // fall through default: @@ -601,7 +602,7 @@ void QHttpNetworkConnectionPrivate::receiveReply(QAbstractSocket *socket, QHttpN if (!socket->bytesAvailable()) { if (reply && reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) { reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState; - channels[i].state = IdleState; + channels[i].state = QHttpNetworkConnectionChannel::IdleState; allDone(socket, reply); } else { // try to reconnect/resend before sending an error. @@ -652,7 +653,7 @@ void QHttpNetworkConnectionPrivate::receiveReply(QAbstractSocket *socket, QHttpN emit reply->headerChanged(); if (!expectContent(reply)) { reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState; - channels[i].state = IdleState; + channels[i].state = QHttpNetworkConnectionChannel::IdleState; allDone(socket, reply); return; } @@ -715,7 +716,7 @@ void QHttpNetworkConnectionPrivate::receiveReply(QAbstractSocket *socket, QHttpN // everything done, fall through } case QHttpNetworkReplyPrivate::AllDoneState: - channels[i].state = IdleState; + channels[i].state = QHttpNetworkConnectionChannel::IdleState; allDone(socket, reply); break; default: @@ -864,11 +865,11 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket eraseData(channels[i].reply); closeChannel(i); channels[i].lastStatus = 0; - channels[i].state = Wait4AuthState; + channels[i].state = QHttpNetworkConnectionChannel::Wait4AuthState; return false; } // cannot use this socket until the slot returns - channels[i].state = WaitingState; + channels[i].state = QHttpNetworkConnectionChannel::WaitingState; socket->blockSignals(true); if (!isProxy) { pendingAuthSignal = true; @@ -883,7 +884,7 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket } socket->blockSignals(false); // socket free to use - channels[i].state = IdleState; + channels[i].state = QHttpNetworkConnectionChannel::IdleState; if (priv->phase != QAuthenticatorPrivate::Done) { // send any pending requests copyCredentials(i, auth, isProxy); @@ -906,8 +907,8 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket socket->close(); // remove pending request on the other channels for (int j = 0; j < channelCount; ++j) { - if (j != i && channels[j].state == Wait4AuthState) - channels[j].state = IdleState; + if (j != i && channels[j].state == QHttpNetworkConnectionChannel::Wait4AuthState) + channels[j].state = QHttpNetworkConnectionChannel::IdleState; } return true; } @@ -1007,7 +1008,7 @@ void QHttpNetworkConnectionPrivate::closeChannel(int channel) socket->blockSignals(true); socket->close(); socket->blockSignals(false); - channels[channel].state = IdleState; + channels[channel].state = QHttpNetworkConnectionChannel::IdleState; } void QHttpNetworkConnectionPrivate::resendCurrentRequest(QAbstractSocket *socket) @@ -1110,7 +1111,7 @@ void QHttpNetworkConnectionPrivate::_q_readyRead() return; // ### error if (isSocketWaiting(socket) || isSocketReading(socket)) { int i = indexOf(socket); - channels[i].state = ReadingState; + channels[i].state = QHttpNetworkConnectionChannel::ReadingState; if (channels[i].reply) receiveReply(socket, channels[i].reply); } @@ -1139,14 +1140,14 @@ void QHttpNetworkConnectionPrivate::_q_disconnected() // read the available data before closing int i = indexOf(socket); if (isSocketWaiting(socket) || isSocketReading(socket)) { - channels[i].state = ReadingState; + channels[i].state = QHttpNetworkConnectionChannel::ReadingState; if (channels[i].reply) receiveReply(socket, channels[i].reply); - } else if (channels[i].state == IdleState && channels[i].resendCurrent) { + } else if (channels[i].state == QHttpNetworkConnectionChannel::IdleState && channels[i].resendCurrent) { // re-sending request because the socket was in ClosingState QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); } - channels[i].state = IdleState; + channels[i].state = QHttpNetworkConnectionChannel::IdleState; } void QHttpNetworkConnectionPrivate::_q_startNextRequest() @@ -1155,7 +1156,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() for (int i = 0; i < channelCount; ++i) { if (channels[i].resendCurrent) { channels[i].resendCurrent = false; - channels[i].state = IdleState; + channels[i].state = QHttpNetworkConnectionChannel::IdleState; if (channels[i].reply) sendRequest(channels[i].socket); } @@ -1179,8 +1180,8 @@ void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests() // send the request using the idle socket for (int i = 0 ; i < channelCount; ++i) { QAbstractSocket *socket = channels[i].socket; - if (channels[i].state == Wait4AuthState) { - channels[i].state = IdleState; + if (channels[i].state == QHttpNetworkConnectionChannel::Wait4AuthState) { + channels[i].state = QHttpNetworkConnectionChannel::IdleState; if (channels[i].reply) sendRequest(socket); } @@ -1201,7 +1202,7 @@ void QHttpNetworkConnectionPrivate::_q_connected() // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again! //channels[i].reconnectAttempts = 2; if (!channels[i].pendingEncrypt) { - channels[i].state = IdleState; + channels[i].state = QHttpNetworkConnectionChannel::IdleState; if (channels[i].reply) sendRequest(socket); else @@ -1230,7 +1231,7 @@ void QHttpNetworkConnectionPrivate::_q_error(QAbstractSocket::SocketError socket case QAbstractSocket::RemoteHostClosedError: // try to reconnect/resend before sending an error. // while "Reading" the _q_disconnected() will handle this. - if (channels[i].state != IdleState && channels[i].state != ReadingState) { + if (channels[i].state != QHttpNetworkConnectionChannel::IdleState && channels[i].state != QHttpNetworkConnectionChannel::ReadingState) { if (channels[i].reconnectAttempts-- > 0) { resendCurrentRequest(socket); return; @@ -1244,7 +1245,7 @@ void QHttpNetworkConnectionPrivate::_q_error(QAbstractSocket::SocketError socket break; case QAbstractSocket::SocketTimeoutError: // try to reconnect/resend before sending an error. - if (channels[i].state == WritingState && (channels[i].reconnectAttempts-- > 0)) { + if (channels[i].state == QHttpNetworkConnectionChannel::WritingState && (channels[i].reconnectAttempts-- > 0)) { resendCurrentRequest(socket); return; } @@ -1403,7 +1404,7 @@ void QHttpNetworkConnectionPrivate::_q_encrypted() if (!socket) return; // ### error int i = indexOf(socket); - channels[i].state = IdleState; + channels[i].state = QHttpNetworkConnectionChannel::IdleState; sendRequest(socket); } diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 52a73a7..db6a140 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -65,6 +65,7 @@ #include <private/qhttpnetworkrequest_p.h> #include <private/qhttpnetworkreply_p.h> +#include "qhttpnetworkconnectionchannel_p.h" #ifndef QT_NO_HTTP @@ -157,8 +158,6 @@ private: }; - - // private classes typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair; @@ -172,16 +171,6 @@ public: void init(); void connectSignals(QAbstractSocket *socket); - enum SocketState { - IdleState = 0, // ready to send request - ConnectingState = 1, // connecting to host - WritingState = 2, // writing the data - WaitingState = 4, // waiting for reply - ReadingState = 8, // reading the reply - Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done - BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState) - }; - enum { ChunkSize = 4096 }; int indexOf(QAbstractSocket *socket) const; @@ -226,35 +215,9 @@ public: quint16 port; bool encrypt; - struct Channel { - QAbstractSocket *socket; - SocketState state; - QHttpNetworkRequest request; // current request - QHttpNetworkReply *reply; // current reply for this request - qint64 written; - qint64 bytesTotal; - bool resendCurrent; - int lastStatus; // last status received on this channel - bool pendingEncrypt; // for https (send after encrypted) - int reconnectAttempts; // maximum 2 reconnection attempts - QAuthenticatorPrivate::Method authMehtod; - QAuthenticatorPrivate::Method proxyAuthMehtod; - QAuthenticator authenticator; - QAuthenticator proxyAuthenticator; -#ifndef QT_NO_OPENSSL - bool ignoreAllSslErrors; - QList<QSslError> ignoreSslErrorsList; -#endif - Channel() : socket(0), state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), - lastStatus(0), pendingEncrypt(false), reconnectAttempts(2), - authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None) -#ifndef QT_NO_OPENSSL - , ignoreAllSslErrors(false) -#endif - {} - }; static const int channelCount; - Channel *channels; // parallel connections to the server + QHttpNetworkConnectionChannel *channels; // parallel connections to the server + bool pendingAuthSignal; // there is an incomplete authentication signal bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp new file mode 100644 index 0000000..a04b530 --- /dev/null +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qhttpnetworkconnection_p.h" +#include "qhttpnetworkconnectionchannel_p.h" + +#include <qpair.h> +#include <qdebug.h> + +#ifndef QT_NO_HTTP + +#ifndef QT_NO_OPENSSL +# include <QtNetwork/qsslkey.h> +# include <QtNetwork/qsslcipher.h> +# include <QtNetwork/qsslconfiguration.h> +#endif + +QT_BEGIN_NAMESPACE + +// TODO: Put channel specific stuff here so it does not polute qhttpnetworkconnection.cpp + +QT_END_NAMESPACE + +#include "moc_qhttpnetworkconnectionchannel_p.cpp" + +#endif // QT_NO_HTTP diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h new file mode 100644 index 0000000..cbabc67 --- /dev/null +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QHTTPNETWORKCONNECTIONCHANNEL_H +#define QHTTPNETWORKCONNECTIONCHANNEL_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the Network Access API. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// +#include <QtNetwork/qnetworkrequest.h> +#include <QtNetwork/qnetworkreply.h> +#include <QtNetwork/qabstractsocket.h> + +#include <private/qobject_p.h> +#include <qauthenticator.h> +#include <qnetworkproxy.h> +#include <qbuffer.h> + +#include <private/qhttpnetworkheader_p.h> +#include <private/qhttpnetworkrequest_p.h> +#include <private/qhttpnetworkreply_p.h> + + +#ifndef QT_NO_HTTP + +#ifndef QT_NO_OPENSSL +# include <QtNetwork/qsslsocket.h> +# include <QtNetwork/qsslerror.h> +#else +# include <QtNetwork/qtcpsocket.h> +#endif + +QT_BEGIN_NAMESPACE + +class QHttpNetworkRequest; +class QHttpNetworkReply; +class QByteArray; + +class QHttpNetworkConnectionChannel : public QObject { + Q_OBJECT +public: + enum ChannelState { + IdleState = 0, // ready to send request + ConnectingState = 1, // connecting to host + WritingState = 2, // writing the data + WaitingState = 4, // waiting for reply + ReadingState = 8, // reading the reply + Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done + BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState) + }; + QAbstractSocket *socket; + ChannelState state; + QHttpNetworkRequest request; // current request + QHttpNetworkReply *reply; // current reply for this request + qint64 written; + qint64 bytesTotal; + bool resendCurrent; + int lastStatus; // last status received on this channel + bool pendingEncrypt; // for https (send after encrypted) + int reconnectAttempts; // maximum 2 reconnection attempts + QAuthenticatorPrivate::Method authMehtod; + QAuthenticatorPrivate::Method proxyAuthMehtod; + QAuthenticator authenticator; + QAuthenticator proxyAuthenticator; +#ifndef QT_NO_OPENSSL + bool ignoreAllSslErrors; + QList<QSslError> ignoreSslErrorsList; +#endif + QHttpNetworkConnectionChannel() : socket(0), state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), + lastStatus(0), pendingEncrypt(false), reconnectAttempts(2), + authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None) +#ifndef QT_NO_OPENSSL + , ignoreAllSslErrors(false) +#endif + {} +}; + + + +QT_END_NAMESPACE + +#endif // QT_NO_HTTP + +#endif diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index f99a863..854bd17 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -1031,259 +1031,4 @@ QDebug operator<<(QDebug s, const QNetworkCookie &cookie) } #endif - - -class QNetworkCookieJarPrivate: public QObjectPrivate -{ -public: - QList<QNetworkCookie> allCookies; - - Q_DECLARE_PUBLIC(QNetworkCookieJar) -}; - -/*! - \class QNetworkCookieJar - \brief The QNetworkCookieJar class implements a simple jar of QNetworkCookie objects - \since 4.4 - - Cookies are small bits of information that stateless protocols - like HTTP use to maintain some persistent information across - requests. - - A cookie is set by a remote server when it replies to a request - and it expects the same cookie to be sent back when further - requests are sent. - - The cookie jar is the object that holds all cookies set in - previous requests. Web browsers save their cookie jars to disk in - order to conserve permanent cookies across invocations of the - application. - - QNetworkCookieJar does not implement permanent storage: it only - keeps the cookies in memory. Once the QNetworkCookieJar object is - deleted, all cookies it held will be discarded as well. If you - want to save the cookies, you should derive from this class and - implement the saving to disk to your own storage format. - - This class implements only the basic security recommended by the - cookie specifications and does not implement any cookie acceptance - policy (it accepts all cookies set by any requests). In order to - override those rules, you should reimplement the - cookiesForUrl() and setCookiesFromUrl() virtual - functions. They are called by QNetworkReply and - QNetworkAccessManager when they detect new cookies and when they - require cookies. - - \sa QNetworkCookie, QNetworkAccessManager, QNetworkReply, - QNetworkRequest, QNetworkAccessManager::setCookieJar() -*/ - -/*! - Creates a QNetworkCookieJar object and sets the parent object to - be \a parent. - - The cookie jar is initialized to empty. -*/ -QNetworkCookieJar::QNetworkCookieJar(QObject *parent) - : QObject(*new QNetworkCookieJarPrivate, parent) -{ -} - -/*! - Destroys this cookie jar object and discards all cookies stored in - it. Cookies are not saved to disk in the QNetworkCookieJar default - implementation. - - If you need to save the cookies to disk, you have to derive from - QNetworkCookieJar and save the cookies to disk yourself. -*/ -QNetworkCookieJar::~QNetworkCookieJar() -{ -} - -/*! - Returns all cookies stored in this cookie jar. This function is - suitable for derived classes to save cookies to disk, as well as - to implement cookie expiration and other policies. - - \sa setAllCookies(), cookiesForUrl() -*/ -QList<QNetworkCookie> QNetworkCookieJar::allCookies() const -{ - return d_func()->allCookies; -} - -/*! - Sets the internal list of cookies held by this cookie jar to be \a - cookieList. This function is suitable for derived classes to - implement loading cookies from permanent storage, or their own - cookie acceptance policies by reimplementing - setCookiesFromUrl(). - - \sa allCookies(), setCookiesFromUrl() -*/ -void QNetworkCookieJar::setAllCookies(const QList<QNetworkCookie> &cookieList) -{ - Q_D(QNetworkCookieJar); - d->allCookies = cookieList; -} - -static inline bool isParentPath(QString path, QString reference) -{ - if (!path.endsWith(QLatin1Char('/'))) - path += QLatin1Char('/'); - if (!reference.endsWith(QLatin1Char('/'))) - reference += QLatin1Char('/'); - return path.startsWith(reference); -} - -static inline bool isParentDomain(QString domain, QString reference) -{ - if (!reference.startsWith(QLatin1Char('.'))) - return domain == reference; - - return domain.endsWith(reference) || domain == reference.mid(1); -} - -/*! - Adds the cookies in the list \a cookieList to this cookie - jar. Default values for path and domain are taken from the \a - url object. - - Returns true if one or more cookes are set for url otherwise false. - - If a cookie already exists in the cookie jar, it will be - overridden by those in \a cookieList. - - The default QNetworkCookieJar class implements only a very basic - security policy (it makes sure that the cookies' domain and path - match the reply's). To enhance the security policy with your own - algorithms, override setCookiesFromUrl(). - - Also, QNetworkCookieJar does not have a maximum cookie jar - size. Reimplement this function to discard older cookies to create - room for new ones. - - \sa cookiesForUrl(), QNetworkAccessManager::setCookieJar() -*/ -bool QNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, - const QUrl &url) -{ - Q_D(QNetworkCookieJar); - QString defaultDomain = url.host(); - QString pathAndFileName = url.path(); - QString defaultPath = pathAndFileName.left(pathAndFileName.lastIndexOf(QLatin1Char('/'))+1); - if (defaultPath.isEmpty()) - defaultPath = QLatin1Char('/'); - - int added = 0; - QDateTime now = QDateTime::currentDateTime(); - foreach (QNetworkCookie cookie, cookieList) { - bool isDeletion = !cookie.isSessionCookie() && - cookie.expirationDate() < now; - - // validate the cookie & set the defaults if unset - if (cookie.path().isEmpty()) - cookie.setPath(defaultPath); - else if (!isParentPath(pathAndFileName, cookie.path())) - continue; // not accepted - - if (cookie.domain().isEmpty()) { - cookie.setDomain(defaultDomain); - } else { - QString domain = cookie.domain(); - if (!(isParentDomain(domain, defaultDomain) - || isParentDomain(defaultDomain, domain))) { - continue; // not accepted - } - - // reject if domain is like ".com" - // (i.e., reject if domain does not contain embedded dots, see RFC 2109 section 4.3.2) - // this is just a rudimentary check and does not cover all cases - if (domain.lastIndexOf(QLatin1Char('.')) == 0) - continue; // not accepted - - } - - QList<QNetworkCookie>::Iterator it = d->allCookies.begin(), - end = d->allCookies.end(); - for ( ; it != end; ++it) - // does this cookie already exist? - if (cookie.name() == it->name() && - cookie.domain() == it->domain() && - cookie.path() == it->path()) { - // found a match - d->allCookies.erase(it); - break; - } - - // did not find a match - if (!isDeletion) { - d->allCookies += cookie; - ++added; - } - } - return (added > 0); -} - -/*! - Returns the cookies to be added to when a request is sent to - \a url. This function is called by the default - QNetworkAccessManager::createRequest(), which adds the - cookies returned by this function to the request being sent. - - If more than one cookie with the same name is found, but with - differing paths, the one with longer path is returned before the - one with shorter path. In other words, this function returns - cookies sorted by path length. - - The default QNetworkCookieJar class implements only a very basic - security policy (it makes sure that the cookies' domain and path - match the reply's). To enhance the security policy with your own - algorithms, override cookiesForUrl(). - - \sa setCookiesFromUrl(), QNetworkAccessManager::setCookieJar() -*/ -QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const -{ -// \b Warning! This is only a dumb implementation! -// It does NOT follow all of the recommendations from -// http://wp.netscape.com/newsref/std/cookie_spec.html -// It does not implement a very good cross-domain verification yet. - - Q_D(const QNetworkCookieJar); - QDateTime now = QDateTime::currentDateTime(); - QList<QNetworkCookie> result; - - // scan our cookies for something that matches - QList<QNetworkCookie>::ConstIterator it = d->allCookies.constBegin(), - end = d->allCookies.constEnd(); - for ( ; it != end; ++it) { - if (!isParentDomain(url.host(), it->domain())) - continue; - if (!isParentPath(url.path(), it->path())) - continue; - if (!(*it).isSessionCookie() && (*it).expirationDate() < now) - continue; - - // insert this cookie into result, sorted by path - QList<QNetworkCookie>::Iterator insertIt = result.begin(); - while (insertIt != result.end()) { - if (insertIt->path().length() < it->path().length()) { - // insert here - insertIt = result.insert(insertIt, *it); - break; - } else { - ++insertIt; - } - } - - // this is the shortest path yet, just append - if (insertIt == result.end()) - result += *it; - } - - return result; -} - QT_END_NAMESPACE diff --git a/src/network/access/qnetworkcookie.h b/src/network/access/qnetworkcookie.h index c11b5b5..ef309a8 100644 --- a/src/network/access/qnetworkcookie.h +++ b/src/network/access/qnetworkcookie.h @@ -106,25 +106,8 @@ private: }; Q_DECLARE_TYPEINFO(QNetworkCookie, Q_MOVABLE_TYPE); -class QNetworkCookieJarPrivate; -class Q_NETWORK_EXPORT QNetworkCookieJar: public QObject -{ - Q_OBJECT -public: - QNetworkCookieJar(QObject *parent = 0); - virtual ~QNetworkCookieJar(); - - virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const; - virtual bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url); - -protected: - QList<QNetworkCookie> allCookies() const; - void setAllCookies(const QList<QNetworkCookie> &cookieList); - -private: - Q_DECLARE_PRIVATE(QNetworkCookieJar) - Q_DISABLE_COPY(QNetworkCookieJar) -}; +// ### Qt5 remove this include +#include "qnetworkcookiejar.h" #ifndef QT_NO_DEBUG_STREAM class QDebug; diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp new file mode 100644 index 0000000..03f7427 --- /dev/null +++ b/src/network/access/qnetworkcookiejar.cpp @@ -0,0 +1,296 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnetworkcookiejar.h" +#include "qnetworkcookiejar_p.h" + +#include "QtNetwork/qnetworkcookie.h" +#include "QtCore/qurl.h" +#include "QtCore/qdatetime.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QNetworkCookieJar + \brief The QNetworkCookieJar class implements a simple jar of QNetworkCookie objects + \since 4.4 + + Cookies are small bits of information that stateless protocols + like HTTP use to maintain some persistent information across + requests. + + A cookie is set by a remote server when it replies to a request + and it expects the same cookie to be sent back when further + requests are sent. + + The cookie jar is the object that holds all cookies set in + previous requests. Web browsers save their cookie jars to disk in + order to conserve permanent cookies across invocations of the + application. + + QNetworkCookieJar does not implement permanent storage: it only + keeps the cookies in memory. Once the QNetworkCookieJar object is + deleted, all cookies it held will be discarded as well. If you + want to save the cookies, you should derive from this class and + implement the saving to disk to your own storage format. + + This class implements only the basic security recommended by the + cookie specifications and does not implement any cookie acceptance + policy (it accepts all cookies set by any requests). In order to + override those rules, you should reimplement the + cookiesForUrl() and setCookiesFromUrl() virtual + functions. They are called by QNetworkReply and + QNetworkAccessManager when they detect new cookies and when they + require cookies. + + \sa QNetworkCookie, QNetworkAccessManager, QNetworkReply, + QNetworkRequest, QNetworkAccessManager::setCookieJar() +*/ + +/*! + Creates a QNetworkCookieJar object and sets the parent object to + be \a parent. + + The cookie jar is initialized to empty. +*/ +QNetworkCookieJar::QNetworkCookieJar(QObject *parent) + : QObject(*new QNetworkCookieJarPrivate, parent) +{ +} + +/*! + Destroys this cookie jar object and discards all cookies stored in + it. Cookies are not saved to disk in the QNetworkCookieJar default + implementation. + + If you need to save the cookies to disk, you have to derive from + QNetworkCookieJar and save the cookies to disk yourself. +*/ +QNetworkCookieJar::~QNetworkCookieJar() +{ +} + +/*! + Returns all cookies stored in this cookie jar. This function is + suitable for derived classes to save cookies to disk, as well as + to implement cookie expiration and other policies. + + \sa setAllCookies(), cookiesForUrl() +*/ +QList<QNetworkCookie> QNetworkCookieJar::allCookies() const +{ + return d_func()->allCookies; +} + +/*! + Sets the internal list of cookies held by this cookie jar to be \a + cookieList. This function is suitable for derived classes to + implement loading cookies from permanent storage, or their own + cookie acceptance policies by reimplementing + setCookiesFromUrl(). + + \sa allCookies(), setCookiesFromUrl() +*/ +void QNetworkCookieJar::setAllCookies(const QList<QNetworkCookie> &cookieList) +{ + Q_D(QNetworkCookieJar); + d->allCookies = cookieList; +} + +static inline bool isParentPath(QString path, QString reference) +{ + if (!path.endsWith(QLatin1Char('/'))) + path += QLatin1Char('/'); + if (!reference.endsWith(QLatin1Char('/'))) + reference += QLatin1Char('/'); + return path.startsWith(reference); +} + +static inline bool isParentDomain(QString domain, QString reference) +{ + if (!reference.startsWith(QLatin1Char('.'))) + return domain == reference; + + return domain.endsWith(reference) || domain == reference.mid(1); +} + +/*! + Adds the cookies in the list \a cookieList to this cookie + jar. Default values for path and domain are taken from the \a + url object. + + Returns true if one or more cookes are set for url otherwise false. + + If a cookie already exists in the cookie jar, it will be + overridden by those in \a cookieList. + + The default QNetworkCookieJar class implements only a very basic + security policy (it makes sure that the cookies' domain and path + match the reply's). To enhance the security policy with your own + algorithms, override setCookiesFromUrl(). + + Also, QNetworkCookieJar does not have a maximum cookie jar + size. Reimplement this function to discard older cookies to create + room for new ones. + + \sa cookiesForUrl(), QNetworkAccessManager::setCookieJar() +*/ +bool QNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, + const QUrl &url) +{ + Q_D(QNetworkCookieJar); + QString defaultDomain = url.host(); + QString pathAndFileName = url.path(); + QString defaultPath = pathAndFileName.left(pathAndFileName.lastIndexOf(QLatin1Char('/'))+1); + if (defaultPath.isEmpty()) + defaultPath = QLatin1Char('/'); + + int added = 0; + QDateTime now = QDateTime::currentDateTime(); + foreach (QNetworkCookie cookie, cookieList) { + bool isDeletion = !cookie.isSessionCookie() && + cookie.expirationDate() < now; + + // validate the cookie & set the defaults if unset + if (cookie.path().isEmpty()) + cookie.setPath(defaultPath); + else if (!isParentPath(pathAndFileName, cookie.path())) + continue; // not accepted + + if (cookie.domain().isEmpty()) { + cookie.setDomain(defaultDomain); + } else { + QString domain = cookie.domain(); + if (!(isParentDomain(domain, defaultDomain) + || isParentDomain(defaultDomain, domain))) { + continue; // not accepted + } + + // reject if domain is like ".com" + // (i.e., reject if domain does not contain embedded dots, see RFC 2109 section 4.3.2) + // this is just a rudimentary check and does not cover all cases + if (domain.lastIndexOf(QLatin1Char('.')) == 0) + continue; // not accepted + + } + + QList<QNetworkCookie>::Iterator it = d->allCookies.begin(), + end = d->allCookies.end(); + for ( ; it != end; ++it) + // does this cookie already exist? + if (cookie.name() == it->name() && + cookie.domain() == it->domain() && + cookie.path() == it->path()) { + // found a match + d->allCookies.erase(it); + break; + } + + // did not find a match + if (!isDeletion) { + d->allCookies += cookie; + ++added; + } + } + return (added > 0); +} + +/*! + Returns the cookies to be added to when a request is sent to + \a url. This function is called by the default + QNetworkAccessManager::createRequest(), which adds the + cookies returned by this function to the request being sent. + + If more than one cookie with the same name is found, but with + differing paths, the one with longer path is returned before the + one with shorter path. In other words, this function returns + cookies sorted by path length. + + The default QNetworkCookieJar class implements only a very basic + security policy (it makes sure that the cookies' domain and path + match the reply's). To enhance the security policy with your own + algorithms, override cookiesForUrl(). + + \sa setCookiesFromUrl(), QNetworkAccessManager::setCookieJar() +*/ +QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const +{ +// \b Warning! This is only a dumb implementation! +// It does NOT follow all of the recommendations from +// http://wp.netscape.com/newsref/std/cookie_spec.html +// It does not implement a very good cross-domain verification yet. + + Q_D(const QNetworkCookieJar); + QDateTime now = QDateTime::currentDateTime(); + QList<QNetworkCookie> result; + + // scan our cookies for something that matches + QList<QNetworkCookie>::ConstIterator it = d->allCookies.constBegin(), + end = d->allCookies.constEnd(); + for ( ; it != end; ++it) { + if (!isParentDomain(url.host(), it->domain())) + continue; + if (!isParentPath(url.path(), it->path())) + continue; + if (!(*it).isSessionCookie() && (*it).expirationDate() < now) + continue; + + // insert this cookie into result, sorted by path + QList<QNetworkCookie>::Iterator insertIt = result.begin(); + while (insertIt != result.end()) { + if (insertIt->path().length() < it->path().length()) { + // insert here + insertIt = result.insert(insertIt, *it); + break; + } else { + ++insertIt; + } + } + + // this is the shortest path yet, just append + if (insertIt == result.end()) + result += *it; + } + + return result; +} + +QT_END_NAMESPACE diff --git a/src/network/access/qnetworkcookiejar.h b/src/network/access/qnetworkcookiejar.h new file mode 100644 index 0000000..b2cdf12 --- /dev/null +++ b/src/network/access/qnetworkcookiejar.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKCOOKIEJAR_H +#define QNETWORKCOOKIEJAR_H + +#include <QtCore/QObject> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Network) + +class QNetworkCookie; + +class QNetworkCookieJarPrivate; +class Q_NETWORK_EXPORT QNetworkCookieJar: public QObject +{ + Q_OBJECT +public: + QNetworkCookieJar(QObject *parent = 0); + virtual ~QNetworkCookieJar(); + + virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const; + virtual bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url); + +protected: + QList<QNetworkCookie> allCookies() const; + void setAllCookies(const QList<QNetworkCookie> &cookieList); + +private: + Q_DECLARE_PRIVATE(QNetworkCookieJar) + Q_DISABLE_COPY(QNetworkCookieJar) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/network/access/qnetworkcookiejar_p.h b/src/network/access/qnetworkcookiejar_p.h new file mode 100644 index 0000000..eea7eee --- /dev/null +++ b/src/network/access/qnetworkcookiejar_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKCOOKIEJAR_P_H +#define QNETWORKCOOKIEJAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the Network Access framework. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include "private/qobject_p.h" +#include "qnetworkcookie.h" + +QT_BEGIN_NAMESPACE + +class QNetworkCookieJarPrivate: public QObjectPrivate +{ +public: + QList<QNetworkCookie> allCookies; + + Q_DECLARE_PUBLIC(QNetworkCookieJar) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index fef488b..64e9e29 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -57,7 +57,11 @@ static const int RESOLVER_TIMEOUT = 2000; #include <sys/types.h> #include <netdb.h> #include <arpa/inet.h> -#include <resolv.h> +#if defined(Q_OS_VXWORKS) +# include <hostLib.h> +#else +# include <resolv.h> +#endif #if defined (QT_NO_GETADDRINFO) #include <qmutex.h> @@ -275,10 +279,12 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) results.setError(QHostInfo::UnknownError); results.setErrorString(tr("Unknown address type")); } +#if !defined(Q_OS_VXWORKS) } else if (h_errno == HOST_NOT_FOUND || h_errno == NO_DATA || h_errno == NO_ADDRESS) { results.setError(QHostInfo::HostNotFound); results.setErrorString(tr("Host not found")); +#endif } else { results.setError(QHostInfo::UnknownError); results.setErrorString(tr("Unknown error")); @@ -315,6 +321,7 @@ QString QHostInfo::localHostName() QString QHostInfo::localDomainName() { +#if !defined(Q_OS_VXWORKS) resolveLibrary(); if (local_res_ninit) { // using thread-safe version @@ -344,7 +351,7 @@ QString QHostInfo::localDomainName() domainName = QUrl::fromAce(local_res->dnsrch[0]); return domainName; } - +#endif // nothing worked, try doing it by ourselves: QFile resolvconf; #if defined(_PATH_RESCONF) diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp index c2e05cd..3df6b6a 100644 --- a/src/network/socket/qlocalserver_unix.cpp +++ b/src/network/socket/qlocalserver_unix.cpp @@ -54,6 +54,10 @@ #include <qdir.h> #include <qdatetime.h> +#ifdef Q_OS_VXWORKS +# include <selectLib.h> +#endif + QT_BEGIN_NAMESPACE void QLocalServerPrivate::init() diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index d038794..08d94ef 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -56,6 +56,10 @@ #include <qdir.h> #include <qdebug.h> +#ifdef Q_OS_VXWORKS +# include <selectLib.h> +#endif + #define QT_CONNECT_TIMEOUT 30000 QT_BEGIN_NAMESPACE diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h index a9479d3..24dc344 100644 --- a/src/network/socket/qnativesocketengine_p.h +++ b/src/network/socket/qnativesocketengine_p.h @@ -56,9 +56,9 @@ #include "QtNetwork/qhostaddress.h" #include "private/qabstractsocketengine_p.h" #ifndef Q_OS_WIN -# include "qplatformdefs.h" +# include "qplatformdefs.h" #else -# include <winsock2.h> +# include <winsock2.h> #endif QT_BEGIN_NAMESPACE diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index b4b673a..6f9ee1a 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -237,7 +237,7 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co int v = -1; QT_SOCKOPTLEN_T len = sizeof(v); - if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1) + if (::getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1) return v; return -1; } @@ -267,6 +267,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt break; case QNativeSocketEngine::NonBlockingSocketOption: { // Make the socket nonblocking. +#if !defined(Q_OS_VXWORKS) int flags = ::fcntl(socketDescriptor, F_GETFL, 0); if (flags == -1) { #ifdef QNATIVESOCKETENGINE_DEBUG @@ -280,7 +281,15 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt #endif return false; } - +#else // Q_OS_VXWORKS + int onoff = 1; + if (qt_safe_ioctl(socketDescriptor, FIONBIO, &onoff) < 0) { +#ifdef QNATIVESOCKETENGINE_DEBUG + perror("QNativeSocketEnginePrivate::setOption(): ioctl(FIONBIO, 1) failed"); +#endif + return false; + } +#endif // Q_OS_VXWORKS return true; } case QNativeSocketEngine::AddressReusable: @@ -652,11 +661,8 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l // ignore the SIGPIPE signal qt_ignore_sigpipe(); - ssize_t sentBytes; - do { - sentBytes = qt_safe_sendto(socketDescriptor, data, len, - 0, sockAddrPtr, sockAddrSize); - } while (sentBytes == -1 && errno == EINTR); + ssize_t sentBytes = qt_safe_sendto(socketDescriptor, data, len, + 0, sockAddrPtr, sockAddrSize); if (sentBytes < 0) { switch (errno) { @@ -722,7 +728,7 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() // Determine the socket type (UDP/TCP) int value = 0; QT_SOCKOPTLEN_T valueSize = sizeof(int); - if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_TYPE, &value, &valueSize) == 0) { + if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_TYPE, (char *) &value, &valueSize) == 0) { if (value == SOCK_STREAM) socketType = QAbstractSocket::TcpSocket; else if (value == SOCK_DGRAM) @@ -767,7 +773,7 @@ qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len) // of an interrupting signal. ssize_t writtenBytes; do { - writtenBytes = ::write(socketDescriptor, data, len); + writtenBytes = QT_WRITE(socketDescriptor, data, len); } while (writtenBytes < 0 && errno == EINTR); if (writtenBytes < 0) { @@ -828,6 +834,9 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize) setError(QAbstractSocket::NetworkError, ReadErrorString); break; case ECONNRESET: +#if defined(Q_OS_VXWORKS) + case ESHUTDOWN: +#endif r = 0; break; default: diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index 03ed3b4..f38c2fc 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -59,11 +59,18 @@ #include <sys/socket.h> #include <netinet/in.h> +#if defined(Q_OS_VXWORKS) +# include <sockLib.h> +#endif + // for inet_addr #include <netdb.h> #include <arpa/inet.h> -#include <resolv.h> - +#if defined(Q_OS_VXWORKS) +# include <hostLib.h> +#else +# include <resolv.h> +#endif QT_BEGIN_NAMESPACE @@ -155,17 +162,28 @@ static inline int qt_safe_connect(int sockfd, const struct sockaddr *addr, QT_SO # undef listen #endif +// VxWorks' headers specify 'int' instead of '...' for the 3rd ioctl() parameter. template <typename T> static inline int qt_safe_ioctl(int sockfd, int request, T arg) { +#ifdef Q_OS_VXWORKS + return ::ioctl(sockfd, request, (int) arg); +#else return ::ioctl(sockfd, request, arg); +#endif } +// VxWorks' headers do not specify any const modifiers static inline in_addr_t qt_safe_inet_addr(const char *cp) { +#ifdef Q_OS_VXWORKS + return ::inet_addr((char *) cp); +#else return ::inet_addr(cp); +#endif } +// VxWorks' headers do not specify any const modifiers static inline int qt_safe_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *to, QT_SOCKLEN_T tolen) { #ifdef MSG_NOSIGNAL @@ -173,7 +191,11 @@ static inline int qt_safe_sendto(int sockfd, const void *buf, size_t len, int fl #endif register int ret; +#ifdef Q_OS_VXWORKS + EINTR_LOOP(ret, ::sendto(sockfd, (char *) buf, len, flags, (struct sockaddr *) to, tolen)); +#else EINTR_LOOP(ret, ::sendto(sockfd, buf, len, flags, to, tolen)); +#endif return ret; } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 167eb64..a3475c7 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1343,10 +1343,30 @@ void QGL2PaintEngineExPrivate::updateDepthScissorTest() else glDisable(GL_DEPTH_TEST); - if (q->state()->scissorTestEnabled) + if (q->state()->scissorTestEnabled) { + QRect bounds = q->state()->rectangleClip; + if (bounds.isNull() || !q->painter()->hasClipping()) { + if (use_system_clip) + bounds = systemClip.boundingRect(); + else + bounds = QRect(0, 0, width, height); + } + glEnable(GL_SCISSOR_TEST); - else + setScissor(bounds); + } else { glDisable(GL_SCISSOR_TEST); + } +} + +void QGL2PaintEngineExPrivate::setScissor(const QRect &rect) +{ + const int left = rect.left(); + const int width = rect.width(); + const int bottom = height - (rect.top() + rect.height()); + const int height = rect.height(); + + glScissor(left, bottom, width, height); } void QGL2PaintEngineEx::clipEnabledChanged() @@ -1362,9 +1382,10 @@ void QGL2PaintEngineEx::clipEnabledChanged() if (d->use_system_clip) { state()->currentDepth = -0.5f; } else { - glDisable(GL_DEPTH_TEST); state()->depthTestEnabled = false; } + + d->updateDepthScissorTest(); } } @@ -1436,9 +1457,42 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) if ((d->use_system_clip && rect.contains(d->systemClip.boundingRect())) || rect.contains(QRect(0, 0, d->width, d->height))) return; + + if (state()->rectangleClip.isValid()) { + state()->rectangleClip = state()->rectangleClip.intersected(rect.toRect()); + + state()->hasRectangleClip = true; + state()->scissorTestEnabled = true; + + glEnable(GL_SCISSOR_TEST); + d->setScissor(state()->rectangleClip); + + return; + } } } + if (!state()->hasRectangleClip) + state()->rectangleClip = QRect(); + + if (state()->rectangleClip.isValid() && op != Qt::NoClip && op != Qt::ReplaceClip) { + QPainterPath path; + path.addRect(state()->rectangleClip); + + state()->rectangleClip = QRect(); + d->updateDepthScissorTest(); + + glDepthFunc(GL_ALWAYS); + + state()->maxDepth = 0.5f; + d->writeClip(qtVectorPathForPath(path), state()->maxDepth); + state()->currentDepth = 0.25f; + state()->depthTestEnabled = true; + + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + } + switch (op) { case Qt::NoClip: if (d->use_system_clip) { @@ -1459,6 +1513,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) break; case Qt::ReplaceClip: d->systemStateChanged(); + state()->rectangleClip = QRect(); state()->maxDepth = 0.5f; glDepthFunc(GL_ALWAYS); d->writeClip(path, state()->maxDepth); @@ -1497,27 +1552,30 @@ void QGL2PaintEngineExPrivate::systemStateChanged() q->state()->depthTestEnabled = false; q->state()->scissorTestEnabled = false; q->state()->needsDepthBufferClear = true; + q->state()->hasRectangleClip = false; glDisable(GL_SCISSOR_TEST); q->state()->currentDepth = -0.5f; q->state()->maxDepth = 0.5f; - if (use_system_clip) { - QRect bounds = systemClip.boundingRect(); - if (systemClip.numRects() == 1 - && bounds == QRect(0, 0, width, height)) - { - q->state()->needsDepthBufferClear = true; - } else { - glEnable(GL_SCISSOR_TEST); + q->state()->rectangleClip = QRect(0, 0, width, height); - const int left = bounds.left(); - const int width = bounds.width(); - const int bottom = height - (bounds.top() + bounds.height()); - const int height = bounds.height(); + if (use_system_clip) { + if (systemClip.numRects() == 1) { + QRect bounds = systemClip.boundingRect(); + if (bounds == QRect(0, 0, width, height)) { + use_system_clip = false; + return; + } - glScissor(left, bottom, width, height); + q->state()->rectangleClip = bounds; + q->state()->scissorTestEnabled = true; + updateDepthScissorTest(); + } else { + q->state()->rectangleClip = QRect(); + q->state()->scissorTestEnabled = true; + updateDepthScissorTest(); QTransform transform = q->state()->matrix; q->state()->matrix = QTransform(); @@ -1539,7 +1597,6 @@ void QGL2PaintEngineExPrivate::systemStateChanged() glEnable(GL_DEPTH_TEST); q->state()->depthTestEnabled = true; - q->state()->scissorTestEnabled = true; q->state()->matrix = transform; q->transformChanged(); @@ -1614,6 +1671,8 @@ QOpenGL2PaintEngineState::QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &oth currentDepth = other.currentDepth; maxDepth = other.maxDepth; canRestoreClip = other.canRestoreClip; + rectangleClip = other.rectangleClip; + hasRectangleClip = other.hasRectangleClip; } QOpenGL2PaintEngineState::QOpenGL2PaintEngineState() @@ -1624,6 +1683,7 @@ QOpenGL2PaintEngineState::QOpenGL2PaintEngineState() currentDepth = -0.5f; maxDepth = 0.5f; canRestoreClip = true; + hasRectangleClip = false; } QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState() diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index ec447a3..906817b 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -86,6 +86,8 @@ public: qreal maxDepth; bool canRestoreClip; + QRect rectangleClip; + bool hasRectangleClip; }; @@ -217,6 +219,7 @@ public: void writeClip(const QVectorPath &path, float depth); void updateDepthScissorTest(); + void setScissor(const QRect &rect); void regenerateDepthClip(); void systemStateChanged(); uint use_system_clip : 1; diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 6381bc2..cf70991 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -66,6 +66,14 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xos.h> +#ifdef Q_OS_VXWORS +# ifdef open +# undef open +# endif +# ifdef getpid +# undef getpid +# endif +#endif // Q_OS_VXWORKS #include <X11/Xatom.h> #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) @@ -823,10 +831,12 @@ void QGLContext::swapBuffers() const if (!glXGetVideoSyncSGI) #endif { +#if !defined(QT_NO_LIBRARY) extern const QString qt_gl_library_name(); QLibrary lib(qt_gl_library_name()); glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) lib.resolve("glXGetVideoSyncSGI"); glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) lib.resolve("glXWaitVideoSyncSGI"); +#endif } } resolved = true; @@ -1067,9 +1077,11 @@ void *QGLContext::getProcAddress(const QString &proc) const if (!glXGetProcAddressARB) #endif { +#if !defined(QT_NO_LIBRARY) extern const QString qt_gl_library_name(); QLibrary lib(qt_gl_library_name()); glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB"); +#endif } } resolved = true; diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 3685661..abec78a 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -746,8 +746,11 @@ QGLFramebufferObject::~QGLFramebufferObject() The framebuffer can become invalid if the initialization process fails, the user attaches an invalid buffer to the framebuffer - object, or a non-power of 2 width/height is specified as the + object, or a non-power of two width/height is specified as the texture size if the texture target is \c{GL_TEXTURE_2D}. + The non-power of two limitation does not apply if the OpenGL version + is 2.0 or higher, or if the GL_ARB_texture_non_power_of_two extension + is present. */ bool QGLFramebufferObject::isValid() const { diff --git a/src/opengl/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp index 9e1f85d..ac2e705 100644 --- a/src/opengl/qglpixelbuffer_x11.cpp +++ b/src/opengl/qglpixelbuffer_x11.cpp @@ -115,6 +115,7 @@ static bool qt_resolve_pbuffer_extensions() if (!qt_glXChooseFBConfig) #endif { +#if !defined(QT_NO_LIBRARY) extern const QString qt_gl_library_name(); QLibrary gl(qt_gl_library_name()); qt_glXChooseFBConfig = (_glXChooseFBConfig) gl.resolve("glXChooseFBConfig"); @@ -123,6 +124,7 @@ static bool qt_resolve_pbuffer_extensions() qt_glXDestroyPbuffer = (_glXDestroyPbuffer) gl.resolve("glXDestroyPbuffer"); qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) gl.resolve("glXGetFBConfigAttrib"); qt_glXMakeContextCurrent = (_glXMakeContextCurrent) gl.resolve("glXMakeContextCurrent"); +#endif } resolved = qt_glXMakeContextCurrent ? true : false; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 4b76ef6..030e51f 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -745,6 +745,7 @@ QPixmapData *QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType typ return new QDirectFBPixmapData(type); } +#if (Q_DIRECTFB_VERSION >= 0x000923) #ifdef QT_NO_DEBUG struct FlagDescription; static const FlagDescription *accelerationDescriptions = 0; @@ -802,9 +803,6 @@ static const FlagDescription drawDescriptions[] = { }; #endif - - -#if (Q_DIRECTFB_VERSION >= 0x000923) static const QByteArray flagDescriptions(uint mask, const FlagDescription *flags) { #ifdef QT_NO_DEBUG diff --git a/src/qt3support/sql/q3sqlcursor.cpp b/src/qt3support/sql/q3sqlcursor.cpp index 6b0c69f..aa6aae2 100644 --- a/src/qt3support/sql/q3sqlcursor.cpp +++ b/src/qt3support/sql/q3sqlcursor.cpp @@ -879,7 +879,7 @@ QString Q3SqlCursor::toString(const QString& prefix, QSqlField* field, const QSt { QString f; if (field && driver()) { - f = (prefix.length() > 0 ? prefix + QLatin1Char('.') : QString()) + field->name(); + f = (prefix.length() > 0 ? prefix + QLatin1Char('.') : QString()) + driver()->escapeIdentifier(field->name(), QSqlDriver::FieldName); f += QLatin1Char(' ') + fieldSep + QLatin1Char(' '); if (field->isNull()) { f += QLatin1String("NULL"); diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index 474c53d..a32b3aa 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -868,11 +868,13 @@ bool QDB2Result::fetch(int i) SQL_FETCH_ABSOLUTE, actualIdx); } - if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { + if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r != SQL_NO_DATA) { setLastError(qMakeError(QCoreApplication::translate("QDB2Result", "Unable to fetch record %1").arg(i), QSqlError::StatementError, d)); return false; } + else if (r == SQL_NO_DATA) + return false; setAt(i); return true; } diff --git a/src/src.pro b/src/src.pro index 9bff20d..34db728 100644 --- a/src/src.pro +++ b/src/src.pro @@ -7,7 +7,7 @@ wince*:{ SRC_SUBDIRS += src_corelib src_xml src_gui src_sql src_network src_script src_testlib } else { SRC_SUBDIRS += src_tools_bootstrap src_tools_moc src_tools_rcc src_tools_uic src_corelib src_xml src_network src_gui src_sql src_script src_testlib - contains(QT_CONFIG, qt3support): SRC_SUBDIRS += src_qt3support + !vxworks:contains(QT_CONFIG, qt3support): SRC_SUBDIRS += src_qt3support contains(QT_CONFIG, dbus):SRC_SUBDIRS += src_dbus !cross_compile { contains(QT_CONFIG, qt3support): SRC_SUBDIRS += src_tools_uic3 diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 5857e1c..f10b26f 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include "qplatformdefs.h" + #include "qsvghandler_p.h" #ifndef QT_NO_SVG @@ -354,7 +356,7 @@ static qreal toDouble(const QChar *&str) if (neg) val = -val; } else { -#ifdef Q_WS_QWS +#if defined(Q_WS_QWS) && !defined(Q_OS_VXWORKS) if(sizeof(qreal) == sizeof(float)) val = strtof(temp, 0); else diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 9d6f68d..8cdfab0 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -53,6 +53,7 @@ #include <QtCore/qstringlist.h> #include <QtCore/qdatetime.h> #include <QtCore/qobject.h> +#include <QtCore/qvariant.h> #include <QtCore/qurl.h> #include <QtCore/qpoint.h> @@ -146,6 +147,30 @@ template<> inline char *toString(const QUrl &uri) return qstrdup(uri.toEncoded().constData()); } +template<> inline char *toString(const QVariant &v) +{ + QByteArray vstring("QVariant("); + if (v.isValid()) { + QByteArray type(v.typeName()); + if (type.isEmpty()) { + type = QByteArray::number(v.userType()); + } + vstring.append(type); + if (!v.isNull()) { + vstring.append(','); + if (v.canConvert(QVariant::String)) { + vstring.append(qVariantValue<QString>(v).toLatin1()); + } + else { + vstring.append("<value not representable as string>"); + } + } + } + vstring.append(')'); + + return qstrdup(vstring.constData()); +} + #ifndef QTEST_NO_SPECIALIZATIONS template<> #endif diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 1d0bbcf..cb05400 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -685,6 +685,13 @@ QT_BEGIN_NAMESPACE Returns a textual representation of the given \a rectangle. */ +/*! + \fn char *QTest::toString(const QVariant &variant) + \overload + + Returns a textual representation of the given \a variant. +*/ + /*! \fn void QTest::qWait(int ms) Waits for \a ms milliseconds. While waiting, events will be processed and diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index fe1e740..3b1726b 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -244,6 +244,16 @@ public: class QXmlParseExceptionPrivate { public: + QXmlParseExceptionPrivate() + : column(-1), line(-1) + { + } + QXmlParseExceptionPrivate(const QXmlParseExceptionPrivate &other) + : msg(other.msg), column(other.column), line(other.line), + pub(other.pub), sys(other.sys) + { + } + QString msg; int column; int line; @@ -553,6 +563,14 @@ QXmlParseException::QXmlParseException(const QString& name, int c, int l, } /*! + Creates a copy of \a other. +*/ +QXmlParseException::QXmlParseException(const QXmlParseException& other) +{ + d = new QXmlParseExceptionPrivate(*other.d); +} + +/*! Destroys the QXmlParseException. */ QXmlParseException::~QXmlParseException() diff --git a/src/xml/sax/qxml.h b/src/xml/sax/qxml.h index 8aa7e63..6ccd44e 100644 --- a/src/xml/sax/qxml.h +++ b/src/xml/sax/qxml.h @@ -193,6 +193,7 @@ class Q_XML_EXPORT QXmlParseException public: explicit QXmlParseException(const QString &name = QString(), int c = -1, int l = -1, const QString &p = QString(), const QString &s = QString()); + QXmlParseException(const QXmlParseException &other); ~QXmlParseException(); int columnNumber() const; diff --git a/src/xmlpatterns/parser/qquerytransformparser_p.h b/src/xmlpatterns/parser/qquerytransformparser_p.h index bb01788..06953d0 100644 --- a/src/xmlpatterns/parser/qquerytransformparser_p.h +++ b/src/xmlpatterns/parser/qquerytransformparser_p.h @@ -154,6 +154,18 @@ #ifdef SELF # undef SELF #endif +/* These tokens are defined in VxWorks kernel mode + * + * Hence this un-break fix. Note that this file was auto generated. */ +#ifdef ERROR +# undef ERROR +#endif +#ifdef IMPORT +# undef IMPORT +#endif +#ifdef MAP +# undef MAP +#endif /* These tokens are defined to nothing on Windows because they're * used in their documentation parser, for use in things like: diff --git a/src/xmlpatterns/parser/winCEWorkaround.sed b/src/xmlpatterns/parser/winCEWorkaround.sed index d1c09e8..46f18ae 100644 --- a/src/xmlpatterns/parser/winCEWorkaround.sed +++ b/src/xmlpatterns/parser/winCEWorkaround.sed @@ -17,4 +17,16 @@ \#ifdef SELF\ \# undef SELF\ \#endif\ +\/\* These tokens are defined in VxWorks kernel mode\ + \*\ + \* Hence this un-break fix. Note that this file was auto generated. *\/\ +\#ifdef ERROR\ +\# undef ERROR\ +\#endif\ +\#ifdef IMPORT\ +\# undef IMPORT\ +\#endif\ +\#ifdef MAP\ +\# undef MAP\ +\#endif\ diff --git a/tests/auto/qbytearray/tst_qbytearray.cpp b/tests/auto/qbytearray/tst_qbytearray.cpp index b7e4717..c004be1 100644 --- a/tests/auto/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/qbytearray/tst_qbytearray.cpp @@ -236,7 +236,7 @@ void tst_QByteArray::qUncompress() #elif defined Q_OS_SOLARIS QSKIP("Corrupt data causes this tests to lock up on Solaris", SkipAll); #elif defined Q_OS_QNX - QSKIP("Currupt data cuases this test to lock up on QNX", SkipAll); + QSKIP("Corrupt data causes this test to lock up on QNX", SkipAll); #endif QTEST(::qUncompress(in), "out"); diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index e5b23ab..e900ed0 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -51,7 +51,9 @@ #include "../network-settings.h" - +#if defined(Q_OS_VXWORKS) +#define Q_NO_SYMLINKS +#endif //TESTED_CLASS= //TESTED_FILES= @@ -370,6 +372,20 @@ void tst_QDir::compare() QVERIFY(dir == QDir::currentPath()); } +static QStringList filterLinks(const QStringList &list) +{ +#ifndef Q_NO_SYMLINKS + return list; +#else + QStringList result; + foreach (QString str, list) { + if (!str.endsWith(QLatin1String(".lnk"))) + result.append(str); + } + return result; +#endif +} + void tst_QDir::entryList_data() { QTest::addColumn<QString>("dirName"); // relative from current path or abs @@ -411,94 +427,95 @@ void tst_QDir::entryList_data() QTest::newRow("nofilter") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::NoFilter) << int(QDir::Name) - << QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','); + << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(',')); QTest::newRow("QDir::AllEntries") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::AllEntries) << int(QDir::Name) - << QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','); + << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(',')); QTest::newRow("QDir::Files") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::Files) << int(QDir::Name) - << QString("file,linktofile.lnk,writable").split(','); + << filterLinks(QString("file,linktofile.lnk,writable").split(',')); QTest::newRow("QDir::Dirs") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::Dirs) << int(QDir::Name) - << QString(".,..,directory,linktodirectory.lnk").split(','); + << filterLinks(QString(".,..,directory,linktodirectory.lnk").split(',')); QTest::newRow("QDir::Dirs | QDir::NoDotAndDotDot") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::Dirs | QDir::NoDotAndDotDot) << int(QDir::Name) - << QString("directory,linktodirectory.lnk").split(','); + << filterLinks(QString("directory,linktodirectory.lnk").split(',')); QTest::newRow("QDir::AllDirs") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::AllDirs) << int(QDir::Name) - << QString(".,..,directory,linktodirectory.lnk").split(','); + << filterLinks(QString(".,..,directory,linktodirectory.lnk").split(',')); QTest::newRow("QDir::AllDirs | QDir::Dirs") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::AllDirs | QDir::Dirs) << int(QDir::Name) - << QString(".,..,directory,linktodirectory.lnk").split(','); + << filterLinks(QString(".,..,directory,linktodirectory.lnk").split(',')); QTest::newRow("QDir::AllDirs | QDir::Files") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::AllDirs | QDir::Files) << int(QDir::Name) - << QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','); + << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(',')); QTest::newRow("QDir::AllEntries | QDir::NoSymLinks") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::AllEntries | QDir::NoSymLinks) << int(QDir::Name) - << QString(".,..,directory,file,writable").split(','); + << filterLinks(QString(".,..,directory,file,writable").split(',')); QTest::newRow("QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot) << int(QDir::Name) - << QString("directory,file,writable").split(','); + << filterLinks(QString("directory,file,writable").split(',')); QTest::newRow("QDir::Files | QDir::NoSymLinks") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::Files | QDir::NoSymLinks) << int(QDir::Name) - << QString("file,writable").split(','); + << filterLinks(QString("file,writable").split(',')); QTest::newRow("QDir::Dirs | QDir::NoSymLinks") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::Dirs | QDir::NoSymLinks) << int(QDir::Name) - << QString(".,..,directory").split(','); + << filterLinks(QString(".,..,directory").split(',')); QTest::newRow("QDir::Drives | QDir::Files | QDir::NoDotAndDotDot") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::Drives | QDir::Files | QDir::NoDotAndDotDot) << int(QDir::Name) - << QString("file,linktofile.lnk,writable").split(','); + << filterLinks(QString("file,linktofile.lnk,writable").split(',')); QTest::newRow("QDir::System") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::System) << int(QDir::Name) - << QStringList("brokenlink.lnk"); + << filterLinks(QStringList("brokenlink.lnk")); QTest::newRow("QDir::Hidden") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::Hidden) << int(QDir::Name) << QStringList(); QTest::newRow("QDir::System | QDir::Hidden") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::System | QDir::Hidden) << int(QDir::Name) - << QStringList("brokenlink.lnk"); + << filterLinks(QStringList("brokenlink.lnk")); QTest::newRow("QDir::AllDirs | QDir::NoSymLinks") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::AllDirs | QDir::NoSymLinks) << int(QDir::Name) - << QString(".,..,directory").split(','); + << filterLinks(QString(".,..,directory").split(',')); #ifdef QT3_SUPPORT QTest::newRow("QDir::All | QDir::Hidden | QDir::System") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::All | QDir::Hidden | QDir::System) << int(QDir::Name) - << QString(".,..,brokenlink.lnk,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','); + << filterLinks(QString(".,..,brokenlink.lnk,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(',')); QTest::newRow("QDir::All | QDir::Readable") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::All | QDir::Readable) << int(QDir::Name) - << QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','); + << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(',')); QTest::newRow("QDir::All | QDir::Writable") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::All | QDir::Writable) << int(QDir::Name) - << QString(".,..,directory,linktodirectory.lnk,writable").split(','); + << filterLinks(QString(".,..,directory,linktodirectory.lnk,writable").split(',')); #else QTest::newRow("QDir::AllEntries | QDir::Hidden | QDir::System") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::AllEntries | QDir::Hidden | QDir::System) << int(QDir::Name) - << QString(".,..,brokenlink.lnk,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','); + << filterLinks(QString(".,..,brokenlink.lnk,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(',')); QTest::newRow("QDir::AllEntries | QDir::Readable") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::AllEntries | QDir::Readable) << int(QDir::Name) - << QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','); + << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(',')); QTest::newRow("QDir::AllEntries | QDir::Writable") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::AllEntries | QDir::Writable) << int(QDir::Name) - << QString(".,..,directory,linktodirectory.lnk,writable").split(','); + << filterLinks(QString(".,..,directory,linktodirectory.lnk,writable").split(',')); #endif QTest::newRow("Namefilters b*") << SRCDIR "entrylist/" << QStringList("d*") << int(QDir::NoFilter) << int(QDir::Name) - << QString("directory").split(','); + << filterLinks(QString("directory").split(',')); QTest::newRow("Namefilters f*") << SRCDIR "entrylist/" << QStringList("f*") << int(QDir::NoFilter) << int(QDir::Name) - << QString("file").split(','); + << filterLinks(QString("file").split(',')); QTest::newRow("Namefilters link*") << SRCDIR "entrylist/" << QStringList("link*") << int(QDir::NoFilter) << int(QDir::Name) - << QString("linktodirectory.lnk,linktofile.lnk").split(','); + << filterLinks(QString("linktodirectory.lnk,linktofile.lnk").split(',')); QTest::newRow("Namefilters *to*") << SRCDIR "entrylist/" << QStringList("*to*") << int(QDir::NoFilter) << int(QDir::Name) - << QString("directory,linktodirectory.lnk,linktofile.lnk").split(','); + << filterLinks(QString("directory,linktodirectory.lnk,linktofile.lnk").split(',')); QTest::newRow("Sorting QDir::Name") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::NoFilter) << int(QDir::Name) - << QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','); + << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(',')); QTest::newRow("Sorting QDir::Name | QDir::Reversed") << SRCDIR "entrylist/" << QStringList("*") << int(QDir::NoFilter) << int(QDir::Name | QDir::Reversed) - << QString("writable,linktofile.lnk,linktodirectory.lnk,file,directory,..,.").split(','); + << filterLinks(QString("writable,linktofile.lnk,linktodirectory.lnk,file,directory,..,.").split(',')); + QTest::newRow("Sorting QDir::Type") << SRCDIR "types/" << QStringList("*") << int(QDir::NoFilter) << int(QDir::Type) << QString(".,..,a,b,c,d,e,f,a.a,b.a,c.a,d.a,e.a,f.a,a.b,b.b,c.b,d.b,e.b,f.b,a.c,b.c,c.c,d.c,e.c,f.c").split(','); @@ -635,6 +652,7 @@ void tst_QDir::entryListSimple() void tst_QDir::entryListWithSymLinks() { +#ifndef Q_NO_SYMLINKS QFile::remove("myLinkToDir.lnk"); QFile::remove("myLinkToFile.lnk"); QFile::remove("testfile.cpp"); @@ -667,6 +685,7 @@ void tst_QDir::entryListWithSymLinks() QFile::remove("myLinkToFile.lnk"); QFile::remove("testfile.cpp"); dir.rmdir("myDir"); +#endif } void tst_QDir::canonicalPath_data() diff --git a/tests/auto/qdiriterator/tst_qdiriterator.cpp b/tests/auto/qdiriterator/tst_qdiriterator.cpp index 2d5758e..79e44d1 100644 --- a/tests/auto/qdiriterator/tst_qdiriterator.cpp +++ b/tests/auto/qdiriterator/tst_qdiriterator.cpp @@ -48,6 +48,10 @@ #include <qfileinfo.h> #include <qstringlist.h> +#if defined(Q_OS_VXWORKS) +#define Q_NO_SYMLINKS +#endif + Q_DECLARE_METATYPE(QDirIterator::IteratorFlags) Q_DECLARE_METATYPE(QDir::Filters) @@ -87,6 +91,7 @@ tst_QDirIterator::tst_QDirIterator() QFile::remove("entrylist/directory/entrylist3.lnk"); QFile::remove("entrylist/directory/entrylist4.lnk"); +#ifndef Q_NO_SYMLINKS #ifdef Q_OS_WIN // ### Sadly, this is a platform difference right now. QFile::link("entrylist/file", "entrylist/linktofile.lnk"); @@ -97,6 +102,7 @@ tst_QDirIterator::tst_QDirIterator() QFile::link("directory", "entrylist/linktodirectory.lnk"); QFile::link("nothing", "entrylist/brokenlink.lnk"); #endif +#endif QFile("entrylist/writable").open(QIODevice::ReadWrite); } @@ -135,9 +141,13 @@ void tst_QDirIterator::iterateRelativeDirectory_data() "entrylist/..," #endif "entrylist/file," +#ifndef Q_NO_SYMLINKS "entrylist/linktofile.lnk," +#endif "entrylist/directory," +#ifndef Q_NO_SYMLINKS "entrylist/linktodirectory.lnk," +#endif "entrylist/writable").split(','); QTest::newRow("QDir::Subdirectories | QDir::FollowSymlinks") @@ -151,10 +161,14 @@ void tst_QDirIterator::iterateRelativeDirectory_data() "entrylist/directory/..," #endif "entrylist/file," +#ifndef Q_NO_SYMLINKS "entrylist/linktofile.lnk," +#endif "entrylist/directory," "entrylist/directory/dummy," +#ifndef Q_NO_SYMLINKS "entrylist/linktodirectory.lnk," +#endif "entrylist/writable").split(','); QTest::newRow("QDir::Subdirectories / QDir::Files") @@ -162,14 +176,18 @@ void tst_QDirIterator::iterateRelativeDirectory_data() << QDir::Filters(QDir::Files) << QStringList("*") << QString("entrylist/directory/dummy," "entrylist/file," +#ifndef Q_NO_SYMLINKS "entrylist/linktofile.lnk," +#endif "entrylist/writable").split(','); QTest::newRow("QDir::Subdirectories | QDir::FollowSymlinks / QDir::Files") << QString("entrylist") << QDirIterator::IteratorFlags(QDirIterator::Subdirectories | QDirIterator::FollowSymlinks) << QDir::Filters(QDir::Files) << QStringList("*") << QString("entrylist/file," +#ifndef Q_NO_SYMLINKS "entrylist/linktofile.lnk," +#endif "entrylist/directory/dummy," "entrylist/writable").split(','); } diff --git a/tests/auto/qdom/qdom.pro b/tests/auto/qdom/qdom.pro index 5466dfa..7738fb7 100644 --- a/tests/auto/qdom/qdom.pro +++ b/tests/auto/qdom/qdom.pro @@ -10,4 +10,8 @@ wince*: { DEPLOYMENT += addFiles DEPLOYMENT_PLUGIN += qcncodecs qjpcodecs qkrcodecs qtwcodecs + DEFINES += SRCDIR=\\\"\\\" +} +else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" } diff --git a/tests/auto/qdom/tst_qdom.cpp b/tests/auto/qdom/tst_qdom.cpp index cea0bfb..ea3b64e 100644 --- a/tests/auto/qdom/tst_qdom.cpp +++ b/tests/auto/qdom/tst_qdom.cpp @@ -290,17 +290,17 @@ void tst_QDom::toString_01_data() { QTest::addColumn<QString>("fileName"); - QTest::newRow( "01" ) << QString("testdata/toString_01/doc01.xml"); - QTest::newRow( "02" ) << QString("testdata/toString_01/doc02.xml"); - QTest::newRow( "03" ) << QString("testdata/toString_01/doc03.xml"); - QTest::newRow( "04" ) << QString("testdata/toString_01/doc04.xml"); - QTest::newRow( "05" ) << QString("testdata/toString_01/doc05.xml"); + QTest::newRow( "01" ) << QString(SRCDIR "testdata/toString_01/doc01.xml"); + QTest::newRow( "02" ) << QString(SRCDIR "testdata/toString_01/doc02.xml"); + QTest::newRow( "03" ) << QString(SRCDIR "testdata/toString_01/doc03.xml"); + QTest::newRow( "04" ) << QString(SRCDIR "testdata/toString_01/doc04.xml"); + QTest::newRow( "05" ) << QString(SRCDIR "testdata/toString_01/doc05.xml"); - QTest::newRow( "euc-jp" ) << QString("testdata/toString_01/doc_euc-jp.xml"); - QTest::newRow( "iso-2022-jp" ) << QString("testdata/toString_01/doc_iso-2022-jp.xml"); - QTest::newRow( "little-endian" ) << QString("testdata/toString_01/doc_little-endian.xml"); - QTest::newRow( "utf-16" ) << QString("testdata/toString_01/doc_utf-16.xml"); - QTest::newRow( "utf-8" ) << QString("testdata/toString_01/doc_utf-8.xml"); + QTest::newRow( "euc-jp" ) << QString(SRCDIR "testdata/toString_01/doc_euc-jp.xml"); + QTest::newRow( "iso-2022-jp" ) << QString(SRCDIR "testdata/toString_01/doc_iso-2022-jp.xml"); + QTest::newRow( "little-endian" ) << QString(SRCDIR "testdata/toString_01/doc_little-endian.xml"); + QTest::newRow( "utf-16" ) << QString(SRCDIR "testdata/toString_01/doc_utf-16.xml"); + QTest::newRow( "utf-8" ) << QString(SRCDIR "testdata/toString_01/doc_utf-8.xml"); } @@ -474,7 +474,7 @@ void tst_QDom::initTestCase() QSKIP("Our current test machine, arsia, is too slow for this auto test.", SkipAll); #endif - QFile file("testdata/excludedCodecs.txt"); + QFile file(SRCDIR "testdata/excludedCodecs.txt"); QVERIFY(file.open(QIODevice::ReadOnly|QIODevice::Text)); QByteArray codecName; @@ -550,18 +550,18 @@ void tst_QDom::saveWithSerialization_data() const { QTest::addColumn<QString>("fileName"); - QTest::newRow("doc01.xml") << QString("testdata/toString_01/doc01.xml"); - QTest::newRow("doc01.xml") << QString("testdata/toString_01/doc01.xml"); - QTest::newRow("doc02.xml") << QString("testdata/toString_01/doc02.xml"); - QTest::newRow("doc03.xml") << QString("testdata/toString_01/doc03.xml"); - QTest::newRow("doc04.xml") << QString("testdata/toString_01/doc04.xml"); - QTest::newRow("doc05.xml") << QString("testdata/toString_01/doc05.xml"); + QTest::newRow("doc01.xml") << QString(SRCDIR "testdata/toString_01/doc01.xml"); + QTest::newRow("doc01.xml") << QString(SRCDIR "testdata/toString_01/doc01.xml"); + QTest::newRow("doc02.xml") << QString(SRCDIR "testdata/toString_01/doc02.xml"); + QTest::newRow("doc03.xml") << QString(SRCDIR "testdata/toString_01/doc03.xml"); + QTest::newRow("doc04.xml") << QString(SRCDIR "testdata/toString_01/doc04.xml"); + QTest::newRow("doc05.xml") << QString(SRCDIR "testdata/toString_01/doc05.xml"); - QTest::newRow("doc_euc-jp.xml") << QString("testdata/toString_01/doc_euc-jp.xml"); - QTest::newRow("doc_iso-2022-jp.xml") << QString("testdata/toString_01/doc_iso-2022-jp.xml"); - QTest::newRow("doc_little-endian.xml") << QString("testdata/toString_01/doc_little-endian.xml"); - QTest::newRow("doc_utf-16.xml") << QString("testdata/toString_01/doc_utf-16.xml"); - QTest::newRow("doc_utf-8.xml") << QString("testdata/toString_01/doc_utf-8.xml"); + QTest::newRow("doc_euc-jp.xml") << QString(SRCDIR "testdata/toString_01/doc_euc-jp.xml"); + QTest::newRow("doc_iso-2022-jp.xml") << QString(SRCDIR "testdata/toString_01/doc_iso-2022-jp.xml"); + QTest::newRow("doc_little-endian.xml") << QString(SRCDIR "testdata/toString_01/doc_little-endian.xml"); + QTest::newRow("doc_utf-16.xml") << QString(SRCDIR "testdata/toString_01/doc_utf-16.xml"); + QTest::newRow("doc_utf-8.xml") << QString(SRCDIR "testdata/toString_01/doc_utf-8.xml"); } void tst_QDom::cloneNode_data() @@ -1780,7 +1780,7 @@ void tst_QDom::doubleNamespaceDeclarations() const { QDomDocument doc; - QFile file("doubleNamespaces.xml" ); + QFile file(SRCDIR "doubleNamespaces.xml" ); QVERIFY(file.open(QIODevice::ReadOnly)); QXmlSimpleReader reader; diff --git a/tests/auto/qfilesystemmodel/qfilesystemmodel.pro b/tests/auto/qfilesystemmodel/qfilesystemmodel.pro index 89f3541..55f3b5c 100644 --- a/tests/auto/qfilesystemmodel/qfilesystemmodel.pro +++ b/tests/auto/qfilesystemmodel/qfilesystemmodel.pro @@ -3,6 +3,8 @@ CONFIG += qttest_p4 include(../../src/qfiledialog.pri) include(../../../../modeltest/modeltest.pri) +QT = core gui + SOURCES += tst_qfilesystemmodel.cpp TARGET = tst_qfilesystemmodel diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 9f1693d..7f6f322 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -44,6 +44,7 @@ #include <private/qtextcontrol_p.h> #include <private/qgraphicsitem_p.h> +#include <private/qgraphicsview_p.h> #include <QStyleOptionGraphicsItem> #include <QAbstractTextDocumentLayout> #include <QBitmap> @@ -6884,44 +6885,21 @@ void tst_QGraphicsItem::update() void tst_QGraphicsItem::setTransformProperties_data() { QTest::addColumn<QPointF>("origin"); - QTest::addColumn<qreal>("rotationX"); - QTest::addColumn<qreal>("rotationY"); - QTest::addColumn<qreal>("rotationZ"); - QTest::addColumn<qreal>("scaleX"); - QTest::addColumn<qreal>("scaleY"); - QTest::addColumn<qreal>("shearX"); - QTest::addColumn<qreal>("shearY"); + QTest::addColumn<qreal>("rotation"); + QTest::addColumn<qreal>("scale"); - QTest::newRow("nothing") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) - << qreal(1.0) << qreal(1.0) << qreal(0.0) << qreal(0.0); + QTest::newRow("nothing") << QPointF() << qreal(0.0) << qreal(1.0); - QTest::newRow("rotationZ") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(42.2) - << qreal(1.0) << qreal(1.0) << qreal(0.0) << qreal(0.0); + QTest::newRow("rotation") << QPointF() << qreal(42.2) << qreal(1.0); - QTest::newRow("rotationXY") << QPointF() << qreal(12.5) << qreal(53.6) << qreal(0.0) - << qreal(1.0) << qreal(1.0) << qreal(0.0) << qreal(0.0); + QTest::newRow("rotation dicentred") << QPointF(qreal(22.3), qreal(-56.2)) + << qreal(-2578.2) + << qreal(1.0); - QTest::newRow("rotationXYZ") << QPointF() << qreal(-25) << qreal(12) << qreal(556) - << qreal(1.0) << qreal(1.0) << qreal(0.0) << qreal(0.0); + QTest::newRow("Scale") << QPointF() << qreal(0.0) + << qreal(6); - QTest::newRow("rotationXYZ dicentred") << QPointF(-53, 25.2) - << qreal(-2578.2) << qreal(4565.2) << qreal(56) - << qreal(1.0) << qreal(1.0) << qreal(0.0) << qreal(0.0); - - QTest::newRow("Scale") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) - << qreal(6) << qreal(0.5) << qreal(0.0) << qreal(0.0); - - QTest::newRow("Shear") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) - << qreal(1.0) << qreal(1.0) << qreal(2.2) << qreal(0.5); - - QTest::newRow("Scale and Shear") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) - << qreal(5.2) << qreal(2.1) << qreal(5.2) << qreal(5.5); - - QTest::newRow("Everything") << QPointF() << qreal(41) << qreal(-23) << qreal(0.56) - << qreal(8.2) << qreal(-0.2) << qreal(-12) << qreal(-0.8); - - QTest::newRow("Everything dicentred") << QPointF(qreal(22.3), qreal(-56.2)) << qreal(-175) << qreal(196) << qreal(-1260) - << qreal(4) << qreal(2) << qreal(2.56) << qreal(0.8); + QTest::newRow("Everything dicentred") << QPointF(qreal(22.3), qreal(-56.2)) << qreal(-175) << qreal(196); } /** @@ -6932,92 +6910,61 @@ void tst_QGraphicsItem::setTransformProperties_data() void tst_QGraphicsItem::setTransformProperties() { QFETCH(QPointF,origin); - QFETCH(qreal,rotationX); - QFETCH(qreal,rotationY); - QFETCH(qreal,rotationZ); - QFETCH(qreal,scaleX); - QFETCH(qreal,scaleY); - QFETCH(qreal,shearX); - QFETCH(qreal,shearY); + QFETCH(qreal,rotation); + QFETCH(qreal,scale); QTransform result; result.translate(origin.x(), origin.y()); - result.rotate(rotationX, Qt::XAxis); - result.rotate(rotationY, Qt::YAxis); - result.rotate(rotationZ, Qt::ZAxis); - result.shear(shearX, shearY); - result.scale(scaleX, scaleY); + result.rotate(rotation, Qt::ZAxis); + result.scale(scale, scale); result.translate(-origin.x(), -origin.y()); QGraphicsScene scene; QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0, 0, 100, 100)); scene.addItem(item); - item->setRotation(rotationX, rotationY, rotationZ); - item->setScale(scaleX, scaleY); - item->setShear(shearX, shearY); - item->setTransformOrigin(origin); + item->setRotation(rotation); + item->setScale(scale); + item->setTransformOriginPoint(origin); - QCOMPARE(item->xRotation(), rotationX); - QCOMPARE(item->yRotation(), rotationY); - QCOMPARE(item->zRotation(), rotationZ); - QCOMPARE(item->xScale(), scaleX); - QCOMPARE(item->yScale(), scaleY); - QCOMPARE(item->horizontalShear(), shearX); - QCOMPARE(item->verticalShear(), shearY); - QCOMPARE(item->transformOrigin(), origin); + QCOMPARE(item->rotation(), rotation); + QCOMPARE(item->scale(), scale); + QCOMPARE(item->transformOriginPoint(), origin); QCOMPARE(QTransform(), item->transform()); QCOMPARE(result, item->sceneTransform()); //----------------------------------------------------------------- //Change the rotation Z - item->setZRotation(45); + item->setRotation(45); QTransform result2; result2.translate(origin.x(), origin.y()); - result2.rotate(rotationX, Qt::XAxis); - result2.rotate(rotationY, Qt::YAxis); - result2.rotate(45, Qt::ZAxis); - result2.shear(shearX, shearY); - result2.scale(scaleX, scaleY); + result2.rotate(45); + result2.scale(scale, scale); result2.translate(-origin.x(), -origin.y()); - QCOMPARE(item->xRotation(), rotationX); - QCOMPARE(item->yRotation(), rotationY); - QCOMPARE(item->zRotation(), 45.0); - QCOMPARE(item->xScale(), scaleX); - QCOMPARE(item->yScale(), scaleY); - QCOMPARE(item->horizontalShear(), shearX); - QCOMPARE(item->verticalShear(), shearY); - QCOMPARE(item->transformOrigin(), origin); + QCOMPARE(item->rotation(), 45.); + QCOMPARE(item->scale(), scale); + QCOMPARE(item->transformOriginPoint(), origin); QCOMPARE(QTransform(), item->transform()); QCOMPARE(result2, item->sceneTransform()); //----------------------------------------------------------------- - // calling setTransform() and setPos shoukld change the sceneTransform + // calling setTransform() and setPos should change the sceneTransform item->setTransform(result); item->setPos(100, -150.5); - QCOMPARE(item->xRotation(), rotationX); - QCOMPARE(item->yRotation(), rotationY); - QCOMPARE(item->zRotation(), 45.0); - QCOMPARE(item->xScale(), scaleX); - QCOMPARE(item->yScale(), scaleY); - QCOMPARE(item->horizontalShear(), shearX); - QCOMPARE(item->verticalShear(), shearY); - QCOMPARE(item->transformOrigin(), origin); + QCOMPARE(item->rotation(), 45.); + QCOMPARE(item->scale(), scale); + QCOMPARE(item->transformOriginPoint(), origin); QCOMPARE(result, item->transform()); - QTransform result3; + QTransform result3(result); result3.translate(origin.x(), origin.y()); - result3 = result * result3; - result3.rotate(rotationX, Qt::XAxis); - result3.rotate(rotationY, Qt::YAxis); - result3.rotate(45, Qt::ZAxis); - result3.shear(shearX, shearY); - result3.scale(scaleX, scaleY); + result3.rotate(45); + result3.scale(scale, scale); result3.translate(-origin.x(), -origin.y()); result3 *= QTransform::fromTranslate(100, -150.5); //the pos; @@ -7034,10 +6981,9 @@ void tst_QGraphicsItem::setTransformProperties() item1->setPos(12.3, -5); item2->setPos(12.3, -5); - item1->setRotation(rotationX, rotationY, rotationZ); - item1->setScale(scaleX, scaleY); - item1->setShear(shearX, shearY); - item1->setTransformOrigin(origin); + item1->setRotation(rotation); + item1->setScale(scale); + item1->setTransformOriginPoint(origin); item2->setTransform(result); @@ -7046,36 +6992,6 @@ void tst_QGraphicsItem::setTransformProperties() QCOMPARE_TRANSFORM(item1->itemTransform(item2), QTransform()); QCOMPARE_TRANSFORM(item2->itemTransform(item1), QTransform()); } - - {//with center origin on the item - QGraphicsRectItem *item1 = new QGraphicsRectItem(QRectF(50.2, -150, 230.5, 119)); - scene.addItem(item1); - QGraphicsRectItem *item2 = new QGraphicsRectItem(QRectF(50.2, -150, 230.5, 119)); - scene.addItem(item2); - - item1->setPos(12.3, -5); - item2->setPos(12.3, -5); - item1->setTransformOrigin(origin); - item2->setTransformOrigin(origin); - - item1->setRotation(rotationX, rotationY, rotationZ); - item1->setScale(scaleX, scaleY); - item1->setShear(shearX, shearY); - - QTransform tr; - tr.rotate(rotationX, Qt::XAxis); - tr.rotate(rotationY, Qt::YAxis); - tr.rotate(rotationZ, Qt::ZAxis); - tr.shear(shearX, shearY); - tr.scale(scaleX, scaleY); - - item2->setTransform(tr); - - QCOMPARE_TRANSFORM(item1->sceneTransform(), item2->sceneTransform()); - - QCOMPARE_TRANSFORM(item1->itemTransform(item2), QTransform()); - QCOMPARE_TRANSFORM(item2->itemTransform(item1), QTransform()); - } } class MyStyleOptionTester : public QGraphicsRectItem diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index f7ea4ce..4ef1cdd 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -255,6 +255,7 @@ private slots: void sendEvent(); void inputMethod_data(); void inputMethod(); + void dispatchHoverOnPress(); // task specific tests below me void task139710_bspTreeCrash(); @@ -3719,5 +3720,73 @@ void tst_QGraphicsScene::inputMethod() QCOMPARE(item->queryCalls, 0); } +void tst_QGraphicsScene::dispatchHoverOnPress() +{ + QGraphicsScene scene; + EventTester *tester1 = new EventTester; + tester1->setAcceptHoverEvents(true); + EventTester *tester2 = new EventTester; + tester2->setAcceptHoverEvents(true); + tester2->setPos(30, 30); + scene.addItem(tester1); + scene.addItem(tester2); + + tester1->eventTypes.clear(); + tester2->eventTypes.clear(); + + { + QGraphicsSceneMouseEvent me(QEvent::GraphicsSceneMousePress); + me.setButton(Qt::LeftButton); + me.setButtons(Qt::LeftButton); + QGraphicsSceneMouseEvent me2(QEvent::GraphicsSceneMouseRelease); + me2.setButton(Qt::LeftButton); + qApp->sendEvent(&scene, &me); + qApp->sendEvent(&scene, &me2); + QCOMPARE(tester1->eventTypes, QList<QEvent::Type>() + << QEvent::GraphicsSceneHoverEnter + << QEvent::GraphicsSceneHoverMove + << QEvent::GrabMouse + << QEvent::GraphicsSceneMousePress + << QEvent::UngrabMouse); + tester1->eventTypes.clear(); + qApp->sendEvent(&scene, &me); + qApp->sendEvent(&scene, &me2); + QCOMPARE(tester1->eventTypes, QList<QEvent::Type>() + << QEvent::GraphicsSceneHoverMove + << QEvent::GrabMouse + << QEvent::GraphicsSceneMousePress + << QEvent::UngrabMouse); + } + { + QGraphicsSceneMouseEvent me(QEvent::GraphicsSceneMousePress); + me.setScenePos(QPointF(30, 30)); + me.setButton(Qt::LeftButton); + me.setButtons(Qt::LeftButton); + QGraphicsSceneMouseEvent me2(QEvent::GraphicsSceneMouseRelease); + me2.setScenePos(QPointF(30, 30)); + me2.setButton(Qt::LeftButton); + tester1->eventTypes.clear(); + qApp->sendEvent(&scene, &me); + qApp->sendEvent(&scene, &me2); + qDebug() << tester1->eventTypes; + QCOMPARE(tester1->eventTypes, QList<QEvent::Type>() + << QEvent::GraphicsSceneHoverLeave); + QCOMPARE(tester2->eventTypes, QList<QEvent::Type>() + << QEvent::GraphicsSceneHoverEnter + << QEvent::GraphicsSceneHoverMove + << QEvent::GrabMouse + << QEvent::GraphicsSceneMousePress + << QEvent::UngrabMouse); + tester2->eventTypes.clear(); + qApp->sendEvent(&scene, &me); + qApp->sendEvent(&scene, &me2); + QCOMPARE(tester2->eventTypes, QList<QEvent::Type>() + << QEvent::GraphicsSceneHoverMove + << QEvent::GrabMouse + << QEvent::GraphicsSceneMousePress + << QEvent::UngrabMouse); + } +} + QTEST_MAIN(tst_QGraphicsScene) #include "tst_qgraphicsscene.moc" diff --git a/tests/auto/qgraphicstransform/qgraphicstransform.pro b/tests/auto/qgraphicstransform/qgraphicstransform.pro new file mode 100644 index 0000000..709cff6 --- /dev/null +++ b/tests/auto/qgraphicstransform/qgraphicstransform.pro @@ -0,0 +1,2 @@ +load(qttest_p4) +SOURCES += tst_qgraphicstransform.cpp diff --git a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp new file mode 100644 index 0000000..672b1f1 --- /dev/null +++ b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <qgraphicsitem.h> +#include <qgraphicstransform.h> +#include "../../shared/util.h" + +class tst_QGraphicsTransform : public QObject { + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void scale(); + void rotation(); + void rotation3d(); +}; + + +// This will be called before the first test function is executed. +// It is only called once. +void tst_QGraphicsTransform::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_QGraphicsTransform::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_QGraphicsTransform::init() +{ +} + +// This will be called after every test function. +void tst_QGraphicsTransform::cleanup() +{ +} + + +void tst_QGraphicsTransform::scale() +{ + QGraphicsScale scale; + scale.setOrigin(QPointF(10, 10)); + + QTransform t; + scale.applyTo(&t); + + QCOMPARE(t, QTransform()); + QCOMPARE(scale.transform(), QTransform()); + + scale.setXScale(10); + scale.setOrigin(QPointF(0, 0)); + + QTransform res; + res.scale(10, 1); + + QCOMPARE(scale.transform(), res); + QCOMPARE(scale.transform().map(QPointF(10, 10)), QPointF(100, 10)); + + scale.setOrigin(QPointF(10, 10)); + QCOMPARE(scale.transform().map(QPointF(10, 10)), QPointF(10, 10)); + QCOMPARE(scale.transform().map(QPointF(11, 10)), QPointF(20, 10)); +} + +void tst_QGraphicsTransform::rotation() +{ + QGraphicsRotation rotation; + rotation.setOrigin(QPointF(10, 10)); + + QTransform t; + rotation.applyTo(&t); + + QCOMPARE(t, QTransform()); + QCOMPARE(rotation.transform(), QTransform()); + + rotation.setAngle(40); + rotation.setOrigin(QPointF(0, 0)); + + QTransform res; + res.rotate(40); + + QCOMPARE(rotation.transform(), res); + + rotation.setOrigin(QPointF(10, 10)); + rotation.setAngle(90); + QCOMPARE(rotation.transform().map(QPointF(10, 10)), QPointF(10, 10)); + QCOMPARE(rotation.transform().map(QPointF(20, 10)), QPointF(10, 20)); +} + +void tst_QGraphicsTransform::rotation3d() +{ + QGraphicsRotation3D rotation; + rotation.setOrigin(QPointF(10, 10)); + + QTransform t; + rotation.applyTo(&t); + + QCOMPARE(t, QTransform()); + QCOMPARE(rotation.transform(), QTransform()); + + rotation.setAngle(180); + + QCOMPARE(t, QTransform()); + QCOMPARE(rotation.transform(), QTransform()); + + rotation.setOrigin(QPointF(0, 0)); + + QCOMPARE(t, QTransform()); + QCOMPARE(rotation.transform(), QTransform()); +} + + +QTEST_MAIN(tst_QGraphicsTransform) +#include "tst_qgraphicstransform.moc" + diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 78d13d3..2cfedb1 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -1315,6 +1315,12 @@ void tst_QGraphicsWidget::focusNextPrevChild() void tst_QGraphicsWidget::verifyFocusChain() { QGraphicsScene scene; + QGraphicsView view(&scene); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(250); { // parent/child focus SubQGraphicsWidget *w = new SubQGraphicsWidget(0, Qt::Window); @@ -1448,6 +1454,11 @@ void tst_QGraphicsWidget::updateFocusChainWhenChildDie() QGraphicsScene scene; QGraphicsView view(&scene); view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(250); + // delete item in focus chain with no focus and verify chain SubQGraphicsWidget *parent = new SubQGraphicsWidget(0, Qt::Window); SubQGraphicsWidget *w = new SubQGraphicsWidget(0, Qt::Window); diff --git a/tests/auto/qhttp/qhttp.pro b/tests/auto/qhttp/qhttp.pro index 9186140..9c2f5cb 100644 --- a/tests/auto/qhttp/qhttp.pro +++ b/tests/auto/qhttp/qhttp.pro @@ -13,6 +13,8 @@ wince*: { addFiles.path = . DEPLOYMENT = addFiles webFiles cgi DEFINES += SRCDIR=\\\"\\\" +} else:vxworks*: { + DEFINES += SRCDIR=\\\"\\\" } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } diff --git a/tests/auto/qline/qline.pro b/tests/auto/qline/qline.pro index ea15cfe..56718d0 100644 --- a/tests/auto/qline/qline.pro +++ b/tests/auto/qline/qline.pro @@ -1,6 +1,6 @@ load(qttest_p4) QT -= gui SOURCES += tst_qline.cpp -unix:!mac:LIBS+=-lm +unix:!mac:!vxworks:LIBS+=-lm diff --git a/tests/auto/qmetaobject/qmetaobject.pro b/tests/auto/qmetaobject/qmetaobject.pro index 22119bc..1df54f7 100644 --- a/tests/auto/qmetaobject/qmetaobject.pro +++ b/tests/auto/qmetaobject/qmetaobject.pro @@ -1,4 +1,7 @@ load(qttest_p4) + +QT = core gui + SOURCES += tst_qmetaobject.cpp diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 788be1e..03b1474 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -2642,6 +2642,8 @@ void tst_QNetworkReply::ioPutToFileFromProcess() QCOMPARE(file.size(), qint64(data.size())); QByteArray contents = file.readAll(); QCOMPARE(contents, data); + + delete reply; #endif } diff --git a/tests/auto/qnumeric/tst_qnumeric.cpp b/tests/auto/qnumeric/tst_qnumeric.cpp index fb01e1b..0c83db4 100644 --- a/tests/auto/qnumeric/tst_qnumeric.cpp +++ b/tests/auto/qnumeric/tst_qnumeric.cpp @@ -41,6 +41,7 @@ #include <QtTest/QtTest> +#include <QtGlobal> #include <math.h> @@ -97,8 +98,12 @@ void tst_QNumeric::qNan() if (0 > nan) QFAIL("compiler thinks 0 > nan"); +# if defined(Q_CC_DIAB) + QWARN("!(0 < nan) would fail due to a bug in dcc"); +# else if (0 < nan) QFAIL("compiler thinks 0 < nan"); +# endif #endif QVERIFY(qIsNaN(nan)); QVERIFY(qIsNaN(nan + 1)); diff --git a/tests/auto/qobjectrace/tst_qobjectrace.cpp b/tests/auto/qobjectrace/tst_qobjectrace.cpp index 98c7a30..6684125 100644 --- a/tests/auto/qobjectrace/tst_qobjectrace.cpp +++ b/tests/auto/qobjectrace/tst_qobjectrace.cpp @@ -121,10 +121,10 @@ signals: private slots: void checkStopWatch() { -#ifndef Q_OS_WINCE - if (stopWatch.elapsed() >= OneMinute) -#else +#if defined(Q_OS_WINCE) || defined(Q_OS_VXWORKS) if (stopWatch.elapsed() >= OneMinute / 2) +#else + if (stopWatch.elapsed() >= OneMinute) #endif quit(); @@ -138,7 +138,7 @@ void tst_QObjectRace::moveToThreadRace() { RaceObject *object = new RaceObject; - enum { ThreadCount = 10 }; + enum { ThreadCount = 6 }; RaceThread *threads[ThreadCount]; for (int i = 0; i < ThreadCount; ++i) { threads[i] = new RaceThread; diff --git a/tests/auto/qreadwritelock/tst_qreadwritelock.cpp b/tests/auto/qreadwritelock/tst_qreadwritelock.cpp index 78ddc99..f298812 100644 --- a/tests/auto/qreadwritelock/tst_qreadwritelock.cpp +++ b/tests/auto/qreadwritelock/tst_qreadwritelock.cpp @@ -719,6 +719,8 @@ void tst_QReadWriteLock::multipleReadersLoop() int wait=0; #if defined (Q_OS_HPUX) const int numthreads=50; +#elif defined(Q_OS_VXWORKS) + const int numthreads=40; #else const int numthreads=75; #endif diff --git a/tests/auto/qregexp/qregexp.pro b/tests/auto/qregexp/qregexp.pro index 0712496..d467cda 100644 --- a/tests/auto/qregexp/qregexp.pro +++ b/tests/auto/qregexp/qregexp.pro @@ -2,6 +2,9 @@ load(qttest_p4) QT = core + +QT = core + SOURCES += tst_qregexp.cpp QT -= gui diff --git a/tests/auto/qresourceengine/qresourceengine.pro b/tests/auto/qresourceengine/qresourceengine.pro index cdbbbd2..8f3ca5c 100644 --- a/tests/auto/qresourceengine/qresourceengine.pro +++ b/tests/auto/qresourceengine/qresourceengine.pro @@ -15,6 +15,7 @@ runtime_resource.commands = $$QMAKE_RCC -root /runtime_resource/ -binary $${runt QMAKE_EXTRA_TARGETS = runtime_resource ALL_DEPS += $${runtime_resource.target} +QT = core wince*:{ deploy.sources += runtime_resource.rcc parentdir.txt test.sources = testqrc/* diff --git a/tests/auto/qresourceengine/tst_resourceengine.cpp b/tests/auto/qresourceengine/tst_resourceengine.cpp index a5e701a..e133a72 100644 --- a/tests/auto/qresourceengine/tst_resourceengine.cpp +++ b/tests/auto/qresourceengine/tst_resourceengine.cpp @@ -108,7 +108,7 @@ void tst_ResourceEngine::checkStructure_data() << QLatin1String("runtime_resource") << QLatin1String("searchpath1") << QLatin1String("searchpath2") << QLatin1String("secondary_root") - << QLatin1String("test") << QLatin1String("trolltech") + << QLatin1String("test") << QLatin1String("withoutslashes")) << QLocale::c() << qlonglong(0); diff --git a/tests/auto/qscriptengine/qscriptengine.pro b/tests/auto/qscriptengine/qscriptengine.pro index b5aa621..7c74b32 100644 --- a/tests/auto/qscriptengine/qscriptengine.pro +++ b/tests/auto/qscriptengine/qscriptengine.pro @@ -1,5 +1,5 @@ load(qttest_p4) -QT += script +QT = core gui script SOURCES += tst_qscriptengine.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index d67ddab..bae2c87 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -123,6 +123,8 @@ private slots: void reentrancy(); void incDecNonObjectProperty(); void installTranslatorFunctions(); + void functionScopes(); + void nativeFunctionScopes(); void qRegExpInport_data(); void qRegExpInport(); @@ -3806,6 +3808,109 @@ void tst_QScriptEngine::installTranslatorFunctions() } } +void tst_QScriptEngine::functionScopes() +{ + QScriptEngine eng; + { + // top-level functions have only the global object in their scope + QScriptValue fun = eng.evaluate("(function() {})"); + QVERIFY(fun.isFunction()); + QVERIFY(fun.scope().isObject()); + QVERIFY(fun.scope().strictlyEquals(eng.globalObject())); + QVERIFY(!eng.globalObject().scope().isValid()); + } + { + QScriptValue fun = eng.globalObject().property("Object"); + QVERIFY(fun.isFunction()); + // native built-in functions don't have scope + QVERIFY(!fun.scope().isValid()); + } + { + // closure + QScriptValue fun = eng.evaluate("(function(arg) { var foo = arg; return function() { return foo; }; })(123)"); + QVERIFY(fun.isFunction()); + { + QScriptValue ret = fun.call(); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } + QScriptValue scope = fun.scope(); + QVERIFY(scope.isObject()); + { + QScriptValue ret = scope.property("foo"); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + QCOMPARE(scope.propertyFlags("foo"), QScriptValue::Undeletable); + } + { + QScriptValue ret = scope.property("arg"); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + QCOMPARE(scope.propertyFlags("arg"), QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + } + + scope.setProperty("foo", 456); + { + QScriptValue ret = fun.call(); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 456); + } + + scope = scope.scope(); + QVERIFY(scope.isObject()); + QVERIFY(scope.strictlyEquals(eng.globalObject())); + } +} + +static QScriptValue counter_inner(QScriptContext *ctx, QScriptEngine *) +{ + QScriptValue outerAct = ctx->callee().scope(); + double count = outerAct.property("count").toNumber(); + outerAct.setProperty("count", count+1); + return count; +} + +static QScriptValue counter(QScriptContext *ctx, QScriptEngine *eng) +{ + QScriptValue act = ctx->activationObject(); + act.setProperty("count", ctx->argument(0).toInt32()); + QScriptValue result = eng->newFunction(counter_inner); + result.setScope(act); + return result; +} + +static QScriptValue counter_hybrid(QScriptContext *ctx, QScriptEngine *eng) +{ + QScriptValue act = ctx->activationObject(); + act.setProperty("count", ctx->argument(0).toInt32()); + return eng->evaluate("function() { return count++; }"); +} + +void tst_QScriptEngine::nativeFunctionScopes() +{ + QScriptEngine eng; + { + QScriptValue fun = eng.newFunction(counter); + QScriptValue cnt = fun.call(QScriptValue(), QScriptValueList() << 123); + QVERIFY(cnt.isFunction()); + { + QScriptValue ret = cnt.call(); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } + } + { + QScriptValue fun = eng.newFunction(counter_hybrid); + QScriptValue cnt = fun.call(QScriptValue(), QScriptValueList() << 123); + QVERIFY(cnt.isFunction()); + { + QScriptValue ret = cnt.call(); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } + } +} + static QRegExp minimal(QRegExp r) { r.setMinimal(true); return r; } void tst_QScriptEngine::qRegExpInport_data() @@ -3858,6 +3963,5 @@ void tst_QScriptEngine::qRegExpInport() } } - QTEST_MAIN(tst_QScriptEngine) #include "tst_qscriptengine.moc" diff --git a/tests/auto/qscriptqobject/qscriptqobject.pro b/tests/auto/qscriptqobject/qscriptqobject.pro index e4e2b56..be3a980 100644 --- a/tests/auto/qscriptqobject/qscriptqobject.pro +++ b/tests/auto/qscriptqobject/qscriptqobject.pro @@ -1,5 +1,5 @@ load(qttest_p4) -QT += script +QT = core gui script SOURCES += tst_qscriptqobject.cpp diff --git a/tests/auto/qscriptvalue/qscriptvalue.pro b/tests/auto/qscriptvalue/qscriptvalue.pro index 98fd63d..9efde80 100644 --- a/tests/auto/qscriptvalue/qscriptvalue.pro +++ b/tests/auto/qscriptvalue/qscriptvalue.pro @@ -1,5 +1,5 @@ load(qttest_p4) -QT += script +QT = core gui script SOURCES += tst_qscriptvalue.cpp diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp index 401161d..99f5770 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp +++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp @@ -2152,6 +2152,14 @@ void tst_QScriptValue::getSetScope() QCOMPARE(object2.scope().strictlyEquals(object), true); + object.setProperty("foo", 123); + QVERIFY(!object2.property("foo").isValid()); + { + QScriptValue ret = object2.property("foo", QScriptValue::ResolveScope); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } + QScriptValue inv; inv.setScope(object); QCOMPARE(inv.scope().isValid(), false); diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index 9c8c313..8253541 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -335,7 +335,7 @@ public: if(table2.compare(table.section('.', -1, -1), Qt::CaseInsensitive) == 0) { table=db.driver()->escapeIdentifier(table2, QSqlDriver::TableName); wasDropped = q.exec( "drop table " + table); - dbtables.removeAll(table); + dbtables.removeAll(table2); } } } @@ -430,8 +430,8 @@ public: return "IDENTITY"; /* if ( db.driverName().startsWith( "QPSQL" ) ) return "SERIAL";*/ - if ( db.driverName().startsWith( "QDB2" ) ) - return "GENERATED BY DEFAULT AS IDENTITY"; +// if ( db.driverName().startsWith( "QDB2" ) ) +// return "GENERATED BY DEFAULT AS IDENTITY"; return QString(); } @@ -483,6 +483,10 @@ public: { return db.driverName().startsWith("QMYSQL") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("MySQL") ); } + static bool isDB2( QSqlDatabase db ) + { + return db.driverName().startsWith("QDB2") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("db2") ); + } // -1 on fail, else Oracle version static int getOraVersion( QSqlDatabase db ) diff --git a/tests/auto/qstring/qstring.pro b/tests/auto/qstring/qstring.pro index 02253c2..eb52d90 100644 --- a/tests/auto/qstring/qstring.pro +++ b/tests/auto/qstring/qstring.pro @@ -1,8 +1,6 @@ load(qttest_p4) SOURCES += tst_qstring.cpp -QT -= gui - QT = core DEFINES += QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qtcpsocket/qtcpsocket.pro b/tests/auto/qtcpsocket/qtcpsocket.pro index 6924309..6a96889 100644 --- a/tests/auto/qtcpsocket/qtcpsocket.pro +++ b/tests/auto/qtcpsocket/qtcpsocket.pro @@ -3,3 +3,4 @@ TEMPLATE = subdirs !wince*: SUBDIRS = test stressTest wince*: SUBDIRS = test +vxworks*: SUBDIRS = test diff --git a/tests/auto/qtcpsocket/test/test.pro b/tests/auto/qtcpsocket/test/test.pro index fecbf11..696375d 100644 --- a/tests/auto/qtcpsocket/test/test.pro +++ b/tests/auto/qtcpsocket/test/test.pro @@ -9,6 +9,7 @@ wince*: { } } QT += network +vxworks:QT -= gui DEFINES += TEST_QNETWORK_PROXY diff --git a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp index 9e55764..6b0a5be 100644 --- a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp @@ -60,10 +60,12 @@ #include <QHostAddress> #include <QHostInfo> #include <QMap> +#ifndef Q_OS_VXWORKS #include <QMessageBox> +#include <QPushButton> +#endif #include <QPointer> #include <QProcess> -#include <QPushButton> #include <QStringList> #include <QTcpServer> #include <QTcpSocket> @@ -172,9 +174,7 @@ private slots: void connectToLocalHostNoService(); #endif void waitForConnectedInHostLookupSlot(); -#ifndef Q_OS_WIN void waitForConnectedInHostLookupSlot2(); -#endif void readyReadSignalsAfterWaitForReadyRead(); #ifdef Q_OS_LINUX void linuxKernelBugLocalSocket(); @@ -1573,6 +1573,7 @@ void tst_QTcpSocket::remoteCloseErrorSlot() void tst_QTcpSocket::messageBoxSlot() { +#if !defined(Q_OS_VXWORKS) // no gui QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); socket->deleteLater(); QMessageBox box; @@ -1583,10 +1584,14 @@ void tst_QTcpSocket::messageBoxSlot() // Fire a non-0 singleshot to leave time for the delete QTimer::singleShot(250, this, SLOT(exitLoopSlot())); +#endif } //---------------------------------------------------------------------------------- void tst_QTcpSocket::openMessageBoxInErrorSlot() { +#if defined(Q_OS_VXWORKS) // no gui + QSKIP("no default gui available on VxWorks", SkipAll); +#else QTcpSocket *socket = newSocket(); QPointer<QTcpSocket> p(socket); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(messageBoxSlot())); @@ -1594,6 +1599,7 @@ void tst_QTcpSocket::openMessageBoxInErrorSlot() socket->connectToHost("hostnotfoundhostnotfound.troll.no", 9999); // Host not found, fyi enterLoop(30); QVERIFY(!p); +#endif } //---------------------------------------------------------------------------------- @@ -1712,9 +1718,11 @@ public slots: }; //---------------------------------------------------------------------------------- -#ifndef Q_OS_WIN void tst_QTcpSocket::waitForConnectedInHostLookupSlot2() { +#if defined(Q_OS_WIN) || defined(Q_OS_VXWORKS) + QSKIP("waitForConnectedInHostLookupSlot2 is not run on Windows and VxWorks", SkipAll); +#else Foo foo; QPushButton top("Go", 0); @@ -1730,8 +1738,8 @@ void tst_QTcpSocket::waitForConnectedInHostLookupSlot2() QVERIFY(foo.attemptedToConnect); QCOMPARE(foo.count, 1); -} #endif +} //---------------------------------------------------------------------------------- void tst_QTcpSocket::readyReadSignalsAfterWaitForReadyRead() @@ -1965,7 +1973,7 @@ void tst_QTcpSocket::suddenRemoteDisconnect_data() void tst_QTcpSocket::suddenRemoteDisconnect() { -#if defined(Q_OS_WINCE) +#if defined(Q_OS_WINCE) || defined(Q_OS_VXWORKS) QSKIP("stressTest subprocess needs Qt3Support", SkipAll); #else QFETCH(QString, client); @@ -2022,6 +2030,9 @@ void tst_QTcpSocket::connectToMultiIP() { QSKIP("TODO: setup DNS in the new network", SkipAll); +#if defined(Q_OS_VXWORKS) + QSKIP("VxSim in standard config doesn't even run a DNS resolver", SkipAll); +#else QFETCH_GLOBAL(bool, ssl); if (ssl) return; @@ -2049,6 +2060,7 @@ void tst_QTcpSocket::connectToMultiIP() QCOMPARE(socket->error(), QAbstractSocket::SocketTimeoutError); delete socket; +#endif } //---------------------------------------------------------------------------------- diff --git a/tests/auto/qthreadonce/tst_qthreadonce.cpp b/tests/auto/qthreadonce/tst_qthreadonce.cpp index 590de0f..5d9062d 100644 --- a/tests/auto/qthreadonce/tst_qthreadonce.cpp +++ b/tests/auto/qthreadonce/tst_qthreadonce.cpp @@ -134,7 +134,7 @@ void tst_QThreadOnce::sameThread() void tst_QThreadOnce::multipleThreads() { -#ifdef Q_OS_WINCE +#if defined(Q_OS_WINCE) || defined(Q_OS_VXWORKS) const int NumberOfThreads = 20; #else const int NumberOfThreads = 100; diff --git a/tests/auto/qthreadpool/tst_qthreadpool.cpp b/tests/auto/qthreadpool/tst_qthreadpool.cpp index 1111ecc..d4c131d 100644 --- a/tests/auto/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/qthreadpool/tst_qthreadpool.cpp @@ -205,7 +205,8 @@ void tst_QThreadPool::runTask() ran = false; manager.start(new TestTask()); // Hang if task is not runned. - while (ran == false); + while (ran == false) + QTest::qSleep(100); // no busy loop - this doesn't work with FIFO schedulers } /* @@ -215,7 +216,8 @@ void tst_QThreadPool::singleton() { ran = false; QThreadPool::globalInstance()->start(new TestTask()); - while (ran == false); + while (ran == false) + QTest::qSleep(100); // no busy loop - this doesn't work with FIFO schedulers } int *value = 0; diff --git a/tests/auto/qxml/tst_qxml.cpp b/tests/auto/qxml/tst_qxml.cpp index 13de82f..1bc5ef5 100644 --- a/tests/auto/qxml/tst_qxml.cpp +++ b/tests/auto/qxml/tst_qxml.cpp @@ -57,6 +57,7 @@ Q_OBJECT private slots: void getSetCheck(); void interpretedAs0D() const; + void exception(); }; class MyXmlEntityResolver : public QXmlEntityResolver @@ -213,5 +214,30 @@ void tst_QXml::interpretedAs0D() const QCOMPARE(myHandler.attrName, QChar(0x010D) + QString::fromLatin1("reated-by")); } +void tst_QXml::exception() +{ +#ifndef QT_NO_EXCEPTIONS + QString message = QString::fromLatin1("message"); + int column = 3; + int line = 2; + QString publicId = QString::fromLatin1("publicId"); + QString systemId = QString::fromLatin1("systemId"); + + try { + QXmlParseException e(message, column, line, publicId, systemId); + throw e; + } + catch (QXmlParseException e) { + QCOMPARE(e.message(), message); + QCOMPARE(e.columnNumber(), column); + QCOMPARE(e.lineNumber(), line); + QCOMPARE(e.publicId(), publicId); + QCOMPARE(e.systemId(), systemId); + } +#else + QSKIP("Exceptions not available", SkipAll); +#endif +} + QTEST_MAIN(tst_QXml) #include "tst_qxml.moc" diff --git a/tests/auto/qxmlsimplereader/parser/main.cpp b/tests/auto/qxmlsimplereader/parser/main.cpp index 4834428..ffb2ecd 100644 --- a/tests/auto/qxmlsimplereader/parser/main.cpp +++ b/tests/auto/qxmlsimplereader/parser/main.cpp @@ -42,6 +42,7 @@ #include <string.h> #include <errno.h> +#include <stdlib.h> #include <qfile.h> #include <qstring.h> diff --git a/tests/auto/selftests/cmptest/tst_cmptest.cpp b/tests/auto/selftests/cmptest/tst_cmptest.cpp index 59dd678..7395210 100644 --- a/tests/auto/selftests/cmptest/tst_cmptest.cpp +++ b/tests/auto/selftests/cmptest/tst_cmptest.cpp @@ -50,6 +50,8 @@ class tst_Cmptest: public QObject private slots: void compare_boolfuncs(); void compare_pointerfuncs(); + void compare_tostring(); + void compare_tostring_data(); }; static bool boolfunc() { return true; } @@ -76,6 +78,50 @@ void tst_Cmptest::compare_pointerfuncs() QCOMPARE(&i, intptr()); } +Q_DECLARE_METATYPE(QVariant) + +class PhonyClass +{}; + +void tst_Cmptest::compare_tostring_data() +{ + QTest::addColumn<QVariant>("actual"); + QTest::addColumn<QVariant>("expected"); + + QTest::newRow("int, string") + << QVariant::fromValue(123) + << QVariant::fromValue(QString("hi")) + ; + + QTest::newRow("both invalid") + << QVariant() + << QVariant() + ; + + QTest::newRow("null hash, invalid") + << QVariant(QVariant::Hash) + << QVariant() + ; + + QTest::newRow("string, null user type") + << QVariant::fromValue(QString::fromLatin1("A simple string")) + << QVariant(QVariant::Type(qRegisterMetaType<PhonyClass>("PhonyClass"))) + ; + + QTest::newRow("both non-null user type") + << QVariant(qRegisterMetaType<PhonyClass>("PhonyClass"), (const void*)0) + << QVariant(qRegisterMetaType<PhonyClass>("PhonyClass"), (const void*)0) + ; +} + +void tst_Cmptest::compare_tostring() +{ + QFETCH(QVariant, actual); + QFETCH(QVariant, expected); + + QCOMPARE(actual, expected); +} + QTEST_MAIN(tst_Cmptest) #include "tst_cmptest.moc" diff --git a/tests/auto/selftests/expected_cmptest.txt b/tests/auto/selftests/expected_cmptest.txt index dc89d9d..f70eba5 100644 --- a/tests/auto/selftests/expected_cmptest.txt +++ b/tests/auto/selftests/expected_cmptest.txt @@ -1,8 +1,24 @@ ********* Start testing of tst_Cmptest ********* -Config: Using QTest library 4.1.0, Qt 4.1.0 +Config: Using QTest library 4.6.0, Qt 4.6.0 PASS : tst_Cmptest::initTestCase() PASS : tst_Cmptest::compare_boolfuncs() PASS : tst_Cmptest::compare_pointerfuncs() +FAIL! : tst_Cmptest::compare_tostring(int, string) Compared values are not the same + Actual (actual): QVariant(int,123) + Expected (expected): QVariant(QString,hi) + Loc: [/home/rmcgover/depot/qt/master/tests/auto/selftests/cmptest/tst_cmptest.cpp(122)] +FAIL! : tst_Cmptest::compare_tostring(null hash, invalid) Compared values are not the same + Actual (actual): QVariant(QVariantHash) + Expected (expected): QVariant() + Loc: [/home/rmcgover/depot/qt/master/tests/auto/selftests/cmptest/tst_cmptest.cpp(122)] +FAIL! : tst_Cmptest::compare_tostring(string, null user type) Compared values are not the same + Actual (actual): QVariant(QString,A simple string) + Expected (expected): QVariant(PhonyClass) + Loc: [/home/rmcgover/depot/qt/master/tests/auto/selftests/cmptest/tst_cmptest.cpp(122)] +FAIL! : tst_Cmptest::compare_tostring(both non-null user type) Compared values are not the same + Actual (actual): QVariant(PhonyClass,<value not representable as string>) + Expected (expected): QVariant(PhonyClass,<value not representable as string>) + Loc: [/home/rmcgover/depot/qt/master/tests/auto/selftests/cmptest/tst_cmptest.cpp(122)] PASS : tst_Cmptest::cleanupTestCase() -Totals: 4 passed, 0 failed, 0 skipped +Totals: 4 passed, 4 failed, 0 skipped ********* Finished testing of tst_Cmptest ********* diff --git a/tests/manual/qdesktopwidget/main.cpp b/tests/manual/qdesktopwidget/main.cpp index 1afc82e..2cbdfb9 100644 --- a/tests/manual/qdesktopwidget/main.cpp +++ b/tests/manual/qdesktopwidget/main.cpp @@ -130,7 +130,7 @@ private slots: screenNumber->setBrush(fillBrush); screenNumber->setFont(QFont("Arial Black", 18)); screenNumber->setTransform(QTransform().scale(10, 10)); - screenNumber->setTransformOrigin(screenNumber->boundingRect().center()); + screenNumber->setTransformOriginPoint(screenNumber->boundingRect().center()); QSizeF center = (workRect.size() - screenNumber->boundingRect().size()) / 2; screenNumber->setPos(center.width(), center.height()); diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 39588e6..c938919 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2045,8 +2045,6 @@ void Configure::generateBuildKey() QStringList build_options; if (!dictionary["QCONFIG"].isEmpty()) build_options += dictionary["QCONFIG"] + "-config "; - if (dictionary["STL"] == "no") - build_options += "no-stl"; build_options.sort(); // Sorted defines that start with QT_NO_ diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h index 4e97d9f..22cb671 100644 --- a/tools/qdoc3/config.h +++ b/tools/qdoc3/config.h @@ -140,6 +140,7 @@ class Config #define CONFIG_INDEXES "indexes" #define CONFIG_LANGUAGE "language" #define CONFIG_MACRO "macro" +#define CONFIG_OBSOLETELINKS "obsoletelinks" #define CONFIG_OUTPUTDIR "outputdir" #define CONFIG_OUTPUTLANGUAGE "outputlanguage" #define CONFIG_OUTPUTFORMATS "outputformats" diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index f92391e..68cad18 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -186,7 +186,7 @@ HtmlGenerator::HtmlGenerator() : helpProjectWriter(0), inLink(false), inContents(false), inSectionHeading(false), inTableHeader(false), numTableRows(0), threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"), - tre(0), slow(false) + tre(0), slow(false), obsoleteLinks(false) { } @@ -215,6 +215,7 @@ void HtmlGenerator::initializeGenerator(const Config &config) }; Generator::initializeGenerator(config); + obsoleteLinks = config.getBool(QLatin1String(CONFIG_OBSOLETELINKS)); setImageFileExtensions(QStringList() << "png" << "jpg" << "jpeg" << "gif"); int i = 0; while (defaults[i].key) { @@ -3534,9 +3535,11 @@ QString HtmlGenerator::getLink(const Atom *atom, } QString name = marker->plainFullName(relative); if (!porting && !name.startsWith("Q3")) { - relative->doc().location().warning(tr("Link to obsolete item '%1' in %2") - .arg(atom->string()) - .arg(name)); + if (obsoleteLinks) { + relative->doc().location().warning(tr("Link to obsolete item '%1' in %2") + .arg(atom->string()) + .arg(name)); + } inObsoleteLink = true; } #if 0 diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h index a7632cd..2ad4697 100644 --- a/tools/qdoc3/htmlgenerator.h +++ b/tools/qdoc3/htmlgenerator.h @@ -252,6 +252,7 @@ class HtmlGenerator : public PageGenerator QStringList customHeadElements; const Tree *tre; bool slow; + bool obsoleteLinks; QMap<QString, QMap<QString, const Node *> > moduleClassMap; QMap<QString, QMap<QString, const Node *> > moduleNamespaceMap; QMap<QString, const Node *> nonCompatClasses; diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp index 6425765..9338203 100644 --- a/tools/qdoc3/main.cpp +++ b/tools/qdoc3/main.cpp @@ -96,6 +96,7 @@ static const struct { static bool slow = false; static bool showInternal = false; +static bool obsoleteLinks = false; static QStringList defines; static QHash<QString, Tree *> trees; @@ -130,7 +131,9 @@ static void printHelp() " -slow " "Turn on features that slow down qdoc\n" " -showinternal " - "Include stuff marked internal") ); + "Include stuff marked internal\n" + " -obsoletelinks " + "Report links from obsolete items to non-obsolete items") ); } /*! @@ -165,6 +168,8 @@ static void processQdocconfFile(const QString &fileName) config.setStringList(CONFIG_SLOW, QStringList(slow ? "true" : "false")); config.setStringList(CONFIG_SHOWINTERNAL, QStringList(showInternal ? "true" : "false")); + config.setStringList(CONFIG_OBSOLETELINKS, + QStringList(obsoleteLinks ? "true" : "false")); /* With the default configuration values in place, load @@ -434,6 +439,9 @@ int main(int argc, char **argv) else if (opt == "-showinternal") { showInternal = true; } + else if (opt == "-obsoletelinks") { + obsoleteLinks = true; + } else { qdocFiles.append(opt); } diff --git a/util/webkit/mkdist-webkit b/util/webkit/mkdist-webkit index 72ce8e8..c601f76 100755 --- a/util/webkit/mkdist-webkit +++ b/util/webkit/mkdist-webkit @@ -5,7 +5,7 @@ die() { exit 1 } -default_tag="origin/qtwebkit-4.6-staging" +default_tag="qtwebkit-4.6-snapshot-29072009" if [ $# -eq 0 ]; then tag="$default_tag" |