diff options
441 files changed, 10617 insertions, 5527 deletions
@@ -206,6 +206,11 @@ plugin_commonU.def *.sis *.sisx *.lst +*.exe +*.mif +*.rsc +*.sym +*.lib # Generated by abldfast.bat from devtools. .abldsteps.* diff --git a/README.s60-mkspec b/README.s60-mkspec new file mode 100644 index 0000000..af500e1 --- /dev/null +++ b/README.s60-mkspec @@ -0,0 +1,99 @@ +How to build Qt for Symbian using the Linux makespec. + +Prerequisites: + + - Working RVCT 2.2 native Linux compiler. The new publicly + available RVCT 4.0 compiler may work, but it hasn't been tested + yet. + + - A working GnuPoc environment. See this page for details: + http://www.martin.st/symbian/ + Download the latest version, unpack it and run the 'install_eka2_tools' script as + described in the last part under the EKA2 part. The part about the your own gcc + are not needed as we use the rvct compiler. + Make sure you do the part about Wine setup as well. + + - Anderson Lizardo's patches for GnuPoc. Look for the + qt_s60_gnupoc_v10.patch on this page: + http://lizardo.wordpress.com/2009/09/24/installing-qt-for-s60-daily-snapshots-on-linux/ + and carry out the instructions under point 8: Installing Open C. + +Compiling: + + 1. First a few environment variables need to be set: + + export RVCT22LIB=<rvct-dir>/lib/armlib + export EPOCROOT=<s60-root> + export PATH=$PATH:<s60-root>/epoc32/tools:<rvctInstallDir>/bin + export PATH=$PATH:<qt-root>/bin + + Replace the s60-root with the installation directory of your SDK, + and the qt-root with the root of your Qt repository. + These are good candidates for putting in a script somewhere. + + 2. Run configure. It needs a bit more switches than usual, so here's + the full line: + + ./configure -developer-build -platform linux-g++ -xplatform \ + symbian/linux-armcc -little-endian -host-little-endian \ + -arch symbian + + 3. Compile Qt + + cd src + make + + and then wait for a while. + + 4. Package and install Qt + + cd s60installs + + Edit Qt_template.pkg and change the first 0x2xxxxxxx to + 0xExxxxxxx. Then execute: + + makesis Qt_template.pkg + signsis Qt_template.sis Qt_template.sisx selfsigned.cer selfsigned.key + + Then put Qt_template.sisx on a memory card and install it from + the phone file manager. + + Alternatively, you can use the runonphone tool found in the tools + directory of Qt. To build, this requires a separately configured + Qt installation for Linux, unfortunately. To use it, you also + need have App TRK running on the phone. At the time of writing, + only bleeding edge Linux kernels are able to autodetect the USB + serial port on the phone, but you can force detection by running: + + modprobe usbserial vendor=0xXXXX product=0xXXXX + + The XXXXs should be replaced with the two values listed for your + device when executing "lsusb". In most distributions, this will + lead to the creation of two devices: /dev/ttyUSB0 and + /dev/ttyUSB1. The latter is usually the one that App TRK responds + to. Then execute: + + runonphone -p /dev/ttyUSB1 -s Qt_template.sisx dummy.exe + + The dummy.exe argument is irrelevant, since we are not executing + anything yet. + + 5. Compile some helloworld application (I leave the details to you + ;-) + + qmake + make + + 6. Package, install and run application. + + makesis helloworld_template.pkg + signsis helloworld_template.sis helloworld_template.sisx \ + <QTDIR>/src/s60installs/selfsigned.cer \ + <QTDIR>/src/s60installs/selfsigned.key + + Then either install by memory card, or install and run like this: + + runonphone -p /dev/ttyUSB1 -s helloworld_template.sisx \ + helloworld.exe + + 7. Enjoy "hello world" on the phone! diff --git a/bin/createpackage.sh b/bin/createpackage index fdd4eeb..fdd4eeb 100755 --- a/bin/createpackage.sh +++ b/bin/createpackage diff --git a/bin/createpackage.pl b/bin/createpackage.pl index 1d6ab6b..554d619 100755 --- a/bin/createpackage.pl +++ b/bin/createpackage.pl @@ -85,7 +85,7 @@ Where parameters are as follows: winscw | gcce | armv5 | armv6 | armv7 certificate = The certificate file used for signing key = The certificate's private key file - passphrase = The certificate's private key file's passphrase + passphrase = The passphrase of the certificate's private key file Example: createpackage.pl fluidlauncher_template.pkg release-armv5 @@ -130,16 +130,21 @@ my $templatepkg = $ARGV[0]; my $targetplatform = lc $ARGV[1]; my @tmpvalues = split('-', $targetplatform); -my $target = $tmpvalues[0]; -my $platform = $tmpvalues[1];; +my $target; +$target = $tmpvalues[0] or $target = ""; +my $platform; +$platform = $tmpvalues[1] or $platform = ""; # Convert visual target to real target (debug->udeb and release->urel) $target =~ s/debug/udeb/i; $target =~ s/release/urel/i; -my $certificate = $ARGV[2]; -my $key = $ARGV[3]; -my $passphrase = $ARGV[4]; +my $certificate; +$certificate = $ARGV[2] or $certificate = ""; +my $key; +$key = $ARGV[3] or $key = ""; +my $passphrase; +$passphrase = $ARGV[4] or $passphrase = ""; # Generate output pkg basename (i.e. file name without extension) my $pkgoutputbasename = $templatepkg; @@ -149,11 +154,11 @@ if ($pkgoutputbasename eq $templatepkg) { $preservePkgOutput = "1"; } $pkgoutputbasename =~ s/\.pkg//g; -$pkgoutputbasename = lc($pkgoutputbasename); +$pkgoutputbasename = $pkgoutputbasename; # Store output file names to variables -my $pkgoutput = lc($pkgoutputbasename.".pkg"); -my $sisoutputbasename = lc($pkgoutputbasename); +my $pkgoutput = $pkgoutputbasename.".pkg"; +my $sisoutputbasename = $pkgoutputbasename; $sisoutputbasename =~ s/_$targetplatform//g; my $unsigned_sis_name = $sisoutputbasename."_unsigned.sis"; my $signed_sis_name = $sisoutputbasename.".sis"; @@ -171,14 +176,6 @@ unless (length($templatepkg)) { Usage(); } -# If the pkg file is not actually a template, there is no need for plaform or target. -if ($templatepkg =~ m/_template\.pkg/i) { - unless (length($platform) && length($target)) { - print "\nError: Platform or target is not defined!\n"; - Usage(); - } -} - # Check template exist stat($templatepkg); unless( -e _ ) { @@ -240,12 +237,25 @@ if (!$preservePkgOutput) { } # Preprocess PKG +if ($certtext eq "Self Signed" && !@certificates) { + print("Patching capabilities for self signed package $certificate\n"); + system ("patch_capabilities $templatepkg $targetplatform"); +} + local $/; # read template file open( TEMPLATE, $templatepkg) or die "Error '$templatepkg': $!\n"; $_=<TEMPLATE>; close (TEMPLATE); +# If the pkg file does not contain macros, there is no need for platform or target. +if (m/\$\(PLATFORM\)/) { + unless (length($platform) && length($target)) { + print "\nError: Platform or target is not defined!\n"; + Usage(); + } +} + # replace the PKG variables s/\$\(PLATFORM\)/$platform/gm; s/\$\(TARGET\)/$target/gm; @@ -268,11 +278,15 @@ if($stub) { system ("makesis -s $pkgoutput $stub_sis_name"); } else { # Create SIS. - system ("makesis $pkgoutput $unsigned_sis_name"); + # The 'and' is because system uses 0 to indicate success. + system ("makesis $pkgoutput $unsigned_sis_name") and die ("makesis failed"); print("\n"); # Sign SIS with certificate info given as an argument. - system ("signsis $unsigned_sis_name $signed_sis_name $certificate $key $passphrase"); + my $relcert = File::Spec->abs2rel($certificate); + my $relkey = File::Spec->abs2rel($key); + # The 'and' is because system uses 0 to indicate success. + system ("signsis $unsigned_sis_name $signed_sis_name $relcert $relkey $passphrase") and die ("signsis failed"); # Check if creating signed SIS Succeeded stat($signed_sis_name); @@ -286,10 +300,10 @@ if($stub) { # Sign with additional certificates & keys for my $row ( @certificates ) { # Get certificate absolute file names, relative paths are relative to certfilepath - my $abscert = File::Spec->rel2abs( $row->[0], $certfilepath); - my $abskey = File::Spec->rel2abs( $row->[1], $certfilepath); + my $relcert = File::Spec->abs2rel(File::Spec->rel2abs( $row->[0], $certfilepath)); + my $relkey = File::Spec->abs2rel(File::Spec->rel2abs( $row->[1], $certfilepath)); - system ("signsis $signed_sis_name $signed_sis_name $abscert $abskey $row->[2]"); + system ("signsis $signed_sis_name $signed_sis_name $relcert $relkey $row->[2]"); print ("\tAdditionally signed the SIS with certificate: $row->[0]!\n"); } diff --git a/bin/patch_capabilities b/bin/patch_capabilities new file mode 100755 index 0000000..0d89622 --- /dev/null +++ b/bin/patch_capabilities @@ -0,0 +1,3 @@ +#!/bin/sh +scriptpath=`dirname $0` +perl $scriptpath/patch_capabilities.pl "$@" diff --git a/bin/patch_capabilities.pl b/bin/patch_capabilities.pl index f82c48f..4390957 100755 --- a/bin/patch_capabilities.pl +++ b/bin/patch_capabilities.pl @@ -50,14 +50,26 @@ sub Usage() { print("This script can be used to set capabilities of all binaries\n"); print("specified for deployment in a .pkg file.\n"); print("If no capabilities are given, the binaries will be given the\n"); - print("capabilities supported by self-signed certificates.\n"); - print("\n *** NOTE: If *_template.pkg file is given, 'target-platform' is REQUIRED. ***\n"); - print("\nUsage: patch_capabilities.pl pkg_filename <target-platform> [capability list]\n"); + print("capabilities supported by self-signed certificates.\n\n"); + print(" *** NOTE: If *_template.pkg file is given and one is using symbian-abld or\n"); + print(" symbian-sbsv2 platform, 'target-platform' is REQUIRED. ***\n"); + print("\nUsage: patch_capabilities.pl pkg_filename [target-platform [capability list]]\n"); print("\nE.g. patch_capabilities.pl myapp_template.pkg release-armv5 \"All -TCB\"\n"); exit(); } -my @capabilitiesToSet = ("LocalServices", "NetworkServices", "ReadUserData", "UserEnvironment", "WriteUserData"); +sub trim($) { + my $string = shift; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; +} + +my $nullDevice = "/dev/null"; +$nullDevice = "NUL" if ($^O =~ /MSWin/); + +my @capabilitiesToAllow = ("LocalServices", "NetworkServices", "ReadUserData", "UserEnvironment", "WriteUserData"); +my @capabilitiesSpecified = (); # If arguments were given to the script, if (@ARGV) @@ -73,11 +85,16 @@ if (@ARGV) if (($pkgFileName =~ m|_template\.pkg$|i) && -r($pkgFileName)) { my $targetplatform; - unless ($targetplatform = shift(@ARGV)) + my $templateFile; + my $templateContents; + open($templateFile, "< $pkgFileName") or die ("Could not open $pkgFileName"); + $templateContents = <$templateFile>; + close($templateFile); + unless (($targetplatform = shift(@ARGV)) || $templateContents !~ /\$\(PLATFORM\)/) { Usage(); } - + $targetplatform = "-" if (!$targetplatform); my @tmpvalues = split('-', $targetplatform); $target = $tmpvalues[0]; $platform = $tmpvalues[1]; @@ -93,10 +110,10 @@ if (@ARGV) # If there are more arguments given, parse them as capabilities. if (@ARGV) { - @capabilitiesToSet = (); + @capabilitiesSpecified = (); while (@ARGV) { - push (@capabilitiesToSet, pop(@ARGV)); + push (@capabilitiesSpecified, pop(@ARGV)); } } @@ -174,7 +191,7 @@ if (@ARGV) my $destinationPath = $2; # If the given file is a binary, check the target and binary type (+ the actual filename) from its path. - if ($sourcePath =~ m:/epoc32/release/([^/]+)/(udeb|urel|\$\(TARGET\))/(\w+(\.dll|\.exe)):i) + if ($sourcePath =~ m:\w+(\.dll|\.exe)$:i) { # Do preprocessing for template pkg, # In case of template pkg target and platform variables are set @@ -197,23 +214,42 @@ if (@ARGV) print ("\n"); - my $baseCommandToExecute = "elftran -vid 0x0 -capability \""; - if (@capabilitiesToSet) - { - $baseCommandToExecute .= join(" ", @capabilitiesToSet); - } - $baseCommandToExecute .= "\" "; + my $baseCommandToExecute = "elftran -vid 0x0 -capability \"%s\" "; # Actually set the capabilities of the listed binaries. foreach my $binaryPath(@binaries) { # Create the command line for setting the capabilities. my $commandToExecute = $baseCommandToExecute; + if (@capabilitiesSpecified) + { + $commandToExecute = sprintf($baseCommandToExecute, join(" ", @capabilitiesSpecified)); + } else { + # Test which capabilities are present and then restrict them to the allowed set. + # This avoid raising the capabilities of apps that already have none. + my $dllCaps; + open($dllCaps, "elftran -dump s $binaryPath |") or die ("Could not execute elftran"); + my $capsFound = 0; + my @capabilitiesToSet; + my $capabilitiesToAllow = join(" ", @capabilitiesToAllow); + while (<$dllCaps>) { + if (!$capsFound) { + $capsFound = 1 if (/Capabilities:/); + } else { + $_ = trim($_); + if ($capabilitiesToAllow =~ /$_/) { + push(@capabilitiesToSet, $_); + } + } + } + close($dllCaps); + $commandToExecute = sprintf($baseCommandToExecute, join(" ", @capabilitiesToSet)); + } $commandToExecute .= $binaryPath; # Actually execute the elftran command to set the capabilities. - system ($commandToExecute." > NUL"); - print ("Executed ".$commandToExecute."\n"); + print ("Executing ".$commandToExecute."\n"); + system ($commandToExecute." > $nullDevice"); ## Create another command line to check that the set capabilities are correct. #$commandToExecute = "elftran -dump s ".$binaryPath; diff --git a/config.tests/.gitignore b/config.tests/.gitignore new file mode 100644 index 0000000..bd76520 --- /dev/null +++ b/config.tests/.gitignore @@ -0,0 +1,2 @@ +*.rpp +*.rsg diff --git a/config.tests/symbian/audio/.gitignore b/config.tests/symbian/audio/.gitignore new file mode 100644 index 0000000..87a251c --- /dev/null +++ b/config.tests/symbian/audio/.gitignore @@ -0,0 +1,2 @@ +audio.rpp +audio.rsg diff --git a/src/imports/webkit/webkitqmlplugin_export.h b/config.tests/symbian/audio/audio.cpp index 974fd24..4ffc728 100644 --- a/src/imports/webkit/webkitqmlplugin_export.h +++ b/config.tests/symbian/audio/audio.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** This file is part of the config.tests of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -39,15 +39,9 @@ ** ****************************************************************************/ -#ifndef WEBKITQMLPLUGIN_EXPORT_H -#define WEBKITQMLPLUGIN_EXPORT_H +#include <sounddevice.h> -#include <QtCore/QtGlobal> - -#if defined WEBKITQMLPLUGIN_EXPORTS -# define WEBKITQMLPLUGIN_EXPORT Q_DECL_EXPORT -#else -# define WEBKITQMLPLUGIN_EXPORT Q_DECL_IMPORT -#endif - -#endif // WEBKITQMLPLUGIN_EXPORT_H +int main(int argc, char **argv) +{ + return 0; +} diff --git a/config.tests/symbian/audio/audio.pro b/config.tests/symbian/audio/audio.pro new file mode 100644 index 0000000..abbde6e --- /dev/null +++ b/config.tests/symbian/audio/audio.pro @@ -0,0 +1,7 @@ +TARGET = audio +SOURCES = audio.cpp + +INCLUDEPATH += $${EPOCROOT}epoc32/include/mmf/server +INCLUDEPATH += $${EPOCROOT}epoc32/include/mmf/common + +LIBS += -lmmfdevsound diff --git a/config.tests/symbian/compile.test b/config.tests/symbian/compile.test new file mode 100755 index 0000000..20a3039 --- /dev/null +++ b/config.tests/symbian/compile.test @@ -0,0 +1,46 @@ +#!/bin/sh + +SUCCESS=no +QMKSPEC=$1 +XPLATFORM=`basename "$1"` +QMAKE_CONFIG=$2 +VERBOSE=$3 +SRCDIR=$4 +OUTDIR=$5 +TEST=$6 +EXE=`basename "$6"` +DESCRIPTION=$7 +shift 7 +LFLAGS="" +INCLUDEPATH="" +CXXFLAGS="" +MAC_ARCH_CXXFLAGS="" +MAC_ARCH_LFLAGS="" + +# debuggery +[ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION auto-detection... ($*)" + +test -d "$OUTDIR/$TEST" || mkdir -p "$OUTDIR/$TEST" + +cd "$OUTDIR/$TEST" + +test -r Makefile && $MAKE distclean >/dev/null 2>&1 + +"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "LIBS*=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile" + +if [ "$VERBOSE" = "yes" ]; then + $MAKE +else + $MAKE >/dev/null 2>&1 +fi + +[ -x "$EXE.exe" ] && SUCCESS=yes + +# done +if [ "$SUCCESS" != "yes" ]; then + [ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION disabled." + exit 1 +else + [ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION enabled." + exit 0 +fi diff --git a/config.tests/unix/largefile/largefile.pro b/config.tests/unix/largefile/largefile.pro deleted file mode 100644 index d7affc6..0000000 --- a/config.tests/unix/largefile/largefile.pro +++ /dev/null @@ -1,3 +0,0 @@ -SOURCES=largefiletest.cpp -CONFIG-=qt dylib -mac:CONFIG -= app_bundle @@ -644,6 +644,8 @@ CFG_XVIDEO=auto CFG_XINERAMA=runtime CFG_XFIXES=runtime CFG_ZLIB=auto +CFG_SYMBIAN_DEFFILES=auto +CFG_S60=auto CFG_SQLITE=qt CFG_GIF=auto CFG_TIFF=auto @@ -678,7 +680,7 @@ CFG_PHONON=auto CFG_PHONON_BACKEND=yes CFG_MULTIMEDIA=yes CFG_MEDIASERVICE=yes -CFG_AUDIO_BACKEND=yes +CFG_AUDIO_BACKEND=auto CFG_SVG=yes CFG_DECLARATIVE=auto CFG_WEBKIT=auto # (yes|no|auto) @@ -723,7 +725,7 @@ CFG_DBUS=auto CFG_GLIB=auto CFG_GSTREAMER=auto CFG_QGTKSTYLE=auto -CFG_LARGEFILE=auto +CFG_LARGEFILE=yes CFG_OPENSSL=auto CFG_PTMALLOC=no CFG_STL=auto @@ -926,8 +928,7 @@ while [ "$#" -gt 0 ]; do VAL=no ;; #Qt style yes options - - -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xvideo|-xsync|-xinput|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-mediaservice|-audio-backend|-svg|-declarative|-webkit|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config) + -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-mediaservice|-audio-backend|-svg|-declarative|-webkit|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles) VAR=`echo $1 | sed "s,^-\(.*\),\1,"` VAL=yes ;; @@ -1492,7 +1493,6 @@ while [ "$#" -gt 0 ]; do fi ;; feature-*) - if [ "$PLATFORM_QWS" = "yes" ]; then FEATURE=`echo $VAR | sed "s,^[^-]*-\([^-]*\),\1," | tr 'abcdefghijklmnopqrstuvwxyz-' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` if [ "$VAL" = "no" ]; then QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_$FEATURE" @@ -1501,9 +1501,6 @@ while [ "$#" -gt 0 ]; do else UNKNOWN_OPT=yes fi - else - UNKNOWN_OPT=yes - fi ;; shared) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then @@ -1657,6 +1654,20 @@ while [ "$#" -gt 0 ]; do # No longer supported: #[ "$VAL" = "no" ] && CFG_LIBPNG=no ;; + s60) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_S60="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; + usedeffiles) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_SYMBIAN_DEFFILES="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; sqlite) if [ "$VAL" = "system" ]; then CFG_SQLITE=system @@ -2170,6 +2181,7 @@ esac # where to find which.. unixtests="$relpath/config.tests/unix" mactests="$relpath/config.tests/mac" +symbiantests="$relpath/config.tests/symbian" WHICH="$unixtests/which.test" PERL=`$WHICH perl 2>/dev/null` @@ -3341,6 +3353,7 @@ Usage: $relconf [-h] [-prefix <dir>] [-prefix-install] [-bindir <dir>] [-libdir [-no-openssl] [-openssl] [-openssl-linked] [-no-gtkstyle] [-gtkstyle] [-no-svg] [-svg] [-no-webkit] [-webkit] [-no-javascript-jit] [-javascript-jit] [-no-script] [-script] [-no-scripttools] [-scripttools] [-no-declarative] [-declarative] + [-no-s60] [-s60] [-no-usedeffiles] [-usedeffiles] [additional platform specific options (see below)] @@ -3524,6 +3537,11 @@ EOF fi cat << EOF + -no-s60 ............ Do not compile in S60 support. + + -s60 ............... Compile with support for the S60 UI Framework. + -no-usedeffiles .... Disable the usage of DEF files. + * -usedeffiles ....... Enable the usage of DEF files. + -no-mmx ............ Do not compile with use of MMX instructions. -no-3dnow .......... Do not compile with use of 3DNOW instructions. -no-sse ............ Do not compile with use of SSE instructions. @@ -3987,7 +4005,7 @@ if [ "$PLATFORM_QWS" = "yes" ]; then Platform="Qt for Embedded Linux" elif [ "$PLATFORM_MAC" = "yes" ]; then Platform="Qt for Mac OS X" -else +elif [ '!' -z "`getQMakeConf \"$XQMAKESPEC\" | grep QMAKE_LIBS_X11 | awk '{print $3;}'`" ]; then PLATFORM_X11=yes Platform="Qt for Linux/X11" fi @@ -4611,6 +4629,22 @@ if [ "$CFG_ZLIB" = "auto" ]; then fi fi +if [ "$CFG_S60" = "auto" ]; then + if echo "$XQMAKESPEC" | grep symbian > /dev/null; then + CFG_S60=yes + else + CFG_S60=no + fi +fi + +if [ "$CFG_SYMBIAN_DEFFILES" = "auto" ]; then + if echo "$XQMAKESPEC" | grep symbian > /dev/null && [ "$CFG_DEV" = "no" ]; then + CFG_SYMBIAN_DEFFILES=yes + else + CFG_SYMBIAN_DEFFILES=no + fi +fi + # detect how jpeg should be built if [ "$CFG_JPEG" = "auto" ]; then if [ "$CFG_SHARED" = "yes" ]; then @@ -4889,6 +4923,14 @@ for _SQLDR in $CFG_SQL_AVAILABLE; do fi ;; sqlite) + if [ "$CFG_SQL_sqlite" = "auto" ]; then # the default + case "$XPLATFORM" in + symbian*) + # sqlite on symbian is typically not build in Qt but deployed as a pre-existing sis file. + CFG_SQL_sqlite=no + ;; + esac + fi if [ "$CFG_SQL_sqlite" != "no" ]; then SQLITE_AUTODETECT_FAILED="no" if [ "$CFG_SQLITE" = "system" ]; then @@ -5714,7 +5756,7 @@ if [ "$CFG_DOUBLEFORMAT" = "auto" ]; then fi HAVE_STL=no -if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/stl "STL" $L_FLAGS $I_FLAGS $l_FLAGS; then +if echo "$XQMAKESPEC" | grep symbian > /dev/null || "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/stl "STL" $L_FLAGS $I_FLAGS $l_FLAGS; then HAVE_STL=yes fi @@ -5848,23 +5890,6 @@ if [ "$CFG_GETIFADDRS" != "no" ]; then fi fi -# find if the platform supports X/Open Large File compilation environment -if [ "$CFG_LARGEFILE" != "no" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/largefile "X/Open Large File" $L_FLAGS $I_FLAGS $l_FLAGS; then - CFG_LARGEFILE=yes - else - if [ "$CFG_LARGEFILE" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "X/Open Large File support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_LARGEFILE=no - fi - fi -fi - # detect OpenSSL if [ "$CFG_OPENSSL" != "no" ]; then if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/openssl "OpenSSL" $L_FLAGS $I_FLAGS $l_FLAGS $MAC_CONFIG_TEST_COMMANDLINE; then @@ -5968,6 +5993,14 @@ elif [ "$CFG_JAVASCRIPTCORE_JIT" = "no" ]; then QMakeVar set JAVASCRIPTCORE_JIT no fi +if [ "$CFG_AUDIO_BACKEND" = "auto" ]; then + if echo "$XQMAKESPEC" | grep symbian > /dev/null 2>&1; then + "$symbiantests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/symbian/audio "audio" $L_FLAGS $I_FLAGS $l_FLAGS + else + CFG_AUDIO_BACKEND=yes + fi +fi + #------------------------------------------------------------------------------- # ask for all that hasn't been auto-detected or specified in the arguments #------------------------------------------------------------------------------- @@ -6083,9 +6116,9 @@ case "$PLATFORM,$CFG_MAC_COCOA" in ;; esac -# disable Qt 3 support on VxWorks +# disable Qt 3 support on VxWorks and Symbian case "$XPLATFORM" in - unsupported/vxworks*) + unsupported/vxworks*|symbian*) CFG_QT3SUPPORT="no" ;; esac @@ -6139,6 +6172,13 @@ else fi fi +# Disable OpenGL on Symbian. +case "$XPLATFORM" in + symbian*) + CFG_OPENGL="no" + ;; +esac + # enable opengl if [ "$CFG_OPENGL" = "no" ]; then QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_OPENGL" @@ -6313,6 +6353,16 @@ elif [ "$CFG_ZLIB" = "system" ]; then QT_CONFIG="$QT_CONFIG system-zlib" fi +if [ "$CFG_S60" = "yes" ]; then + QT_CONFIG="$QT_CONFIG s60" +fi + +if [ "$CFG_SYMBIAN_DEFFILES" = "yes" ]; then + QMAKE_CONFIG="$QMAKE_CONFIG def_files" +else + QMAKE_CONFIG="$QMAKE_CONFIG def_files_disabled" +fi + [ "$CFG_NIS" = "yes" ] && QT_CONFIG="$QT_CONFIG nis" [ "$CFG_CUPS" = "yes" ] && QT_CONFIG="$QT_CONFIG cups" [ "$CFG_ICONV" = "yes" ] && QT_CONFIG="$QT_CONFIG iconv" @@ -7117,6 +7167,7 @@ QMakeVar set sql-plugins "$SQL_PLUGINS" [ "$CFG_JPEG" != "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_IMAGEFORMAT_JPEG" [ "$CFG_MNG" != "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_IMAGEFORMAT_MNG" [ "$CFG_ZLIB" != "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_ZLIB" +[ "$CFG_S60" != "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_S60" [ "$CFG_EXCEPTIONS" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_EXCEPTIONS" [ "$CFG_IPV6" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_IPV6" [ "$CFG_SXE" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_SXE" @@ -7172,6 +7223,15 @@ fi [ '!' -z "$AWK" ] && QCONFIG_FLAGS=`echo $QCONFIG_FLAGS | $AWK '{ gsub(" ", "\n"); print }' | sort | uniq` QCONFIG_FLAGS=`echo $QCONFIG_FLAGS` +if echo $XPLATFORM | grep symbian >/dev/null +then + # Enable Symbian DLLs and export rules. + # We cannot use Linux's default export rules since they export everything. + QCONFIG_FLAGS="$QCONFIG_FLAGS QT_DLL" + # Disable non-working features. + QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_CONCURRENT QT_NO_QFUTURE QT_NO_CRASHHANDLER QT_NO_PRINTER QT_NO_CURSOR QT_NO_SYSTEMTRAYICON" +fi + if [ -n "$QCONFIG_FLAGS" ]; then for cfg in $QCONFIG_FLAGS; do cfgd=`echo $cfg | sed 's/=.*$//'` # trim pushed 'Foo=Bar' defines @@ -7543,9 +7603,11 @@ if [ "$CFG_WEBKIT" = "yes" ]; then fi fi echo "Declarative module ..... $CFG_DECLARATIVE" +echo "Support for S60 ........ $CFG_S60" +echo "Symbian DEF files ...... $CFG_SYMBIAN_DEFFILES" echo "STL support ............ $CFG_STL" echo "PCH support ............ $CFG_PRECOMPILE" -echo "MMX/3DNOW/SSE/SSE2 ..... ${CFG_MMX}/${CFG_3DNOW}/${CFG_SSE}/${CFG_SSE2}" +echo "MMX/3DNOW/SSE/SSE2...... ${CFG_MMX}/${CFG_3DNOW}/${CFG_SSE}/${CFG_SSE2}" if [ "$CFG_ARCH" = "arm" ] || [ "$CFG_ARCH" = "armv6" ]; then echo "iWMMXt support ......... ${CFG_IWMMXT}" echo "NEON support ........... ${CFG_NEON}" diff --git a/demos/declarative/declarative.pro b/demos/declarative/declarative.pro index 4d169e3..aa60db0 100644 --- a/demos/declarative/declarative.pro +++ b/demos/declarative/declarative.pro @@ -8,6 +8,7 @@ SUBDIRS = \ sources.files = \ calculator \ flickr \ + photoviewer \ samegame \ snake \ twitter \ diff --git a/demos/declarative/flickr/common/qmldir b/demos/declarative/flickr/common/qmldir index 0c94f60..adc2479 100644 --- a/demos/declarative/flickr/common/qmldir +++ b/demos/declarative/flickr/common/qmldir @@ -1,10 +1,10 @@ -ImageDetails 0.0 ImageDetails.qml -LikeOMeter 0.0 LikeOMeter.qml -Loading 0.0 Loading.qml -MediaButton 0.0 MediaButton.qml -MediaLineEdit 0.0 MediaLineEdit.qml -Progress 0.0 Progress.qml -RssModel 0.0 RssModel.qml -ScrollBar 0.0 ScrollBar.qml -Slider 0.0 Slider.qml -Star 0.0 Star.qml +ImageDetails ImageDetails.qml +LikeOMeter LikeOMeter.qml +Loading Loading.qml +MediaButton MediaButton.qml +MediaLineEdit MediaLineEdit.qml +Progress Progress.qml +RssModel RssModel.qml +ScrollBar ScrollBar.qml +Slider Slider.qml +Star Star.qml diff --git a/demos/declarative/minehunt/MinehuntCore/Explosion.qml b/demos/declarative/minehunt/MinehuntCore/Explosion.qml index e337c46..172fcc0 100644 --- a/demos/declarative/minehunt/MinehuntCore/Explosion.qml +++ b/demos/declarative/minehunt/MinehuntCore/Explosion.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { property bool explode : false diff --git a/demos/declarative/minehunt/minehunt.cpp b/demos/declarative/minehunt/minehunt.cpp index 89845ef..5e44d1b 100644 --- a/demos/declarative/minehunt/minehunt.cpp +++ b/demos/declarative/minehunt/minehunt.cpp @@ -292,9 +292,8 @@ class MinehuntExtensionPlugin : public QDeclarativeExtensionPlugin public: void registerTypes(const char *uri) { - Q_UNUSED(uri); - QML_REGISTER_TYPE(SameGameCore, 0, 1, Tile, Tile); - QML_REGISTER_TYPE(SameGameCore, 0, 1, Game, MinehuntGame); + qmlRegisterType<Tile>(uri, 0, 1, "Tile"); + qmlRegisterType<MinehuntGame>(uri, 0, 1, "Game"); } void initializeEngine(QDeclarativeEngine *engine, const char *uri) { @@ -304,7 +303,7 @@ class MinehuntExtensionPlugin : public QDeclarativeExtensionPlugin MinehuntGame* game = new MinehuntGame(); - engine->rootContext()->addDefaultObject(game); + engine->rootContext()->setContextObject(game); } }; diff --git a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml new file mode 100644 index 0000000..fca7232 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml @@ -0,0 +1,100 @@ +import Qt 4.6 + +Component { + id: albumDelegate + Package { + + Item { + Package.name: 'browser' + GridView { + id: photosGridView; model: visualModel.parts.grid; width: mainWindow.width; height: mainWindow.height - 21 + x: 0; y: 21; cellWidth: 160; cellHeight: 153; interactive: false + onCurrentIndexChanged: photosListView.positionViewAtIndex(currentIndex, ListView.Contain) + } + } + + Item { + Package.name: 'fullscreen' + ListView { + id: photosListView; model: visualModel.parts.list; orientation: Qt.Horizontal + width: mainWindow.width; height: mainWindow.height; interactive: false + onCurrentIndexChanged: photosGridView.positionViewAtIndex(currentIndex, GridView.Contain) + highlightRangeMode: ListView.StrictlyEnforceRange; snapMode: ListView.SnapOneItem + } + } + + Item { + Package.name: 'album' + id: albumWrapper + width: 210; height: 220 + + VisualDataModel { + id: visualModel; delegate: PhotoDelegate { } + model: RssModel { id: rssModel; tags: tag } + } + + BusyIndicator { + anchors { centerIn: parent; verticalCenterOffset: -20 } + on: rssModel.status != XmlListModel.Ready + } + + PathView { + id: photosPathView; model: visualModel.parts.stack; pathItemCount: 5 + anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + path: Path { + PathAttribute { name: 'z'; value: 9999.0 } + PathLine { x: 1; y: 1 } + PathAttribute { name: 'z'; value: 0.0 } + } + } + + Tag { + anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom + frontLabel: tag; backLabel: "Delete"; rotation: Math.random() * (2 * 6 + 1) - 6 + flipped: mainWindow.editMode + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (mainWindow.editMode) { + photosModel.remove(index) + } else { + albumWrapper.state = 'inGrid' + } + } + } + + states: [ + State { + name: 'inGrid' + PropertyChanges { target: photosGridView; interactive: true } + PropertyChanges { target: albumsShade; opacity: 1 } + PropertyChanges { target: backButton; onClicked: albumWrapper.state = ''; y: 6 } + }, + State { + name: 'fullscreen'; extend: 'inGrid' + PropertyChanges { target: photosGridView; interactive: false } + PropertyChanges { target: photosListView; interactive: true } + PropertyChanges { target: photosShade; opacity: 1 } + PropertyChanges { target: backButton; y: -backTag.height - 8 } + } + ] + + transitions: [ + Transition { + from: '*'; to: 'inGrid' + SequentialAnimation { + NumberAnimation { properties: 'opacity'; duration: 250 } + PauseAnimation { duration: 350 } + NumberAnimation { target: backButton; properties: "y"; duration: 200; easing.type: "OutQuad" } + } + }, + Transition { + from: 'inGrid'; to: '*' + NumberAnimation { properties: "y,opacity"; easing.type: "OutQuad"; duration: 300 } + } + ] + } + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml b/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml new file mode 100644 index 0000000..919ac43 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml @@ -0,0 +1,9 @@ +import Qt 4.6 + +Image { + id: container + property bool on: false + + source: "images/busy.png"; visible: container.on + NumberAnimation on rotation { running: container.on; from: 0; to: 360; repeat: true; duration: 1200 } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Button.qml b/demos/declarative/photoviewer/PhotoViewerCore/Button.qml new file mode 100644 index 0000000..fb28314 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/Button.qml @@ -0,0 +1,25 @@ +import Qt 4.6 + +Item { + id: container + + property alias label: labelText.text + signal clicked + + width: labelText.width + 70 ; height: labelText.height + 18 + + BorderImage { + anchors { fill: container; leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 } + source: 'images/box-shadow.png'; smooth: true + border.left: 10; border.top: 10; border.right: 10; border.bottom: 10 + } + + Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true } + + Text { id: labelText; font.pixelSize: 15; anchors.centerIn: parent; smooth: true } + + MouseArea { + anchors { fill: parent; leftMargin: -20; topMargin: -20; rightMargin: -20; bottomMargin: -20 } + onClicked: container.clicked() + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml new file mode 100644 index 0000000..89fe3e8 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml @@ -0,0 +1,142 @@ +import Qt 4.6 + +Package { + Item { id: stackItem; Package.name: 'stack'; width: 160; height: 153; z: stackItem.PathView.z } + Item { id: listItem; Package.name: 'list'; width: mainWindow.width + 40; height: 153 } + Item { id: gridItem; Package.name: 'grid'; width: 160; height: 153 } + + Item { + width: 160; height: 153 + + Item { + id: photoWrapper + + property double randomAngle: Math.random() * (2 * 6 + 1) - 6 + property double randomAngle2: Math.random() * (2 * 6 + 1) - 6 + + x: 0; y: 0; width: 140; height: 133 + z: stackItem.PathView.z; rotation: photoWrapper.randomAngle + + BorderImage { + anchors { + fill: border.visible ? border : placeHolder + leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 + } + source: 'images/box-shadow.png'; smooth: true + border.left: 10; border.top: 10; border.right: 10; border.bottom: 10 + } + Rectangle { + id: placeHolder + + property int w: getWidth(content) + property int h: getHeight(content) + property double s: calculateScale(w, h, photoWrapper.width) + + color: '#878787'; anchors.centerIn: parent; smooth: true; border.color: 'white'; border.width: 3 + width: w * s; height: h * s; visible: originalImage.status != Image.Ready + } + Rectangle { + id: border; color: 'white'; anchors.centerIn: parent; smooth: true + width: originalImage.paintedWidth + 6; height: originalImage.paintedHeight + 6 + visible: !placeHolder.visible + } + BusyIndicator { anchors.centerIn: parent; on: originalImage.status != Image.Ready } + Image { + id: originalImage; smooth: true; source: "http://" + getImagePath(content) + fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height + } + Image { + id: hqImage; smooth: true; source: ""; visible: false + fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height + } + Binding { + target: mainWindow; property: "downloadProgress"; value: hqImage.progress + when: listItem.ListView.isCurrentItem + } + Binding { + target: mainWindow; property: "imageLoading" + value: (hqImage.status == Image.Loading) ? 1 : 0; when: listItem.ListView.isCurrentItem + } + MouseArea { + width: originalImage.paintedWidth; height: originalImage.paintedHeight; anchors.centerIn: originalImage + onClicked: { + if (albumWrapper.state == 'inGrid') { + gridItem.GridView.view.currentIndex = index; + albumWrapper.state = 'fullscreen' + } else { + gridItem.GridView.view.currentIndex = index; + albumWrapper.state = 'inGrid' + } + } + } + + states: [ + State { + name: 'stacked'; when: albumWrapper.state == '' + ParentChange { target: photoWrapper; parent: stackItem; x: 10; y: 10 } + PropertyChanges { target: photoWrapper; opacity: stackItem.PathView.onPath ? 1.0 : 0.0 } + }, + State { + name: 'inGrid'; when: albumWrapper.state == 'inGrid' + ParentChange { target: photoWrapper; parent: gridItem; x: 10; y: 10; rotation: photoWrapper.randomAngle2 } + }, + State { + name: 'fullscreen'; when: albumWrapper.state == 'fullscreen' + ParentChange { + target: photoWrapper; parent: listItem; x: 0; y: 0; rotation: 0 + width: mainWindow.width; height: mainWindow.height + } + PropertyChanges { target: border; opacity: 0 } + PropertyChanges { target: hqImage; source: listItem.ListView.isCurrentItem ? hq : ""; visible: true } + } + ] + + transitions: [ + Transition { + from: 'stacked'; to: 'inGrid' + SequentialAnimation { + PauseAnimation { duration: 10 * index } + ParentAnimation { + target: photoWrapper; via: foreground + NumberAnimation { + target: photoWrapper; properties: 'x,y,rotation,opacity'; duration: 600; easing.type: 'OutQuart' + } + } + } + }, + Transition { + from: 'inGrid'; to: 'stacked' + ParentAnimation { + target: photoWrapper; via: foreground + NumberAnimation { properties: 'x,y,rotation,opacity'; duration: 600; easing.type: 'OutQuart' } + } + }, + Transition { + from: 'inGrid'; to: 'fullscreen' + SequentialAnimation { + PauseAnimation { duration: gridItem.GridView.isCurrentItem ? 0 : 600 } + ParentAnimation { + target: photoWrapper; via: foreground + NumberAnimation { + targets: [ photoWrapper, border ] + properties: 'x,y,width,height,opacity,rotation' + duration: gridItem.GridView.isCurrentItem ? 600 : 1; easing.type: 'OutQuart' + } + } + } + }, + Transition { + from: 'fullscreen'; to: 'inGrid' + ParentAnimation { + target: photoWrapper; via: foreground + NumberAnimation { + targets: [ photoWrapper, border ] + properties: 'x,y,width,height,rotation,opacity' + duration: gridItem.GridView.isCurrentItem ? 600 : 1; easing.type: 'OutQuart' + } + } + } + ] + } + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml b/demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml new file mode 100644 index 0000000..bd6b30f --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml @@ -0,0 +1,16 @@ +import Qt 4.6 + +Item { + id: container + + property real progress: 0 + + Behavior on opacity { NumberAnimation { duration: 600 } } + + Rectangle { anchors.fill: parent; color: "black"; opacity: 0.5 } + + Rectangle { + id: fill; color: "white"; height: container.height + width: container.width * container.progress + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml b/demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml new file mode 100644 index 0000000..ddbc02b --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml @@ -0,0 +1,13 @@ +import Qt 4.6 + +XmlListModel { + property string tags : "" + + source: "http://api.flickr.com/services/feeds/photos_public.gne?"+(tags ? "tags="+tags+"&" : "") + query: "/feed/entry" + namespaceDeclarations: "declare default element namespace 'http://www.w3.org/2005/Atom';" + + XmlRole { name: "title"; query: "title/string()" } + XmlRole { name: "content"; query: "content/string()" } + XmlRole { name: "hq"; query: "link[@rel='enclosure']/@href/string()" } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml new file mode 100644 index 0000000..d32fcd0 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml @@ -0,0 +1,45 @@ +import Qt 4.6 + +Flipable { + id: flipable + + property alias frontLabel: frontButton.label + property alias backLabel: backButton.label + + property int angle: 0 + property bool flipped: false + + signal frontClicked + signal backClicked + + front: Button { + id: frontButton; anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + onClicked: flipable.frontClicked() + } + + back: Button { + id: backButton; anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + onClicked: flipable.backClicked() + } + + transform: Rotation { + origin.x: flipable.width / 2; origin.y: flipable.height / 2 + axis.x: 0; axis.y: 1; axis.z: 0 + angle: flipable.angle + } + + states: State { + name: "back"; when: flipable.flipped + PropertyChanges { target: flipable; angle: 180 } + } + + transitions: Transition { + ParallelAnimation { + NumberAnimation { properties: "angle"; duration: 400 } + SequentialAnimation { + NumberAnimation { target: flipable; property: "scale"; to: 0.8; duration: 200 } + NumberAnimation { target: flipable; property: "scale"; to: 1.0; duration: 200 } + } + } + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.png b/demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.png Binary files differnew file mode 100644 index 0000000..431af85 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.png diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/busy.png b/demos/declarative/photoviewer/PhotoViewerCore/images/busy.png Binary files differnew file mode 100644 index 0000000..664c2b1 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/images/busy.png diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.png b/demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.png Binary files differnew file mode 100644 index 0000000..1847ab5 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.png diff --git a/demos/declarative/photoviewer/PhotoViewerCore/qmldir b/demos/declarative/photoviewer/PhotoViewerCore/qmldir new file mode 100644 index 0000000..f94a560 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/qmldir @@ -0,0 +1,7 @@ +AlbumDelegate AlbumDelegate.qml +PhotoDelegate PhotoDelegate.qml +ProgressBar ProgressBar.qml +RssModel RssModel.qml +Button Button.qml +Tag Tag.qml +BusyIndicator BusyIndicator.qml diff --git a/demos/declarative/photoviewer/PhotoViewerCore/script/script.js b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js new file mode 100644 index 0000000..ae24ea1 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js @@ -0,0 +1,25 @@ +function getWidth(string) { + return (string.match(/width=\"([0-9]+)\"/))[1] +} + +function getHeight(string) { + return (string.match(/height=\"([0-9]+)\"/))[1] +} + +function getImagePath(string) { + var pattern = /src=\"http:\/\/(\S+)\"/ + return (string.match(pattern))[1] +} + +function calculateScale(width, height, cellSize) { + var widthScale = (cellSize * 1.0) / width + var heightScale = (cellSize * 1.0) / height + var scale = 0 + + if (widthScale <= heightScale) { + scale = widthScale; + } else if (heightScale < widthScale) { + scale = heightScale; + } + return scale; +} diff --git a/demos/declarative/photoviewer/photoviewer.qml b/demos/declarative/photoviewer/photoviewer.qml new file mode 100644 index 0000000..02134ac --- /dev/null +++ b/demos/declarative/photoviewer/photoviewer.qml @@ -0,0 +1,60 @@ +import Qt 4.6 +import PhotoViewerCore 1.0 + +Rectangle { + id: mainWindow + + property real downloadProgress: 0 + property bool imageLoading: false + property bool editMode: false + + width: 800; height: 480; color: "#d5d6d8" + + Script { source: "PhotoViewerCore/script/script.js" } + + ListModel { + id: photosModel + ListElement { tag: "Flowers" } + ListElement { tag: "Savanna" } + ListElement { tag: "Central Park" } + } + + VisualDataModel { id: albumVisualModel; model: photosModel; delegate: AlbumDelegate {} } + + GridView { + id: albumView; width: parent.width; height: parent.height; cellWidth: 210; cellHeight: 220 + model: albumVisualModel.parts.album; visible: albumsShade.opacity != 1.0 + } + + Column { + spacing: 20; anchors { bottom: parent.bottom; right: parent.right; rightMargin: 20; bottomMargin: 20 } + Button { id: deleteButton; label: "Edit"; rotation: -2; onClicked: mainWindow.editMode = !mainWindow.editMode } + Button { + id: newButton; label: "New"; rotation: 3 + onClicked: { + photosModel.append( { tag: "" } ) + albumView.positionViewAtIndex(albumView.count - 1, GridView.Contain) + } + } + } + + Rectangle { + id: albumsShade; color: mainWindow.color + width: parent.width; height: parent.height; opacity: 0.0 + } + + ListView { anchors.fill: parent; model: albumVisualModel.parts.browser; interactive: false } + + Button { id: backButton; label: "Back"; rotation: 3; x: parent.width - backButton.width - 6; y: -backButton.height - 8 } + + Rectangle { id: photosShade; color: 'black'; width: parent.width; height: parent.height; opacity: 0; visible: opacity != 0.0 } + + ListView { anchors.fill: parent; model: albumVisualModel.parts.fullscreen; interactive: false } + + Item { id: foreground; anchors.fill: parent } + + ProgressBar { + progress: mainWindow.downloadProgress; width: parent.width; height: 4 + anchors.bottom: parent.bottom; opacity: mainWindow.imageLoading; visible: opacity != 0.0 + } +} diff --git a/demos/declarative/samegame/SamegameCore/BoomBlock.qml b/demos/declarative/samegame/SamegameCore/BoomBlock.qml index e48194a..b14531d 100644 --- a/demos/declarative/samegame/SamegameCore/BoomBlock.qml +++ b/demos/declarative/samegame/SamegameCore/BoomBlock.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id:block property bool dying: false diff --git a/demos/declarative/samegame/SamegameCore/qmldir b/demos/declarative/samegame/SamegameCore/qmldir index a8f8a98..e17b1f5 100644 --- a/demos/declarative/samegame/SamegameCore/qmldir +++ b/demos/declarative/samegame/SamegameCore/qmldir @@ -1,3 +1,3 @@ -BoomBlock 0.0 BoomBlock.qml -Button 0.0 Button.qml -Dialog 0.0 Dialog.qml +BoomBlock BoomBlock.qml +Button Button.qml +Dialog Dialog.qml diff --git a/demos/declarative/snake/content/Cookie.qml b/demos/declarative/snake/content/Cookie.qml index 0ea95cb..b64987e 100644 --- a/demos/declarative/snake/content/Cookie.qml +++ b/demos/declarative/snake/content/Cookie.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id: root diff --git a/demos/declarative/snake/content/Link.qml b/demos/declarative/snake/content/Link.qml index 31ac4b9..4171247 100644 --- a/demos/declarative/snake/content/Link.qml +++ b/demos/declarative/snake/content/Link.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id:link property bool dying: false diff --git a/demos/declarative/snake/snake.qml b/demos/declarative/snake/snake.qml index f9d02c7..317c7de 100644 --- a/demos/declarative/snake/snake.qml +++ b/demos/declarative/snake/snake.qml @@ -1,5 +1,5 @@ import Qt 4.6 -import "content" +import "content" as Content Rectangle { id: screen; @@ -27,7 +27,7 @@ Rectangle { property var head; - HighScoreModel { + Content.HighScoreModel { id: highScores game: "Snake" } @@ -46,7 +46,7 @@ Rectangle { onTriggered: { moveSkull() } } Timer { - id: startNewGameTimer; + interval: 700; onTriggered: {startNewGame(); } } @@ -97,7 +97,7 @@ Rectangle { height: numRowsAvailable * gridSize + 2*margin - Skull { + Content.Skull { id: skull } @@ -148,7 +148,7 @@ Rectangle { height: 32; width: parent.width anchors.bottom: screen.bottom - Button { + Content.Button { id: btnA; text: "New Game"; onClicked: {startNewGame();} anchors.left: parent.left; anchors.leftMargin: 3 anchors.verticalCenter: parent.verticalCenter diff --git a/demos/declarative/webbrowser/content/RetractingWebBrowserHeader.qml b/demos/declarative/webbrowser/content/RetractingWebBrowserHeader.qml index 94c94f2..46dbc98 100644 --- a/demos/declarative/webbrowser/content/RetractingWebBrowserHeader.qml +++ b/demos/declarative/webbrowser/content/RetractingWebBrowserHeader.qml @@ -18,7 +18,7 @@ Image { anchors.top: header.top anchors.topMargin: 4 - anchors.horizontalCenter: parent.horizontalCenter + x: parent.width > headerIcon.width+headerText.width+6 ? (parent.width-headerIcon.width-headerText.width-6)/2 : 0 spacing: 6 Image { @@ -30,8 +30,6 @@ Image { id: headerText text: webView.title!='' || webView.progress == 1.0 ? webView.title : 'Loading...' - elide: Text.ElideRight - //width: parent.width - headerIcon.width-4 color: "white" styleColor: "black" diff --git a/demos/demos.pro b/demos/demos.pro index 83e9355..013d40f 100644 --- a/demos/demos.pro +++ b/demos/demos.pro @@ -43,7 +43,7 @@ SUBDIRS += demos_boxes } mac*: SUBDIRS += demos_macmainwindow -wince*|symbian|embedded|x11: SUBDIRS += embedded +wince*|symbian|embedded|x11: SUBDIRS += demos_embedded !contains(QT_EDITION, Console):!cross_compile:!embedded:!wince*:SUBDIRS += demos_arthurplugin @@ -67,6 +67,9 @@ symbian: include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) demos_chip.subdir = chip demos_embeddeddialogs.subdir = embeddeddialogs +demos_embedded.subdir = embedded +# Because of fluidlauncher +demos_embedded.depends = demos_deform demos_pathstroke demos_shared.subdir = shared demos_deform.subdir = deform demos_gradients.subdir = gradients diff --git a/demos/embedded/anomaly/anomaly.pro b/demos/embedded/anomaly/anomaly.pro index e16ef66..584e5cd 100644 --- a/demos/embedded/anomaly/anomaly.pro +++ b/demos/embedded/anomaly/anomaly.pro @@ -26,7 +26,7 @@ RESOURCES += src/anomaly.qrc symbian { TARGET.UID3 = 0xA000CF71 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h + INCLUDEPATH += $$QT_SOURCE_TREE/examples/network/qftp/ LIBS += -lesock -lcommdb -linsock # For IAP selection TARGET.CAPABILITY = NetworkServices TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 diff --git a/demos/embedded/anomaly/src/BrowserView.cpp b/demos/embedded/anomaly/src/BrowserView.cpp index 0945b89..41318ad 100644 --- a/demos/embedded/anomaly/src/BrowserView.cpp +++ b/demos/embedded/anomaly/src/BrowserView.cpp @@ -82,6 +82,7 @@ void BrowserView::initialize() connect(m_controlStrip, SIGNAL(menuClicked()), SIGNAL(menuButtonClicked())); connect(m_controlStrip, SIGNAL(backClicked()), m_webView, SLOT(back())); connect(m_controlStrip, SIGNAL(forwardClicked()), m_webView, SLOT(forward())); + connect(m_controlStrip, SIGNAL(closeClicked()), qApp, SLOT(quit())); QPalette pal = m_webView->palette(); pal.setBrush(QPalette::Base, Qt::white); diff --git a/demos/embedded/anomaly/src/ControlStrip.cpp b/demos/embedded/anomaly/src/ControlStrip.cpp index 265d9a0..dc6d5c2 100644 --- a/demos/embedded/anomaly/src/ControlStrip.cpp +++ b/demos/embedded/anomaly/src/ControlStrip.cpp @@ -50,6 +50,7 @@ ControlStrip::ControlStrip(QWidget *parent) menuPixmap.load(":/images/edit-find.png"); backPixmap.load(":/images/go-previous.png"); forwardPixmap.load(":/images/go-next.png"); + closePixmap.load(":/images/button-close.png"); } QSize ControlStrip::sizeHint() const @@ -74,12 +75,18 @@ void ControlStrip::mousePressEvent(QMouseEvent *event) } if (x > width() - h) { - emit forwardClicked(); + emit closeClicked(); event->accept(); return; } if ((x < width() - 2 * h) && (x > width() - 3 * h)) { + emit forwardClicked(); + event->accept(); + return; + } + + if ((x < width() - 3 * h) && (x > width() - 5 * h)) { emit backClicked(); event->accept(); return; @@ -95,7 +102,9 @@ void ControlStrip::paintEvent(QPaintEvent *event) p.fillRect(event->rect(), QColor(32, 32, 32, 192)); p.setCompositionMode(QPainter::CompositionMode_SourceOver); p.drawPixmap(s, s, menuPixmap); - p.drawPixmap(width() - 3 * h + s, s, backPixmap); - p.drawPixmap(width() - h + s, s, forwardPixmap); + p.drawPixmap(width() - h + s, s, closePixmap); + p.drawPixmap(width() - 3 * h + s, s, forwardPixmap); + p.drawPixmap(width() - 5 * h + s, s, backPixmap); + p.end(); } diff --git a/demos/embedded/anomaly/src/ControlStrip.h b/demos/embedded/anomaly/src/ControlStrip.h index bbaea87..b6003a1 100644 --- a/demos/embedded/anomaly/src/ControlStrip.h +++ b/demos/embedded/anomaly/src/ControlStrip.h @@ -58,6 +58,7 @@ signals: void menuClicked(); void backClicked(); void forwardClicked(); + void closeClicked(); protected: void paintEvent(QPaintEvent *event); @@ -67,6 +68,7 @@ private: QPixmap menuPixmap; QPixmap backPixmap; QPixmap forwardPixmap; + QPixmap closePixmap; }; #endif // CONTROLSTRIP_H diff --git a/demos/embedded/anomaly/src/anomaly.qrc b/demos/embedded/anomaly/src/anomaly.qrc index 601a34e..d8ea630 100644 --- a/demos/embedded/anomaly/src/anomaly.qrc +++ b/demos/embedded/anomaly/src/anomaly.qrc @@ -5,5 +5,6 @@ <file>images/edit-find.png</file> <file>images/list-add.png</file> <file>images/list-remove.png</file> + <file>images/button-close.png</file> </qresource> </RCC> diff --git a/demos/embedded/anomaly/src/images/button-close.png b/demos/embedded/anomaly/src/images/button-close.png Binary files differnew file mode 100644 index 0000000..7a7b048 --- /dev/null +++ b/demos/embedded/anomaly/src/images/button-close.png diff --git a/demos/embedded/embedded.pro b/demos/embedded/embedded.pro index 5bd3276..da764d1 100644 --- a/demos/embedded/embedded.pro +++ b/demos/embedded/embedded.pro @@ -4,6 +4,8 @@ SUBDIRS = styledemo raycasting flickable digiflip contains(QT_CONFIG, svg) { SUBDIRS += embeddedsvgviewer \ desktopservices + fluidlauncher.subdir = fluidlauncher + fluidlauncher.depends = styledemo desktopservices raycasting flickable digiflip lightmaps flightinfo !vxworks:!qnx:SUBDIRS += fluidlauncher } diff --git a/demos/embedded/flightinfo/flightinfo.pro b/demos/embedded/flightinfo/flightinfo.pro index 7391f88..985cc42 100644 --- a/demos/embedded/flightinfo/flightinfo.pro +++ b/demos/embedded/flightinfo/flightinfo.pro @@ -8,7 +8,7 @@ QT += network symbian { TARGET.UID3 = 0xA000CF74 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h + INCLUDEPATH += $$QT_SOURCE_TREE/examples/network/qftp/ LIBS += -lesock -lcommdb -linsock # For IAP selection TARGET.CAPABILITY = NetworkServices } diff --git a/demos/embedded/fluidlauncher/fluidlauncher.pro b/demos/embedded/fluidlauncher/fluidlauncher.pro index f71388c..b2916d7 100644 --- a/demos/embedded/fluidlauncher/fluidlauncher.pro +++ b/demos/embedded/fluidlauncher/fluidlauncher.pro @@ -61,108 +61,124 @@ symbian { TARGET.UID3 = 0xA000A641 ICON = $$QT_SOURCE_TREE/src/s60installs/qt.svg + defineReplace(regResourceDir) { + symbian-abld|symbian-sbsv2 { + return($${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/$$basename(1)) + } else { + return($${QT_BUILD_TREE}/$$1) + } + } + + defineReplace(appResourceDir) { + symbian-abld|symbian-sbsv2 { + return($${EPOCROOT}$${HW_ZDIR}$${APP_RESOURCE_DIR}/$$basename(1)) + } else { + return($${QT_BUILD_TREE}/$$1) + } + } + executables.sources = \ - styledemo.exe \ - deform.exe \ - pathstroke.exe \ - wiggly.exe \ - qftp.exe \ - saxbookmarks.exe \ - desktopservices.exe \ - fridgemagnets.exe \ - softkeys.exe \ - raycasting.exe \ - flickable.exe \ - digiflip.exe \ - lightmaps.exe \ - flightinfo.exe + $$QT_BUILD_TREE/demos/embedded/styledemo/styledemo.exe \ + $$QT_BUILD_TREE/demos/deform/deform.exe \ + $$QT_BUILD_TREE/demos/pathstroke/pathstroke.exe \ + $$QT_BUILD_TREE/examples/widgets/wiggly/wiggly.exe \ + $$QT_BUILD_TREE/examples/network/qftp/qftp.exe \ + $$QT_BUILD_TREE/examples/xml/saxbookmarks/saxbookmarks.exe \ + $$QT_BUILD_TREE/demos/embedded/desktopservices/desktopservices.exe \ + $$QT_BUILD_TREE/examples/draganddrop/fridgemagnets/fridgemagnets.exe \ + $$QT_BUILD_TREE/examples/widgets/softkeys/softkeys.exe \ + $$QT_BUILD_TREE/demos/embedded/raycasting/raycasting.exe \ + $$QT_BUILD_TREE/demos/embedded/flickable/flickable.exe \ + $$QT_BUILD_TREE/demos/embedded/digiflip/digiflip.exe \ + $$QT_BUILD_TREE/demos/embedded/lightmaps/lightmaps.exe \ + $$QT_BUILD_TREE/demos/embedded/flightinfo/flightinfo.exe executables.path = /sys/bin reg_resource.sources = \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/styledemo_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/deform_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/pathstroke_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/wiggly_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/qftp_reg.rsc\ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/saxbookmarks_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/desktopservices_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/fridgemagnets_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/softkeys_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/raycasting_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/flickable_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/digiflip_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/lightmaps_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/flightinfo_reg.rsc + $$regResourceDir(demos/embedded/styledemo/styledemo_reg.rsc) \ + $$regResourceDir(demos/deform/deform_reg.rsc) \ + $$regResourceDir(demos/pathstroke/pathstroke_reg.rsc) \ + $$regResourceDir(examples/widgets/wiggly/wiggly_reg.rsc) \ + $$regResourceDir(examples/network/qftp/qftp_reg.rsc)\ + $$regResourceDir(examples/xml/saxbookmarks/saxbookmarks_reg.rsc) \ + $$regResourceDir(demos/embedded/desktopservices/desktopservices_reg.rsc) \ + $$regResourceDir(examples/draganddrop/fridgemagnets/fridgemagnets_reg.rsc) \ + $$regResourceDir(examples/widgets/softkeys/softkeys_reg.rsc) \ + $$regResourceDir(demos/embedded/raycasting/raycasting_reg.rsc) \ + $$regResourceDir(demos/embedded/flickable/flickable_reg.rsc) \ + $$regResourceDir(demos/embedded/digiflip/digiflip_reg.rsc) \ + $$regResourceDir(demos/embedded/lightmaps/lightmaps_reg.rsc) \ + $$regResourceDir(demos/embedded/flightinfo/flightinfo_reg.rsc) contains(QT_CONFIG, phonon) { - reg_resource.sources += $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/qmediaplayer_reg.rsc + reg_resource.sources += $$regResourceDir(demos/qmediaplayer/qmediaplayer_reg.rsc) } reg_resource.path = $$REG_RESOURCE_IMPORT_DIR resource.sources = \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/styledemo.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/deform.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/pathstroke.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/wiggly.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/qftp.rsc\ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/saxbookmarks.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/desktopservices.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/fridgemagnets.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/softkeys.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/raycasting.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/flickable.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/digiflip.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/lightmaps.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/flightinfo.rsc + $$appResourceDir(demos/embedded/styledemo/styledemo.rsc) \ + $$appResourceDir(demos/deform/deform.rsc) \ + $$appResourceDir(demos/pathstroke/pathstroke.rsc) \ + $$appResourceDir(examples/widgets/wiggly/wiggly.rsc) \ + $$appResourceDir(examples/network/qftp/qftp.rsc)\ + $$appResourceDir(examples/xml/saxbookmarks/saxbookmarks.rsc) \ + $$appResourceDir(demos/embedded/desktopservices/desktopservices.rsc) \ + $$appResourceDir(examples/draganddrop/fridgemagnets/fridgemagnets.rsc) \ + $$appResourceDir(examples/widgets/softkeys/softkeys.rsc) \ + $$appResourceDir(demos/embedded/raycasting/raycasting.rsc) \ + $$appResourceDir(demos/embedded/flickable/flickable.rsc) \ + $$appResourceDir(demos/embedded/digiflip/digiflip.rsc) \ + $$appResourceDir(demos/embedded/lightmaps/lightmaps.rsc) \ + $$appResourceDir(demos/embedded/flightinfo/flightinfo.rsc) resource.path = $$APP_RESOURCE_DIR mifs.sources = \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/fluidlauncher.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/styledemo.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/deform.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/pathstroke.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/wiggly.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/qftp.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/saxbookmarks.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/desktopservices.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/fridgemagnets.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/softkeys.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/raycasting.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/flickable.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/digiflip.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/lightmaps.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/flightinfo.mif + $$appResourceDir(demos/embedded/fluidlauncher/fluidlauncher.mif) \ + $$appResourceDir(demos/embedded/styledemo/styledemo.mif) \ + $$appResourceDir(demos/deform/deform.mif) \ + $$appResourceDir(demos/pathstroke/pathstroke.mif) \ + $$appResourceDir(examples/widgets/wiggly/wiggly.mif) \ + $$appResourceDir(examples/network/qftp/qftp.mif) \ + $$appResourceDir(examples/xml/saxbookmarks/saxbookmarks.mif) \ + $$appResourceDir(demos/embedded/desktopservices/desktopservices.mif) \ + $$appResourceDir(examples/draganddrop/fridgemagnets/fridgemagnets.mif) \ + $$appResourceDir(examples/widgets/softkeys/softkeys.mif) \ + $$appResourceDir(demos/embedded/raycasting/raycasting.mif) \ + $$appResourceDir(demos/embedded/flickable/flickable.mif) \ + $$appResourceDir(demos/embedded/digiflip/digiflip.mif) \ + $$appResourceDir(demos/embedded/lightmaps/lightmaps.mif) \ + $$appResourceDir(demos/embedded/flightinfo/flightinfo.mif) mifs.path = $$APP_RESOURCE_DIR contains(QT_CONFIG, svg) { executables.sources += \ - embeddedsvgviewer.exe \ - weatherinfo.exe + $$QT_BUILD_TREE/demos/embedded/embeddedsvgviewer/embeddedsvgviewer.exe \ + $$QT_BUILD_TREE/demos/embedded/weatherinfo/weatherinfo.exe reg_resource.sources += \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/embeddedsvgviewer_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/weatherinfo_reg.rsc + $$regResourceDir(demos/embedded/embeddedsvgviewer/embeddedsvgviewer_reg.rsc) \ + $$regResourceDir(demos/embedded/weatherinfo/weatherinfo_reg.rsc) resource.sources += \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/embeddedsvgviewer.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/weatherinfo.rsc + $$appResourceDir(demos/embedded/embeddedsvgviewer/embeddedsvgviewer.rsc) \ + $$appResourceDir(demos/embedded/weatherinfo/weatherinfo.rsc) mifs.sources += \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/embeddedsvgviewer.mif \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/weatherinfo.mif + $$appResourceDir(demos/embedded/embeddedsvgviewer/embeddedsvgviewer.mif) \ + $$appResourceDir(demos/embedded/weatherinfo/weatherinfo.mif) } contains(QT_CONFIG, webkit) { - executables.sources += anomaly.exe - reg_resource.sources += $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/anomaly_reg.rsc - resource.sources += $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/anomaly.rsc + executables.sources += $$QT_BUILD_TREE/demos/embedded/anomaly/anomaly.exe + reg_resource.sources += $$regResourceDir(demos/embedded/anomaly/anomaly_reg.rsc) + resource.sources += $$appResourceDir(demos/embedded/anomaly/anomaly.rsc) mifs.sources += \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/anomaly.mif + $$appResourceDir(demos/embedded/anomaly/anomaly.mif) # Since Fluidlauncher itself doesn't link webkit, we won't get dependency automatically executables.pkg_prerules += \ @@ -171,18 +187,18 @@ symbian { } contains(QT_CONFIG, phonon) { - executables.sources += qmediaplayer.exe - resource.sources += $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/qmediaplayer.rsc + executables.sources += $$QT_BUILD_TREE/demos/qmediaplayer/qmediaplayer.exe + resource.sources += $$appResourceDir(demos/qmediaplayer/qmediaplayer.rsc) mifs.sources += \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/qmediaplayer.mif + $$appResourceDir(demos/qmediaplayer/qmediaplayer.mif) } contains(QT_CONFIG, script) { - executables.sources += context2d.exe - reg_resource.sources += $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/context2d_reg.rsc - resource.sources += $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/context2d.rsc + executables.sources += $$QT_BUILD_TREE/examples/script/context2d/context2d.exe + reg_resource.sources += $$regResourceDir(examples/script/context2d/context2d_reg.rsc) + resource.sources += $$appResourceDir(examples/script/context2d/context2d.rsc) mifs.sources += \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/context2d.mif + $$appResourceDir(examples/script/context2d/context2d.mif) } files.sources = $$PWD/screenshots $$PWD/slides diff --git a/demos/embedded/lightmaps/lightmaps.pro b/demos/embedded/lightmaps/lightmaps.pro index ef1a0a6..ee4cc5a 100644 --- a/demos/embedded/lightmaps/lightmaps.pro +++ b/demos/embedded/lightmaps/lightmaps.pro @@ -5,7 +5,7 @@ QT += network symbian { TARGET.UID3 = 0xA000CF75 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h + INCLUDEPATH += $$QT_SOURCE_TREE/examples/network/qftp/ LIBS += -lesock -lcommdb -linsock # For IAP selection TARGET.CAPABILITY = NetworkServices TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 diff --git a/demos/embedded/weatherinfo/weatherinfo.pro b/demos/embedded/weatherinfo/weatherinfo.pro index f007bbb..9addbbb 100644 --- a/demos/embedded/weatherinfo/weatherinfo.pro +++ b/demos/embedded/weatherinfo/weatherinfo.pro @@ -7,7 +7,7 @@ QT += network svg symbian { TARGET.UID3 = 0xA000CF77 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h + INCLUDEPATH += $$QT_SOURCE_TREE/examples/network/qftp/ LIBS += -lesock -lcommdb -linsock # For IAP selection TARGET.CAPABILITY = NetworkServices } diff --git a/demos/shared/shared.pri b/demos/shared/shared.pri index 1541fa7..fb7b04c 100644 --- a/demos/shared/shared.pri +++ b/demos/shared/shared.pri @@ -6,12 +6,12 @@ build_all:!build_pass { } contains(CONFIG, debug_and_release_target) { CONFIG(debug, debug|release) { - LIBS+=-L$$SHARED_FOLDER/debug + QMAKE_LIBDIR += $$SHARED_FOLDER/debug } else { - LIBS+=-L$$SHARED_FOLDER/release + QMAKE_LIBDIR += $$SHARED_FOLDER/release } } else { - LIBS += -L$$SHARED_FOLDER + QMAKE_LIBDIR += $$SHARED_FOLDER } hpux-acc*:LIBS += $$SHARED_FOLDER/libdemo_shared.a diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc index 2b75211..7e0a787 100644 --- a/doc/src/declarative/animation.qdoc +++ b/doc/src/declarative/animation.qdoc @@ -58,7 +58,8 @@ types listed above. If the property you are animating is a number or color, you NumberAnimation or ColorAnimation. These elements don't add any additional functionality, but will help enforce type correctness and are slightly more efficient. -A property animation can be specified as a value source. This is especially useful for repeating animations. +A property animation can be specified as a value source using the \e Animation \bold on \e property syntax. This is especially useful +for repeating animations. The following example creates a bouncing effect: \qml @@ -70,7 +71,7 @@ Rectangle { source: "qt-logo.png" x: 60-img.width/2 y: 0 - y: SequentialAnimation { + SequentialAnimation on y { repeat: true NumberAnimation { to: 200-img.height; easing.type: "OutBounce"; duration: 2000 } PauseAnimation { duration: 1000 } @@ -93,7 +94,7 @@ Rectangle { Rectangle { color: "red" width: 50; height: 50 - x: NumberAnimation { to: 50; } + NumberAnimation on x { to: 50; } } } \endqml @@ -226,7 +227,7 @@ Rectangle { id: redRect color: "red" width: 100; height: 100 - x: Behavior { NumberAnimation { duration: 300; easing.type: "InOutQuad" } } + Behavior on x { NumberAnimation { duration: 300; easing.type: "InOutQuad" } } } \endqml diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 4b61bd9..ed63367 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -68,7 +68,7 @@ internet-enabled applications like a \l {http://www.flickr.com}{Flickr} photo br Qt Declarative builds on \l {QML for Qt programmers}{Qt's existing strengths}. QML can be be used to incrementally extend an existing application or to build -completely new applications. QML is fully \l {Extending QML}{extensible from C++}. +completely new applications. QML is fully \l {Extending QML in C++}{extensible from C++}. \section1 Getting Started: \list @@ -100,7 +100,7 @@ completely new applications. QML is fully \l {Extending QML}{extensible from C+ \list \o \l {QML Elements} \o \l {QML Global Object} -\o \l {Extending QML} +\o \l {Extending QML in C++} \o \l {QML Internationalization} \o \l {QtDeclarative Module} \o \l {Debugging QML} diff --git a/doc/src/declarative/dynamicobjects.qdoc b/doc/src/declarative/dynamicobjects.qdoc index 033c0d1..b2e3f90 100644 --- a/doc/src/declarative/dynamicobjects.qdoc +++ b/doc/src/declarative/dynamicobjects.qdoc @@ -76,25 +76,25 @@ the component. Example QML script is below. Remember that QML files that might b \code var component; var sprite; - function finishCreation(){ - if(component.isReady()){ + function finishCreation() { + if(component.isReady()) { sprite = component.createObject(); - if(sprite == 0){ + if(sprite == 0) { // Error Handling - }else{ + } else { sprite.parent = page; sprite.x = 200; //... } - }else if(component.isError()){ + } else if(component.isError()) { // Error Handling } } component = createComponent("Sprite.qml"); - if(component.isReady()){ + if(component.isReady()) { finishCreation(); - }else{ + } else { component.statusChanged.connect(finishCreation); } \endcode @@ -104,10 +104,10 @@ the component. Example QML script is below. Remember that QML files that might b \code component = createComponent("Sprite.qml"); sprite = component.createObject(); - if(sprite == 0){ + if(sprite == 0) { // Error Handling console.log(component.errorsString()); - }else{ + } else { sprite.parent = page; sprite.x = 200; //... @@ -122,7 +122,7 @@ If the QML does not exist until runtime, you can create a QML item from a string of QML using the createQmlObject function, as in the following example: \code - newObject = createQmlObject('import Qt 4.6; Rectangle {color: "red"; width: 20; height: 20}', + newObject = createQmlObject('import Qt 4.6; Rectangle { color: "red"; width: 20; height: 20 }', targetItem, "dynamicSnippet1"); \endcode The first argument is the string of QML to create. Just like in a new file, you will need to @@ -158,11 +158,12 @@ argument, which is an approximate delay in ms and which defaults to zero. This allows you to wait until the completion of an animation or transition. An example: \code - Component{ id:fadesOut + Component { + id: fadesOut Rectangle{ id: rect width: 40; height: 40; - opacity: NumberAnimation{from:1; to:0; duration: 1000;} + NumberAnimation on opacity { from:1; to:0; duration: 1000 } Component.onCompleted: rect.destroy(1000); } } diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc index 67aadcf..75f8b97 100644 --- a/doc/src/declarative/elements.qdoc +++ b/doc/src/declarative/elements.qdoc @@ -76,6 +76,7 @@ The following table lists the QML elements provided by the Qt Declarative module \o \l ParallelAnimation \o \l PauseAnimation \o \l ParentAnimation +\o \l AnchorAnimation \o \l PropertyAction \o \l ParentAction \o \l ScriptAction @@ -93,7 +94,6 @@ The following table lists the QML elements provided by the Qt Declarative module \o \l VisualDataModel \o \l Package \o \l XmlListModel and XmlRole -\o \l WorkerListModel \endlist \o diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 5aaa7bd..0ae4f7d 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -41,7 +41,7 @@ /*! \page qml-extending.html -\title Extending QML +\title Extending QML in C++ The QML syntax declaratively describes how to construct an in memory object tree. In Qt, QML is mainly used to describe a visual scene graph, but it is @@ -67,21 +67,23 @@ that derive from QObject. The QML engine has no intrinsic knowledge of any class types. Instead the programmer must define the C++ types, and their corresponding QML name. -Custom C++ types are made available to QML using these two macros: +Custom C++ types are declared QML types using a macro and a template function: \quotation + \code #define QML_DECLARE_TYPE(T) -#define QML_REGISTER_TYPE(URI,VMAJ,VMIN,QDeclarativeName,T) +template<typename T> +int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) \endcode -Register the C++ type \a T with the QML system, and make it available in QML -under the name \a QDeclarativeName in library URI version VMAJ.VMIN. -\a T and \a QDeclarativeName may be the same. +Calling qmlRegisterType() registers the C++ type \a T with the QML system, and makes it available in QML +under the name \a qmlName in library \a uri version \a versionMajor.versionMinor. +The \a qmlName can be the same as the C++ type name. Generally the QML_DECLARE_TYPE() macro should be included immediately following -the type declaration (usually in its header file), and the QML_REGISTER_TYPE() -macro called by the implementation. +the type declaration (usually in its header file), and the template function qmlRegisterType() +called by the implementation. Type \a T must be a concrete type that inherits QObject and has a default constructor. @@ -147,19 +149,20 @@ property can be assigned. QML also supports assigning Qt interfaces. To assign to a property whose type is a Qt interface pointer, the interface must also be registered with QML. As they cannot be instantiated directly, registering a Qt interface is different -from registering a new QML type. The following macros are used instead: +from registering a new QML type. The following macro and function are used instead: \quotation \code - #define QML_DECLARE_INTERFACE(T) - #define QML_REGISTER_INTERFACE(T) +#define QML_DECLARE_INTERFACE(T) +template<typename T> +int qmlRegisterInterface(const char *typeName) \endcode -Register the C++ interface \a T with the QML system. +Registers the C++ interface \a T with the QML system as \a typeName. Generally the QML_DECLARE_INTERFACE() macro should be included immediately following the interface declaration (usually in its header file), and the -QML_REGISTER_INTERFACE() macro called by the implementation. +qmlRegisterInterface() template function called by the implementation. Following registration, QML can coerce objects that implement this interface for assignment to appropriately typed properties. @@ -174,7 +177,7 @@ The guest property declaration looks like this: \snippet examples/declarative/extending/properties/birthdayparty.h 2 -\l {Extending QML - Object and List Property Types Example} shows the complete +\l {Extending QML in C++ - Object and List Property Types Example} shows the complete code used to create the \c BirthdayParty type. \section1 Inheritance and Coercion @@ -192,25 +195,26 @@ type used in the previous section, but the assignment is valid as both the Boy and Girl objects inherit from Person. To assign to a property, the property's type must have been registered with QML. -Both the QML_REGISTER_TYPE() and QML_REGISTER_INTERFACE() macros already shown can -be used to register a type with QML. Additionally, if a type that acts purely +Both the qmlRegisterType() and qmlRegisterInterface() template functions already +shown can be used to register a type with QML. Additionally, if a type that acts purely as a base class that cannot be instantiated from QML needs to be -registered these macros can be used: +registered these macro and function can be used: \quotation \code #define QML_DECLARE_TYPE(T) - #define QML_REGISTER_NOCREATE_TYPE(T) + template<typename T> + int qmlRegisterType() \endcode -Register the C++ type \a T with the QML system. QML_REGISTER_NOCREATE_TYPE() -differs from QML_REGISTER_TYPE() in that it does not define a mapping between the +Registers the C++ type \a T with the QML system. The parameterless call to the template +function qmlRegisterType() does not define a mapping between the C++ class and a QML element name, so the type is not instantiable from QML, but it is available for type coercion. Generally the QML_DECLARE_TYPE() macro should be included immediately following the type declaration (usually in its header file), and the -QML_REGISTER_NOCREATE_TYPE() macro called from the implementation. +qmlRegisterType() template function called from the implementation. Type \a T must inherit QObject, but there are no restrictions on whether it is concrete or the signature of its constructor. @@ -220,7 +224,7 @@ QML will automatically coerce C++ types when assigning to either an object property, or to a list property. Only if coercion fails does an assignment error occur. -\l {Extending QML - Inheritance and Coercion Example} shows the complete +\l {Extending QML in C++ - Inheritance and Coercion Example} shows the complete code used to create the \c Boy and \c Girl types. \section1 Default Property @@ -252,7 +256,7 @@ refer to a property declared in the class itself, or a property inherited from a base class. \endquotation -\l {Extending QML - Default Property Example} shows the complete code used to +\l {Extending QML in C++ - Default Property Example} shows the complete code used to specify a default property. \section1 Grouped Properties @@ -277,7 +281,7 @@ property block - in this case the size, color, brand and price properties. Grouped property blocks may declared and accessed be recusively. -\l {Extending QML - Grouped Properties Example} shows the complete code used to +\l {Extending QML in C++ - Grouped Properties Example} shows the complete code used to implement the \c shoe property grouping. \section1 Attached Properties @@ -369,7 +373,7 @@ creating it if it does not already exist. If \a create is false, the attachment object will only be returned if it has previously been created. \endquotation -\l {Extending QML - Attached Properties Example} shows the complete code used to +\l {Extending QML in C++ - Attached Properties Example} shows the complete code used to implement the rsvp attached property. \section1 Memory Management and QVariant types @@ -431,7 +435,7 @@ listed in \l {Adding Types}, as well registered object types are permitted as signal parameter types. Using other types is not an error, but the parameter value will not be accessible from script. -\l {Extending QML - Signal Support Example} shows the complete code used to +\l {Extending QML in C++ - Signal Support Example} shows the complete code used to implement the onPartyStarted signal property. \section1 Property Value Sources @@ -478,7 +482,7 @@ to assign it normally, as though it were a regular QML type. Only if this assignment fails does the engine call the setTarget() method. This allows the type to also be used in contexts other than just as a value source. -\l {Extending QML - Property Value Source Example} shows the complete code used +\l {Extending QML in C++ - Property Value Source Example} shows the complete code used implement the HappyBirthday property value source. \section1 Property Binding @@ -550,7 +554,7 @@ The CONSTANT attribute should only be used for properties whose value is set, and finalized, only in the class constructor. All other properties that want to be used in bindings should have a NOTIFY signal instead. -\l {Extending QML - Binding Example} shows the BirthdayParty example updated to +\l {Extending QML in C++ - Binding Example} shows the BirthdayParty example updated to include NOTIFY signals for use in binding. \section1 Extension Objects @@ -623,7 +627,7 @@ public: \title Extending types from QML Many of the elements available for use in QML are implemented in -\l {Extending QML}{C++}. These types are know as "core types". QML +\l {Extending QML in C++}{C++}. These types are know as "core types". QML allows programmers to build new, fully functional elements without using C++. Existing core types can be extended, and new types defined entirely in the QML language. diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc index 4b1c7d3..9f6be12 100644 --- a/doc/src/declarative/globalobject.qdoc +++ b/doc/src/declarative/globalobject.qdoc @@ -182,18 +182,6 @@ This function returns a color 50% darker than \c baseColor. See QColor::darker() \image declarative-rect_tint.png Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color. -\section3 Qt.closestAngle(number fromAngle, number toAngle) -This function returns an equivalent angle to toAngle, such that the difference between fromAngle and toAngle is never more than 180 degrees. This is useful when animating angles using a NumberAnimation, which does not know about equivalent angles, when you always want to take the shortest path. - -For example, the following would rotate myItem counterclockwise from 350 degrees to 10 degrees, for a total of 340 degrees of rotation. -\qml -NumberAnimation { target: myItem; property: "rotation"; from: 350; to: 10 } -\endqml - -while the following would rotate myItem clockwise from 350 degrees to 370 degrees (which is visually equivilant to 10 degrees), for a total of 20 degrees of rotation. -\qml -NumberAnimation { target: myItem; property: "rotation"; from: 350; to: Qt.closetAngle(350, 10) } -\endqml \section3 Qt.openUrlExternally(url target) This function attempts to open the specified \c target url in an external application, based on the user's desktop preferences. It will return true if it succeeds, and false otherwise. diff --git a/doc/src/declarative/qdeclarativemodels.qdoc b/doc/src/declarative/qdeclarativemodels.qdoc index c0e028e..e80824d 100644 --- a/doc/src/declarative/qdeclarativemodels.qdoc +++ b/doc/src/declarative/qdeclarativemodels.qdoc @@ -191,6 +191,23 @@ will be positioned by the view. \section2 QAbstractItemModel QAbstractItemModel provides the roles set via the QAbstractItemModel::setRoleNames() method. +The default role names set by Qt are: + +\table +\header +\o Qt Role +\o QML Role Name +\row +\o Qt::DisplayRole +\o display +\row +\o Qt::DecorationRole +\o decoration +\endtable + +QAbstractItemModel presents a heirachy of tables. Views currently provided by QML +can only display list data. In order to display child lists of a heirachical model +use the VisualDataModel element with \e rootIndex set to a parent node. \section2 QStringList @@ -198,9 +215,6 @@ QAbstractItemModel provides the roles set via the QAbstractItemModel::setRoleNam QStringList provides the contents of the list via the \e modelData role: \table -\header -\o -\o \row \o \code @@ -208,7 +222,7 @@ QStringList provides the contents of the list via the \e modelData role: QStringList dataList; dataList.append("Fred"); dataList.append("Ginger"); -dataList.appenf("Skipper"); +dataList.append("Skipper"); QDeclarativeContext *ctxt = view.rootContext(); ctxt->setContextProperty("myModel", QVariant::fromValue(&dataList)); diff --git a/doc/src/declarative/qtdeclarative.qdoc b/doc/src/declarative/qtdeclarative.qdoc index 41d6338..b43d0ec 100644 --- a/doc/src/declarative/qtdeclarative.qdoc +++ b/doc/src/declarative/qtdeclarative.qdoc @@ -65,3 +65,51 @@ For more information on the Qt Declarative module, see the \l{declarativeui.html}{Declarative UI} documentation. */ + + +/*! + \macro QML_DECLARE_TYPE(T) + \relates QDeclarativeEngine + + yada yada yada + +*/ + + +/*! + \fn int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) + \relates QDeclarativeEngine + + This template function registers the C++ type \a T with the QML system, and make it available in + QML under the name \a qmlName in the import library \a uri version \a versionMajor.versionMajor. + + Returns the QML type id. + + Example: Register the C++ class \c MinehuntGame as QML type \c Game version 0.1 in the import + library \c MinehuntCore: + + \code + qmlRegisterType<MinehuntGame>("MinehuntCore", 0, 1, "Game"); + \endcode + +*/ + +/*! + \fn int qmlRegisterType() + \relates QDeclarativeEngine + \overload + + This template function registers the C++ type \a T with the QML system. Instances of this type cannot + be created from the QML system. + + Returns the QML type id. +*/ + +/*! \fn int qmlRegisterInterface(const char *typeName) + \relates QDeclarativeEngine + + This template function registers the C++ type \a T as interface with the QML system, under the name + \a typeName. + + Returns the QML type id. + */ diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index 8e1d970..8cb8705 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -1329,9 +1329,13 @@ \target DEF_FILE \section1 DEF_FILE - \e {This is only used on Windows when using the \c app template}. + \e {This is only used on Windows when using the \c app template, + and on Symbian when building a shared DLL}. - Specifies a \c .def file to be included in the project. + Specifies a \c .def file to be included in the project. On Symbian + a directory may be specified instead, in which case the real files + will be located under the standard Symbian directories \c bwins and + \c eabi. \target DEPENDPATH \section1 DEPENDPATH @@ -2601,7 +2605,7 @@ For example: \section1 QMAKE_LIBS_THREAD - \e {This is used on Unix platforms only.} + \e {This is used on Unix and Symbian platforms only.} This variable contains all libraries that need to be linked against when building a multi-threaded application. The diff --git a/examples/declarative/animations/color-animation.qml b/examples/declarative/animations/color-animation.qml index 6740522..025134b 100644 --- a/examples/declarative/animations/color-animation.qml +++ b/examples/declarative/animations/color-animation.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id: window diff --git a/examples/declarative/behaviours/behavior.qml b/examples/declarative/behaviours/behavior-example.qml index c84bf62..c84bf62 100644 --- a/examples/declarative/behaviours/behavior.qml +++ b/examples/declarative/behaviours/behavior-example.qml diff --git a/examples/declarative/colorbrowser/colorbrowser.qml b/examples/declarative/colorbrowser/colorbrowser.qml index 421ae07..d4c21e7 100644 --- a/examples/declarative/colorbrowser/colorbrowser.qml +++ b/examples/declarative/colorbrowser/colorbrowser.qml @@ -16,7 +16,7 @@ Rectangle { GridView { id: gridView; model: visualModel.parts.grid; width: mainWindow.width; height: mainWindow.height cellWidth: 160; cellHeight: 160; interactive: false - onCurrentIndexChanged: listView.positionViewAtIndex(currentIndex) + onCurrentIndexChanged: listView.positionViewAtIndex(currentIndex, ListView.Contain) } } @@ -25,7 +25,7 @@ Rectangle { ListView { id: listView; model: visualModel.parts.list; orientation: Qt.Horizontal width: mainWindow.width; height: mainWindow.height; interactive: false - onCurrentIndexChanged: gridView.positionViewAtIndex(currentIndex) + onCurrentIndexChanged: gridView.positionViewAtIndex(currentIndex, GridView.Contain) highlightRangeMode: ListView.StrictlyEnforceRange; snapMode: ListView.SnapOneItem } } diff --git a/examples/declarative/connections/connections.qml b/examples/declarative/connections/connections-example.qml index c35bda5..c35bda5 100644 --- a/examples/declarative/connections/connections.qml +++ b/examples/declarative/connections/connections-example.qml diff --git a/examples/declarative/dial/dial.qml b/examples/declarative/dial/dial-example.qml index 3aed70e..3aed70e 100644 --- a/examples/declarative/dial/dial.qml +++ b/examples/declarative/dial/dial-example.qml diff --git a/examples/declarative/dynamic/dynamic.qml b/examples/declarative/dynamic/dynamic.qml index 6af3e81..7de4d38 100644 --- a/examples/declarative/dynamic/dynamic.qml +++ b/examples/declarative/dynamic/dynamic.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 import "qml" Item { diff --git a/examples/declarative/extending/adding/main.cpp b/examples/declarative/extending/adding/main.cpp index 76e0736..b9e5aa3 100644 --- a/examples/declarative/extending/adding/main.cpp +++ b/examples/declarative/extending/adding/main.cpp @@ -48,7 +48,7 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_TYPE(People, 1,0, Person, Person); + qmlRegisterType<Person>("People", 1,0, "Person"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/attached/main.cpp b/examples/declarative/extending/attached/main.cpp index 684d8d3..fd2d525 100644 --- a/examples/declarative/extending/attached/main.cpp +++ b/examples/declarative/extending/attached/main.cpp @@ -49,12 +49,12 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_NOCREATE_TYPE(BirthdayPartyAttached); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_NOCREATE_TYPE(ShoeDescription); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType<BirthdayPartyAttached>(); + qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty"); + qmlRegisterType<ShoeDescription>(); + qmlRegisterType<Person>(); + qmlRegisterType<Boy>("People", 1,0, "Boy"); + qmlRegisterType<Girl>("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/binding/main.cpp b/examples/declarative/extending/binding/main.cpp index 873f8c9..ce6c50d 100644 --- a/examples/declarative/extending/binding/main.cpp +++ b/examples/declarative/extending/binding/main.cpp @@ -49,14 +49,13 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - - QML_REGISTER_NOCREATE_TYPE(BirthdayPartyAttached); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_TYPE(People, 1,0, HappyBirthday, HappyBirthday); - QML_REGISTER_NOCREATE_TYPE(ShoeDescription); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType<BirthdayPartyAttached>(); + qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty"); + qmlRegisterType<HappyBirthday>("People", 1,0, "HappyBirthday"); + qmlRegisterType<ShoeDescription>(); + qmlRegisterType<Person>(); + qmlRegisterType<Boy>("People", 1,0, "Boy"); + qmlRegisterType<Girl>("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/coercion/main.cpp b/examples/declarative/extending/coercion/main.cpp index 1e2209f..312aff9 100644 --- a/examples/declarative/extending/coercion/main.cpp +++ b/examples/declarative/extending/coercion/main.cpp @@ -49,12 +49,12 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); + qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty"); // ![0] - QML_REGISTER_NOCREATE_TYPE(Person); + qmlRegisterType<Person>(); // ![0] - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType<Boy>("People", 1,0, "Boy"); + qmlRegisterType<Girl>("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/default/main.cpp b/examples/declarative/extending/default/main.cpp index 7d7f8a1..06282ad 100644 --- a/examples/declarative/extending/default/main.cpp +++ b/examples/declarative/extending/default/main.cpp @@ -49,10 +49,10 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty"); + qmlRegisterType<Person>(); + qmlRegisterType<Boy>("People", 1,0, "Boy"); + qmlRegisterType<Girl>("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/extended/main.cpp b/examples/declarative/extending/extended/main.cpp index 5cbeea3..ca7242d 100644 --- a/examples/declarative/extending/extended/main.cpp +++ b/examples/declarative/extending/extended/main.cpp @@ -49,7 +49,7 @@ int main(int argc, char ** argv) { QApplication app(argc, argv); - QML_REGISTER_EXTENDED_TYPE(People, 1,0, QLineEdit, QLineEdit, LineEditExtension); + qmlRegisterExtendedType<QLineEdit, LineEditExtension>("People", 1,0, "QLineEdit"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/grouped/main.cpp b/examples/declarative/extending/grouped/main.cpp index 15a0bb5..b383a8b 100644 --- a/examples/declarative/extending/grouped/main.cpp +++ b/examples/declarative/extending/grouped/main.cpp @@ -49,11 +49,11 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_NOCREATE_TYPE(ShoeDescription); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty"); + qmlRegisterType<ShoeDescription>(); + qmlRegisterType<Person>(); + qmlRegisterType<Boy>("People", 1,0, "Boy"); + qmlRegisterType<Girl>("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/properties/main.cpp b/examples/declarative/extending/properties/main.cpp index ce69ad2..350f8bd 100644 --- a/examples/declarative/extending/properties/main.cpp +++ b/examples/declarative/extending/properties/main.cpp @@ -49,8 +49,8 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_TYPE(People, 1,0, Person, Person); + qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty"); + qmlRegisterType<Person>("People", 1,0, "Person"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/signal/main.cpp b/examples/declarative/extending/signal/main.cpp index afc1a66..1b23a46 100644 --- a/examples/declarative/extending/signal/main.cpp +++ b/examples/declarative/extending/signal/main.cpp @@ -49,12 +49,12 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_NOCREATE_TYPE(BirthdayPartyAttached); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_NOCREATE_TYPE(ShoeDescription); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType<BirthdayPartyAttached>(); + qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty"); + qmlRegisterType<ShoeDescription>(); + qmlRegisterType<Person>(); + qmlRegisterType<Boy>("People", 1,0, "Boy"); + qmlRegisterType<Girl>("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/valuesource/main.cpp b/examples/declarative/extending/valuesource/main.cpp index 873f8c9..2574917 100644 --- a/examples/declarative/extending/valuesource/main.cpp +++ b/examples/declarative/extending/valuesource/main.cpp @@ -50,13 +50,13 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_NOCREATE_TYPE(BirthdayPartyAttached); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_TYPE(People, 1,0, HappyBirthday, HappyBirthday); - QML_REGISTER_NOCREATE_TYPE(ShoeDescription); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType<BirthdayPartyAttached>(); + qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty"); + qmlRegisterType<HappyBirthday>("People", 1,0, "HappyBirthday"); + qmlRegisterType<ShoeDescription>(); + qmlRegisterType<Person>(); + qmlRegisterType<Boy>("People", 1,0, "Boy"); + qmlRegisterType<Girl>("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/flipable/flipable.qml b/examples/declarative/flipable/flipable-example.qml index c837ebc..c837ebc 100644 --- a/examples/declarative/flipable/flipable.qml +++ b/examples/declarative/flipable/flipable-example.qml diff --git a/examples/declarative/gridview/gridview.qml b/examples/declarative/gridview/gridview-example.qml index 93931c7..93931c7 100644 --- a/examples/declarative/gridview/gridview.qml +++ b/examples/declarative/gridview/gridview-example.qml diff --git a/examples/declarative/imageprovider/imageprovider.qml b/examples/declarative/imageprovider/imageprovider-example.qml index f899b1e..a1f2794 100644 --- a/examples/declarative/imageprovider/imageprovider.qml +++ b/examples/declarative/imageprovider/imageprovider-example.qml @@ -1,5 +1,5 @@ import Qt 4.6 -import "ImageProviderCore" +import ImageProviderCore 1.0 //![0] ListView { width: 100 diff --git a/examples/declarative/workerlistmodel/dataloader.js b/examples/declarative/listmodel-threaded/dataloader.js index eac7478..eac7478 100644 --- a/examples/declarative/workerlistmodel/dataloader.js +++ b/examples/declarative/listmodel-threaded/dataloader.js diff --git a/examples/declarative/workerlistmodel/timedisplay.qml b/examples/declarative/listmodel-threaded/timedisplay.qml index 3bf2630..e8d8fe2 100644 --- a/examples/declarative/workerlistmodel/timedisplay.qml +++ b/examples/declarative/listmodel-threaded/timedisplay.qml @@ -10,7 +10,7 @@ ListView { Text { text: time } } - WorkerListModel { id: listModel } + ListModel { id: listModel } WorkerScript { id: worker diff --git a/examples/declarative/listview/listview.qml b/examples/declarative/listview/listview-example.qml index 92acce1..92acce1 100644 --- a/examples/declarative/listview/listview.qml +++ b/examples/declarative/listview/listview-example.qml diff --git a/examples/declarative/plugins/README b/examples/declarative/plugins/README index 621f570..3ae256d 100644 --- a/examples/declarative/plugins/README +++ b/examples/declarative/plugins/README @@ -1,9 +1,9 @@ -This example shows a module "com.nokia.TimeExample" that is implelement +This example shows a module "com.nokia.TimeExample" that is implemented by a C++ plugin (providing the "Time" type), and by QML files (providing the "Clock" type). To run: make install - qmlviewer plugins.qml + qml plugins.qml diff --git a/examples/declarative/plugins/plugins.qml b/examples/declarative/plugins/plugins.qml index 44b552b..449cd9a 100644 --- a/examples/declarative/plugins/plugins.qml +++ b/examples/declarative/plugins/plugins.qml @@ -1,8 +1,8 @@ import com.nokia.TimeExample 1.0 // import types from the plugin -Clock { // this class is defined in QML (files/Clock.qml) +Clock { // this class is defined in QML (com/nokia/TimeExample/Clock.qml) - Time { // this class is defined in C++ (plugins.cpp) + Time { // this class is defined in C++ (plugin.cpp) id: time } diff --git a/examples/declarative/tic-tac-toe/content/Button.qml b/examples/declarative/tic-tac-toe/content/Button.qml new file mode 100644 index 0000000..cfc2f04 --- /dev/null +++ b/examples/declarative/tic-tac-toe/content/Button.qml @@ -0,0 +1,35 @@ +import Qt 4.6 + +Rectangle { + id: container + + signal clicked + property string text: "Button" + property bool down: false + property string mainCol: "lightgray" + property string darkCol: "darkgray" + property string lightCol: "white" + + color: mainCol; smooth: true + width: txtItem.width + 20; height: txtItem.height + 6 + border.width: 1; border.color: Qt.darker(mainCol); radius: 8; + + gradient: Gradient { + GradientStop { + id: topGrad; position: 0.0 + color: if (container.down) { darkCol } else { lightCol } } + GradientStop { position: 1.0; color: mainCol } + } + + MouseArea { id: mr; anchors.fill: parent; onClicked: container.clicked() } + + Text { + id: txtItem; text: container.text; + anchors.centerIn: container + color: "blue" + styleColor: "white" + style: Text.Outline + font.pixelSize: 14 + font.bold: true + } +} diff --git a/examples/declarative/tic-tac-toe/content/pics/board.png b/examples/declarative/tic-tac-toe/content/pics/board.png Binary files differindex cd85971..e7a7324 100644 --- a/examples/declarative/tic-tac-toe/content/pics/board.png +++ b/examples/declarative/tic-tac-toe/content/pics/board.png diff --git a/examples/declarative/tic-tac-toe/tic-tac-toe.qml b/examples/declarative/tic-tac-toe/tic-tac-toe.qml index 63ee483..ae187d2 100644 --- a/examples/declarative/tic-tac-toe/tic-tac-toe.qml +++ b/examples/declarative/tic-tac-toe/tic-tac-toe.qml @@ -2,11 +2,17 @@ import Qt 4.6 import "content" Item { - width: boardimage.width - height: boardimage.height + id: game + property bool show: false; + width: 440 + height: 480 + anchors.fill: parent + property real difficulty: 1.0; //chance it will actually think Image { id: boardimage + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter source: "content/pics/board.png" } @@ -31,7 +37,7 @@ Item { } Script { - function winner() + function winner(board) { for (var i=0; i<3; ++i) { if (board.children[i].state!="" @@ -68,7 +74,7 @@ Item { function makeMove(pos,player) { board.children[pos].state = player - if (winner()) { + if (winner(board)) { win(player + " wins") return true } else { @@ -78,13 +84,95 @@ Item { function computerTurn() { - // world's dumbest player - for (var i=0; i<9; ++i) + var r = Math.random(); + if(r < game.difficulty){ + smartAI(); + }else{ + randAI(); + } + } + + function smartAI() + { + function boardCopy(a){ + var ret = new Object; + ret.children = new Array(9); + for(var i = 0; i<9; i++){ + ret.children[i] = new Object; + ret.children[i].state = a.children[i].state; + } + return ret; + } + for(var i=0; i<9; i++){ + var simpleBoard = boardCopy(board); + if (board.children[i].state == "") { + simpleBoard.children[i].state = "O"; + if(winner(simpleBoard)){ + makeMove(i,"O") + return + } + } + } + for(var i=0; i<9; i++){ + var simpleBoard = boardCopy(board); + if (board.children[i].state == "") { + simpleBoard.children[i].state = "X"; + if(winner(simpleBoard)){ + makeMove(i,"O") + return + } + } + } + function thwart(a,b,c){//If they are at a, try b or c + if (board.children[a].state == "X") { + if (board.children[b].state == "") { + makeMove(b,"O") + return true + }else if (board.children[c].state == "") { + makeMove(c,"O") + return true + } + } + return false; + } + if(thwart(4,0,2)) return; + if(thwart(0,4,3)) return; + if(thwart(2,4,1)) return; + if(thwart(6,4,7)) return; + if(thwart(8,4,5)) return; + if(thwart(1,4,2)) return; + if(thwart(3,4,0)) return; + if(thwart(5,4,8)) return; + if(thwart(7,4,6)) return; + for(var i =0; i<9; i++){//Backup if (board.children[i].state == "") { makeMove(i,"O") return } - restart() + } + restart(); + } + + function randAI() + { + var open = 0; + for (var i=0; i<9; ++i) + if (board.children[i].state == "") { + open += 1; + } + if(open == 0){ + restart(); + return; + } + var openA = new Array(open);//JS doesn't have lists I can append to (i think) + var acc = 0; + for (var i=0; i<9; ++i) + if (board.children[i].state == "") { + openA[acc] = i; + acc += 1; + } + var choice = openA[Math.floor(Math.random() * open)]; + makeMove(choice, "O"); } function win(s) @@ -102,6 +190,27 @@ Item { } } + Row { + spacing: 4 + anchors.top: board.bottom + anchors.horizontalCenter: board.horizontalCenter + Button { + text: "Hard" + onClicked: game.difficulty=1.0; + down: game.difficulty == 1.0 + } + Button { + text: "Moderate" + onClicked: game.difficulty=0.8; + down: game.difficulty == 0.8 + } + Button { + text: "Easy" + onClicked: game.difficulty=0.2; + down: game.difficulty == 0.2 + } + } + Text { id: msg opacity: 0 diff --git a/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml b/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml index 9ef455a..a6ef62c 100644 --- a/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml +++ b/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id:block property int type: 0 diff --git a/examples/graphicsview/padnavigator/padnavigator.qrc b/examples/graphicsview/padnavigator/padnavigator.qrc index 30ee8e1..b26ab92 100644 --- a/examples/graphicsview/padnavigator/padnavigator.qrc +++ b/examples/graphicsview/padnavigator/padnavigator.qrc @@ -9,6 +9,5 @@ <file>images/kopeteavailable.png</file> <file>images/metacontact_online.png</file> <file>images/minitools.png</file> - <file>images/blue_angle_swirl.jpg</file> </qresource> </RCC> diff --git a/examples/network/fortuneclient/fortuneclient.pro b/examples/network/fortuneclient/fortuneclient.pro index 2b65f2f..edbf14d 100644 --- a/examples/network/fortuneclient/fortuneclient.pro +++ b/examples/network/fortuneclient/fortuneclient.pro @@ -11,7 +11,7 @@ INSTALLS += target sources symbian { include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h + INCLUDEPATH += $$QT_SOURCE_TREE/examples/network/qftp/ LIBS += -lesock -lcommdb -linsock # For IAP selection TARGET.CAPABILITY = "NetworkServices ReadUserData WriteUserData" TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 diff --git a/examples/network/fortuneserver/fortuneserver.pro b/examples/network/fortuneserver/fortuneserver.pro index acb285b..29ba313 100644 --- a/examples/network/fortuneserver/fortuneserver.pro +++ b/examples/network/fortuneserver/fortuneserver.pro @@ -12,7 +12,7 @@ INSTALLS += target sources symbian { TARGET.UID3 = 0xA000CF71 include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h + INCLUDEPATH += $$QT_SOURCE_TREE/examples/network/qftp/ LIBS += -lesock -lcommdb -linsock # For IAP selection TARGET.CAPABILITY = "All -TCB" TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 diff --git a/examples/network/network-chat/network-chat.pro b/examples/network/network-chat/network-chat.pro index 7438641..1215aea 100644 --- a/examples/network/network-chat/network-chat.pro +++ b/examples/network/network-chat/network-chat.pro @@ -20,7 +20,7 @@ INSTALLS += target sources symbian { include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h + INCLUDEPATH += $$QT_SOURCE_TREE/examples/network/qftp/ LIBS += -lesock -lcommdb -linsock # For IAP selection LIBS += -lcharconv TARGET.CAPABILITY = "NetworkServices ReadUserData WriteUserData" diff --git a/imports/Qt/.gitignore b/imports/Qt/.gitignore new file mode 100644 index 0000000..bc54bd5 --- /dev/null +++ b/imports/Qt/.gitignore @@ -0,0 +1,2 @@ +*.dll +*.dso diff --git a/mkspecs/common/armcc.conf b/mkspecs/common/armcc.conf new file mode 100644 index 0000000..2c765bc --- /dev/null +++ b/mkspecs/common/armcc.conf @@ -0,0 +1,41 @@ +# +# qmake configuration for armcc +# + +CONFIG += rvct_linker +QMAKE_CC = armcc +QMAKE_CFLAGS += +QMAKE_CFLAGS_DEPS += -M +QMAKE_CFLAGS_WARN_ON += +QMAKE_CFLAGS_WARN_OFF += -W +QMAKE_CFLAGS_RELEASE += -O2 +QMAKE_CFLAGS_DEBUG += -g -O0 +QMAKE_CFLAGS_HIDESYMS += --visibility_inlines_hidden + +QMAKE_CXX = armcc +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS --exceptions --exceptions_unwind +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_LINK = armlink +QMAKE_LINK_SHLIB = armlink +QMAKE_LINK_C = armlink +QMAKE_LINK_C_SHLIB = armlink +QMAKE_LFLAGS += +QMAKE_LFLAGS_RELEASE += +QMAKE_LFLAGS_DEBUG += +QMAKE_LFLAGS_APP += +QMAKE_LFLAGS_SHLIB += +QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_THREAD += + +QMAKE_AR = armar --create +QMAKE_RANLIB = + diff --git a/mkspecs/common/symbian/header-wrappers/AknDoc.h b/mkspecs/common/symbian/header-wrappers/AknDoc.h new file mode 100644 index 0000000..d4dbd7d --- /dev/null +++ b/mkspecs/common/symbian/header-wrappers/AknDoc.h @@ -0,0 +1 @@ +#include <akndoc.h> diff --git a/mkspecs/common/symbian/header-wrappers/AknPopupFader.h b/mkspecs/common/symbian/header-wrappers/AknPopupFader.h new file mode 100644 index 0000000..60a007a --- /dev/null +++ b/mkspecs/common/symbian/header-wrappers/AknPopupFader.h @@ -0,0 +1 @@ +#include <aknpopupfader.h> diff --git a/mkspecs/common/symbian/header-wrappers/AknServerApp.h b/mkspecs/common/symbian/header-wrappers/AknServerApp.h new file mode 100644 index 0000000..b4dc69f --- /dev/null +++ b/mkspecs/common/symbian/header-wrappers/AknServerApp.h @@ -0,0 +1 @@ +#include <aknserverapp.h> diff --git a/mkspecs/common/symbian/header-wrappers/AknUtils.h b/mkspecs/common/symbian/header-wrappers/AknUtils.h new file mode 100644 index 0000000..66a3784 --- /dev/null +++ b/mkspecs/common/symbian/header-wrappers/AknUtils.h @@ -0,0 +1 @@ +#include <aknutils.h> diff --git a/mkspecs/common/symbian/header-wrappers/CDirectoryLocalizer.h b/mkspecs/common/symbian/header-wrappers/CDirectoryLocalizer.h new file mode 100644 index 0000000..f251302 --- /dev/null +++ b/mkspecs/common/symbian/header-wrappers/CDirectoryLocalizer.h @@ -0,0 +1 @@ +#include <cdirectorylocalizer.h> diff --git a/mkspecs/common/symbian/header-wrappers/DocumentHandler.h b/mkspecs/common/symbian/header-wrappers/DocumentHandler.h new file mode 100644 index 0000000..8981af6 --- /dev/null +++ b/mkspecs/common/symbian/header-wrappers/DocumentHandler.h @@ -0,0 +1 @@ +#include <documenthandler.h> diff --git a/mkspecs/common/symbian/qplatformdefs.h b/mkspecs/common/symbian/qplatformdefs.h index 38a1314..2b075ba 100644 --- a/mkspecs/common/symbian/qplatformdefs.h +++ b/mkspecs/common/symbian/qplatformdefs.h @@ -85,6 +85,8 @@ #include <arpa/inet.h> #define QT_USE_XOPEN_LFS_EXTENSIONS +// unset large file as symbian doesn't support it +#undef QT_LARGEFILE_SUPPORT #include "../posix/qplatformdefs.h" #undef QT_OPEN_LARGEFILE diff --git a/mkspecs/common/symbian/symbian-makefile.conf b/mkspecs/common/symbian/symbian-makefile.conf new file mode 100644 index 0000000..3801eff --- /dev/null +++ b/mkspecs/common/symbian/symbian-makefile.conf @@ -0,0 +1,45 @@ +# +# qmake configuration for makefile based symbian +# + +MAKEFILE_GENERATOR = SYMBIAN_UNIX + +include(symbian.conf) + +QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] + +QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src +QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< +QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src +QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +QMAKE_ELF2E32_FLAGS += + +include(../../common/unix.conf) + +QMAKE_PREFIX_SHLIB = +QMAKE_EXTENSION_SHLIB = dll +CONFIG *= no_plugin_name_prefix +QMAKE_EXTENSION_PLUGIN = dll +QMAKE_PREFIX_STATICLIB = +QMAKE_EXTENSION_STATICLIB = lib +QMAKE_SYMBIAN_SHLIB = 1 + +DEFINES *= __PRODUCT_INCLUDE__=\<$${EPOCROOT}epoc32/include/variant/symbian_os.hrh\> \ + __SYMBIAN32__ \ + __MARM_INTERWORK__ \ + _UNICODE \ + __S60_50__ \ + __S60_3X__ \ + __SERIES60_3X__ \ + __EPOC32__ \ + __MARM__ \ + __EABI__ \ + __MARM_ARMV5__ \ + __SUPPORT_CPP_EXCEPTIONS__ + +QMAKE_CFLAGS_DEBUG += -g +QMAKE_CXXFLAGS_DEBUG += -g +QMAKE_CFLAGS_RELEASE += -O2 -Otime +QMAKE_CXXFLAGS_RELEASE += -O2 -Otime + diff --git a/mkspecs/common/symbian/symbian-mmp.conf b/mkspecs/common/symbian/symbian-mmp.conf new file mode 100644 index 0000000..e54e878 --- /dev/null +++ b/mkspecs/common/symbian/symbian-mmp.conf @@ -0,0 +1,76 @@ +# +# qmake configuration for symbian-* +# + +contains(QMAKE_HOST.os, "Windows") { + QMAKE_MOC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc.exe + QMAKE_UIC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic.exe + QMAKE_IDC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc.exe +} else { + QMAKE_MOC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc + QMAKE_UIC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic + QMAKE_IDC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc +} + +include(symbian.conf) +load(symbian/add_mmp_rules) + +symbian-abld { +# Versions of abld prior to Symbian^3 have a bug where you cannot remove something from the command line without replacing it +# Rather than figure out which version of abld we're using, we'll replace the command with a macro *that should never be used* + MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA = "OPTION_REPLACE ARMCC --export_all_vtbl -D__QT_NOEFFECTMACRO_DONOTUSE" +} else { + MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA = "OPTION_REPLACE ARMCC --export_all_vtbl // don't use --export_all_vtbl" +} +MMP_RULES += PAGED BYTEPAIRCOMPRESSTARGET +MMP_RULES += $$MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA +SYMBIAN_PLATFORMS = WINSCW GCCE ARMV5 ARMV6 + +INCLUDEPATH = \ + $$[QT_INSTALL_PREFIX]/mkspecs/common/symbian/stl-off \ + $$[QT_INSTALL_PREFIX]/mkspecs/common/symbian \ + $${EPOCROOT}epoc32/include \ + $$OS_LAYER_LIBC_SYSTEMINCLUDE \ + $$INCLUDEPATH + +# Ensure '.' directory is the first in include path. +# RVCT seems to do this automatically, but WINSCW compiler does not, so add it here. +MMP_RULES += "USERINCLUDE ." + +# Supports S60 3.0, 3.1, 3.2 and 5.0 by default +default_deployment.pkg_prerules = \ + "; Default HW/platform dependencies" \ + "[0x101F7961],0,0,0,{\"S60ProductID\"}" \ + "[0x102032BE],0,0,0,{\"S60ProductID\"}" \ + "[0x102752AE],0,0,0,{\"S60ProductID\"}" \ + "[0x1028315F],0,0,0,{\"S60ProductID\"}" \ + " " + +DEPLOYMENT += default_deployment + +exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v5.0.sis )|exists($${EPOCROOT}epoc32/data/z/system/install/series60v5.0.sis) { + S60_VERSION = 5.0 +} else { + exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v3.2.sis )|exists($${EPOCROOT}epoc32/data/z/system/install/series60v3.2.sis) { + S60_VERSION = 3.2 + } else { + S60_VERSION = 3.1 + MMP_RULES -= PAGED BYTEPAIRCOMPRESSTARGET + } +} + +QMAKE_CXXFLAGS_FAST_VFP.ARMCC = --fpmode fast +# [TODO] QMAKE_CXXFLAGS_FAST_VFP.GCCE = + +symbian { + armfpu = $$find(MMP_RULES, "ARMFPU") + !isEmpty(armfpu) { + vfpv2 = $$find(MMP_RULES, "vfpv2") + !isEmpty(vfpv2) { + # we will respect fpu setting obtained from configure, but, + # if vfpv2 or softvfp+vfpv2 used we want to force RunFast VFP mode + QMAKE_CXXFLAGS.ARMCC += $${QMAKE_CXXFLAGS_FAST_VFP.ARMCC} + # [TODO] QMAKE_CXXFLAGS.GCCE += $${QMAKE_CXXFLAGS_FAST_VFP.GCCE} + } + } +} diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 16b9a28..4dd81b0 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -1,9 +1,9 @@ # -# qmake configuration for symbian-* +# qmake configuration for all symbian mkspecs # TEMPLATE = app -CONFIG += qt warn_on release incremental +CONFIG += qt warn_on release incremental link_prl sis_targets QT += core gui QMAKE_INCREMENTAL_STYLE = sublib @@ -17,7 +17,6 @@ QMAKE_COMPILER_DEFINES += SYMBIAN QMAKE_EXT_OBJ = .o QMAKE_EXT_RES = _res.o -QMAKE_CC = gcc QMAKE_LEX = flex QMAKE_LEXFLAGS = QMAKE_YACC = byacc @@ -30,7 +29,6 @@ QMAKE_CFLAGS_RELEASE = QMAKE_CFLAGS_DEBUG = QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses -QMAKE_CXX = g++ QMAKE_CXXFLAGS = $$QMAKE_CFLAGS # Symbian build system applies -cwd source on the MWCC command line. # this causes problems with include paths, -cwd include uses the same @@ -55,12 +53,6 @@ QMAKE_CXXFLAGS_EXCEPTIONS_OFF = QMAKE_INCDIR = QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] -QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src -QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< -QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src -QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< - -QMAKE_LINK = QMAKE_LFLAGS = QMAKE_LFLAGS.ARMCC = QMAKE_LFLAGS_EXCEPTIONS_ON = @@ -74,12 +66,13 @@ QMAKE_LINK_OBJECT_MAX = QMAKE_LINK_OBJECT_SCRIPT= QMAKE_LIBS = -llibc -llibm -leuser -llibdl -QMAKE_LIBS_CORE = $$QMAKE_LIBS -llibpthread -lefsrv +QMAKE_LIBS_CORE = $$QMAKE_LIBS -lefsrv QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lhal -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -leikcoctl -leiksrv -lapparc -lcentralrepository QMAKE_LIBS_NETWORK = QMAKE_LIBS_EGL = -llibEGL QMAKE_LIBS_OPENGL = QMAKE_LIBS_OPENVG = -llibOpenVG -lgraphicsresource -lfbscli -lbitgdi -lgdi +QMAKE_LIBS_THREAD = -llibpthread QMAKE_LIBS_COMPAT = QMAKE_LIBS_QT_ENTRY = -llibcrt0.lib QMAKE_LIBS_S60 = -lavkon @@ -104,84 +97,15 @@ contains(QMAKE_HOST.os,Windows) { QMAKE_CHK_DIR_EXISTS = test -d } -contains(QMAKE_HOST.os, "Windows") { - QMAKE_MOC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc.exe - QMAKE_UIC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic.exe - QMAKE_IDC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc.exe -} else { - QMAKE_MOC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc - QMAKE_UIC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic - QMAKE_IDC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc -} +QMAKE_IDL = midl +QMAKE_LIB = ar -ru +QMAKE_RC = windres +QMAKE_ZIP = zip -r -9 -QMAKE_IDL = midl -QMAKE_LIB = ar -ru -QMAKE_RC = windres -QMAKE_ZIP = zip -r -9 +QMAKE_TAR = tar -cf +QMAKE_GZIP = gzip -9f -QMAKE_STRIP = strip -QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QT_ARCH = symbian load(qt_config) load(symbian/platform_paths) -load(symbian/add_mmp_rules) - -symbian-abld { -# Versions of abld prior to Symbian^3 have a bug where you cannot remove something from the command line without replacing it -# Rather than figure out which version of abld we're using, we'll replace the command with a macro *that should never be used* - MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA = "OPTION_REPLACE ARMCC --export_all_vtbl -D__QT_NOEFFECTMACRO_DONOTUSE" -} else { - MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA = "OPTION_REPLACE ARMCC --export_all_vtbl // don't use --export_all_vtbl" -} -MMP_RULES += PAGED BYTEPAIRCOMPRESSTARGET -MMP_RULES += $$MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA -SYMBIAN_PLATFORMS = WINSCW GCCE ARMV5 ARMV6 - -INCLUDEPATH = \ - $$[QT_INSTALL_PREFIX]/mkspecs/common/symbian/stl-off \ - $$[QT_INSTALL_PREFIX]/mkspecs/common/symbian \ - $${EPOCROOT}epoc32/include \ - $$OS_LAYER_LIBC_SYSTEMINCLUDE \ - $$INCLUDEPATH - -# Ensure '.' directory is the first in include path. -# RVCT seems to do this automatically, but WINSCW compiler does not, so add it here. -MMP_RULES += "USERINCLUDE ." - -# Supports S60 3.0, 3.1, 3.2 and 5.0 by default -default_deployment.pkg_prerules = \ - "; Default HW/platform dependencies" \ - "[0x101F7961],0,0,0,{\"S60ProductID\"}" \ - "[0x102032BE],0,0,0,{\"S60ProductID\"}" \ - "[0x102752AE],0,0,0,{\"S60ProductID\"}" \ - "[0x1028315F],0,0,0,{\"S60ProductID\"}" \ - " " - -DEPLOYMENT += default_deployment - -exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v5.0.sis )|exists($${EPOCROOT}epoc32/data/z/system/install/series60v5.0.sis) { - S60_VERSION = 5.0 -} else { - exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v3.2.sis )|exists($${EPOCROOT}epoc32/data/z/system/install/series60v3.2.sis) { - S60_VERSION = 3.2 - } else { - S60_VERSION = 3.1 - MMP_RULES -= PAGED BYTEPAIRCOMPRESSTARGET - } -} - -QMAKE_CXXFLAGS_FAST_VFP.ARMCC = --fpmode fast -# [TODO] QMAKE_CXXFLAGS_FAST_VFP.GCCE = - -symbian { - armfpu = $$find(MMP_RULES, "ARMFPU") - !isEmpty(armfpu) { - vfpv2 = $$find(MMP_RULES, "vfpv2") - !isEmpty(vfpv2) { - # we will respect fpu setting obtained from configure, but, - # if vfpv2 or softvfp+vfpv2 used we want to force RunFast VFP mode - QMAKE_CXXFLAGS.ARMCC += $${QMAKE_CXXFLAGS_FAST_VFP.ARMCC} - # [TODO] QMAKE_CXXFLAGS.GCCE += $${QMAKE_CXXFLAGS_FAST_VFP.GCCE} - } - } -} diff --git a/mkspecs/common/unix.conf b/mkspecs/common/unix.conf index 4cb171e..c480ba4 100644 --- a/mkspecs/common/unix.conf +++ b/mkspecs/common/unix.conf @@ -9,3 +9,6 @@ QMAKE_YACCFLAGS += -d QMAKE_YACCFLAGS_MANGLE += -p $base -b $base QMAKE_YACC_HEADER = $base.tab.h QMAKE_YACC_SOURCE = $base.tab.c +QMAKE_PREFIX_SHLIB = lib +QMAKE_PREFIX_STATICLIB = lib +QMAKE_EXTENSION_STATICLIB = a diff --git a/mkspecs/features/sis_targets.prf b/mkspecs/features/sis_targets.prf new file mode 100644 index 0000000..66a7a9d --- /dev/null +++ b/mkspecs/features/sis_targets.prf @@ -0,0 +1,139 @@ +# Sis file creation +contains(TEMPLATE, app)|!isEmpty(DEPLOYMENT) { + symbian-abld|symbian-sbsv2 { + sis_destdir = + make_cache_name = .make.cache + sis_target.target = sis + sis_target.commands = $(if $(wildcard $$basename(TARGET)_template.pkg), \ + $(if $(wildcard $$make_cache_name), \ + $(MAKE) -f $(MAKEFILE) ok_sis MAKEFILES=$$make_cache_name \ + , \ + $(if $(QT_SIS_TARGET), \ + $(MAKE) -f $(MAKEFILE) ok_sis \ + , \ + $(MAKE) -f $(MAKEFILE) fail_sis_nocache \ + ) \ + ) \ + , \ + $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ + ) + + ok_sis_target.target = ok_sis + ok_sis_target.commands = createpackage.bat $(QT_SIS_OPTIONS) $$basename(TARGET)_template.pkg \ + $(QT_SIS_TARGET) $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) + + target_sis_target.target = $${sis_destdir}$${TARGET}.sis + target_sis_target.commands = $(MAKE) -f $(MAKEFILE) sis + + installer_sis_target.target = installer_sis + installer_sis_target.commands = $(if $(wildcard $$basename(TARGET)_installer.pkg), \ + $(MAKE) -f $(MAKEFILE) ok_installer_sis \ + , \ + $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ + ) + installer_sis_target.depends = $${sis_destdir}$${TARGET}.sis + + ok_installer_sis_target.target = ok_installer_sis + ok_installer_sis_target.commands = createpackage.bat $(QT_SIS_OPTIONS) $$basename(TARGET)_installer.pkg - \ + $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) + + fail_sis_nopkg_target.target = fail_sis_nopkg + fail_sis_nopkg_target.commands = "$(error PKG file does not exist, 'sis' and 'installer_sis' target are only supported for executables or projects with DEPLOYMENT statement)" + + fail_sis_nocache_target.target = fail_sis_nocache + fail_sis_nocache_target.commands = "$(error Project has to be built or QT_SIS_TARGET environment variable has to be set before calling 'SIS' target)" + + stub_sis_target.target = stub_sis + stub_sis_target.commands = $(if $(wildcard $$basename(TARGET)_template.pkg), \ + $(if $(wildcard $$make_cache_name), \ + $(MAKE) -f $(MAKEFILE) ok_stub_sis MAKEFILES=$$make_cache_name \ + , \ + $(if $(QT_SIS_TARGET), \ + $(MAKE) -f $(MAKEFILE) ok_stub_sis \ + , \ + $(MAKE) -f $(MAKEFILE) fail_sis_nocache \ + ) \ + ) \ + , \ + $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ + ) + + ok_stub_sis_target.target = ok_stub_sis + ok_stub_sis_target.commands = createpackage.bat -s $(QT_SIS_OPTIONS) $$basename(TARGET)_template.pkg \ + $(QT_SIS_TARGET) $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) + + QMAKE_EXTRA_TARGETS += sis_target \ + ok_sis_target \ + target_sis_target \ + installer_sis_target \ + ok_installer_sis_target \ + fail_sis_nopkg_target \ + fail_sis_nocache_target \ + stub_sis_target \ + ok_stub_sis_target + # Sbsv2 has its own store_build target which is using flms. + !symbian-sbsv2 { + contains(QMAKE_HOST.os, "Windows") { + shellFixedHash = $${LITERAL_HASH} + } else { + shellFixedHash = \\$${LITERAL_HASH} + } + store_build_target.target = store_build + store_build_target.commands = \ + @echo $${shellFixedHash} ============================================================================== > $$make_cache_name \ + && echo $${shellFixedHash} This file is generated by make and should not be modified by the user >> $$make_cache_name \ + && echo $${shellFixedHash} Name : $$make_cache_name >> $$make_cache_name \ + && echo $${shellFixedHash} Part of : lineedits >> $$make_cache_name \ + && echo $${shellFixedHash} Description : This file is used to cache last build target for >> $$make_cache_name \ + && echo $${shellFixedHash} make sis target. >> $$make_cache_name \ + && echo $${shellFixedHash} Version : >> $$make_cache_name \ + && echo $${shellFixedHash} >> $$make_cache_name \ + && echo $${shellFixedHash} ============================================================================== >> $$make_cache_name \ + && echo. >> $$make_cache_name \ + && echo QT_SIS_TARGET ?= $(QT_SIS_TARGET) >> $$make_cache_name + + QMAKE_EXTRA_TARGETS += store_build_target + } + } else { + sis_destdir = $$DESTDIR + !isEmpty(sis_destdir):!contains(sis_destdir, "[/\\]$"):sis_destdir = $${sis_destdir}/ + contains(QMAKE_HOST.os, "Windows"):sis_destdir = $$replace(sis_destdir, "/", "\\") + + sis_target.target = sis + sis_target.commands = createpackage $(QT_SIS_OPTIONS) $$basename(TARGET)_template.pkg \ + - $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) + sis_target.depends = first + + target_sis_target.target = $${sis_destdir}$${TARGET}.sis + target_sis_target.commands = $(MAKE) -f $(MAKEFILE) sis + + installer_sis_target.target = installer_sis + installer_sis_target.commands = createpackage $(QT_SIS_OPTIONS) $$basename(TARGET)_installer.pkg - \ + $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) + installer_sis_target.depends = $${sis_destdir}$${TARGET}.sis + + !isEmpty(DESTDIR) { + sis_target.commands += && $$QMAKE_MOVE $$basename(TARGET).sis $$DESTDIR + installer_sis_target.commands += && $$QMAKE_MOVE $$basename(TARGET).sis $$DESTDIR + } + + QMAKE_EXTRA_TARGETS += sis_target \ + target_sis_target \ + installer_sis_target + } +} else { + contains(TEMPLATE, subdirs) { + # Enable recursive sis target. + sis_target.CONFIG = recursive + sis_target.recurse = $$SUBDIRS + } else { + # Make sure we build everything, since other sis targets in a recursive invocation + # may depend on them, even if this one is empty. + sis_target.depends = first + } + sis_target.commands = + sis_target.target = sis + QMAKE_EXTRA_TARGETS += sis_target +} + +QMAKE_DISTCLEAN += $${sis_destdir}$${TARGET}.sis diff --git a/mkspecs/features/symbian/application_icon.prf b/mkspecs/features/symbian/application_icon.prf index ebef8b2..1109060 100644 --- a/mkspecs/features/symbian/application_icon.prf +++ b/mkspecs/features/symbian/application_icon.prf @@ -15,36 +15,48 @@ contains( CONFIG, no_icon ) { } # Try to produce indentical string to fixedTarget in SymbianMakefileGenerator, replaced chars taken - # from SymbianMakefileGenerator::removeSpecialCharacters. + # from SymbianCommonGenerator::removeSpecialCharacters. # # Note: it is not a major problem even baseTarget is not 100% identical to fixedTarget since qmake # only uses filename from RSS_RULES.icon_file when referring to icon file name. baseTarget = $$basename(TARGET) baseTarget = $$replace(baseTarget, /,_) baseTarget = $$replace(baseTarget, \\,_) - baseTarget = $$replace(baseTarget, -,_) - baseTarget = $$replace(baseTarget, :,_) - baseTarget = $$replace(baseTarget, \.,_) baseTarget = $$replace(baseTarget, " ",_) + symbian-abld|symbian-sbsv2 { + baseTarget = $$replace(baseTarget, -,_) + baseTarget = $$replace(baseTarget, \.,_) + baseTarget = $$replace(baseTarget, :,_) + } # Note: symbian-sbsv2 builds can't utilize extra compiler for mifconv, so ICON handling is done in code - symbian-abld { + !symbian-sbsv2 { #Makefile: requires paths with backslash - contains(QMAKE_HOST.os, "Windows"):ICON = $$replace(ICON, /, \\) + ICON_backslashed = $$ICON + contains(QMAKE_HOST.os, "Windows"):ICON_backslashed = $$replace( ICON_backslashed, /, \\) + + symbian-abld { + mifIconZDir = ${ZDIR}$$APP_RESOURCE_DIR + } else { + isEmpty(DESTDIR) { + mifIconZDir = . + } else { + mifIconZDir = $$DESTDIR + } + } # Extra compiler rules for mifconv - mifconv.output = ${ZDIR}$$APP_RESOURCE_DIR/$${baseTarget}.mif + mifconv.target = $$mifIconZDir/$${baseTarget}.mif # Based on: http://www.forum.nokia.com/document/Cpp_Developers_Library # svg-t icons should always use /c32 depth - mifconv.commands = mifconv ${QMAKE_FILE_OUT} /c32 ${QMAKE_FILE_IN} - mifconv.input = ICON - mifconv.CONFIG = no_link combine - # target_predeps together with combine seems not to work correctly, lets define it by ourselves - PRE_TARGETDEPS += $$mifconv.output - QMAKE_EXTRA_COMPILERS += mifconv + mifconv.commands = mifconv $$mifconv.target /c32 $$ICON_backslashed + mifconv.depends = $$ICON + PRE_TARGETDEPS += $$mifconv.target + QMAKE_EXTRA_TARGETS += mifconv + QMAKE_DISTCLEAN += $$mifconv.target } # Rules to use generated MIF file from symbian resources - RSS_RULES.number_of_icons = $$size(ICON) + RSS_RULES.number_of_icons = $$size(ICON_backslashed) RSS_RULES.icon_file = $$APP_RESOURCE_DIR/$${baseTarget}.mif } } diff --git a/mkspecs/features/symbian/debug.prf b/mkspecs/features/symbian/debug.prf new file mode 100644 index 0000000..b5afeb6 --- /dev/null +++ b/mkspecs/features/symbian/debug.prf @@ -0,0 +1 @@ +QMAKE_LIBDIR += $${EPOCROOT}epoc32/release/armv5/udeb diff --git a/mkspecs/features/symbian/def_files.prf b/mkspecs/features/symbian/def_files.prf index 48d91aa..a1f0c8d 100644 --- a/mkspecs/features/symbian/def_files.prf +++ b/mkspecs/features/symbian/def_files.prf @@ -3,32 +3,75 @@ CONFIG -= def_files_disabled -# Firstly, if the MMP_RULES already contain a defBlock variable, don't generate another one -# (this bit is slightly magic, because it depends upon everyone creating their DEFFILE statements -# in a defBlock variable; but otherwise we have to expand MMP_RULES then scan for the DEFFILE keyword) -!contains(MMP_RULES, defBlock) { - # Apps are executables on Symbian, so don't have exports, and therefore don't have DEF files - # Plugins use standard DEF files, which qmake generates, so shouldn't be using these DEFFILE - # statements - they use the qmake generated statements instead - # Static libraries obviously don't have DEF files, as they don't take part in dynamic linkage - !contains(TEMPLATE, app):!contains(CONFIG, plugin):!contains(CONFIG, staticlib): { - !isEmpty(defFilePath) { - defBlock = \ - "$${LITERAL_HASH}ifdef WINSCW" \ - "DEFFILE $$defFilePath/bwins/$${TARGET}.def" \ - "$${LITERAL_HASH}elif defined EABI" \ - "DEFFILE $$defFilePath/eabi/$${TARGET}.def" \ - "$${LITERAL_HASH}endif" - } else { - # If defFilePath is not defined, then put the folders containing the DEF files at the - # same level as the .pro (and generated MMP) file(s) - defBlock = \ - "$${LITERAL_HASH}ifdef WINSCW" \ - "DEFFILE ./bwins/$${TARGET}.def" \ - "$${LITERAL_HASH}elif defined EABI" \ - "DEFFILE ./eabi/$${TARGET}.def" \ - "$${LITERAL_HASH}endif" +symbian-abld|symbian-sbsv2 { + # Firstly, if the MMP_RULES already contain a defBlock variable, don't generate another one + # (this bit is slightly magic, because it depends upon everyone creating their DEFFILE statements + # in a defBlock variable; but otherwise we have to expand MMP_RULES then scan for the DEFFILE keyword) + !contains(MMP_RULES, defBlock) { + # Apps are executables on Symbian, so don't have exports, and therefore don't have DEF files + # Plugins use standard DEF files, which qmake generates, so shouldn't be using these DEFFILE + # statements - they use the qmake generated statements instead + # Static libraries obviously don't have DEF files, as they don't take part in dynamic linkage + !contains(TEMPLATE, app):!contains(CONFIG, plugin):!contains(CONFIG, staticlib): { + !isEmpty(DEF_FILE) { + defBlock = \ + "$${LITERAL_HASH}ifdef WINSCW" \ + "DEFFILE $$DEF_FILE/bwins/$${TARGET}.def" \ + "$${LITERAL_HASH}elif defined EABI" \ + "DEFFILE $$DEF_FILE/eabi/$${TARGET}.def" \ + "$${LITERAL_HASH}endif" + } else:!isEmpty(defFilePath) { + defBlock = \ + "$${LITERAL_HASH}ifdef WINSCW" \ + "DEFFILE $$defFilePath/bwins/$${TARGET}.def" \ + "$${LITERAL_HASH}elif defined EABI" \ + "DEFFILE $$defFilePath/eabi/$${TARGET}.def" \ + "$${LITERAL_HASH}endif" + } else { + # If defFilePath is not defined, then put the folders containing the DEF files at the + # same level as the .pro (and generated MMP) file(s) + defBlock = \ + "$${LITERAL_HASH}ifdef WINSCW" \ + "DEFFILE ./bwins/$${TARGET}.def" \ + "$${LITERAL_HASH}elif defined EABI" \ + "DEFFILE ./eabi/$${TARGET}.def" \ + "$${LITERAL_HASH}endif" + } + MMP_RULES += defBlock } - MMP_RULES += defBlock } + +} else:contains(TEMPLATE, lib):!contains(CONFIG, static):!contains(CONFIG, staticlib) { + !isEmpty(DEF_FILE) { + defFile = $$DEF_FILE + } else { + defFile = . + } + system("$$QMAKE_CHK_DIR_EXISTS $$_PRO_FILE_PWD_/$$defFile") { + !exists("$$_PRO_FILE_PWD_/$$defFile/eabi") { + system("$$QMAKE_MKDIR $$_PRO_FILE_PWD_/$$defFile/eabi") + } + elf2e32FileToAdd = $$_PRO_FILE_PWD_/$$defFile/eabi/$$basename(TARGET)u.def + } else { + elf2e32FileToAdd = $$_PRO_FILE_PWD_/$$defFile + } + QMAKE_ELF2E32_FLAGS += "`test -e $$elf2e32FileToAdd && echo --definput=$$elf2e32FileToAdd`" + + symbianObjdir = $$OBJECTS_DIR + isEmpty(symbianObjdir):symbianObjdir = . + + freeze_target.target = freeze + freeze_target.depends = first + # The perl part is to convert to unix line endings and remove comments, which the s60 tools refuse to do. + freeze_target.commands = perl -n -e \'next if (/; NEW/); s/\r//g; if (/MISSING:(.*)/x) { print(\"\$\$1 ABSENT\\n\"); } else { print; }\' < $$symbianObjdir/$${TARGET}.def > $$elf2e32FileToAdd + #QMAKE_EXTRA_TARGETS += freeze_target +} else:contains(TEMPLATE, subdirs) { + freeze_target.target = freeze + freeze_target.CONFIG = recursive + freeze_target.recurse = $$SUBDIRS + #QMAKE_EXTRA_TARGETS += freeze_target +} else { + freeze_target.target = freeze + freeze_target.commands = + #QMAKE_EXTRA_TARGETS += freeze_target } diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index 7c9e8ee..d29e460 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -28,4 +28,21 @@ contains(TEMPLATE, lib): { contains(TEMPLATE, ".*app"):contains(QT, gui):contains(CONFIG,qt) { load(application_icon.prf) -}
\ No newline at end of file +} + +isEmpty(TARGET.UID3):TARGET.UID3 = $$generate_uid("$${OUT_PWD}/$${TARGET}") +isEmpty(TARGET.UID2) { + contains(CONFIG, stdbinary) { + TARGET.UID2 = 0x20004C45 + } else { + contains(TEMPLATE, app) { + contains(QT, gui) { + TARGET.UID2 = 0x100039CE + } else { + TARGET.UID2 = 0 + } + } else:contains(TEMPLATE, lib):!contains(CONFIG, static):!contains(CONFIG, staticlib) { + TARGET.UID2 = 0x1000008d + } + } +} diff --git a/mkspecs/features/symbian/do_not_build_as_thumb.prf b/mkspecs/features/symbian/do_not_build_as_thumb.prf new file mode 100644 index 0000000..60d9382 --- /dev/null +++ b/mkspecs/features/symbian/do_not_build_as_thumb.prf @@ -0,0 +1,8 @@ +symbian-abld|symbian-sbsv2 { + MMP_RULES += ALWAYS_BUILD_AS_ARM +} else:linux-armcc { + QMAKE_CFLAGS -= --thumb + QMAKE_CFLAGS += --arm + QMAKE_CXXFLAGS -= --thumb + QMAKE_CXXFLAGS += --arm +} diff --git a/mkspecs/features/symbian/moc.prf b/mkspecs/features/symbian/moc.prf index 9c21ed7..29e0d8d 100644 --- a/mkspecs/features/symbian/moc.prf +++ b/mkspecs/features/symbian/moc.prf @@ -1,16 +1,18 @@ load(moc) -RET = $$find(MOC_DIR, "(/|^)\.[^/]+/?$") -!isEmpty(RET):{ - error("Symbian does not support directories starting with a dot. Please set MOC_DIR to a different value in your profile. MOC_DIR: $$MOC_DIR") -} +symbian-abld|symbian-sbsv2 { + RET = $$find(MOC_DIR, "(/|^)\.[^/]+/?$") + !isEmpty(RET):{ + error("Symbian does not support directories starting with a dot. Please set MOC_DIR to a different value in your profile. MOC_DIR: $$MOC_DIR") + } -RET = $$find(RCC_DIR, "(/|^)\.[^/]+/?$") -!isEmpty(RET):{ - error("Symbian does not support directories starting with a dot. Please set RCC_DIR to a different value in your profile. RCC_DIR: $$RCC_DIR") -} + RET = $$find(RCC_DIR, "(/|^)\.[^/]+/?$") + !isEmpty(RET):{ + error("Symbian does not support directories starting with a dot. Please set RCC_DIR to a different value in your profile. RCC_DIR: $$RCC_DIR") + } -RET = $$find(OBJECTS_DIR, "(/|^)\.[^/]+/?$") -!isEmpty(RET):{ - error("Symbian does not support directories starting with a dot. Please set OBJECTS_DIR to a different value in your profile. OBJECTS_DIR: $$OBJECTS_DIR") + RET = $$find(OBJECTS_DIR, "(/|^)\.[^/]+/?$") + !isEmpty(RET):{ + error("Symbian does not support directories starting with a dot. Please set OBJECTS_DIR to a different value in your profile. OBJECTS_DIR: $$OBJECTS_DIR") + } } diff --git a/mkspecs/features/symbian/platform_paths.prf b/mkspecs/features/symbian/platform_paths.prf index a55e842..f05a885 100644 --- a/mkspecs/features/symbian/platform_paths.prf +++ b/mkspecs/features/symbian/platform_paths.prf @@ -50,6 +50,12 @@ # # ============================================================================== +symbian-abld|symbian-sbsv2 { + epocroot_prefix = / +} else { + epocroot_prefix = $${EPOCROOT} +} + exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # Load platform specific paths @@ -66,10 +72,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(APP_LAYER_SDK_EXPORT_PATH) { - return (/epoc32/include/app/$$1) + return ($${epocroot_prefix}epoc32/include/app/$$1) } defineReplace(APP_LAYER_PUBLIC_EXPORT_PATH) { - return (/epoc32/include/app/$$1) + return ($${epocroot_prefix}epoc32/include/app/$$1) } # --------------------------------------- @@ -77,10 +83,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(APP_LAYER_DOMAIN_EXPORT_PATH) { - return (/epoc32/include/platform/app/$$1) + return ($${epocroot_prefix}epoc32/include/platform/app/$$1) } defineReplace(APP_LAYER_PLATFORM_EXPORT_PATH) { - return (/epoc32/include/platform/app/$$1) + return ($${epocroot_prefix}epoc32/include/platform/app/$$1) } # --------------------------------------- @@ -88,10 +94,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(MW_LAYER_SDK_EXPORT_PATH) { - return (/epoc32/include/mw/$$1) + return ($${epocroot_prefix}epoc32/include/mw/$$1) } defineReplace(MW_LAYER_PUBLIC_EXPORT_PATH) { - return (/epoc32/include/mw/$$1) + return ($${epocroot_prefix}epoc32/include/mw/$$1) } # --------------------------------------- @@ -99,10 +105,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(MW_LAYER_DOMAIN_EXPORT_PATH) { - return (/epoc32/include/platform/mw/$$1) + return ($${epocroot_prefix}epoc32/include/platform/mw/$$1) } defineReplace(MW_LAYER_PLATFORM_EXPORT_PATH) { - return (/epoc32/include/platform/mw/$$1) + return ($${epocroot_prefix}epoc32/include/platform/mw/$$1) } # --------------------------------------- @@ -110,11 +116,11 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(OSEXT_LAYER_SDK_EXPORT_PATH) { - return (/epoc32/include/$$1) + return ($${epocroot_prefix}epoc32/include/$$1) } # WARNING: If the following path changes see the exists() function around line 219 defineReplace(OS_LAYER_PUBLIC_EXPORT_PATH) { - return (/epoc32/include/$$1) + return ($${epocroot_prefix}epoc32/include/$$1) } # --------------------------------------- @@ -122,10 +128,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(OSEXT_LAYER_DOMAIN_EXPORT_PATH) { - return (/epoc32/include/platform/$$1) + return ($${epocroot_prefix}epoc32/include/platform/$$1) } defineReplace(OS_LAYER_PLATFORM_EXPORT_PATH) { - return (/epoc32/include/platform/$$1) + return ($${epocroot_prefix}epoc32/include/platform/$$1) } # --------------------------------------- @@ -152,18 +158,18 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # the headers come from middleware or os-layer => thus they are first. APP_LAYER_SYSTEMINCLUDE = \ - /epoc32/include \ - /epoc32/include/mw \ - /epoc32/include/platform/mw \ - /epoc32/include/platform \ - /epoc32/include/app \ - /epoc32/include/platform/app \ - /epoc32/include/platform/loc \ - /epoc32/include/platform/mw/loc \ - /epoc32/include/platform/app/loc \ - /epoc32/include/platform/loc/sc \ - /epoc32/include/platform/mw/loc/sc \ - /epoc32/include/platform/app/loc/sc + $${epocroot_prefix}epoc32/include \ + $${epocroot_prefix}epoc32/include/mw \ + $${epocroot_prefix}epoc32/include/platform/mw \ + $${epocroot_prefix}epoc32/include/platform \ + $${epocroot_prefix}epoc32/include/app \ + $${epocroot_prefix}epoc32/include/platform/app \ + $${epocroot_prefix}epoc32/include/platform/loc \ + $${epocroot_prefix}epoc32/include/platform/mw/loc \ + $${epocroot_prefix}epoc32/include/platform/app/loc \ + $${epocroot_prefix}epoc32/include/platform/loc/sc \ + $${epocroot_prefix}epoc32/include/platform/mw/loc/sc \ + $${epocroot_prefix}epoc32/include/platform/app/loc/sc # This define statements defines the include paths, which are intended to be # used in the pro-files that are part of the middleware-layer. It includes all @@ -171,14 +177,14 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # middleware-layer components. MW_LAYER_SYSTEMINCLUDE = \ - /epoc32/include \ - /epoc32/include/mw \ - /epoc32/include/platform/mw \ - /epoc32/include/platform \ - /epoc32/include/platform/loc \ - /epoc32/include/platform/mw/loc \ - /epoc32/include/platform/loc/sc \ - /epoc32/include/platform/mw/loc/sc + $${epocroot_prefix}epoc32/include \ + $${epocroot_prefix}epoc32/include/mw \ + $${epocroot_prefix}epoc32/include/platform/mw \ + $${epocroot_prefix}epoc32/include/platform \ + $${epocroot_prefix}epoc32/include/platform/loc \ + $${epocroot_prefix}epoc32/include/platform/mw/loc \ + $${epocroot_prefix}epoc32/include/platform/loc/sc \ + $${epocroot_prefix}epoc32/include/platform/mw/loc/sc # This define statements defines the include paths, which are intended to be # used in the pro-files that are part of the osextensions-layer. It includes all @@ -186,10 +192,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # os-layer components. OS_LAYER_SYSTEMINCLUDE = \ - /epoc32/include \ - /epoc32/include/platform \ - /epoc32/include/platform/loc \ - /epoc32/include/platform/loc/sc + $${epocroot_prefix}epoc32/include \ + $${epocroot_prefix}epoc32/include/platform \ + $${epocroot_prefix}epoc32/include/platform/loc \ + $${epocroot_prefix}epoc32/include/platform/loc/sc # This define statements defines the include paths, which are intended to be # used in the pro-files that are part of the os-layer. This is intended @@ -198,7 +204,7 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # 2 files already contain the /epoc32/include as system include path. OS_LAYER_KERNEL_SYSTEMINCLUDE = \ - /epoc32/include/platform + $${epocroot_prefix}epoc32/include/platform # --------------------------------------- @@ -237,10 +243,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(APP_LAYER_SDK_EXPORT_PATH) { - return (/epoc32/include/applications/$$1) + return ($${epocroot_prefix}epoc32/include/applications/$$1) } defineReplace(APP_LAYER_PUBLIC_EXPORT_PATH) { - return (/epoc32/include/applications/$$1) + return ($${epocroot_prefix}epoc32/include/applications/$$1) } # --------------------------------------- @@ -248,10 +254,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(APP_LAYER_DOMAIN_EXPORT_PATH) { - return (/epoc32/include/domain/applications/$$1) + return ($${epocroot_prefix}epoc32/include/domain/applications/$$1) } defineReplace(APP_LAYER_PLATFORM_EXPORT_PATH) { - return (/epoc32/include/domain/applications/$$1) + return ($${epocroot_prefix}epoc32/include/domain/applications/$$1) } # --------------------------------------- @@ -259,10 +265,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(MW_LAYER_SDK_EXPORT_PATH) { - return (/epoc32/include/middleware/$$1) + return ($${epocroot_prefix}epoc32/include/middleware/$$1) } defineReplace(MW_LAYER_PUBLIC_EXPORT_PATH) { - return (/epoc32/include/middleware/$$1) + return ($${epocroot_prefix}epoc32/include/middleware/$$1) } # --------------------------------------- @@ -270,10 +276,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(MW_LAYER_DOMAIN_EXPORT_PATH) { - return (/epoc32/include/domain/middleware/$$1) + return ($${epocroot_prefix}epoc32/include/domain/middleware/$$1) } defineReplace(MW_LAYER_PLATFORM_EXPORT_PATH) { - return (/epoc32/include/domain/middleware/$$1) + return ($${epocroot_prefix}epoc32/include/domain/middleware/$$1) } # --------------------------------------- @@ -281,11 +287,11 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(OSEXT_LAYER_SDK_EXPORT_PATH) { - return (/epoc32/include/osextensions/$$1) + return ($${epocroot_prefix}epoc32/include/osextensions/$$1) } # WARNING: If the following path changes see the exists() function around line 430 defineReplace(OS_LAYER_PUBLIC_EXPORT_PATH) { - return (/epoc32/include/osextensions/$$1) + return ($${epocroot_prefix}epoc32/include/osextensions/$$1) } # --------------------------------------- @@ -293,10 +299,10 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(OSEXT_LAYER_DOMAIN_EXPORT_PATH) { - return (/epoc32/include/domain/osextensions/$$1) + return ($${epocroot_prefix}epoc32/include/domain/osextensions/$$1) } defineReplace(OS_LAYER_PLATFORM_EXPORT_PATH) { - return (/epoc32/include/domain/osextensions/$$1) + return ($${epocroot_prefix}epoc32/include/domain/osextensions/$$1) } # --------------------------------------- @@ -323,20 +329,20 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # the headers come from middleware or os-layer => thus they are first. APP_LAYER_SYSTEMINCLUDE = \ - /epoc32/include \ - /epoc32/include/oem \ - /epoc32/include/middleware \ - /epoc32/include/domain/middleware \ - /epoc32/include/osextensions \ - /epoc32/include/domain/osextensions \ - /epoc32/include/applications \ - /epoc32/include/domain/applications \ - /epoc32/include/domain/osextensions/loc \ - /epoc32/include/domain/middleware/loc \ - /epoc32/include/domain/applications/loc \ - /epoc32/include/domain/osextensions/loc/sc \ - /epoc32/include/domain/middleware/loc/sc \ - /epoc32/include/domain/applications/loc/sc + $${epocroot_prefix}epoc32/include \ + $${epocroot_prefix}epoc32/include/oem \ + $${epocroot_prefix}epoc32/include/middleware \ + $${epocroot_prefix}epoc32/include/domain/middleware \ + $${epocroot_prefix}epoc32/include/osextensions \ + $${epocroot_prefix}epoc32/include/domain/osextensions \ + $${epocroot_prefix}epoc32/include/applications \ + $${epocroot_prefix}epoc32/include/domain/applications \ + $${epocroot_prefix}epoc32/include/domain/osextensions/loc \ + $${epocroot_prefix}epoc32/include/domain/middleware/loc \ + $${epocroot_prefix}epoc32/include/domain/applications/loc \ + $${epocroot_prefix}epoc32/include/domain/osextensions/loc/sc \ + $${epocroot_prefix}epoc32/include/domain/middleware/loc/sc \ + $${epocroot_prefix}epoc32/include/domain/applications/loc/sc # This define statements defines the include paths, which are intended to be # used in the pro-files that are part of the middleware-layer. It includes all @@ -344,16 +350,16 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # middleware-layer components. MW_LAYER_SYSTEMINCLUDE = \ - /epoc32/include \ - /epoc32/include/oem \ - /epoc32/include/middleware \ - /epoc32/include/domain/middleware \ - /epoc32/include/osextensions \ - /epoc32/include/domain/osextensions \ - /epoc32/include/domain/osextensions/loc \ - /epoc32/include/domain/middleware/loc \ - /epoc32/include/domain/osextensions/loc/sc \ - /epoc32/include/domain/middleware/loc/sc + $${epocroot_prefix}epoc32/include \ + $${epocroot_prefix}epoc32/include/oem \ + $${epocroot_prefix}epoc32/include/middleware \ + $${epocroot_prefix}epoc32/include/domain/middleware \ + $${epocroot_prefix}epoc32/include/osextensions \ + $${epocroot_prefix}epoc32/include/domain/osextensions \ + $${epocroot_prefix}epoc32/include/domain/osextensions/loc \ + $${epocroot_prefix}epoc32/include/domain/middleware/loc \ + $${epocroot_prefix}epoc32/include/domain/osextensions/loc/sc \ + $${epocroot_prefix}epoc32/include/domain/middleware/loc/sc # This define statements defines the include paths, which are intended to be # used in the pro-files that are part of the osextensions-layer. It includes all @@ -361,12 +367,12 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # os-layer components. OS_LAYER_SYSTEMINCLUDE = \ - /epoc32/include \ - /epoc32/include/oem \ - /epoc32/include/osextensions \ - /epoc32/include/domain/osextensions \ - /epoc32/include/domain/osextensions/loc \ - /epoc32/include/domain/osextensions/loc/sc + $${epocroot_prefix}epoc32/include \ + $${epocroot_prefix}epoc32/include/oem \ + $${epocroot_prefix}epoc32/include/osextensions \ + $${epocroot_prefix}epoc32/include/domain/osextensions \ + $${epocroot_prefix}epoc32/include/domain/osextensions/loc \ + $${epocroot_prefix}epoc32/include/domain/osextensions/loc/sc # This define statements defines the include paths, which are intended to be # used in the pro-files that are part of the os-layer. This is intended @@ -375,9 +381,9 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # 2 files already contain the /epoc32/include as system include path. OS_LAYER_KERNEL_SYSTEMINCLUDE = \ - /epoc32/include/oem \ - /epoc32/include/osextensions \ - /epoc32/include/domain/osextensions + $${epocroot_prefix}epoc32/include/oem \ + $${epocroot_prefix}epoc32/include/osextensions \ + $${epocroot_prefix}epoc32/include/domain/osextensions # --------------------------------------- @@ -387,41 +393,41 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { OS_LAYER_LIBC_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis) \ $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/sys) \ - /epoc32/include/stdapis \ - /epoc32/include/stdapis/sys + $${epocroot_prefix}epoc32/include/stdapis \ + $${epocroot_prefix}epoc32/include/stdapis/sys OS_LAYER_GLIB_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/glib-2.0) \ $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/glib-2.0/glib) \ $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/glib-2.0/gObject) \ - /epoc32/include/stdapis/glib-2.0 \ - /epoc32/include/stdapis/glib-2.0/glib \ - /epoc32/include/stdapis/glib-2.0/gObject + $${epocroot_prefix}epoc32/include/stdapis/glib-2.0 \ + $${epocroot_prefix}epoc32/include/stdapis/glib-2.0/glib \ + $${epocroot_prefix}epoc32/include/stdapis/glib-2.0/gObject OS_LAYER_SSL_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/openssl) \ - /epoc32/include/stdapis/openssl + $${epocroot_prefix}epoc32/include/stdapis/openssl # stlportv5 is preferred over stlport as it has the throwing version of operator new OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlportv5) \ - /epoc32/include/stdapis/stlportv5 + $${epocroot_prefix}epoc32/include/stdapis/stlportv5 exists($${EPOCROOT}epoc32/include/osextensions/stdapis/stlport) \ |exists($${EPOCROOT}epoc32/include/stdapis/stlport) { !exists($${EPOCROOT}epoc32/include/osextensions/stdapis/stlportv5) \ :!exists($${EPOCROOT}epoc32/include/stdapis/stlportv5) { OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlport) \ - /epoc32/include/stdapis/stlport + $${epocroot_prefix}epoc32/include/stdapis/stlport } } OS_LAYER_BOOST_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/boost) \ - /epoc32/include/stdapis/boost + $${epocroot_prefix}epoc32/include/stdapis/boost OS_LAYER_DBUS_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/dbus-1.0) \ $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/dbus-1.0/dbus) \ - /epoc32/include/stdapis/dbus-1.0 \ - /epoc32/include/stdapis/dbus-1.0/dbus + $${epocroot_prefix}epoc32/include/stdapis/dbus-1.0 \ + $${epocroot_prefix}epoc32/include/stdapis/dbus-1.0/dbus OS_LAYER_LIBUTILITY_SYSTEMINCLUDE = $$OS_LAYER_PLATFORM_EXPORT_PATH(stdapis/utility) \ - /epoc32/include/stdapis/utility + $${epocroot_prefix}epoc32/include/stdapis/utility } @@ -433,31 +439,31 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # --------------------------------------- defineReplace(CORE_APP_LAYER_IBY_EXPORT_PATH) { - return(/epoc32/rom/include/core/app/$$1) + return($${epocroot_prefix}epoc32/rom/include/core/app/$$1) } defineReplace(CORE_MW_LAYER_IBY_EXPORT_PATH) { - return(/epoc32/rom/include/core/mw/$$1) + return($${epocroot_prefix}epoc32/rom/include/core/mw/$$1) } defineReplace(LANGUAGE_APP_LAYER_IBY_EXPORT_PATH) { - return(/epoc32/rom/include/language/app/$$1) + return($${epocroot_prefix}epoc32/rom/include/language/app/$$1) } defineReplace(LANGUAGE_MW_LAYER_IBY_EXPORT_PATH) { - return(/epoc32/rom/include/language/mw/$$1) + return($${epocroot_prefix}epoc32/rom/include/language/mw/$$1) } defineReplace(CUSTOMER_APP_LAYER_IBY_EXPORT_PATH) { - return(/epoc32/rom/include/customer/app/$$1) + return($${epocroot_prefix}epoc32/rom/include/customer/app/$$1) } defineReplace(CUSTOMER_MW_LAYER_IBY_EXPORT_PATH) { - return(/epoc32/rom/include/customer/mw/$$1) + return($${epocroot_prefix}epoc32/rom/include/customer/mw/$$1) } defineReplace(CUSTOMER_VARIANT_APP_LAYER_IBY_EXPORT_PATH) { - return(/epoc32/rom/include/customervariant/app/$$1) + return($${epocroot_prefix}epoc32/rom/include/customervariant/app/$$1) } defineReplace(CUSTOMER_VARIANT_MW_LAYER_IBY_EXPORT_PATH) { - return(/epoc32/rom/include/customervariant/mw/$$1) + return($${epocroot_prefix}epoc32/rom/include/customervariant/mw/$$1) } # You need to define the following in pro-file, if you are using the stllib: @@ -468,5 +474,4 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { } - - +epocroot_prefix = diff --git a/mkspecs/features/symbian/qt.prf b/mkspecs/features/symbian/qt.prf index 02b3003..294a68c 100644 --- a/mkspecs/features/symbian/qt.prf +++ b/mkspecs/features/symbian/qt.prf @@ -40,116 +40,8 @@ contains(CONFIG, qt):!contains(TARGET.UID3, 0x2001E61C):!contains(TARGET.UID3, 0 isEmpty(TARGET.EPOCSTACKSIZE):TARGET.EPOCSTACKSIZE = 0x14000 isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x020000 0x800000 -# Sis file creation -make_cache_name = .make.cache -!symbian-abld:!symbian-sbsv2 { - fixedDestdir = $$DESTDIR - !isEmpty(fixedDestdir):!contains(fixedDestdir, "[/\\]$"):fixedDestdir = $${fixedDestdir}/ - contains(QMAKE_HOST.os, "Windows"):fixedDestdir = $$replace(fixedDestdir, "/", "\\") -} else { - fixedDestdir = -} - -sis_target.target = sis -sis_target.commands = $(if $(wildcard $$basename(TARGET)_template.pkg), \ - $(if $(wildcard $$make_cache_name), \ - $(MAKE) -f $(MAKEFILE) ok_sis MAKEFILES=$$make_cache_name \ - , \ - $(if $(QT_SIS_TARGET), \ - $(MAKE) -f $(MAKEFILE) ok_sis \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nocache \ - ) \ - ) \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ - ) - -ok_sis_target.target = ok_sis -ok_sis_target.commands = createpackage.bat $(QT_SIS_OPTIONS) $$basename(TARGET)_template.pkg \ - $(QT_SIS_TARGET) $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) - -target_sis_target.target = $${fixedDestdir}$${TARGET}.sis -target_sis_target.commands = $(MAKE) -f $(MAKEFILE) sis - -installer_sis_target.target = installer_sis -installer_sis_target.commands = $(if $(wildcard $$basename(TARGET)_installer.pkg), \ - $(MAKE) -f $(MAKEFILE) ok_installer_sis \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ - ) -installer_sis_target.depends = $${fixedDestdir}$${TARGET}.sis - -ok_installer_sis_target.target = ok_installer_sis -ok_installer_sis_target.commands = createpackage.bat $(QT_SIS_OPTIONS) $$basename(TARGET)_installer.pkg - \ - $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) - -fail_sis_nopkg_target.target = fail_sis_nopkg -fail_sis_nopkg_target.commands = "$(error PKG file does not exist, 'sis' and 'installer_sis' target are only supported for executables or projects with DEPLOYMENT statement)" - -fail_sis_nocache_target.target = fail_sis_nocache -fail_sis_nocache_target.commands = "$(error Project has to be built or QT_SIS_TARGET environment variable has to be set before calling 'SIS' target)" - -symbian-abld|symbian-sbsv2 { - # Only enable stub_sis files for the abld/sbsv2 build systems for now, since we don't - # support ROM builds for any other Symbian build system. - stub_sis_target.target = stub_sis - stub_sis_target.commands = $(if $(wildcard $$basename(TARGET)_template.pkg), \ - $(if $(wildcard $$make_cache_name), \ - $(MAKE) -f $(MAKEFILE) ok_stub_sis MAKEFILES=$$make_cache_name \ - , \ - $(if $(QT_SIS_TARGET), \ - $(MAKE) -f $(MAKEFILE) ok_stub_sis \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nocache \ - ) \ - ) \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ - ) - - ok_stub_sis_target.target = ok_stub_sis - ok_stub_sis_target.commands = createpackage.bat -s $(QT_SIS_OPTIONS) $$basename(TARGET)_template.pkg \ - $(QT_SIS_TARGET) $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) - - QMAKE_EXTRA_TARGETS += stub_sis_target \ - ok_stub_sis_target -} else { - # DESTDIR is not honored on abld and sbsv2 - !isEmpty(DESTDIR) { - ok_sis_target.commands += && $$QMAKE_MOVE $$basename(TARGET).sis $$DESTDIR - ok_installer_sis_target.commands += && $$QMAKE_MOVE $$basename(TARGET).sis $$DESTDIR - } -} - -QMAKE_EXTRA_TARGETS += sis_target \ - ok_sis_target \ - target_sis_target \ - installer_sis_target \ - ok_installer_sis_target \ - fail_sis_nopkg_target \ - fail_sis_nocache_target - -# Sbsv2 has its own store_build target which is using flms. -!symbian-sbsv2 { - contains(QMAKE_HOST.os, "Windows") { - shellFixedHash = $${LITERAL_HASH} - } else { - shellFixedHash = \\$${LITERAL_HASH} - } - store_build_target.target = store_build - store_build_target.commands = \ - @echo $${shellFixedHash} ============================================================================== > $$make_cache_name \ - && echo $${shellFixedHash} This file is generated by make and should not be modified by the user >> $$make_cache_name \ - && echo $${shellFixedHash} Name : $$make_cache_name >> $$make_cache_name \ - && echo $${shellFixedHash} Part of : lineedits >> $$make_cache_name \ - && echo $${shellFixedHash} Description : This file is used to cache last build target for >> $$make_cache_name \ - && echo $${shellFixedHash} make sis target. >> $$make_cache_name \ - && echo $${shellFixedHash} Version : >> $$make_cache_name \ - && echo $${shellFixedHash} >> $$make_cache_name \ - && echo $${shellFixedHash} ============================================================================== >> $$make_cache_name \ - && echo. >> $$make_cache_name \ - && echo QT_SIS_TARGET ?= $(QT_SIS_TARGET) >> $$make_cache_name - - QMAKE_EXTRA_TARGETS += store_build_target +# Workaround for the fact that Gnupoc and Symbian chose different approaches to +# the letter casing of headers. +contains(CONFIG, is_using_gnupoc) { + INCLUDEPATH += $$QT_SOURCE_TREE/mkspecs/common/symbian/header-wrappers } diff --git a/mkspecs/features/symbian/qt_config.prf b/mkspecs/features/symbian/qt_config.prf new file mode 100644 index 0000000..2f446dc --- /dev/null +++ b/mkspecs/features/symbian/qt_config.prf @@ -0,0 +1,9 @@ +load(qt_config) + +!contains(QMAKE_HOST.os, "Windows") { + # Test for the existence of lower cased headers, a sign of using Gnupoc. + # Note that the qmake "exists" test won't do because it is case insensitive. + system("test -f $${EPOCROOT}/epoc32/include/akndoc.h") { + CONFIG += is_using_gnupoc + } +} diff --git a/mkspecs/features/symbian/release.prf b/mkspecs/features/symbian/release.prf new file mode 100644 index 0000000..8164495 --- /dev/null +++ b/mkspecs/features/symbian/release.prf @@ -0,0 +1 @@ +QMAKE_LIBDIR += $${EPOCROOT}epoc32/release/armv5/urel diff --git a/mkspecs/features/symbian/symbian_building.prf b/mkspecs/features/symbian/symbian_building.prf new file mode 100644 index 0000000..9ccfd2f --- /dev/null +++ b/mkspecs/features/symbian/symbian_building.prf @@ -0,0 +1,277 @@ +# we have some module specific options (defined in qt.prf) lets add them +eval(TMPVAR = \$\$QMAKE_$${TARGET}_CXXFLAGS) +!isEmpty(TMPVAR):QMAKE_CXXFLAGS += $$TMPVAR +eval(TMPVAR = \$\$QMAKE_$${TARGET}_LFLAGS) +!isEmpty(TMPVAR) { + QMAKE_LFLAGS += $$TMPVAR +} else :linux-gcce { # lets provide a simple default. Without elf2e32 complains + QMAKE_LFLAGS += -Ttext 0x80000 -Tdata 0x400000 +} + +symbianObjdir=$$OBJECTS_DIR +isEmpty(symbianObjdir) { + symbianObjdir = . +} +symbianDestdir=$$DESTDIR +isEmpty(symbianDestdir) { + symbianDestdir = . +} + +contains(QMAKE_CFLAGS, "--thumb")|contains(QMAKE_CXXFLAGS, "--thumb")|contains(QMAKE_CFLAGS, "-mthumb")|contains(QMAKE_CXXFLAGS, "-mthumb") { + DEFINES += __MARM_THUMB__ +} + +defineReplace(processSymbianLibraries) { + library = $$replace(1, "\.dll$", ".dso") + library = $$replace(library, "^-l", "") + isFullName = $$find(library, \.) + isEmpty(isFullName):library="$${library}.dso" + linux-gcce { + newLIB = "-l:$${library}" + } else { + newLIB = "$${library}" + } + contains(library, "\.dso$")|contains(library, ".lib$"):PRE_TARGETDEPS += $$library + return($$newLIB) +} + +for(libraries, LIBS) { + newLIBS += $$processSymbianLibraries($$libraries) +} +LIBS = $$newLIBS +newLIBS = +for(libraries, QMAKE_LIBS) { + newLIBS += $$processSymbianLibraries($$libraries) +} +QMAKE_LIBS = $$newLIBS + +linux-gcce { + QMAKE_LIBS += -l:usrt2_2.lib \ + -l:dfpaeabi.dso \ + -l:drtaeabi.dso \ + -l:scppnwdl.dso \ + -lsupc++ \ + -lgcc +} + +elf2e32_LIBPATH = +for(libPath, QMAKE_LIBDIR) { + elf2e32_LIBPATH += "--libpath=$$libPath" +} + +isEmpty(VERSION) { + VERSION = $$QT_VERSION +} + +# Check for version validity. +!isEmpty(VERSION):!contains(VERSION, "[0-9]+"):!contains(VERSION, "[0-9]+\.[0-9]+")!contains(VERSION, "[0-9]+(\.[0-9]+){2}") { + error("Invalid VERSION for Symbian: $$VERSION") +} + +splitVersion = $$split(VERSION, ".") +count(splitVersion, 0) { + # Default Symbian version if none is specified. + hexVersion = "000a0000" + decVersion = "10.0" +} else { + count(splitVersion, 3) { + hexVersion = $$system("sh -c 'printf %02x $$member(splitVersion, 0)'") + hexPart2 = $$system("sh -c 'printf %02x $$member(splitVersion, 1)'")" + hexPart2 = $$hexPart2$$system("sh -c 'printf %02x $$member(splitVersion, 2)'")" + decVersion = $$system("sh -c 'printf %1d 0x$$hexVersion'"). + hexVersion = $$hexVersion$$hexPart2 + decVersion = $$decVersion$$system("sh -c 'printf %d 0x$$hexPart2'") + !contains(hexVersion, "[0-9a-f]{8}"):hexVersion = "00$${hexVersion}" + } else { # app code may have different numbering... + hexVersion = $$VERSION + decVersion = $$VERSION + } +} +#error ("hexVersion: $$hexVersion, decVersion: $$decVersion") + +intUid3 = $$lower($$replace(TARGET.UID3, "^0x", "")) +isEmpty(TARGET.SID):TARGET.SID = $$TARGET.UID3 +isEmpty(TARGET.UID2):TARGET.UID2 = 0x00000000 + +capability = $$replace(TARGET.CAPABILITY, " ", "+") +capability = $$join(capability, "+") +capability = $$replace(capability, "\+-", "-") +isEmpty(capability): capability = "None" +capability = "--capability=$$capability" + +contains(TEMPLATE, lib):!contains(CONFIG, static):!contains(CONFIG, staticlib) { + !isEmpty(QMAKE_POST_LINK) { + # No way to honor the '@' :-( + QMAKE_POST_LINK = $$replace(QMAKE_POST_LINK, "^@", "") + QMAKE_POST_LINK = && $$QMAKE_POST_LINK + } + # The tee and grep at the end work around the issue that elf2e32 doesn't return non-null on error. + # The comparison of dso files is to avoid extra building of modules that depend on this dso, in + # case it has not changed. + QMAKE_POST_LINK = $$QMAKE_MOVE $$symbianDestdir/$${TARGET}.dll $$symbianDestdir/$${TARGET}.sym \ + && elf2e32 --version=$$decVersion --sid=$$TARGET.SID --uid1=0x10000079 \ + --uid2=$$TARGET.UID2 --uid3=$$TARGET.UID3 --dlldata --heap=0x00020000,0x00800000 \ + --stack=0x00014000 --fpu=softvfp --targettype=DLL \ + --elfinput=$${symbianDestdir}/$${TARGET}.sym --output=$${symbianDestdir}/$${TARGET}.dll \ + --dso=$$symbianObjdir/$${TARGET}.dso --defoutput=$$symbianObjdir/$${TARGET}.def \ + --unfrozen --linkas=$${TARGET}\\{$${hexVersion}\\}\\[$${intUid3}\\].dll \ + --compressionmethod bytepair $$elf2e32_LIBPATH --unpaged $$capability \ + $$QMAKE_ELF2E32_FLAGS \ + | tee elf2e32.log && test `grep -c 'Error:' elf2e32.log` = 0 && rm elf2e32.log \ + && if ! diff -q $${symbianObjdir}/$${TARGET}.dso $${symbianDestdir}/$${TARGET}.dso \ + > /dev/null 2>&1; then \ + $$QMAKE_COPY $${symbianObjdir}/$${TARGET}.dso $${symbianDestdir}/$${TARGET}.dso; \ + fi \ + $$QMAKE_POST_LINK + QMAKE_DISTCLEAN += $${symbianDestdir}/$${TARGET}.sym + QMAKE_DISTCLEAN += $${symbianDestdir}/$${TARGET}.dso + QMAKE_CLEAN += $${symbianObjdir}/$${TARGET}.dso + QMAKE_CLEAN += $${symbianObjdir}/$${TARGET}.def + + linux-armcc: { + QMAKE_LIBS += -ledllstub.lib -ledll.lib\\(uc_dll_.o\\) + } else :linux-gcce { + #QMAKE_LIBS += -l:edllstub.lib -l:edll.lib + } + + QMAKE_LFLAGS += --soname $${TARGET}\\{$${hexVersion}\\}\\[$${intUid3}\\].dll + DEFINES += __DLL__ +} + +contains(TEMPLATE, app):!contains(QMAKE_LINK, "^@.*") { + !isEmpty(QMAKE_POST_LINK) { + # No way to honor the '@' :-( + QMAKE_POST_LINK = $$replace(QMAKE_POST_LINK, "^@", "") + QMAKE_POST_LINK = && $$QMAKE_POST_LINK + } + # the tee and grep at the end work around the issue that elf2e32 doesn't return non-null on error + QMAKE_POST_LINK = $$QMAKE_MOVE $$symbianDestdir/$${TARGET} $$symbianDestdir/$${TARGET}.sym \ + && elf2e32 --version $$decVersion --sid=$$TARGET.SID --uid1=0x1000007a \ + --uid2=$$TARGET.UID2 --uid3=$$TARGET.UID3 --dlldata --heap=0x00020000,0x00800000 \ + --stack=0x00014000 --fpu=softvfp --targettype=EXE \ + --elfinput=$${symbianDestdir}/$${TARGET}.sym --output=$${symbianDestdir}/$${TARGET}.exe \ + --unfrozen --linkas=$${TARGET}\\{$${hexVersion}\\}\\[$${intUid3}\\].exe \ + --compressionmethod bytepair $$elf2e32_LIBPATH --unpaged $$capability \ + $$QMAKE_ELF2E32_FLAGS \ + | tee elf2e32.log && test `grep -c 'Error:' elf2e32.log` = 0 && rm elf2e32.log \ + && ln "$${symbianDestdir}/$${TARGET}.exe" "$${symbianDestdir}/$$TARGET" \ + $$QMAKE_POST_LINK + QMAKE_DISTCLEAN += $${symbianDestdir}/$${TARGET}.sym + QMAKE_DISTCLEAN += $${symbianDestdir}/$${TARGET}.exe + QMAKE_CLEAN += $${symbianDestdir}/$${TARGET} + + linux-armcc: { + QMAKE_LIBS += -leexe.lib\\(uc_exe_.o\\) + } else :linux-gcce { + #QMAKE_LIBS += -l:eexe.lib + } + + QMAKE_LFLAGS += --soname $${TARGET}\\{$${hexVersion}\\}\\[$${intUid3}\\].exe +# TODO gcce added --shared here... + DEFINES += __EXE__ +} + +# Symbian resource files +linux-armcc: { + SYMBIAN_RVCT22INC=$$(RVCT22INC) + !isEmpty(SYMBIAN_RVCT22INC):symbian_resources_INCLUDES = -I$${SYMBIAN_RVCT22INC} +} +symbian_resources_INCLUDES = $$replace(symbian_resources_INCLUDES, ",", " -I") +symbian_resources_INCLUDES += $$join(INCLUDEPATH, " -I", "-I") +symbian_resources_DEFINES = $$join(DEFINES, " -D", "-D") +symbian_resources_RCC_DIR = $$replace(RCC_DIR, "/$", "") +symbian_resources_INCLUDES += "-I $$symbian_resources_RCC_DIR" + +for(symbian_resource, SYMBIAN_RESOURCES) { + symbian_resource = $$basename(symbian_resource) + symbian_resource_clean = $$replace(symbian_resource, "\.rss$", ".rsc") + QMAKE_DISTCLEAN += $${symbianDestdir}/$${symbian_resource_clean} + symbian_resource_clean = $$replace(symbian_resource, "\.rss$", ".rpp") + QMAKE_CLEAN += $${symbian_resources_RCC_DIR}/$${symbian_resource_clean} +} + +symbianresources.input = SYMBIAN_RESOURCES +symbianresources.output = $$symbian_resources_RCC_DIR/${QMAKE_FILE_BASE}.rsg +symbianresources.commands = cpp -nostdinc -undef \ + $$symbian_resources_INCLUDES \ + $$symbian_resources_DEFINES \ + ${QMAKE_FILE_NAME} \ + -o $${symbian_resources_RCC_DIR}/${QMAKE_FILE_BASE}.rpp \ + && rcomp -u -m045,046,047 \ + -s$${symbian_resources_RCC_DIR}/${QMAKE_FILE_BASE}.rpp \ + -o$${symbianDestdir}/${QMAKE_FILE_BASE}.rsc \ + -h$${symbian_resources_RCC_DIR}/${QMAKE_FILE_BASE}.rsg \ + -i${QMAKE_FILE_NAME} +symbianresources.dependency_type = TYPE_C +symbianresources.CONFIG = no_link target_predeps + +QMAKE_EXTRA_COMPILERS += symbianresources + +contains(TEMPLATE, "app"):!contains(CONFIG, "no_icon") { + baseTarget = $$basename(TARGET) + # If you change this, also see application_icon.prf + baseTarget = $$replace(baseTarget, " ",_) + + # Make our own extra target in order to get dependencies for generated + # files right. This also avoids the warning about files not found. + symbianGenResource.target = $${symbian_resources_RCC_DIR}/$${baseTarget}.rsg + symbianGenResource.commands = cpp -nostdinc -undef \ + $$symbian_resources_INCLUDES \ + $$symbian_resources_DEFINES \ + $${baseTarget}.rss \ + -o $${symbian_resources_RCC_DIR}/$${baseTarget}.rpp \ + && rcomp -u -m045,046,047 \ + -s$${symbian_resources_RCC_DIR}/$${baseTarget}.rpp \ + -o$${symbianDestdir}/$${baseTarget}.rsc \ + -h$${symbian_resources_RCC_DIR}/$${baseTarget}.rsg \ + -i$${baseTarget}.rss + symbianGenResource.depends = $${baseTarget}.rss + PRE_TARGETDEPS += $${symbian_resources_RCC_DIR}/$${baseTarget}.rsg + QMAKE_CLEAN += $${symbian_resources_RCC_DIR}/$${baseTarget}.rsg + QMAKE_CLEAN += $${symbian_resources_RCC_DIR}/$${baseTarget}.rpp + QMAKE_DISTCLEAN += $${baseTarget}.rss + QMAKE_DISTCLEAN += $${symbianDestdir}/$${baseTarget}.rsc + + symbianGenRegResource.target = $${symbian_resources_RCC_DIR}/$${baseTarget}_reg.rsg + symbianGenRegResource.commands = cpp -nostdinc -undef \ + $$symbian_resources_INCLUDES \ + $$symbian_resources_DEFINES \ + $${baseTarget}_reg.rss \ + -o $${symbian_resources_RCC_DIR}/$${baseTarget}_reg.rpp \ + && rcomp -u -m045,046,047 \ + -s$${symbian_resources_RCC_DIR}/$${baseTarget}_reg.rpp \ + -o$${symbianDestdir}/$${baseTarget}_reg.rsc \ + -h$${symbian_resources_RCC_DIR}/$${baseTarget}_reg.rsg \ + -i$${baseTarget}_reg.rss + symbianGenRegResource.depends = $${baseTarget}_reg.rss $${symbian_resources_RCC_DIR}/$${baseTarget}.rsg + PRE_TARGETDEPS += $${symbian_resources_RCC_DIR}/$${baseTarget}_reg.rsg + QMAKE_CLEAN += $${symbian_resources_RCC_DIR}/$${baseTarget}_reg.rsg + QMAKE_CLEAN += $${symbian_resources_RCC_DIR}/$${baseTarget}_reg.rpp + QMAKE_DISTCLEAN += $${TARGET}_reg.rss + QMAKE_DISTCLEAN += $${symbianDestdir}/$${TARGET}_reg.rsc + + # Trick to get qmake to create the RCC_DIR for us. + symbianRccDirCreation.input = SOURCES + symbianRccDirCreation.commands = + symbianRccDirCreation.output = $${symbian_resources_RCC_DIR}/symbian_resource_dummy + symbianRccDirCreation.CONFIG = no_link combine + + QMAKE_EXTRA_TARGETS += symbianGenResource symbianGenRegResource + QMAKE_EXTRA_COMPILERS += symbianRccDirCreation + + QMAKE_DISTCLEAN += $${TARGET}.loc +} + +# Generated pkg files + +QMAKE_DISTCLEAN += $${TARGET}_template.pkg + +# Pre 2.6.23 Linux kernels have a limit on the environment size that can be passed to +# a forked process. We quite easily overstep this boundary when building big projects +# on Symbian, and since we depend on running the system() command, this causes the build +# to fail. Test here that system() can be successfully run. It is important that this +# check happens as late as possible, otherwise it will not be caught. +execve_sanity_test = $$system("echo testing") +!contains(execve_sanity_test, "testing") { + error("Running system() failed. Maybe your kernel is too old? (Linux kernels need at least version 2.6.23)") +} diff --git a/mkspecs/features/symbian/thread.prf b/mkspecs/features/symbian/thread.prf new file mode 100644 index 0000000..885438a --- /dev/null +++ b/mkspecs/features/symbian/thread.prf @@ -0,0 +1,2 @@ +# Symbian behaves like POSIX when it comes to threads. +include(../unix/thread.prf) diff --git a/mkspecs/symbian-abld/qmake.conf b/mkspecs/symbian-abld/qmake.conf index 33b897d..fe9cd60 100644 --- a/mkspecs/symbian-abld/qmake.conf +++ b/mkspecs/symbian-abld/qmake.conf @@ -7,4 +7,4 @@ MAKEFILE_GENERATOR = SYMBIAN_ABLD option(recursive) -include(../common/symbian/symbian.conf) +include(../common/symbian/symbian-mmp.conf) diff --git a/mkspecs/symbian-sbsv2/flm/qt/qmake_extra_pre_targetdep.flm b/mkspecs/symbian-sbsv2/flm/qt/qmake_extra_pre_targetdep.flm index daf33d4..1338515 100644 --- a/mkspecs/symbian-sbsv2/flm/qt/qmake_extra_pre_targetdep.flm +++ b/mkspecs/symbian-sbsv2/flm/qt/qmake_extra_pre_targetdep.flm @@ -10,6 +10,8 @@ SINGLETON:=$(call sanitise,TARGET_$(PREDEP_TARGET)) +$(call makepathfor,$(PREDEP_TARGET)) + define qmake_extra_pre_targetdep EXPORT:: $(PREDEP_TARGET) diff --git a/mkspecs/symbian-sbsv2/qmake.conf b/mkspecs/symbian-sbsv2/qmake.conf index 585e645..73d3ee3 100644 --- a/mkspecs/symbian-sbsv2/qmake.conf +++ b/mkspecs/symbian-sbsv2/qmake.conf @@ -7,4 +7,4 @@ MAKEFILE_GENERATOR = SYMBIAN_SBSV2 option(recursive) -include(../common/symbian/symbian.conf) +include(../common/symbian/symbian-mmp.conf) diff --git a/mkspecs/symbian/linux-armcc/features/default_post.prf b/mkspecs/symbian/linux-armcc/features/default_post.prf new file mode 100644 index 0000000..7aa1f4d --- /dev/null +++ b/mkspecs/symbian/linux-armcc/features/default_post.prf @@ -0,0 +1,5 @@ +load(default_post.prf) + +# It is important that this config be executed last, +# and qmake does them in reverse order. +CONFIG = symbian_building $$CONFIG diff --git a/mkspecs/symbian/linux-armcc/qmake.conf b/mkspecs/symbian/linux-armcc/qmake.conf new file mode 100644 index 0000000..6042fa4 --- /dev/null +++ b/mkspecs/symbian/linux-armcc/qmake.conf @@ -0,0 +1,54 @@ +# +# qmake configuration for symbian/linux-armcc +# + +include(../../common/symbian/symbian-makefile.conf) + +include(../../common/armcc.conf) + +QMAKE_LIBS += usrt2_2.lib dfpaeabi.dso dfprvct2_2.dso drtaeabi.dso scppnwdl.dso drtrvct2_2.dso h_t__uf.l\\(switch8.o\\) + +QMAKE_RVCT_LINKSTYLE = 1 + +# notice that the middle part of the following set of vars matches the TARGET content of the libs + +#QMAKE_qtmain_CXXFLAGS = --arm +#QMAKE_QtCore_CXXFLAGS = +QMAKE_QtGui_LFLAGS = "--rw-base 0x800000" +#QMAKE_QtDBus_CXXFLAGS = +#QMAKE_QtDeclarative_CXXFLAGS = +#QMAKE_QtMultimedia_CXXFLAGS = +#QMAKE_QtNetwork_CXXFLAGS = +#QMAKE_QtOpenGL_CXXFLAGS = +#QMAKE_QtOpenVG_CXXFLAGS = +#QMAKE_phonon_CXXFLAGS = +#QMAKE_QtScript_CXXFLAGS = +#QMAKE_QtScriptTools_CXXFLAGS = +#QMAKE_QtSql_CXXFLAGS = +#QMAKE_QtSvg_CXXFLAGS = +#QMAKE_QtTest_CXXFLAGS = +#QMAKE_QtXmlPatterns_CXXFLAGS = +#QMAKE_QtXml_CXXFLAGS = +# Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000. +QMAKE_QtWebKit_LFLAGS = --rw-base 0xE00000 + +QMAKE_CFLAGS += --dllimport_runtime --preinclude rvct2_2.h --diag_suppress 186,654,1300 --thumb --fpu softvfp --cpu 5T --enum_is_int -Ono_known_library --fpmode ieee_no_fenv --export_all_vtbl --no_vfe --apcs /inter $$QMAKE_CFLAGS.ARMCC +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS --no_parse_templates $$QMAKE_CXXFLAGS.ARMCC +QMAKE_LFLAGS += --symver_soname --diag_suppress 6331,6780 --bpabi --reloc --datacompressor=off --split --dll --no_scanlib +QMAKE_LFLAGS_APP += --entry _E32Startup +QMAKE_LFLAGS_SHLIB += --entry _E32Dll +QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB + +DEFINES += EKA2 \ + __ARMCC__ \ + __ARMcc_2__ \ + __ARMCC_2_2__ + +QMAKE_LIBDIR += $${EPOCROOT}epoc32/release/armv5/lib +QMAKE_LIBDIR *= $$(RVCT22LIB) + +INCLUDEPATH = $${EPOCROOT}epoc32/include \ + $${EPOCROOT}epoc32/include/rvct2_2 \ + $${EPOCROOT}epoc32/include/variant \ + $${EPOCROOT}epoc32/include/stdapis \ + $$INCLUDEPATH diff --git a/mkspecs/symbian/linux-armcc/qplatformdefs.h b/mkspecs/symbian/linux-armcc/qplatformdefs.h new file mode 100644 index 0000000..db67648 --- /dev/null +++ b/mkspecs/symbian/linux-armcc/qplatformdefs.h @@ -0,0 +1 @@ +#include "../../common/symbian/qplatformdefs.h" diff --git a/mkspecs/symbian/linux-gcce/features/default_post.prf b/mkspecs/symbian/linux-gcce/features/default_post.prf new file mode 100644 index 0000000..7aa1f4d --- /dev/null +++ b/mkspecs/symbian/linux-gcce/features/default_post.prf @@ -0,0 +1,5 @@ +load(default_post.prf) + +# It is important that this config be executed last, +# and qmake does them in reverse order. +CONFIG = symbian_building $$CONFIG diff --git a/mkspecs/symbian/linux-gcce/qmake.conf b/mkspecs/symbian/linux-gcce/qmake.conf new file mode 100644 index 0000000..de3791c --- /dev/null +++ b/mkspecs/symbian/linux-gcce/qmake.conf @@ -0,0 +1,92 @@ +# +# qmake configuration for symbian/linux-gcce +# + +include(../../common/symbian/symbian-makefile.conf) + +include(../../common/g++.conf) + +QMAKE_CC = arm-none-symbianelf-gcc +QMAKE_CXX = arm-none-symbianelf-g++ +QMAKE_LINK = arm-none-symbianelf-ld +QMAKE_LINK_SHLIB = arm-none-symbianelf-ld +QMAKE_LINK_C = arm-none-symbianelf-ld +QMAKE_LINK_C_SHLIB = arm-none-symbianelf-ld +QMAKE_AR = arm-none-symbianelf-ar cqs + +# gcce defaults to 'arm' instruction set. Lets use the better 'thumb' if possible +# notice that the middle part of the following set of vars matches the TARGET content of the libs + +QMAKE_qtmain_CXXFLAGS = -mthumb +QMAKE_QtCore_CXXFLAGS = -mthumb +QMAKE_QtGui_LFLAGS = -Ttext 0x8000 -Tdata 0xE00000 +QMAKE_QtDBus_CXXFLAGS = -mthumb +QMAKE_QtDeclarative_CXXFLAGS = -mthumb +QMAKE_QtMultimedia_CXXFLAGS = -mthumb +QMAKE_QtNetwork_CXXFLAGS = -mthumb +QMAKE_QtOpenGL_CXXFLAGS = -mthumb +QMAKE_QtOpenVG_CXXFLAGS = -mthumb +QMAKE_phonon_CXXFLAGS = -mthumb +QMAKE_QtScript_CXXFLAGS = -mthumb +QMAKE_QtScriptTools_CXXFLAGS = -mthumb +QMAKE_QtSql_CXXFLAGS = -mthumb +QMAKE_QtSvg_CXXFLAGS = -mthumb +QMAKE_QtTest_CXXFLAGS = -mthumb +QMAKE_QtXmlPatterns_CXXFLAGS = -mthumb +QMAKE_QtXml_CXXFLAGS = -mthumb +#TODO fails with; arm-none-symbianelf-ld: section .data loaded at [00e00000,00e05973] overlaps section .text loaded at [00008000,00fe748b] +QMAKE_QtWebKit_LFLAGS = -Ttext 0x8000 -Tdata 0xE00000 + +# never use -fPIC, gcce-linker doesn't like it. +# g++ conf above adds it if the host platform is 64 bit, so we remove it again +QMAKE_CFLAGS_SHLIB -= -fPIC +QMAKE_CFLAGS_STATIC_LIB -= -fPIC +QMAKE_CXXFLAGS_SHLIB -= -fPIC +QMAKE_CXXFLAGS_STATIC_LIB -= -fPIC + +QMAKE_LFLAGS_SONAME = +#QMAKE_LFLAGS_THREAD += +#QMAKE_LFLAGS_NOUNDEF += -Wl,--no-undefined +QMAKE_RPATH = --rpath= + +DEFINES += __GCCE__ \ + UNICODE \ + _STLP_NO_EXCEPTION_HEADER + +QMAKE_LFLAGS_APP += --entry _E32Startup +QMAKE_LFLAGS_SHLIB += --default-symver --entry _E32Dll +QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB + +gcceExtraFlags = --include=${EPOCROOT}epoc32/include/gcce/gcce.h -march=armv5t -mapcs -mthumb-interwork -nostdinc -c -fvisibility-inlines-hidden -msoft-float -T script +QMAKE_CFLAGS += $${gcceExtraFlags} +QMAKE_CXXFLAGS += $${gcceExtraFlags} -x c++ -fexceptions -fno-unit-at-a-time + +QMAKE_LFLAGS += --target1-abs \ + --no-undefined \ + --strip-debug \ + --nostdlib + +QMAKE_LIBDIR += ${EPOCROOT}/epoc32/release/armv5/udeb/ + +# g++ knows the path to the gcc-shipped-libs, ld doesn't. So cache the full path in the generate Makefile +QMAKE_GCC_SEARCH_DIRS =$$system($$QMAKE_CXX -print-search-dirs) +for(line, QMAKE_GCC_SEARCH_DIRS) { + contains(line, "libraries:") { + foundIt="1" + } else { + contains(foundIt, "1") { + QMAKE_LFLAGS += $$replace(line, "[=:]", " -L") + } + } +} + +QMAKE_LIBDIR += $${EPOCROOT}epoc32/release/armv5/lib + +INCLUDEPATH = ${EPOCROOT}epoc32/include/ \ + $${EPOCROOT}epoc32/include/variant \ + $${EPOCROOT}epoc32/include/stdapis \ + $${EPOCROOT}epoc32/include/gcce \ + ${EPOCROOT}epoc32/include/stdapis/sys \ + ${EPOCROOT}epoc32/include/stdapis/stlport \ + $$INCLUDEPATH + diff --git a/mkspecs/symbian/linux-gcce/qplatformdefs.h b/mkspecs/symbian/linux-gcce/qplatformdefs.h new file mode 100644 index 0000000..4a658c5 --- /dev/null +++ b/mkspecs/symbian/linux-gcce/qplatformdefs.h @@ -0,0 +1,2 @@ +#include "../../common/symbian/qplatformdefs.h" + diff --git a/projects.pro b/projects.pro index 19a5ff8..fc7db1d 100644 --- a/projects.pro +++ b/projects.pro @@ -48,7 +48,7 @@ for(PROJECT, $$list($$lower($$unique(QT_BUILD_PARTS)))) { contains(QT_BUILD_PARTS, tools) { include(translations/translations.pri) # ts targets } else { - !wince*:!symbian:SUBDIRS += tools/linguist/lrelease + !wince*:SUBDIRS += tools/linguist/lrelease } SUBDIRS += translations # qm build step } else:isEqual(PROJECT, qmake) { diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index c101626..875b9d1 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -11,8 +11,7 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \ symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o \ - registry.o \ - epocroot.o + symbiancommon.o registry.o epocroot.o #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ @@ -37,6 +36,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp \ generators/symbian/symmake_abld.cpp generators/symbian/symmake_sbsv2.cpp \ + generaters/symbian/symbiancommon.cpp \ $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \ $(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \ $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp \ @@ -235,7 +235,7 @@ option.o: option.cpp option.h $(BUILD_PATH)/src/corelib/global/qconfig.cpp qcryptographichash.o: $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp -metamakefile.o: generators/metamakefile.cpp +metamakefile.o: generators/metamakefile.cpp generators/symbian/symbian_makefile.h $(CXX) -c -o $@ $(CXXFLAGS) generators/metamakefile.cpp xmloutput.o: generators/xmloutput.cpp @@ -280,6 +280,9 @@ symmake_abld.o: generators/symbian/symmake_abld.cpp symmake_sbsv2.o: generators/symbian/symmake_sbsv2.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/symmake_sbsv2.cpp +symbiancommon.o: generators/symbian/symbiancommon.cpp + $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/symbiancommon.cpp + initprojectdeploy_symbian.o: generators/symbian/initprojectdeploy_symbian.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index a598350..63156b3 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -77,9 +77,7 @@ OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw makefiledeps.obj metamakefile.obj xmloutput.obj pbuilder_pbx.obj \ borland_bmake.obj msvc_nmake.obj msvc_vcproj.obj \ msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ - registry.obj \ - epocroot.obj \ - symmake_abld.obj symmake_sbsv2.obj + symmake_abld.obj symmake_sbsv2.obj symbiancommon.obj registry.obj epocroot.obj !IFDEF QMAKE_OPENSOURCE_EDITION CFLAGS = $(CFLAGS) -DQMAKE_OPENSOURCE_EDITION @@ -200,6 +198,7 @@ clean:: -del symmake.obj -del symmake_abld.obj -del symmake_sbsv2.obj + -del symbiancommon.obj -del initprojectdeploy_symbian.obj -del registry.obj -del epocroot.obj @@ -396,6 +395,9 @@ symmake_abld.obj: $(SOURCE_PATH)/qmake/generators/symbian/symmake_abld.cpp symmake_sbsv2.obj: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp $(CXX) $(CXXFLAGS) generators/symbian/symmake_sbsv2.cpp +symbiancommon.obj: $(SOURCE_PATH)/qmake/generators/symbian/symbiancommon.cpp + $(CXX) $(CXXFLAGS) generators/symbian/symbiancommon.cpp + initprojectdeploy_symbian.obj: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp @@ -432,7 +434,7 @@ pbuilder_pbx.obj: $(SOURCE_PATH)/qmake/generators/mac/pbuilder_pbx.cpp makefiledeps.obj: $(SOURCE_PATH)/qmake/generators/makefiledeps.cpp $(CXX) $(CXXFLAGS) generators/makefiledeps.cpp -metamakefile.obj: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp +metamakefile.obj: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp $(SOURCE_PATH)/qmake/generators/symbian/symbiancommon.obj $(CXX) $(CXXFLAGS) generators/metamakefile.cpp xmloutput.obj: $(SOURCE_PATH)/qmake/generators/xmloutput.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index 27ae27b..ab7d558 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -39,9 +39,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_nmake.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ - registry.o \ - epocroot.o \ - symmake_abld.o symmake_sbsv2.o + symmake_abld.o symmake_sbsv2.o symbiancommon.o registry.o epocroot.o ifdef QMAKE_OPENSOURCE_EDITION CFLAGS += -DQMAKE_OPENSOURCE_EDITION @@ -275,6 +273,9 @@ symmake_abld.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_abld.cpp symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp $(CXX) $(CXXFLAGS) generators/symbian/symmake_sbsv2.cpp +symbiancommon.o: $(SOURCE_PATH)/qmake/generators/symbian/symbiancommon.cpp + $(CXX) $(CXXFLAGS) generators/symbian/symbiancommon.cpp + initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp @@ -308,7 +309,7 @@ pbuilder_pbx.o: $(SOURCE_PATH)/qmake/generators/mac/pbuilder_pbx.cpp makefiledeps.o: $(SOURCE_PATH)/qmake/generators/makefiledeps.cpp $(CXX) $(CXXFLAGS) generators/makefiledeps.cpp -metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp +metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp $(SOURCE_PATH)/qmake/generators/symbian/symbian_makefile.h $(CXX) $(CXXFLAGS) generators/metamakefile.cpp xmloutput.o: $(SOURCE_PATH)/qmake/generators/xmloutput.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index f7b486f..755d046 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -39,9 +39,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_nmake.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ - registry.o \ - epocroot.o \ - symmake_abld.o symmake_sbsv2.o + symmake_abld.o symmake_sbsv2.o symbiancommon.o registry.o epocroot.o ifdef QMAKE_OPENSOURCE_EDITION CFLAGS += -DQMAKE_OPENSOURCE_EDITION @@ -274,6 +272,9 @@ symmake_abld.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_abld.cpp symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp $(CXX) $(CXXFLAGS) generators/symbian/symmake_sbsv2.cpp +symbiancommon.o: $(SOURCE_PATH)/qmake/generators/symbian/symbiancommon.cpp + $(CXX) $(CXXFLAGS) generators/symbian/symbiancommon.cpp + initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp @@ -307,7 +308,7 @@ pbuilder_pbx.o: $(SOURCE_PATH)/qmake/generators/mac/pbuilder_pbx.cpp makefiledeps.o: $(SOURCE_PATH)/qmake/generators/makefiledeps.cpp $(CXX) $(CXXFLAGS) generators/makefiledeps.cpp -metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp +metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp $(SOURCE_PATH)/qmake/generators/symbian/symbian_makefile.h $(CXX) $(CXXFLAGS) generators/metamakefile.cpp xmloutput.o: $(SOURCE_PATH)/qmake/generators/xmloutput.cpp diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index addb1f5..4c3be3d 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -249,6 +249,39 @@ public: virtual bool openOutput(QFile &, const QString &build) const; virtual bool isWindowsShell() const { return Option::host_mode == Option::HOST_WIN_MODE; } virtual bool isForSymbianSbsv2() const { return false; } // FIXME: killme - i'm ugly! + + /* The next one is to avoid having SymbianCommonGenerator as a virtually + inherited class of this class. Instead it is without a base class + (avoiding the virtual inheritance problem), and is allowed to use + functions defined in here. + + To illustrate: + +-------------------+ + | MakefileGenerator | + +-------------------+ + ^ ^ + | | + | X <-- Avoid this inheritance + | | + +------------------------+ +------------------------+ + | UnixMakefileGenerator | | SymbianCommonGenerator | + | or | | | + | NmakeMakefileGenerator | | | + +------------------------+ +------------------------+ + ^ ^ + | | + | | + | | + +-----------------------------+ + | SymbianMakefileTemplate<> | + +-----------------------------+ + + We want to avoid the famous diamond problem, because if we have that, we need + virtual inheritance, which not all compilers like. Therefore, we break the + link as illustrated. Instead, we have a pointer to MakefileGenerator inside + SymbianCommonGenerator, and allows full access by making it a friend here. + */ + friend class SymbianCommonGenerator; }; inline void MakefileGenerator::setNoIO(bool o) diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index bc8927c..e76e596 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -443,6 +443,7 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "msvc_vcproj.h" #include "symmake_abld.h" #include "symmake_sbsv2.h" +#include "symbian_makefile.h" QT_END_INCLUDE_NAMESPACE MakefileGenerator * @@ -476,6 +477,8 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO) mkfile = new SymbianAbldMakefileGenerator; } else if(gen == "SYMBIAN_SBSV2") { mkfile = new SymbianSbsv2MakefileGenerator; + } else if(gen == "SYMBIAN_UNIX") { + mkfile = new SymbianMakefileTemplate<UnixMakefileGenerator>; } else { fprintf(stderr, "Unknown generator specified: %s\n", gen.toLatin1().constData()); } @@ -504,7 +507,7 @@ MetaMakefileGenerator::modesForGenerator(const QString &gen, } else if (gen == "PROJECTBUILDER" || gen == "XCODE") { *host_mode = Option::HOST_MACX_MODE; *target_mode = Option::TARG_MACX_MODE; - } else if (gen == "SYMBIAN_ABLD" || gen == "SYMBIAN_SBSV2") { + } else if (gen == "SYMBIAN_ABLD" || gen == "SYMBIAN_SBSV2" || gen == "SYMBIAN_UNIX") { #if defined(Q_OS_MAC) *host_mode = Option::HOST_MACX_MODE; #elif defined(Q_OS_UNIX) diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.cpp b/qmake/generators/symbian/initprojectdeploy_symbian.cpp index 81c9408..6407412 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.cpp +++ b/qmake/generators/symbian/initprojectdeploy_symbian.cpp @@ -155,6 +155,7 @@ void initProjectDeploySymbian(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath, bool deployBinaries, + bool epocBuild, const QString &platform, const QString &build, QStringList& generatedDirs, @@ -264,7 +265,11 @@ void initProjectDeploySymbian(QMakeProject* project, if (isBinary(info)) { if (deployBinaries) { // Executables and libraries are deployed to \sys\bin - QFileInfo targetPath(epocRoot() + "epoc32/release/" + platform + "/" + build + "/"); + QFileInfo targetPath; + if (epocBuild) + targetPath.setFile(epocRoot() + "epoc32/release/" + platform + "/" + build + "/"); + else + targetPath.setFile(info.path() + QDir::separator()); if(devicePathHasDriveLetter) { deploymentList.append(CopyItem( Option::fixPathToLocalOS(targetPath.absolutePath() + "/" + info.fileName(), diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.h b/qmake/generators/symbian/initprojectdeploy_symbian.h index c621915..2653d2a 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.h +++ b/qmake/generators/symbian/initprojectdeploy_symbian.h @@ -69,6 +69,7 @@ extern void initProjectDeploySymbian(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath, bool deployBinaries, + bool epocBuild, const QString &platform, const QString &build, QStringList& generatedDirs, diff --git a/qmake/generators/symbian/symbian_makefile.h b/qmake/generators/symbian/symbian_makefile.h new file mode 100644 index 0000000..f9d3c24 --- /dev/null +++ b/qmake/generators/symbian/symbian_makefile.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIAN_MAKEFILE_H +#define SYMBIAN_MAKEFILE_H + +#include "symbiancommon.h" + +// This allows us to reuse the code for both win32 and unix makefile generators. +template <class T> +class SymbianMakefileTemplate : public T, public SymbianCommonGenerator +{ +public: + SymbianMakefileTemplate() : SymbianCommonGenerator(this) {} + + void init() + { + T::init(); + SymbianCommonGenerator::init(); + } + + bool writeMakefile(QTextStream &t) + { + QString numberOfIcons; + QString iconFile; + QMap<QString, QStringList> userRssRules; + readRssRules(numberOfIcons, iconFile, userRssRules); + + // Generate pkg files if there are any actual files to deploy + bool generatePkg = false; + DeploymentList depList; + + if (targetType == TypeExe) { + generatePkg = true; + } else { + foreach(QString item, this->project->values("DEPLOYMENT")) { + if (!this->project->values(item + ".sources").isEmpty()) { + generatePkg = true; + break; + } + } + } + + if (generatePkg) { + generatePkgFile(iconFile, depList, false); + } + + // Get the application translations and convert to symbian OS lang code, i.e. decical number + QStringList symbianLangCodes = symbianLangCodesFromTsFiles(); + + if (targetType == TypeExe) { + if (!this->project->values("CONFIG").contains("no_icon", Qt::CaseInsensitive)) { + writeRegRssFile(userRssRules); + writeRssFile(numberOfIcons, iconFile); + writeLocFile(symbianLangCodes); + } + } + + return T::writeMakefile(t); + } +}; + +#endif // SYMBIAN_MAKEFILE_H diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp new file mode 100644 index 0000000..1de4b65 --- /dev/null +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -0,0 +1,872 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "symbiancommon.h" +#include <qdebug.h> + +// Included from tools/shared +#include <symbian/epocroot.h> + +#define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\" + +#define RSS_RULES "RSS_RULES" +#define RSS_RULES_BASE "RSS_RULES." +#define RSS_TAG_NBROFICONS "number_of_icons" +#define RSS_TAG_ICONFILE "icon_file" +#define RSS_TAG_HEADER "header" +#define RSS_TAG_SERVICE_LIST "service_list" +#define RSS_TAG_FILE_OWNERSHIP_LIST "file_ownership_list" +#define RSS_TAG_DATATYPE_LIST "datatype_list" +#define RSS_TAG_FOOTER "footer" +#define RSS_TAG_DEFAULT "default_rules" // Same as just giving rules without tag + +#define MANUFACTURER_NOTE_FILE "manufacturer_note.txt" +#define DEFAULT_MANUFACTURER_NOTE \ + "The package is not supported for devices from this manufacturer. Please try the selfsigned " \ + "version of the package instead." + +SymbianCommonGenerator::SymbianCommonGenerator(MakefileGenerator *generator) + : generator(generator) +{ +} + +void SymbianCommonGenerator::init() +{ + QMakeProject *project = generator->project; + fixedTarget = project->first("QMAKE_ORIG_TARGET"); + if (fixedTarget.isEmpty()) + fixedTarget = project->first("TARGET"); + fixedTarget = generator->unescapeFilePath(fixedTarget); + fixedTarget = removePathSeparators(fixedTarget); + if (project->first("MAKEFILE_GENERATOR") == "SYMBIAN_ABLD" + || project->first("MAKEFILE_GENERATOR") == "SYMBIAN_SBSV2") + removeEpocSpecialCharacters(fixedTarget); + else + removeSpecialCharacters(fixedTarget); + + // This should not be empty since the mkspecs are supposed to set it if missing. + uid3 = project->first("TARGET.UID3").trimmed(); + + if ((project->values("TEMPLATE")).contains("app")) + targetType = TypeExe; + else if ((project->values("TEMPLATE")).contains("lib")) { + // Check CONFIG to see if we are to build staticlib or dll + if (project->isActiveConfig("staticlib") || project->isActiveConfig("static")) + targetType = TypeLib; + else if (project->isActiveConfig("plugin")) + targetType = TypePlugin; + else + targetType = TypeDll; + } else { + targetType = TypeSubdirs; + } + + // UID is valid as either hex or decimal, so just convert it to number and back to hex + // to get proper string for private dir + bool conversionOk = false; + uint uidNum = uid3.toUInt(&conversionOk, 0); + + if (!conversionOk) { + fprintf(stderr, "Error: Invalid UID \"%s\".\n", uid3.toUtf8().constData()); + } else { + privateDirUid.setNum(uidNum, 16); + while (privateDirUid.length() < 8) + privateDirUid.insert(0, QLatin1Char('0')); + } +} + +bool SymbianCommonGenerator::containsStartWithItem(const QChar &c, const QStringList& src) +{ + bool result = false; + foreach(QString str, src) { + if (str.startsWith(c)) { + result = true; + break; + } + } + return result; +} + +void SymbianCommonGenerator::removeSpecialCharacters(QString& str) +{ + // When modifying this method check also application_icon.prf + str.replace(QString("/"), QString("_")); + str.replace(QString("\\"), QString("_")); + str.replace(QString(" "), QString("_")); +} + +void SymbianCommonGenerator::removeEpocSpecialCharacters(QString& str) +{ + // When modifying this method check also application_icon.prf + str.replace(QString("-"), QString("_")); + str.replace(QString(":"), QString("_")); + str.replace(QString("."), QString("_")); + removeSpecialCharacters(str); +} + +void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, DeploymentList &depList, bool epocBuild) +{ + QMakeProject *project = generator->project; + QString pkgTarget = project->first("QMAKE_ORIG_TARGET"); + if (pkgTarget.isEmpty()) + pkgTarget = project->first("TARGET"); + pkgTarget = generator->unescapeFilePath(pkgTarget); + pkgTarget = removePathSeparators(pkgTarget); + QString pkgFilename = QString("%1_template.%2").arg(pkgTarget).arg("pkg"); + if (!Option::output_dir.isEmpty()) + pkgFilename = Option::output_dir + '/' + pkgFilename; + + QFile pkgFile(pkgFilename); + if (!pkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + PRINT_FILE_CREATE_ERROR(pkgFilename); + return; + } + + generatedFiles << pkgFile.fileName(); + QTextStream t(&pkgFile); + + QString installerSisHeader = project->values("DEPLOYMENT.installer_header").join("\n"); + QString wrapperStreamBuffer; + QTextStream tw(&wrapperStreamBuffer); + + QString dateStr = QDateTime::currentDateTime().toString(Qt::ISODate); + + // Header info + QString wrapperPkgFilename = QString("%1_installer.%2") + .arg(pkgTarget) + .arg("pkg"); + QString headerComment = "; %1 generated by qmake at %2\n" + "; This file is generated by qmake and should not be modified by the user\n" + ";\n\n"; + t << headerComment.arg(pkgFilename).arg(dateStr); + tw << headerComment.arg(wrapperPkgFilename).arg(dateStr); + + // Construct QStringList from pkg_prerules since we need search it before printed to file + QStringList rawPkgPreRules; + foreach(QString deploymentItem, project->values("DEPLOYMENT")) { + foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) { + QStringList pkgrulesValue = project->values(pkgrulesItem); + // If there is no stringlist defined for a rule, use rule name directly + // This is convenience for defining single line mmp statements + if (pkgrulesValue.isEmpty()) { + rawPkgPreRules << pkgrulesItem; + } else { + foreach(QString pkgrule, pkgrulesValue) { + rawPkgPreRules << pkgrule; + } + } + } + } + + // Apply some defaults if specific data does not exist in PKG pre-rules + + if (!containsStartWithItem('&', rawPkgPreRules)) { + // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS) + QString languageCode = "; Language\n&EN\n\n"; + t << languageCode; + tw << languageCode; + } else { + // In case user defines langs, he must take care also about SIS header + if (!containsStartWithItem('#', rawPkgPreRules)) + fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n"); + } + + // name of application, UID and version + QString applicationVersion = project->first("VERSION").isEmpty() ? "1,0,0" : project->first("VERSION").replace('.', ','); + QString sisHeader = "; SIS header: name, uid, version\n#{\"%1\"},(%2),%3\n\n"; + QString visualTarget = generator->escapeFilePath(project->first("TARGET")); + + visualTarget = removePathSeparators(visualTarget); + QString wrapperTarget = visualTarget + " installer"; + + if (installerSisHeader.startsWith("0x", Qt::CaseInsensitive)) { + tw << sisHeader.arg(wrapperTarget).arg(installerSisHeader).arg(applicationVersion); + } else { + tw << installerSisHeader << endl; + } + if (!containsStartWithItem('#', rawPkgPreRules)) { + t << sisHeader.arg(visualTarget).arg(uid3).arg(applicationVersion); + } + + // Localized vendor name + QString vendorName; + if (!containsStartWithItem('%', rawPkgPreRules)) { + vendorName += "; Localised Vendor name\n%{\"Vendor\"}\n\n"; + } + + // Unique vendor name + if (!containsStartWithItem(':', rawPkgPreRules)) { + vendorName += "; Unique Vendor name\n:\"Vendor\"\n\n"; + } + + t << vendorName; + tw << vendorName; + + // PKG pre-rules - these are added before actual file installations i.e. SIS package body + if (rawPkgPreRules.size()) { + QString comment = "\n; Manual PKG pre-rules from PRO files\n"; + t << comment; + tw << comment; + + foreach(QString item, rawPkgPreRules) { + // Only regular pkg file should have package dependencies or pkg header if that is + // defined using prerules. + if (!item.startsWith("(") && !item.startsWith("#")) { + tw << item << endl; + } + t << item << endl; + } + t << endl; + tw << endl; + } + + // Begin Manufacturer block + if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { + QString manufacturerStr("IF "); + foreach(QString manufacturer, project->values("DEPLOYMENT.manufacturers")) { + manufacturerStr.append(QString("(MANUFACTURER)=(%1) OR \n ").arg(manufacturer)); + } + // Remove the final OR + manufacturerStr.chop(8); + t << manufacturerStr << endl; + } + + // Install paths on the phone *** should be dynamic at some point + QString installPathBin = "!:\\sys\\bin"; + QString installPathResource = "!:\\resource\\apps"; + QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps"; + + // Find location of builds + QString destDirBin; + QString destDirResource; + QString destDirRegResource; + if (epocBuild) { + destDirBin = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)").arg(epocRoot()); + destDirResource = QString("%1epoc32/data/z/resource/apps").arg(epocRoot()); + destDirRegResource = QString("%1epoc32/data/z/private/10003a3f/import/apps").arg(epocRoot()); + } else { + destDirBin = project->first("DESTDIR"); + if (destDirBin.isEmpty()) + destDirBin = "."; + else if (destDirBin.endsWith('/') || destDirBin.endsWith('\\')) + destDirBin.chop(1); + destDirResource = destDirBin; + destDirRegResource = destDirBin; + } + + if (targetType == TypeExe) { + // deploy .exe file + t << "; Executable and default resource files" << endl; + QString exeFile = fixedTarget + ".exe"; + t << QString("\"%1/%2\" - \"%3\\%4\"") + .arg(destDirBin) + .arg(exeFile) + .arg(installPathBin) + .arg(exeFile) << endl; + + // deploy rsc & reg_rsc file + if (!project->isActiveConfig("no_icon")) { + t << QString("\"%1/%2\" - \"%3\\%4\"") + .arg(destDirResource) + .arg(fixedTarget + ".rsc") + .arg(installPathResource) + .arg(fixedTarget + ".rsc") << endl; + + t << QString("\"%1/%2\" - \"%3\\%4\"") + .arg(destDirRegResource) + .arg(fixedTarget + "_reg.rsc") + .arg(installPathRegResource) + .arg(fixedTarget + "_reg.rsc") << endl; + + if (!iconFile.isEmpty()) { + if (epocBuild) { + t << QString("\"%1epoc32/data/z%2\" - \"!:%3\"") + .arg(epocRoot()) + .arg(iconFile) + .arg(QDir::toNativeSeparators(iconFile)) << endl << endl; + } else { + QDir mifIconDir(project->first("DESTDIR")); + QFileInfo mifIcon(mifIconDir.relativeFilePath(project->first("TARGET"))); + QString mifIconFileName = mifIcon.fileName(); + mifIconFileName.append(".mif"); + t << QString("\"%1/%2\" - \"!:%3\"") + .arg(mifIcon.path()) + .arg(mifIconFileName) + .arg(QDir::toNativeSeparators(iconFile)) << endl << endl; + } + } + } + } + + // deploy any additional DEPLOYMENT files + QString remoteTestPath; + remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid); + + initProjectDeploySymbian(project, depList, remoteTestPath, true, epocBuild, "$(PLATFORM)", "$(TARGET)", generatedDirs, generatedFiles); + if (depList.size()) + t << "; DEPLOYMENT" << endl; + for (int i = 0; i < depList.size(); ++i) { + t << QString("\"%1\" - \"%2\"") + .arg(depList.at(i).from) + .arg(depList.at(i).to) << endl; + } + t << endl; + + // PKG post-rules - these are added after actual file installations i.e. SIS package body + t << "; Manual PKG post-rules from PRO files" << endl; + foreach(QString deploymentItem, project->values("DEPLOYMENT")) { + foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_postrules")) { + QStringList pkgrulesValue = project->values(pkgrulesItem); + // If there is no stringlist defined for a rule, use rule name directly + // This is convenience for defining single line statements + if (pkgrulesValue.isEmpty()) { + t << pkgrulesItem << endl; + } else { + foreach(QString pkgrule, pkgrulesValue) { + t << pkgrule << endl; + } + } + t << endl; + } + } + + // Close Manufacturer block + if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { + QString manufacturerFailNoteFile; + if (project->values("DEPLOYMENT.manufacturers.fail_note").isEmpty()) { + manufacturerFailNoteFile = QString("%1_" MANUFACTURER_NOTE_FILE).arg(uid3); + QFile ft(manufacturerFailNoteFile); + if (ft.open(QIODevice::WriteOnly)) { + generatedFiles << ft.fileName(); + QTextStream t2(&ft); + + t2 << QString(DEFAULT_MANUFACTURER_NOTE) << endl; + } else { + PRINT_FILE_CREATE_ERROR(manufacturerFailNoteFile) + } + } else { + manufacturerFailNoteFile = project->values("DEPLOYMENT.manufacturers.fail_note").join(""); + } + + t << "ELSEIF NOT(0) ; MANUFACTURER" << endl + << "\"" << generator->fileInfo(manufacturerFailNoteFile).absoluteFilePath() << "\"" + << " - \"\", FILETEXT, TEXTEXIT" << endl + << "ENDIF ; MANUFACTURER" << endl; + } + + // Write wrapper pkg + if (!installerSisHeader.isEmpty()) { + QFile wrapperPkgFile(wrapperPkgFilename); + if (!wrapperPkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + PRINT_FILE_CREATE_ERROR(wrapperPkgFilename); + return; + } + + generatedFiles << wrapperPkgFile.fileName(); + QTextStream twf(&wrapperPkgFile); + + twf << wrapperStreamBuffer << endl; + + // Wrapped files deployment + QString currentPath = qmake_getpwd(); + QString sisName = QString("%1.sis").arg(pkgTarget); + twf << "\"" << currentPath << "/" << sisName << "\" - \"c:\\adm\\" << sisName << "\"" << endl; + + QString bootStrapPath = QLibraryInfo::location(QLibraryInfo::PrefixPath); + bootStrapPath.append("/bootstrap.sis"); + QFileInfo fi(generator->fileInfo(bootStrapPath)); + twf << "@\"" << fi.absoluteFilePath() << "\",(0x2002CCCD)" << endl; + } +} + +QString SymbianCommonGenerator::removePathSeparators(QString &file) +{ + QString ret = file; + while (ret.indexOf(QDir::separator()) > 0) { + ret.remove(0, ret.indexOf(QDir::separator()) + 1); + } + + return ret; +} + +void SymbianCommonGenerator::writeRegRssFile(QMap<QString, QStringList> &userItems) +{ + QString filename(fixedTarget); + filename.append("_reg.rss"); + if (!Option::output_dir.isEmpty()) + filename = Option::output_dir + '/' + filename; + QFile ft(filename); + if (ft.open(QIODevice::WriteOnly)) { + generatedFiles << ft.fileName(); + QTextStream t(&ft); + t << "// ============================================================================" << endl; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; + t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; + t << "// * This file is generated by qmake and should not be modified by the" << endl; + t << "// * user." << endl; + t << "// ============================================================================" << endl; + t << endl; + t << "#include <" << fixedTarget << ".rsg>" << endl; + t << "#include <appinfo.rh>" << endl; + foreach(QString item, userItems[RSS_TAG_HEADER]) + t << item << endl; + t << endl; + t << "UID2 KUidAppRegistrationResourceFile" << endl; + t << "UID3 " << uid3 << endl << endl; + t << "RESOURCE APP_REGISTRATION_INFO" << endl; + t << "\t{" << endl; + t << "\tapp_file=\"" << fixedTarget << "\";" << endl; + t << "\tlocalisable_resource_file=\"" RESOURCE_DIRECTORY_RESOURCE << fixedTarget << "\";" << endl; + + writeRegRssList(t, userItems[RSS_TAG_SERVICE_LIST], + QLatin1String(RSS_TAG_SERVICE_LIST), + QLatin1String("SERVICE_INFO")); + writeRegRssList(t, userItems[RSS_TAG_FILE_OWNERSHIP_LIST], + QLatin1String(RSS_TAG_FILE_OWNERSHIP_LIST), + QLatin1String("FILE_OWNERSHIP_INFO")); + writeRegRssList(t, userItems[RSS_TAG_DATATYPE_LIST], + QLatin1String(RSS_TAG_DATATYPE_LIST), + QLatin1String("DATATYPE")); + t << endl; + + foreach(QString item, userItems[RSS_TAG_DEFAULT]) + t << "\t" << item.replace("\n","\n\t") << endl; + t << "\t}" << endl; + + foreach(QString item, userItems[RSS_TAG_FOOTER]) + t << item << endl; + } else { + PRINT_FILE_CREATE_ERROR(filename) + } +} + +void SymbianCommonGenerator::writeRegRssList(QTextStream &t, + QStringList &userList, + const QString &listTag, + const QString &listItem) +{ + int itemCount = userList.count(); + if (itemCount) { + t << "\t" << listTag << " ="<< endl; + t << "\t\t{" << endl; + foreach(QString item, userList) { + t << "\t\t" << listItem << endl; + t << "\t\t\t{" << endl; + t << "\t\t\t" << item.replace("\n","\n\t\t\t") << endl; + t << "\t\t\t}"; + if (--itemCount) + t << ","; + t << endl; + } + t << "\t\t}; "<< endl; + } +} + +void SymbianCommonGenerator::writeRssFile(QString &numberOfIcons, QString &iconFile) +{ + QString filename(fixedTarget); + if (!Option::output_dir.isEmpty()) + filename = Option::output_dir + '/' + filename; + filename.append(".rss"); + QFile ft(filename); + if (ft.open(QIODevice::WriteOnly)) { + generatedFiles << ft.fileName(); + QTextStream t(&ft); + t << "// ============================================================================" << endl; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; + t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; + t << "// * This file is generated by qmake and should not be modified by the" << endl; + t << "// * user." << endl; + t << "// ============================================================================" << endl; + t << endl; + t << "#include <appinfo.rh>" << endl; + t << "#include \"" << fixedTarget << ".loc\"" << endl; + t << endl; + t << "RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info" << endl; + t << "\t{" << endl; + t << "\tshort_caption = STRING_r_short_caption;" << endl; + t << "\tcaption_and_icon =" << endl; + t << "\tCAPTION_AND_ICON_INFO" << endl; + t << "\t\t{" << endl; + t << "\t\tcaption = STRING_r_caption;" << endl; + + QString rssIconFile = iconFile; + rssIconFile = rssIconFile.replace("/", "\\\\"); + + if (numberOfIcons.isEmpty() || rssIconFile.isEmpty()) { + // There can be maximum one item in this tag, validated when parsed + t << "\t\tnumber_of_icons = 0;" << endl; + t << "\t\ticon_file = \"\";" << endl; + } else { + // There can be maximum one item in this tag, validated when parsed + t << "\t\tnumber_of_icons = " << numberOfIcons << ";" << endl; + t << "\t\ticon_file = \"" << rssIconFile << "\";" << endl; + } + t << "\t\t};" << endl; + t << "\t}" << endl; + t << endl; + } else { + PRINT_FILE_CREATE_ERROR(filename); + } +} + +void SymbianCommonGenerator::writeLocFile(QStringList &symbianLangCodes) +{ + QString filename(fixedTarget); + if (!Option::output_dir.isEmpty()) + filename = Option::output_dir + '/' + filename; + filename.append(".loc"); + QFile ft(filename); + if (ft.open(QIODevice::WriteOnly)) { + generatedFiles << ft.fileName(); + QTextStream t(&ft); + t << "// ============================================================================" << endl; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; + t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; + t << "// * This file is generated by qmake and should not be modified by the" << endl; + t << "// * user." << endl; + t << "// ============================================================================" << endl; + t << endl; + t << "#ifdef LANGUAGE_SC" << endl; + t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; + t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; + foreach(QString lang, symbianLangCodes) { + t << "#elif defined LANGUAGE_" << lang << endl; + t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; + t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; + } + t << "#else" << endl; + t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; + t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; + t << "#endif" << endl; + } else { + PRINT_FILE_CREATE_ERROR(filename); + } +} + +void SymbianCommonGenerator::readRssRules(QString &numberOfIcons, + QString &iconFile, QMap<QString, + QStringList> &userRssRules) +{ + QMakeProject *project = generator->project; + for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) { + if (it.key().startsWith(RSS_RULES_BASE)) { + QString newKey = it.key().mid(sizeof(RSS_RULES_BASE) - 1); + if (newKey.isEmpty()) { + fprintf(stderr, "Warning: Empty RSS_RULES_BASE key encountered\n"); + continue; + } + QStringList newValues; + QStringList values = it.value(); + foreach(QString item, values) { + // If there is no stringlist defined for a rule, use rule value directly + // This is convenience for defining single line statements + if (project->values(item).isEmpty()) { + newValues << item; + } else { + QStringList itemList; + foreach(QString itemRow, project->values(item)) { + itemList << itemRow; + } + newValues << itemList.join("\n"); + } + } + // Verify thet there is exactly one value in RSS_TAG_NBROFICONS + if (newKey == RSS_TAG_NBROFICONS) { + if (newValues.count() == 1) { + numberOfIcons = newValues[0]; + } else { + fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n", + RSS_RULES_BASE, RSS_TAG_NBROFICONS); + continue; + } + // Verify thet there is exactly one value in RSS_TAG_ICONFILE + } else if (newKey == RSS_TAG_ICONFILE) { + if (newValues.count() == 1) { + iconFile = newValues[0]; + } else { + fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n", + RSS_RULES_BASE, RSS_TAG_ICONFILE); + continue; + } + } else if (newKey == RSS_TAG_HEADER + || newKey == RSS_TAG_SERVICE_LIST + || newKey == RSS_TAG_FILE_OWNERSHIP_LIST + || newKey == RSS_TAG_DATATYPE_LIST + || newKey == RSS_TAG_FOOTER + || newKey == RSS_TAG_DEFAULT) { + userRssRules[newKey] = newValues; + continue; + } else { + fprintf(stderr, "Warning: Unsupported key:'%s%s'\n", + RSS_RULES_BASE, newKey.toLatin1().constData()); + continue; + } + } + } + + QStringList newValues; + foreach(QString item, project->values(RSS_RULES)) { + // If there is no stringlist defined for a rule, use rule value directly + // This is convenience for defining single line statements + if (project->values(item).isEmpty()) { + newValues << item; + } else { + newValues << project->values(item); + } + } + userRssRules[RSS_TAG_DEFAULT] << newValues; + + // Validate that either both RSS_TAG_NBROFICONS and RSS_TAG_ICONFILE keys exist + // or neither of them exist + if (!((numberOfIcons.isEmpty() && iconFile.isEmpty()) || + (!numberOfIcons.isEmpty() && !iconFile.isEmpty()))) { + numberOfIcons.clear(); + iconFile.clear(); + fprintf(stderr, "Warning: Both or neither of '%s%s' and '%s%s' keys must exist.\n", + RSS_RULES_BASE, RSS_TAG_NBROFICONS, RSS_RULES_BASE, RSS_TAG_ICONFILE); + } + + // Validate that RSS_TAG_NBROFICONS contains only numbers + if (!numberOfIcons.isEmpty()) { + bool ok; + numberOfIcons = numberOfIcons.simplified(); + numberOfIcons.toInt(&ok); + if (!ok) { + numberOfIcons.clear(); + iconFile.clear(); + fprintf(stderr, "Warning: '%s%s' must be integer in decimal format.\n", + RSS_RULES_BASE, RSS_TAG_NBROFICONS); + } + } +} + +QStringList SymbianCommonGenerator::symbianLangCodesFromTsFiles() +{ + QStringList tsfiles; + QStringList symbianLangCodes; + tsfiles << generator->project->values("TRANSLATIONS"); + + fillQt2S60LangMapTable(); + + foreach(QString file, tsfiles) { + int extIndex = file.lastIndexOf("."); + int langIndex = file.lastIndexOf("_", (extIndex - file.length())); + langIndex += 1; + QString qtlang = file.mid(langIndex, extIndex - langIndex); + QString s60lang = qt2S60LangMapTable.value(qtlang, QString("SC")); + + if (!symbianLangCodes.contains(s60lang) && s60lang != "SC") + symbianLangCodes += s60lang; + } + + return symbianLangCodes; +} + +void SymbianCommonGenerator::fillQt2S60LangMapTable() +{ + qt2S60LangMapTable.reserve(170); // 165 items at time of writing. + qt2S60LangMapTable.insert("ab", "SC"); //Abkhazian // + qt2S60LangMapTable.insert("om", "SC"); //Afan // + qt2S60LangMapTable.insert("aa", "SC"); //Afar // + qt2S60LangMapTable.insert("af", "34"); //Afrikaans //Afrikaans + qt2S60LangMapTable.insert("sq", "35"); //Albanian //Albanian + qt2S60LangMapTable.insert("am", "36"); //Amharic //Amharic + qt2S60LangMapTable.insert("ar", "37"); //Arabic //Arabic + qt2S60LangMapTable.insert("hy", "38"); //Armenian //Armenian + qt2S60LangMapTable.insert("as", "SC"); //Assamese // + qt2S60LangMapTable.insert("ay", "SC"); //Aymara // + qt2S60LangMapTable.insert("az", "SC"); //Azerbaijani // + qt2S60LangMapTable.insert("ba", "SC"); //Bashkir // + qt2S60LangMapTable.insert("eu", "SC"); //Basque // + qt2S60LangMapTable.insert("bn", "41"); //Bengali //Bengali + qt2S60LangMapTable.insert("dz", "SC"); //Bhutani // + qt2S60LangMapTable.insert("bh", "SC"); //Bihari // + qt2S60LangMapTable.insert("bi", "SC"); //Bislama // + qt2S60LangMapTable.insert("br", "SC"); //Breton // + qt2S60LangMapTable.insert("bg", "42"); //Bulgarian //Bulgarian + qt2S60LangMapTable.insert("my", "43"); //Burmese //Burmese + qt2S60LangMapTable.insert("be", "40"); //Byelorussian //Belarussian + qt2S60LangMapTable.insert("km", "SC"); //Cambodian // + qt2S60LangMapTable.insert("ca", "44"); //Catalan //Catalan + qt2S60LangMapTable.insert("zh", "SC"); //Chinese // + qt2S60LangMapTable.insert("co", "SC"); //Corsican // + qt2S60LangMapTable.insert("hr", "45"); //Croatian //Croatian + qt2S60LangMapTable.insert("cs", "25"); //Czech //Czech + qt2S60LangMapTable.insert("da", "07"); //Danish //Danish + qt2S60LangMapTable.insert("nl", "18"); //Dutch //Dutch + qt2S60LangMapTable.insert("en", "01"); //English //English(UK) + qt2S60LangMapTable.insert("eo", "SC"); //Esperanto // + qt2S60LangMapTable.insert("et", "49"); //Estonian //Estonian + qt2S60LangMapTable.insert("fo", "SC"); //Faroese // + qt2S60LangMapTable.insert("fj", "SC"); //Fiji // + qt2S60LangMapTable.insert("fi", "09"); //Finnish //Finnish + qt2S60LangMapTable.insert("fr", "02"); //French //French + qt2S60LangMapTable.insert("fy", "SC"); //Frisian // + qt2S60LangMapTable.insert("gd", "52"); //Gaelic //Gaelic + qt2S60LangMapTable.insert("gl", "SC"); //Galician // + qt2S60LangMapTable.insert("ka", "53"); //Georgian //Georgian + qt2S60LangMapTable.insert("de", "03"); //German //German + qt2S60LangMapTable.insert("el", "54"); //Greek //Greek + qt2S60LangMapTable.insert("kl", "SC"); //Greenlandic // + qt2S60LangMapTable.insert("gn", "SC"); //Guarani // + qt2S60LangMapTable.insert("gu", "56"); //Gujarati //Gujarati + qt2S60LangMapTable.insert("ha", "SC"); //Hausa // + qt2S60LangMapTable.insert("he", "57"); //Hebrew //Hebrew + qt2S60LangMapTable.insert("hi", "58"); //Hindi //Hindi + qt2S60LangMapTable.insert("hu", "17"); //Hungarian //Hungarian + qt2S60LangMapTable.insert("is", "15"); //Icelandic //Icelandic + qt2S60LangMapTable.insert("id", "59"); //Indonesian //Indonesian + qt2S60LangMapTable.insert("ia", "SC"); //Interlingua // + qt2S60LangMapTable.insert("ie", "SC"); //Interlingue // + qt2S60LangMapTable.insert("iu", "SC"); //Inuktitut // + qt2S60LangMapTable.insert("ik", "SC"); //Inupiak // + qt2S60LangMapTable.insert("ga", "60"); //Irish //Irish + qt2S60LangMapTable.insert("it", "05"); //Italian //Italian + qt2S60LangMapTable.insert("ja", "32"); //Japanese //Japanese + qt2S60LangMapTable.insert("jv", "SC"); //Javanese // + qt2S60LangMapTable.insert("kn", "62"); //Kannada //Kannada + qt2S60LangMapTable.insert("ks", "SC"); //Kashmiri // + qt2S60LangMapTable.insert("kk", "63"); //Kazakh //Kazakh + qt2S60LangMapTable.insert("rw", "SC"); //Kinyarwanda // + qt2S60LangMapTable.insert("ky", "SC"); //Kirghiz // + qt2S60LangMapTable.insert("ko", "65"); //Korean //Korean + qt2S60LangMapTable.insert("ku", "SC"); //Kurdish // + qt2S60LangMapTable.insert("rn", "SC"); //Kurundi // + qt2S60LangMapTable.insert("lo", "66"); //Laothian //Laothian + qt2S60LangMapTable.insert("la", "SC"); //Latin // + qt2S60LangMapTable.insert("lv", "67"); //Latvian //Latvian + qt2S60LangMapTable.insert("ln", "SC"); //Lingala // + qt2S60LangMapTable.insert("lt", "68"); //Lithuanian //Lithuanian + qt2S60LangMapTable.insert("mk", "69"); //Macedonian //Macedonian + qt2S60LangMapTable.insert("mg", "SC"); //Malagasy // + qt2S60LangMapTable.insert("ms", "70"); //Malay //Malay + qt2S60LangMapTable.insert("ml", "71"); //Malayalam //Malayalam + qt2S60LangMapTable.insert("mt", "SC"); //Maltese // + qt2S60LangMapTable.insert("mi", "SC"); //Maori // + qt2S60LangMapTable.insert("mr", "72"); //Marathi //Marathi + qt2S60LangMapTable.insert("mo", "73"); //Moldavian //Moldovian + qt2S60LangMapTable.insert("mn", "74"); //Mongolian //Mongolian + qt2S60LangMapTable.insert("na", "SC"); //Nauru // + qt2S60LangMapTable.insert("ne", "SC"); //Nepali // + qt2S60LangMapTable.insert("nb", "08"); //Norwegian //Norwegian + qt2S60LangMapTable.insert("oc", "SC"); //Occitan // + qt2S60LangMapTable.insert("or", "SC"); //Oriya // + qt2S60LangMapTable.insert("ps", "SC"); //Pashto // + qt2S60LangMapTable.insert("fa", "SC"); //Persian // + qt2S60LangMapTable.insert("pl", "27"); //Polish //Polish + qt2S60LangMapTable.insert("pt", "13"); //Portuguese //Portuguese + qt2S60LangMapTable.insert("pa", "77"); //Punjabi //Punjabi + qt2S60LangMapTable.insert("qu", "SC"); //Quechua // + qt2S60LangMapTable.insert("rm", "SC"); //RhaetoRomance // + qt2S60LangMapTable.insert("ro", "78"); //Romanian //Romanian + qt2S60LangMapTable.insert("ru", "16"); //Russian //Russian + qt2S60LangMapTable.insert("sm", "SC"); //Samoan // + qt2S60LangMapTable.insert("sg", "SC"); //Sangho // + qt2S60LangMapTable.insert("sa", "SC"); //Sanskrit // + qt2S60LangMapTable.insert("sr", "79"); //Serbian //Serbian + qt2S60LangMapTable.insert("sh", "SC"); //SerboCroatian // + qt2S60LangMapTable.insert("st", "SC"); //Sesotho // + qt2S60LangMapTable.insert("tn", "SC"); //Setswana // + qt2S60LangMapTable.insert("sn", "SC"); //Shona // + qt2S60LangMapTable.insert("sd", "SC"); //Sindhi // + qt2S60LangMapTable.insert("si", "80"); //Singhalese //Sinhalese + qt2S60LangMapTable.insert("ss", "SC"); //Siswati // + qt2S60LangMapTable.insert("sk", "26"); //Slovak //Slovak + qt2S60LangMapTable.insert("sl", "28"); //Slovenian //Slovenian + qt2S60LangMapTable.insert("so", "81"); //Somali //Somali + qt2S60LangMapTable.insert("es", "04"); //Spanish //Spanish + qt2S60LangMapTable.insert("su", "SC"); //Sundanese // + qt2S60LangMapTable.insert("sw", "84"); //Swahili //Swahili + qt2S60LangMapTable.insert("sv", "06"); //Swedish //Swedish + qt2S60LangMapTable.insert("tl", "39"); //Tagalog //Tagalog + qt2S60LangMapTable.insert("tg", "SC"); //Tajik // + qt2S60LangMapTable.insert("ta", "87"); //Tamil //Tamil + qt2S60LangMapTable.insert("tt", "SC"); //Tatar // + qt2S60LangMapTable.insert("te", "88"); //Telugu //Telugu + qt2S60LangMapTable.insert("th", "33"); //Thai //Thai + qt2S60LangMapTable.insert("bo", "89"); //Tibetan //Tibetan + qt2S60LangMapTable.insert("ti", "90"); //Tigrinya //Tigrinya + qt2S60LangMapTable.insert("to", "SC"); //Tonga // + qt2S60LangMapTable.insert("ts", "SC"); //Tsonga // + qt2S60LangMapTable.insert("tr", "14"); //Turkish //Turkish + qt2S60LangMapTable.insert("tk", "92"); //Turkmen //Turkmen + qt2S60LangMapTable.insert("tw", "SC"); //Twi // + qt2S60LangMapTable.insert("ug", "SC"); //Uigur // + qt2S60LangMapTable.insert("uk", "93"); //Ukrainian //Ukrainian + qt2S60LangMapTable.insert("ur", "94"); //Urdu //Urdu + qt2S60LangMapTable.insert("uz", "SC"); //Uzbek // + qt2S60LangMapTable.insert("vi", "96"); //Vietnamese //Vietnamese + qt2S60LangMapTable.insert("vo", "SC"); //Volapuk // + qt2S60LangMapTable.insert("cy", "97"); //Welsh //Welsh + qt2S60LangMapTable.insert("wo", "SC"); //Wolof // + qt2S60LangMapTable.insert("xh", "SC"); //Xhosa // + qt2S60LangMapTable.insert("yi", "SC"); //Yiddish // + qt2S60LangMapTable.insert("yo", "SC"); //Yoruba // + qt2S60LangMapTable.insert("za", "SC"); //Zhuang // + qt2S60LangMapTable.insert("zu", "98"); //Zulu //Zulu + qt2S60LangMapTable.insert("nn", "75"); //Nynorsk //NorwegianNynorsk + qt2S60LangMapTable.insert("bs", "SC"); //Bosnian // + qt2S60LangMapTable.insert("dv", "SC"); //Divehi // + qt2S60LangMapTable.insert("gv", "SC"); //Manx // + qt2S60LangMapTable.insert("kw", "SC"); //Cornish // + qt2S60LangMapTable.insert("ak", "SC"); //Akan // + qt2S60LangMapTable.insert("kok", "SC"); //Konkani // + qt2S60LangMapTable.insert("gaa", "SC"); //Ga // + qt2S60LangMapTable.insert("ig", "SC"); //Igbo // + qt2S60LangMapTable.insert("kam", "SC"); //Kamba // + qt2S60LangMapTable.insert("syr", "SC"); //Syriac // + qt2S60LangMapTable.insert("byn", "SC"); //Blin // + qt2S60LangMapTable.insert("gez", "SC"); //Geez // + qt2S60LangMapTable.insert("kfo", "SC"); //Koro // + qt2S60LangMapTable.insert("sid", "SC"); //Sidamo // + qt2S60LangMapTable.insert("cch", "SC"); //Atsam // + qt2S60LangMapTable.insert("tig", "SC"); //Tigre // + qt2S60LangMapTable.insert("kaj", "SC"); //Jju // + qt2S60LangMapTable.insert("fur", "SC"); //Friulian // + qt2S60LangMapTable.insert("ve", "SC"); //Venda // + qt2S60LangMapTable.insert("ee", "SC"); //Ewe // + qt2S60LangMapTable.insert("wa", "SC"); //Walamo // + qt2S60LangMapTable.insert("haw", "SC"); //Hawaiian // + qt2S60LangMapTable.insert("kcg", "SC"); //Tyap // + qt2S60LangMapTable.insert("ny", "SC"); //Chewa // +} + diff --git a/qmake/generators/symbian/symbiancommon.h b/qmake/generators/symbian/symbiancommon.h new file mode 100644 index 0000000..e2b1173 --- /dev/null +++ b/qmake/generators/symbian/symbiancommon.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANCOMMON_H +#define SYMBIANCOMMON_H + +#include <project.h> +#include <makefile.h> +#include "initprojectdeploy_symbian.h" + +#define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename)); + +class SymbianCommonGenerator +{ +public: + enum TargetType { + TypeExe, + TypeDll, + TypeLib, + TypePlugin, + TypeSubdirs + }; + + SymbianCommonGenerator(MakefileGenerator *generator); + + virtual void init(); + +protected: + + QString removePathSeparators(QString &file); + void removeSpecialCharacters(QString& str); + void removeEpocSpecialCharacters(QString& str); + void generatePkgFile(const QString &iconFile, DeploymentList &depList, bool epocBuild); + bool containsStartWithItem(const QChar &c, const QStringList& src); + + void writeRegRssFile(QMap<QString, QStringList> &useritems); + void writeRegRssList(QTextStream &t, QStringList &userList, + const QString &listTag, + const QString &listItem); + void writeRssFile(QString &numberOfIcons, QString &iconfile); + void writeLocFile(QStringList &symbianLangCodes); + void readRssRules(QString &numberOfIcons, + QString &iconFile, + QMap<QString, QStringList> &userRssRules); + + QStringList symbianLangCodesFromTsFiles(); + void fillQt2S60LangMapTable(); + +protected: + MakefileGenerator *generator; + + QStringList generatedFiles; + QStringList generatedDirs; + QString fixedTarget; + QString privateDirUid; + QString uid3; + TargetType targetType; + + QHash<QString, QString> qt2S60LangMapTable; +}; + +#endif // SYMBIANCOMMON_H diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 76ff7fe..af85a2a 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -53,7 +53,6 @@ #include <symbian/epocroot.h> #define RESOURCE_DIRECTORY_MMP "/resource/apps" -#define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\" #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps" #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def" #define PLUGIN_COMMON_DEF_FILE_ACTUAL "plugin_commonu.def" @@ -66,17 +65,6 @@ #define BLD_INF_TAG_EXTENSIONS "prj_extensions" #define BLD_INF_TAG_TESTEXTENSIONS "prj_testextensions" -#define RSS_RULES "RSS_RULES" -#define RSS_RULES_BASE "RSS_RULES." -#define RSS_TAG_NBROFICONS "number_of_icons" -#define RSS_TAG_ICONFILE "icon_file" -#define RSS_TAG_HEADER "header" -#define RSS_TAG_SERVICE_LIST "service_list" -#define RSS_TAG_FILE_OWNERSHIP_LIST "file_ownership_list" -#define RSS_TAG_DATATYPE_LIST "datatype_list" -#define RSS_TAG_FOOTER "footer" -#define RSS_TAG_DEFAULT "default_rules" // Same as just giving rules without tag - #define MMP_TARGET "TARGET" #define MMP_TARGETTYPE "TARGETTYPE" #define MMP_SECUREID "SECUREID" @@ -96,13 +84,6 @@ #define MMP_START_RESOURCE "START RESOURCE" #define MMP_END_RESOURCE "END" -#define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename)); - -#define MANUFACTURER_NOTE_FILE "manufacturer_note.txt" -#define DEFAULT_MANUFACTURER_NOTE \ - "The package is not supported for devices from this manufacturer. Please try the selfsigned " \ - "version of the package instead." - QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir) { static QString epocRootStr; @@ -160,7 +141,7 @@ QString SymbianMakefileGenerator::absolutizePath(const QString& origPath) return resultPath; } -SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator() { } +SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator(), SymbianCommonGenerator(this) { } SymbianMakefileGenerator::~SymbianMakefileGenerator() { } void SymbianMakefileGenerator::writeHeader(QTextStream &t) @@ -187,7 +168,7 @@ void SymbianMakefileGenerator::writeHeader(QTextStream &t) bldinfDefine.append(generate_uid(project->projectFile())); bldinfDefine.prepend("BLD_INF_"); - removeSpecialCharacters(bldinfDefine); + removeEpocSpecialCharacters(bldinfDefine); t << "#define " << bldinfDefine.toUpper() << endl << endl; } @@ -220,7 +201,7 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) } if (generatePkg) { - generatePkgFile(iconFile, depList); + generatePkgFile(iconFile, depList, true); } writeBldInfContent(t, generatePkg, iconFile, depList); @@ -280,264 +261,6 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) return true; } -void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile, DeploymentList &depList) -{ - QString pkgFilename = QString("%1_template.%2") - .arg(fixedTarget) - .arg("pkg"); - QFile pkgFile(pkgFilename); - if (!pkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - PRINT_FILE_CREATE_ERROR(pkgFilename); - return; - } - - generatedFiles << pkgFile.fileName(); - QTextStream t(&pkgFile); - - QString installerSisHeader = project->values("DEPLOYMENT.installer_header").join("\n"); - if (installerSisHeader.isEmpty()) - installerSisHeader = "0xA000D7CE"; // Use default self-signable UID if not defined - - QString wrapperStreamBuffer; - QTextStream tw(&wrapperStreamBuffer); - - QString dateStr = QDateTime::currentDateTime().toString(Qt::ISODate); - - // Header info - QString wrapperPkgFilename = QString("%1_installer.%2") - .arg(fixedTarget) - .arg("pkg"); - QString headerComment = "; %1 generated by qmake at %2\n" - "; This file is generated by qmake and should not be modified by the user\n" - ";\n\n"; - t << headerComment.arg(pkgFilename).arg(dateStr); - tw << headerComment.arg(wrapperPkgFilename).arg(dateStr); - - // Construct QStringList from pkg_prerules since we need search it before printed to file - QStringList rawPkgPreRules; - foreach(QString deploymentItem, project->values("DEPLOYMENT")) { - foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) { - QStringList pkgrulesValue = project->values(pkgrulesItem); - // If there is no stringlist defined for a rule, use rule name directly - // This is convenience for defining single line mmp statements - if (pkgrulesValue.isEmpty()) { - rawPkgPreRules << pkgrulesItem; - } else { - foreach(QString pkgrule, pkgrulesValue) { - rawPkgPreRules << pkgrule; - } - } - } - } - - // Apply some defaults if specific data does not exist in PKG pre-rules - - if (!containsStartWithItem('&', rawPkgPreRules)) { - // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS) - QString languageCode = "; Language\n&EN\n\n"; - t << languageCode; - tw << languageCode; - } else { - // In case user defines langs, he must take care also about SIS header - if (!containsStartWithItem('#', rawPkgPreRules)) - fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n"); - } - - // name of application, UID and version - QString applicationVersion = project->first("VERSION").isEmpty() ? "1,0,0" : project->first("VERSION").replace('.', ','); - QString sisHeader = "; SIS header: name, uid, version\n#{\"%1\"},(%2),%3\n\n"; - QString visualTarget = escapeFilePath(fileFixify(project->first("TARGET"))); - visualTarget = removePathSeparators(visualTarget); - QString wrapperTarget = visualTarget + " installer"; - - if (installerSisHeader.startsWith("0x", Qt::CaseInsensitive)) { - tw << sisHeader.arg(wrapperTarget).arg(installerSisHeader).arg(applicationVersion); - } else { - tw << installerSisHeader << endl; - } - - if (!containsStartWithItem('#', rawPkgPreRules)) { - t << sisHeader.arg(visualTarget).arg(uid3).arg(applicationVersion); - } - - // Localized vendor name - QString vendorName; - if (!containsStartWithItem('%', rawPkgPreRules)) { - vendorName += "; Localised Vendor name\n%{\"Vendor\"}\n\n"; - } - - // Unique vendor name - if (!containsStartWithItem(':', rawPkgPreRules)) { - vendorName += "; Unique Vendor name\n:\"Vendor\"\n\n"; - } - - t << vendorName; - tw << vendorName; - - // PKG pre-rules - these are added before actual file installations i.e. SIS package body - if (rawPkgPreRules.size()) { - QString comment = "\n; Manual PKG pre-rules from PRO files\n"; - t << comment; - tw << comment; - - foreach(QString item, rawPkgPreRules) { - // Only regular pkg file should have package dependencies or pkg header if that is - // defined using prerules. - if (!item.startsWith("(") && !item.startsWith("#")) { - tw << item << endl; - } - t << item << endl; - } - t << endl; - tw << endl; - } - - // Begin Manufacturer block - if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { - QString manufacturerStr("IF "); - foreach(QString manufacturer, project->values("DEPLOYMENT.manufacturers")) { - manufacturerStr.append(QString("(MANUFACTURER)=(%1) OR \n ").arg(manufacturer)); - } - // Remove the final OR - manufacturerStr.chop(8); - t << manufacturerStr << endl; - } - - // Install paths on the phone *** should be dynamic at some point - QString installPathBin = "!:\\sys\\bin"; - QString installPathResource = "!:\\resource\\apps"; - QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps"; - - // Find location of builds - QString epocReleasePath = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)") - .arg(epocRoot()); - - if (targetType == TypeExe) { - // deploy .exe file - t << "; Executable and default resource files" << endl; - QString exeFile = fixedTarget + ".exe"; - t << QString("\"%1/%2\" - \"%3\\%4\"") - .arg(epocReleasePath) - .arg(exeFile) - .arg(installPathBin) - .arg(exeFile) << endl; - - // deploy rsc & reg_rsc file - if (!project->isActiveConfig("no_icon")) { - t << QString("\"%1epoc32/data/z/resource/apps/%2\" - \"%3\\%4\"") - .arg(epocRoot()) - .arg(fixedTarget + ".rsc") - .arg(installPathResource) - .arg(fixedTarget + ".rsc") << endl; - - t << QString("\"%1epoc32/data/z/private/10003a3f/import/apps/%2\" - \"%3\\%4\"") - .arg(epocRoot()) - .arg(fixedTarget + "_reg.rsc") - .arg(installPathRegResource) - .arg(fixedTarget + "_reg.rsc") << endl; - - if (!iconFile.isEmpty()) { - t << QString("\"%1epoc32/data/z%2\" - \"!:%3\"") - .arg(epocRoot()) - .arg(iconFile) - .arg(QDir::toNativeSeparators(iconFile)) << endl << endl; - } - } - } - - // deploy any additional DEPLOYMENT files - QString remoteTestPath; - remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid); - - initProjectDeploySymbian(project, depList, remoteTestPath, true, "$(PLATFORM)", "$(TARGET)", generatedDirs, generatedFiles); - if (depList.size()) - t << "; DEPLOYMENT" << endl; - for (int i = 0; i < depList.size(); ++i) { - t << QString("\"%1\" - \"%2\"") - .arg(QString(depList.at(i).from).replace('\\','/')) - .arg(QString(depList.at(i).to).replace('/','\\')) << endl; - } - t << endl; - - // PKG post-rules - these are added after actual file installations i.e. SIS package body - t << "; Manual PKG post-rules from PRO files" << endl; - foreach(QString deploymentItem, project->values("DEPLOYMENT")) { - foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_postrules")) { - QStringList pkgrulesValue = project->values(pkgrulesItem); - // If there is no stringlist defined for a rule, use rule name directly - // This is convenience for defining single line statements - if (pkgrulesValue.isEmpty()) { - t << pkgrulesItem << endl; - } else { - foreach(QString pkgrule, pkgrulesValue) { - t << pkgrule << endl; - } - } - t << endl; - } - } - - // Close Manufacturer block - if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { - QString manufacturerFailNoteFile; - if (project->values("DEPLOYMENT.manufacturers.fail_note").isEmpty()) { - manufacturerFailNoteFile = QString("%1_" MANUFACTURER_NOTE_FILE).arg(uid3); - QFile ft(manufacturerFailNoteFile); - if (ft.open(QIODevice::WriteOnly)) { - generatedFiles << ft.fileName(); - QTextStream t2(&ft); - - t2 << QString(DEFAULT_MANUFACTURER_NOTE) << endl; - } else { - PRINT_FILE_CREATE_ERROR(manufacturerFailNoteFile) - } - } else { - manufacturerFailNoteFile = project->values("DEPLOYMENT.manufacturers.fail_note").join(""); - } - - t << "ELSEIF NOT(0) ; MANUFACTURER" << endl - << "\"" << fileInfo(manufacturerFailNoteFile).absoluteFilePath() << "\"" - << " - \"\", FILETEXT, TEXTEXIT" << endl - << "ENDIF ; MANUFACTURER" << endl; - } - - // Write wrapper pkg - if (!installerSisHeader.isEmpty()) { - QFile wrapperPkgFile(wrapperPkgFilename); - if (!wrapperPkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - PRINT_FILE_CREATE_ERROR(wrapperPkgFilename); - return; - } - - generatedFiles << wrapperPkgFile.fileName(); - QTextStream twf(&wrapperPkgFile); - - twf << wrapperStreamBuffer << endl; - - // Wrapped files deployment - QString currentPath = qmake_getpwd(); - QString sisName = QString("%1.sis").arg(fixedTarget); - twf << "\"" << currentPath << "/" << sisName << "\" - \"c:\\adm\\" << sisName << "\"" << endl; - - QString bootStrapPath = QLibraryInfo::location(QLibraryInfo::PrefixPath); - bootStrapPath.append("/smartinstaller.sis"); - QFileInfo fi(fileInfo(bootStrapPath)); - twf << "@\"" << fi.absoluteFilePath() << "\",(0x2002CCCD)" << endl; - } -} - -bool SymbianMakefileGenerator::containsStartWithItem(const QChar &c, const QStringList& src) -{ - bool result = false; - foreach(QString str, src) { - if (str.startsWith(c)) { - result = true; - break; - } - } - return result; -} - void SymbianMakefileGenerator::writeCustomDefFile() { if (targetType == TypePlugin && !project->isActiveConfig("stdbinary")) { @@ -575,9 +298,7 @@ void SymbianMakefileGenerator::writeCustomDefFile() void SymbianMakefileGenerator::init() { MakefileGenerator::init(); - fixedTarget = escapeFilePath(fileFixify(project->first("TARGET"))); - fixedTarget = removePathSeparators(fixedTarget); - removeSpecialCharacters(fixedTarget); + SymbianCommonGenerator::init(); if (0 != project->values("QMAKE_PLATFORM").size()) platform = varGlue("QMAKE_PLATFORM", "", " ", ""); @@ -594,60 +315,9 @@ void SymbianMakefileGenerator::init() // .mmp initMmpVariables(); - // Check TARGET.UID3 presence - if (0 != project->values("TARGET.UID3").size()) { - uid3 = project->first("TARGET.UID3"); - } else { - uid3 = generateUID3(); - } - - if ((project->values("TEMPLATE")).contains("app")) - targetType = TypeExe; - else if ((project->values("TEMPLATE")).contains("lib")) { - // Check CONFIG to see if we are to build staticlib or dll - if (project->isActiveConfig("staticlib") || project->isActiveConfig("static")) - targetType = TypeLib; - else if (project->isActiveConfig("plugin")) - targetType = TypePlugin; - else - targetType = TypeDll; - } else { - targetType = TypeSubdirs; - } - - if (0 != project->values("TARGET.UID2").size()) { - uid2 = project->first("TARGET.UID2"); - } else if (project->isActiveConfig("stdbinary")) { - uid2 = "0x20004C45"; - } else { - if (targetType == TypeExe) { - if (project->values("QT").contains("gui", Qt::CaseInsensitive)) { - // exe and gui -> uid2 needed - uid2 = "0x100039CE"; - } else { - // exe but not gui: uid2 is ignored anyway -> set it to 0 - uid2 = "0"; - } - } else if (targetType == TypeDll || targetType == TypeLib || targetType == TypePlugin) { - uid2 = "0x1000008d"; - } - } + uid2 = project->first("TARGET.UID2"); uid2 = uid2.trimmed(); - uid3 = uid3.trimmed(); - - // UID is valid as either hex or decimal, so just convert it to number and back to hex - // to get proper string for private dir - bool conversionOk = false; - uint uidNum = uid3.toUInt(&conversionOk, 0); - - if (!conversionOk) { - fprintf(stderr, "Error: Invalid UID \"%s\".\n", uid3.toUtf8().constData()); - } else { - privateDirUid.setNum(uidNum, 16); - while (privateDirUid.length() < 8) - privateDirUid.insert(0, QLatin1Char('0')); - } } QString SymbianMakefileGenerator::getTargetExtension() @@ -1345,7 +1015,7 @@ void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploy QString uid = generate_uid(fullProName); QString bldinfDefine = QString("BLD_INF_") + subdirFileName + QString("_") + uid; bldinfDefine = bldinfDefine.toUpper(); - removeSpecialCharacters(bldinfDefine); + removeEpocSpecialCharacters(bldinfDefine); if (!condition.isEmpty()) t << "#if defined(" << condition << ")" << endl; @@ -1424,442 +1094,6 @@ void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploy } } -void SymbianMakefileGenerator::writeRegRssFile(QMap<QString, QStringList> &userItems) -{ - QString filename(fixedTarget); - filename.append("_reg.rss"); - QFile ft(filename); - if (ft.open(QIODevice::WriteOnly)) { - generatedFiles << ft.fileName(); - QTextStream t(&ft); - t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; - t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; - t << "// * This file is generated by qmake and should not be modified by the" << endl; - t << "// * user." << endl; - t << "// ============================================================================" << endl; - t << endl; - t << "#include <" << fixedTarget << ".rsg>" << endl; - t << "#include <appinfo.rh>" << endl; - foreach(QString item, userItems[RSS_TAG_HEADER]) - t << item << endl; - t << endl; - t << "UID2 KUidAppRegistrationResourceFile" << endl; - t << "UID3 " << uid3 << endl << endl; - t << "RESOURCE APP_REGISTRATION_INFO" << endl; - t << "\t{" << endl; - t << "\tapp_file=\"" << fixedTarget << "\";" << endl; - t << "\tlocalisable_resource_file=\"" RESOURCE_DIRECTORY_RESOURCE << fixedTarget << "\";" << endl; - - writeRegRssList(t, userItems[RSS_TAG_SERVICE_LIST], - QLatin1String(RSS_TAG_SERVICE_LIST), - QLatin1String("SERVICE_INFO")); - writeRegRssList(t, userItems[RSS_TAG_FILE_OWNERSHIP_LIST], - QLatin1String(RSS_TAG_FILE_OWNERSHIP_LIST), - QLatin1String("FILE_OWNERSHIP_INFO")); - writeRegRssList(t, userItems[RSS_TAG_DATATYPE_LIST], - QLatin1String(RSS_TAG_DATATYPE_LIST), - QLatin1String("DATATYPE")); - t << endl; - - foreach(QString item, userItems[RSS_TAG_DEFAULT]) - t << "\t" << item.replace("\n","\n\t") << endl; - t << "\t}" << endl; - - foreach(QString item, userItems[RSS_TAG_FOOTER]) - t << item << endl; - } else { - PRINT_FILE_CREATE_ERROR(filename) - } -} - -void SymbianMakefileGenerator::writeRegRssList(QTextStream &t, - QStringList &userList, - const QString &listTag, - const QString &listItem) -{ - int itemCount = userList.count(); - if (itemCount) { - t << "\t" << listTag << " ="<< endl; - t << "\t\t{" << endl; - foreach(QString item, userList) { - t << "\t\t" << listItem << endl; - t << "\t\t\t{" << endl; - t << "\t\t\t" << item.replace("\n","\n\t\t\t") << endl; - t << "\t\t\t}"; - if (--itemCount) - t << ","; - t << endl; - } - t << "\t\t}; "<< endl; - } -} - -void SymbianMakefileGenerator::writeRssFile(QString &numberOfIcons, QString &iconFile) -{ - QString filename(fixedTarget); - filename.append(".rss"); - QFile ft(filename); - if (ft.open(QIODevice::WriteOnly)) { - generatedFiles << ft.fileName(); - QTextStream t(&ft); - t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; - t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; - t << "// * This file is generated by qmake and should not be modified by the" << endl; - t << "// * user." << endl; - t << "// ============================================================================" << endl; - t << endl; - t << "#include <appinfo.rh>" << endl; - t << "#include \"" << fixedTarget << ".loc\"" << endl; - t << endl; - t << "RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info" << endl; - t << "\t{" << endl; - t << "\tshort_caption = STRING_r_short_caption;" << endl; - t << "\tcaption_and_icon =" << endl; - t << "\tCAPTION_AND_ICON_INFO" << endl; - t << "\t\t{" << endl; - t << "\t\tcaption = STRING_r_caption;" << endl; - - QString rssIconFile = iconFile; - rssIconFile = rssIconFile.replace("/", "\\\\"); - - if (numberOfIcons.isEmpty() || rssIconFile.isEmpty()) { - // There can be maximum one item in this tag, validated when parsed - t << "\t\tnumber_of_icons = 0;" << endl; - t << "\t\ticon_file = \"\";" << endl; - } else { - // There can be maximum one item in this tag, validated when parsed - t << "\t\tnumber_of_icons = " << numberOfIcons << ";" << endl; - t << "\t\ticon_file = \"" << rssIconFile << "\";" << endl; - } - t << "\t\t};" << endl; - t << "\t}" << endl; - t << endl; - } else { - PRINT_FILE_CREATE_ERROR(filename); - } -} - -void SymbianMakefileGenerator::writeLocFile(QStringList &symbianLangCodes) -{ - QString filename(fixedTarget); - filename.append(".loc"); - QFile ft(filename); - if (ft.open(QIODevice::WriteOnly)) { - generatedFiles << ft.fileName(); - QTextStream t(&ft); - t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; - t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; - t << "// * This file is generated by qmake and should not be modified by the" << endl; - t << "// * user." << endl; - t << "// ============================================================================" << endl; - t << endl; - t << "#ifdef LANGUAGE_SC" << endl; - t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; - t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; - foreach(QString lang, symbianLangCodes) { - t << "#elif defined LANGUAGE_" << lang << endl; - t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; - t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; - } - t << "#else" << endl; - t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; - t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; - t << "#endif" << endl; - } else { - PRINT_FILE_CREATE_ERROR(filename); - } -} - -void SymbianMakefileGenerator::readRssRules(QString &numberOfIcons, - QString &iconFile, QMap<QString, - QStringList> &userRssRules) -{ - for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) { - if (it.key().startsWith(RSS_RULES_BASE)) { - QString newKey = it.key().mid(sizeof(RSS_RULES_BASE) - 1); - if (newKey.isEmpty()) { - fprintf(stderr, "Warning: Empty RSS_RULES_BASE key encountered\n"); - continue; - } - QStringList newValues; - QStringList values = it.value(); - foreach(QString item, values) { - // If there is no stringlist defined for a rule, use rule value directly - // This is convenience for defining single line statements - if (project->values(item).isEmpty()) { - newValues << item; - } else { - QStringList itemList; - foreach(QString itemRow, project->values(item)) { - itemList << itemRow; - } - newValues << itemList.join("\n"); - } - } - // Verify thet there is exactly one value in RSS_TAG_NBROFICONS - if (newKey == RSS_TAG_NBROFICONS) { - if (newValues.count() == 1) { - numberOfIcons = newValues[0]; - } else { - fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n", - RSS_RULES_BASE, RSS_TAG_NBROFICONS); - continue; - } - // Verify thet there is exactly one value in RSS_TAG_ICONFILE - } else if (newKey == RSS_TAG_ICONFILE) { - if (newValues.count() == 1) { - iconFile = newValues[0]; - } else { - fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n", - RSS_RULES_BASE, RSS_TAG_ICONFILE); - continue; - } - } else if (newKey == RSS_TAG_HEADER - || newKey == RSS_TAG_SERVICE_LIST - || newKey == RSS_TAG_FILE_OWNERSHIP_LIST - || newKey == RSS_TAG_DATATYPE_LIST - || newKey == RSS_TAG_FOOTER - || newKey == RSS_TAG_DEFAULT) { - userRssRules[newKey] = newValues; - continue; - } else { - fprintf(stderr, "Warning: Unsupported key:'%s%s'\n", - RSS_RULES_BASE, newKey.toLatin1().constData()); - continue; - } - } - } - - QStringList newValues; - foreach(QString item, project->values(RSS_RULES)) { - // If there is no stringlist defined for a rule, use rule value directly - // This is convenience for defining single line statements - if (project->values(item).isEmpty()) { - newValues << item; - } else { - newValues << project->values(item); - } - } - userRssRules[RSS_TAG_DEFAULT] << newValues; - - // Validate that either both RSS_TAG_NBROFICONS and RSS_TAG_ICONFILE keys exist - // or neither of them exist - if (!((numberOfIcons.isEmpty() && iconFile.isEmpty()) || - (!numberOfIcons.isEmpty() && !iconFile.isEmpty()))) { - numberOfIcons.clear(); - iconFile.clear(); - fprintf(stderr, "Warning: Both or neither of '%s%s' and '%s%s' keys must exist.\n", - RSS_RULES_BASE, RSS_TAG_NBROFICONS, RSS_RULES_BASE, RSS_TAG_ICONFILE); - } - - // Validate that RSS_TAG_NBROFICONS contains only numbers - if (!numberOfIcons.isEmpty()) { - bool ok; - numberOfIcons = numberOfIcons.simplified(); - numberOfIcons.toInt(&ok); - if (!ok) { - numberOfIcons.clear(); - iconFile.clear(); - fprintf(stderr, "Warning: '%s%s' must be integer in decimal format.\n", - RSS_RULES_BASE, RSS_TAG_NBROFICONS); - } - } -} - -QStringList SymbianMakefileGenerator::symbianLangCodesFromTsFiles() -{ - QStringList tsfiles; - QStringList symbianLangCodes; - tsfiles << project->values("TRANSLATIONS"); - - fillQt2S60LangMapTable(); - - foreach(QString file, tsfiles) { - int extIndex = file.lastIndexOf("."); - int langIndex = file.lastIndexOf("_", (extIndex - file.length())); - langIndex += 1; - QString qtlang = file.mid(langIndex, extIndex - langIndex); - QString s60lang = qt2S60LangMapTable.value(qtlang, QString("SC")); - - if (!symbianLangCodes.contains(s60lang) && s60lang != "SC") - symbianLangCodes += s60lang; - } - - return symbianLangCodes; -} - -void SymbianMakefileGenerator::fillQt2S60LangMapTable() -{ - qt2S60LangMapTable.reserve(170); // 165 items at time of writing. - qt2S60LangMapTable.insert("ab", "SC"); //Abkhazian // - qt2S60LangMapTable.insert("om", "SC"); //Afan // - qt2S60LangMapTable.insert("aa", "SC"); //Afar // - qt2S60LangMapTable.insert("af", "34"); //Afrikaans //Afrikaans - qt2S60LangMapTable.insert("sq", "35"); //Albanian //Albanian - qt2S60LangMapTable.insert("am", "36"); //Amharic //Amharic - qt2S60LangMapTable.insert("ar", "37"); //Arabic //Arabic - qt2S60LangMapTable.insert("hy", "38"); //Armenian //Armenian - qt2S60LangMapTable.insert("as", "SC"); //Assamese // - qt2S60LangMapTable.insert("ay", "SC"); //Aymara // - qt2S60LangMapTable.insert("az", "SC"); //Azerbaijani // - qt2S60LangMapTable.insert("ba", "SC"); //Bashkir // - qt2S60LangMapTable.insert("eu", "SC"); //Basque // - qt2S60LangMapTable.insert("bn", "41"); //Bengali //Bengali - qt2S60LangMapTable.insert("dz", "SC"); //Bhutani // - qt2S60LangMapTable.insert("bh", "SC"); //Bihari // - qt2S60LangMapTable.insert("bi", "SC"); //Bislama // - qt2S60LangMapTable.insert("br", "SC"); //Breton // - qt2S60LangMapTable.insert("bg", "42"); //Bulgarian //Bulgarian - qt2S60LangMapTable.insert("my", "43"); //Burmese //Burmese - qt2S60LangMapTable.insert("be", "40"); //Byelorussian //Belarussian - qt2S60LangMapTable.insert("km", "SC"); //Cambodian // - qt2S60LangMapTable.insert("ca", "44"); //Catalan //Catalan - qt2S60LangMapTable.insert("zh", "SC"); //Chinese // - qt2S60LangMapTable.insert("co", "SC"); //Corsican // - qt2S60LangMapTable.insert("hr", "45"); //Croatian //Croatian - qt2S60LangMapTable.insert("cs", "25"); //Czech //Czech - qt2S60LangMapTable.insert("da", "07"); //Danish //Danish - qt2S60LangMapTable.insert("nl", "18"); //Dutch //Dutch - qt2S60LangMapTable.insert("en", "01"); //English //English(UK) - qt2S60LangMapTable.insert("eo", "SC"); //Esperanto // - qt2S60LangMapTable.insert("et", "49"); //Estonian //Estonian - qt2S60LangMapTable.insert("fo", "SC"); //Faroese // - qt2S60LangMapTable.insert("fj", "SC"); //Fiji // - qt2S60LangMapTable.insert("fi", "09"); //Finnish //Finnish - qt2S60LangMapTable.insert("fr", "02"); //French //French - qt2S60LangMapTable.insert("fy", "SC"); //Frisian // - qt2S60LangMapTable.insert("gd", "52"); //Gaelic //Gaelic - qt2S60LangMapTable.insert("gl", "SC"); //Galician // - qt2S60LangMapTable.insert("ka", "53"); //Georgian //Georgian - qt2S60LangMapTable.insert("de", "03"); //German //German - qt2S60LangMapTable.insert("el", "54"); //Greek //Greek - qt2S60LangMapTable.insert("kl", "SC"); //Greenlandic // - qt2S60LangMapTable.insert("gn", "SC"); //Guarani // - qt2S60LangMapTable.insert("gu", "56"); //Gujarati //Gujarati - qt2S60LangMapTable.insert("ha", "SC"); //Hausa // - qt2S60LangMapTable.insert("he", "57"); //Hebrew //Hebrew - qt2S60LangMapTable.insert("hi", "58"); //Hindi //Hindi - qt2S60LangMapTable.insert("hu", "17"); //Hungarian //Hungarian - qt2S60LangMapTable.insert("is", "15"); //Icelandic //Icelandic - qt2S60LangMapTable.insert("id", "59"); //Indonesian //Indonesian - qt2S60LangMapTable.insert("ia", "SC"); //Interlingua // - qt2S60LangMapTable.insert("ie", "SC"); //Interlingue // - qt2S60LangMapTable.insert("iu", "SC"); //Inuktitut // - qt2S60LangMapTable.insert("ik", "SC"); //Inupiak // - qt2S60LangMapTable.insert("ga", "60"); //Irish //Irish - qt2S60LangMapTable.insert("it", "05"); //Italian //Italian - qt2S60LangMapTable.insert("ja", "32"); //Japanese //Japanese - qt2S60LangMapTable.insert("jv", "SC"); //Javanese // - qt2S60LangMapTable.insert("kn", "62"); //Kannada //Kannada - qt2S60LangMapTable.insert("ks", "SC"); //Kashmiri // - qt2S60LangMapTable.insert("kk", "63"); //Kazakh //Kazakh - qt2S60LangMapTable.insert("rw", "SC"); //Kinyarwanda // - qt2S60LangMapTable.insert("ky", "SC"); //Kirghiz // - qt2S60LangMapTable.insert("ko", "65"); //Korean //Korean - qt2S60LangMapTable.insert("ku", "SC"); //Kurdish // - qt2S60LangMapTable.insert("rn", "SC"); //Kurundi // - qt2S60LangMapTable.insert("lo", "66"); //Laothian //Laothian - qt2S60LangMapTable.insert("la", "SC"); //Latin // - qt2S60LangMapTable.insert("lv", "67"); //Latvian //Latvian - qt2S60LangMapTable.insert("ln", "SC"); //Lingala // - qt2S60LangMapTable.insert("lt", "68"); //Lithuanian //Lithuanian - qt2S60LangMapTable.insert("mk", "69"); //Macedonian //Macedonian - qt2S60LangMapTable.insert("mg", "SC"); //Malagasy // - qt2S60LangMapTable.insert("ms", "70"); //Malay //Malay - qt2S60LangMapTable.insert("ml", "71"); //Malayalam //Malayalam - qt2S60LangMapTable.insert("mt", "SC"); //Maltese // - qt2S60LangMapTable.insert("mi", "SC"); //Maori // - qt2S60LangMapTable.insert("mr", "72"); //Marathi //Marathi - qt2S60LangMapTable.insert("mo", "73"); //Moldavian //Moldovian - qt2S60LangMapTable.insert("mn", "74"); //Mongolian //Mongolian - qt2S60LangMapTable.insert("na", "SC"); //Nauru // - qt2S60LangMapTable.insert("ne", "SC"); //Nepali // - qt2S60LangMapTable.insert("nb", "08"); //Norwegian //Norwegian - qt2S60LangMapTable.insert("oc", "SC"); //Occitan // - qt2S60LangMapTable.insert("or", "SC"); //Oriya // - qt2S60LangMapTable.insert("ps", "SC"); //Pashto // - qt2S60LangMapTable.insert("fa", "SC"); //Persian // - qt2S60LangMapTable.insert("pl", "27"); //Polish //Polish - qt2S60LangMapTable.insert("pt", "13"); //Portuguese //Portuguese - qt2S60LangMapTable.insert("pa", "77"); //Punjabi //Punjabi - qt2S60LangMapTable.insert("qu", "SC"); //Quechua // - qt2S60LangMapTable.insert("rm", "SC"); //RhaetoRomance // - qt2S60LangMapTable.insert("ro", "78"); //Romanian //Romanian - qt2S60LangMapTable.insert("ru", "16"); //Russian //Russian - qt2S60LangMapTable.insert("sm", "SC"); //Samoan // - qt2S60LangMapTable.insert("sg", "SC"); //Sangho // - qt2S60LangMapTable.insert("sa", "SC"); //Sanskrit // - qt2S60LangMapTable.insert("sr", "79"); //Serbian //Serbian - qt2S60LangMapTable.insert("sh", "SC"); //SerboCroatian // - qt2S60LangMapTable.insert("st", "SC"); //Sesotho // - qt2S60LangMapTable.insert("tn", "SC"); //Setswana // - qt2S60LangMapTable.insert("sn", "SC"); //Shona // - qt2S60LangMapTable.insert("sd", "SC"); //Sindhi // - qt2S60LangMapTable.insert("si", "80"); //Singhalese //Sinhalese - qt2S60LangMapTable.insert("ss", "SC"); //Siswati // - qt2S60LangMapTable.insert("sk", "26"); //Slovak //Slovak - qt2S60LangMapTable.insert("sl", "28"); //Slovenian //Slovenian - qt2S60LangMapTable.insert("so", "81"); //Somali //Somali - qt2S60LangMapTable.insert("es", "04"); //Spanish //Spanish - qt2S60LangMapTable.insert("su", "SC"); //Sundanese // - qt2S60LangMapTable.insert("sw", "84"); //Swahili //Swahili - qt2S60LangMapTable.insert("sv", "06"); //Swedish //Swedish - qt2S60LangMapTable.insert("tl", "39"); //Tagalog //Tagalog - qt2S60LangMapTable.insert("tg", "SC"); //Tajik // - qt2S60LangMapTable.insert("ta", "87"); //Tamil //Tamil - qt2S60LangMapTable.insert("tt", "SC"); //Tatar // - qt2S60LangMapTable.insert("te", "88"); //Telugu //Telugu - qt2S60LangMapTable.insert("th", "33"); //Thai //Thai - qt2S60LangMapTable.insert("bo", "89"); //Tibetan //Tibetan - qt2S60LangMapTable.insert("ti", "90"); //Tigrinya //Tigrinya - qt2S60LangMapTable.insert("to", "SC"); //Tonga // - qt2S60LangMapTable.insert("ts", "SC"); //Tsonga // - qt2S60LangMapTable.insert("tr", "14"); //Turkish //Turkish - qt2S60LangMapTable.insert("tk", "92"); //Turkmen //Turkmen - qt2S60LangMapTable.insert("tw", "SC"); //Twi // - qt2S60LangMapTable.insert("ug", "SC"); //Uigur // - qt2S60LangMapTable.insert("uk", "93"); //Ukrainian //Ukrainian - qt2S60LangMapTable.insert("ur", "94"); //Urdu //Urdu - qt2S60LangMapTable.insert("uz", "SC"); //Uzbek // - qt2S60LangMapTable.insert("vi", "96"); //Vietnamese //Vietnamese - qt2S60LangMapTable.insert("vo", "SC"); //Volapuk // - qt2S60LangMapTable.insert("cy", "97"); //Welsh //Welsh - qt2S60LangMapTable.insert("wo", "SC"); //Wolof // - qt2S60LangMapTable.insert("xh", "SC"); //Xhosa // - qt2S60LangMapTable.insert("yi", "SC"); //Yiddish // - qt2S60LangMapTable.insert("yo", "SC"); //Yoruba // - qt2S60LangMapTable.insert("za", "SC"); //Zhuang // - qt2S60LangMapTable.insert("zu", "98"); //Zulu //Zulu - qt2S60LangMapTable.insert("nn", "75"); //Nynorsk //NorwegianNynorsk - qt2S60LangMapTable.insert("bs", "SC"); //Bosnian // - qt2S60LangMapTable.insert("dv", "SC"); //Divehi // - qt2S60LangMapTable.insert("gv", "SC"); //Manx // - qt2S60LangMapTable.insert("kw", "SC"); //Cornish // - qt2S60LangMapTable.insert("ak", "SC"); //Akan // - qt2S60LangMapTable.insert("kok", "SC"); //Konkani // - qt2S60LangMapTable.insert("gaa", "SC"); //Ga // - qt2S60LangMapTable.insert("ig", "SC"); //Igbo // - qt2S60LangMapTable.insert("kam", "SC"); //Kamba // - qt2S60LangMapTable.insert("syr", "SC"); //Syriac // - qt2S60LangMapTable.insert("byn", "SC"); //Blin // - qt2S60LangMapTable.insert("gez", "SC"); //Geez // - qt2S60LangMapTable.insert("kfo", "SC"); //Koro // - qt2S60LangMapTable.insert("sid", "SC"); //Sidamo // - qt2S60LangMapTable.insert("cch", "SC"); //Atsam // - qt2S60LangMapTable.insert("tig", "SC"); //Tigre // - qt2S60LangMapTable.insert("kaj", "SC"); //Jju // - qt2S60LangMapTable.insert("fur", "SC"); //Friulian // - qt2S60LangMapTable.insert("ve", "SC"); //Venda // - qt2S60LangMapTable.insert("ee", "SC"); //Ewe // - qt2S60LangMapTable.insert("wa", "SC"); //Walamo // - qt2S60LangMapTable.insert("haw", "SC"); //Hawaiian // - qt2S60LangMapTable.insert("kcg", "SC"); //Tyap // - qt2S60LangMapTable.insert("ny", "SC"); //Chewa // -} - void SymbianMakefileGenerator::appendIfnotExist(QStringList &list, QString value) { if (!list.contains(value)) @@ -1872,16 +1106,6 @@ void SymbianMakefileGenerator::appendIfnotExist(QStringList &list, QStringList v appendIfnotExist(list, item); } -QString SymbianMakefileGenerator::removePathSeparators(QString &file) -{ - QString ret = file; - while (ret.indexOf(QDir::separator()) > 0) { - ret.remove(0, ret.indexOf(QDir::separator()) + 1); - } - - return ret; -} - QString SymbianMakefileGenerator::removeTrailingPathSeparators(QString &file) { @@ -1913,17 +1137,6 @@ void SymbianMakefileGenerator::generateCleanCommands(QTextStream& t, } } -void SymbianMakefileGenerator::removeSpecialCharacters(QString& str) -{ - // When modifying this method check also application_icon.prf - str.replace(QString("/"), QString("_")); - str.replace(QString("\\"), QString("_")); - str.replace(QString("-"), QString("_")); - str.replace(QString(":"), QString("_")); - str.replace(QString("."), QString("_")); - str.replace(QString(" "), QString("_")); -} - void SymbianMakefileGenerator::generateDistcleanTargets(QTextStream& t) { t << "dodistclean:" << endl; diff --git a/qmake/generators/symbian/symmake.h b/qmake/generators/symbian/symmake.h index 0847ee8..d9ca390 100644 --- a/qmake/generators/symbian/symmake.h +++ b/qmake/generators/symbian/symmake.h @@ -43,6 +43,7 @@ #define SYMMAKEFILE_H #include "initprojectdeploy_symbian.h" +#include "symbiancommon.h" #include <makefile.h> QT_BEGIN_NAMESPACE @@ -53,22 +54,11 @@ QT_BEGIN_NAMESPACE #define MAKE_CACHE_NAME ".make.cache" #define SYMBIAN_TEST_CONFIG "symbian_test" -class SymbianMakefileGenerator : public MakefileGenerator +class SymbianMakefileGenerator : public MakefileGenerator, public SymbianCommonGenerator { protected: - enum TargetType { - TypeExe, - TypeDll, - TypeLib, - TypePlugin, - TypeSubdirs - }; - QString platform; QString uid2; - QString uid3; - QString privateDirUid; - TargetType targetType; QMap<QString, QStringList> sources; QMap<QString, QStringList> systeminclude; QMap<QString, QStringList> library; @@ -76,19 +66,10 @@ protected: QMap<QString, QStringList> makmakeCommands; QStringList overriddenMmpKeywords; - QStringList generatedFiles; - QStringList generatedDirs; - QHash<QString, QString> qt2S60LangMapTable; - - QString fixedTarget; - - void removeSpecialCharacters(QString& str); QString fixPathForMmp(const QString& origPath, const QDir& parentDir); QString absolutizePath(const QString& origPath); virtual bool writeMakefile(QTextStream &t); - void generatePkgFile(const QString &iconFile, DeploymentList &depList); - bool containsStartWithItem(const QChar &c, const QStringList& src); virtual void init(); @@ -130,23 +111,9 @@ protected: void writeCustomDefFile(); - void writeRegRssFile(QMap<QString, QStringList> &useritems); - void writeRegRssList(QTextStream &t, QStringList &userList, - const QString &listTag, - const QString &listItem); - void writeRssFile(QString &numberOfIcons, QString &iconfile); - void writeLocFile(QStringList &symbianLangCodes); - void readRssRules(QString &numberOfIcons, - QString &iconFile, - QMap<QString, QStringList> &userRssRules); - - QStringList symbianLangCodesFromTsFiles(); - void fillQt2S60LangMapTable(); - void appendIfnotExist(QStringList &list, QString value); void appendIfnotExist(QStringList &list, QStringList values); - QString removePathSeparators(QString &file); QString removeTrailingPathSeparators(QString &file); void generateCleanCommands(QTextStream& t, const QStringList& toClean, diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index f90421b..0ba1a3c 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -71,7 +71,7 @@ SymbianAbldMakefileGenerator::~SymbianAbldMakefileGenerator() { } void SymbianAbldMakefileGenerator::writeMkFile(const QString& wrapperFileName, bool deploymentOnly) { QString gnuMakefileName = QLatin1String("Makefile_") + uid3; - removeSpecialCharacters(gnuMakefileName); + removeEpocSpecialCharacters(gnuMakefileName); gnuMakefileName.append(".mk"); QFile ft(gnuMakefileName); @@ -204,6 +204,8 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; + t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; #ifdef Q_OS_WIN32 t << "XCOPY = xcopy /d /f /h /r /y /i" << endl; t << "ABLD = ABLD.BAT" << endl; @@ -430,7 +432,7 @@ bool SymbianAbldMakefileGenerator::writeDeploymentTargets(QTextStream &t, bool i + privateDirUid; DeploymentList depList; - initProjectDeploySymbian(project, depList, remoteTestPath, false, + initProjectDeploySymbian(project, depList, remoteTestPath, false, true, QLatin1String(isRom ? ROM_DEPLOYMENT_PLATFORM : EMULATOR_DEPLOYMENT_PLATFORM), QString(), generatedDirs, generatedFiles); @@ -472,7 +474,7 @@ void SymbianAbldMakefileGenerator::writeBldInfMkFilePart(QTextStream& t, bool ad // do not get that, special deployment only makefile is generated for them if needed. if (targetType != TypeSubdirs || addDeploymentExtension) { QString gnuMakefileName = QLatin1String("Makefile_") + uid3; - removeSpecialCharacters(gnuMakefileName); + removeEpocSpecialCharacters(gnuMakefileName); gnuMakefileName.append(".mk"); t << "gnumakefile " << gnuMakefileName << endl; } diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index 79663fb..c817056 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -147,6 +147,8 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << "QMAKE = " << var("QMAKE_QMAKE") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; + t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; t << "DEBUG_PLATFORMS = " << debugPlatforms.join(" ") << endl; t << "RELEASE_PLATFORMS = " << releasePlatforms.join(" ") << endl; @@ -386,7 +388,7 @@ void SymbianSbsv2MakefileGenerator::writeBldInfExtensionRulesPart(QTextStream& t //write emulator deployment t << "#if defined(WINSCW)" << endl; - initProjectDeploySymbian(project, depList, remoteTestPath, false, + initProjectDeploySymbian(project, depList, remoteTestPath, false, true, QLatin1String(EMULATOR_DEPLOYMENT_PLATFORM), QString(), generatedDirs, generatedFiles); writeSbsDeploymentList(depList, t); t << "#endif" << endl; @@ -394,7 +396,7 @@ void SymbianSbsv2MakefileGenerator::writeBldInfExtensionRulesPart(QTextStream& t //write ROM deployment remoteTestPath = epocRoot() + QLatin1String("epoc32/data/z/private/") + privateDirUid; depList.clear(); - initProjectDeploySymbian(project, depList, remoteTestPath, false, + initProjectDeploySymbian(project, depList, remoteTestPath, false, true, QLatin1String(ROM_DEPLOYMENT_PLATFORM), QString(), generatedDirs, generatedFiles); writeSbsDeploymentList(depList, t); t << endl; diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index f85d707..db5b957 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -65,6 +65,10 @@ UnixMakefileGenerator::init() } } + if (project->isEmpty("QMAKE_PREFIX_SHLIB")) + // Prevent crash when using the empty variable. + project->values("QMAKE_PREFIX_SHLIB").append(""); + if(!project->isEmpty("QMAKE_FAILED_REQUIREMENTS")) /* no point */ return; @@ -449,7 +453,9 @@ UnixMakefileGenerator::findLibraries() if(!libdirs.contains(f)) libdirs.append(f); } else if(opt.startsWith("-l")) { - if (project->isActiveConfig("rvct_linker")) { + if (!project->isEmpty("QMAKE_RVCT_LINKSTYLE")) { + (*it) = opt.mid(2); + } else if (project->isActiveConfig("rvct_linker")) { (*it) = "lib" + opt.mid(2) + ".so"; } else { stub = opt.mid(2); @@ -489,26 +495,29 @@ UnixMakefileGenerator::findLibraries() QStringList extens; if(!extn.isNull()) extens << extn; + else if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) + // In Symbian you link to the stub .lib file, but run with the .dll file. + extens << "lib"; else extens << project->values("QMAKE_EXTENSION_SHLIB").first() << "a"; for(QStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) { if(dir.isNull()) { - QString lib_stub; for(QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) { - if(exists((*dep_it).local() + Option::dir_sep + "lib" + stub + - "." + (*extit))) { - lib_stub = stub; + QString pathToLib = ((*dep_it).local() + Option::dir_sep + + project->values("QMAKE_PREFIX_SHLIB").first() + + stub + "." + (*extit)); + if(exists(pathToLib)) { + if (!project->isEmpty("QMAKE_RVCT_LINKSTYLE")) + (*it) = pathToLib; + else + (*it) = "-l" + stub; + found = true; break; } } - if(!lib_stub.isNull()) { - (*it) = "-l" + lib_stub; - found = true; - break; - } } else { - if(exists("lib" + stub + "." + (*extit))) { - (*it) = "lib" + stub + "." + (*extit); + if(exists(project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit))) { + (*it) = project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit); found = true; break; } @@ -516,8 +525,8 @@ UnixMakefileGenerator::findLibraries() } if(!found && project->isActiveConfig("compile_libtool")) { for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { - if(exists(libdirs[dep_i].local() + Option::dir_sep + "lib" + stub + Option::libtool_ext)) { - (*it) = libdirs[dep_i].real() + Option::dir_sep + "lib" + stub + Option::libtool_ext; + if(exists(libdirs[dep_i].local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext)) { + (*it) = libdirs[dep_i].real() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext; found = true; break; } @@ -557,7 +566,7 @@ UnixMakefileGenerator::processPrlFiles() for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { const QMakeLocalFileName &lfn = libdirs[dep_i]; if(!project->isActiveConfig("compile_libtool")) { //give them the .libs.. - QString la = lfn.local() + Option::dir_sep + "lib" + lib + Option::libtool_ext; + QString la = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib + Option::libtool_ext; if(exists(la) && QFile::exists(lfn.local() + Option::dir_sep + ".libs")) { QString dot_libs = lfn.real() + Option::dir_sep + ".libs"; l.append("-L" + dot_libs); @@ -565,7 +574,7 @@ UnixMakefileGenerator::processPrlFiles() } } - QString prl = lfn.local() + Option::dir_sep + "lib" + lib; + QString prl = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib; if(!project->isEmpty("QMAKE_" + lib.toUpper() + "_SUFFIX")) prl += project->first("QMAKE_" + lib.toUpper() + "_SUFFIX"); if(processPrlFile(prl)) { diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h index 77bdd01..0ea3350 100644 --- a/qmake/generators/unix/unixmake.h +++ b/qmake/generators/unix/unixmake.h @@ -49,7 +49,6 @@ QT_BEGIN_NAMESPACE class UnixMakefileGenerator : public MakefileGenerator { bool init_flag, include_deps; - bool writeMakefile(QTextStream &); QString libtoolFileName(bool fixify=true); void writeLibtoolFile(); // for libtool QString pkgConfigPrefix() const; @@ -75,6 +74,7 @@ protected: virtual void init(); void writeMakeParts(QTextStream &); + bool writeMakefile(QTextStream &); private: void init2(); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 5def030..3e731a1 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -177,6 +177,12 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_MACOSX_DEPLOYMENT_TARGET")) t << "export MACOSX_DEPLOYMENT_TARGET = " //exported to children processes << project->first("QMAKE_MACOSX_DEPLOYMENT_TARGET") << endl; + + if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) { + t << "vpath %.dso " << project->values("QMAKE_LIBDIR").join(":") << endl; + t << "vpath %.lib " << project->values("QMAKE_LIBDIR").join(":") << endl; + } + t << endl; t << "####### Output directory" << endl << endl; @@ -233,6 +239,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_BUNDLE")) { t << "TARGETD = " << escapeFilePath(var("TARGET_x.y")) << endl; t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; + } else if(!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) { + t << "TARGETD = " << escapeFilePath(var("TARGET")) << endl; } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { t << "TARGETD = " << escapeFilePath(var("TARGET_x.y.z")) << endl; t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; @@ -332,7 +340,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "SUBLIBS = "; QStringList &l = project->values("SUBLIBS"); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) - t << libdir << "lib" << (*it) << ".a "; + t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "." + << project->first("QMAKE_EXTENSION_STATICLIB") << " "; t << endl << endl; } if(project->isActiveConfig("depend_prl") && !project->isEmpty("QMAKE_PRL_INTERNAL_FILES")) { @@ -545,6 +554,17 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; + } else if(!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) { + t << "\n\t" + << "-$(DEL_FILE) $(TARGET)" << "\n\t" + << var("QMAKE_LINK_SHLIB_CMD"); + if(!destdir.isEmpty()) + t << "\n\t" + << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t" + << "-$(MOVE) $(TARGET) " << destdir; + if(!project->isEmpty("QMAKE_POST_LINK")) + t << "\n\t" << var("QMAKE_POST_LINK"); + t << endl << endl; } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { t << "\n\t" << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)" << "\n\t" @@ -860,7 +880,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) libdir = project->first("SUBLIBS_DIR"); QStringList &l = project->values("SUBLIBS"); for(it = l.begin(); it != l.end(); ++it) - t << libdir << "lib" << (*it) << ".a" << ":\n\t" + t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "." + << project->first("QMAKE_EXTENSION_STATICLIB") << ":\n\t" << var(QString("MAKELIB") + (*it)) << endl << endl; } @@ -875,9 +896,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t-$(LIBTOOL) --mode=clean $(DEL_FILE) " << "$(TARGET)" << endl; } else if(!project->isActiveConfig("staticlib") && project->values("QMAKE_APP_FLAG").isEmpty() && !project->isActiveConfig("plugin")) { - t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << endl - << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " - << destdir << "$(TARGET2) $(TARGETA)" << endl; + t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << endl; + if (project->values("QMAKE_SYMBIAN_SHLIB").isEmpty()) + t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " + << destdir << "$(TARGET2) $(TARGETA)" << endl; } else { t << "\t-$(DEL_FILE) " << "$(TARGET)" << " " << endl; } @@ -992,12 +1014,13 @@ void UnixMakefileGenerator::init2() if (!project->values("QMAKE_CYGWIN_EXE").isEmpty()) project->values("TARGET_EXT").append(".exe"); } else if (project->isActiveConfig("staticlib")) { - project->values("TARGET").first().prepend("lib"); - project->values("TARGET").first() += ".a"; + project->values("TARGET").first().prepend(project->first("QMAKE_PREFIX_STATICLIB")); + project->values("TARGET").first() += "." + project->first("QMAKE_EXTENSION_STATICLIB"); if(project->values("QMAKE_AR_CMD").isEmpty()) project->values("QMAKE_AR_CMD").append("$(AR) $(TARGET) $(OBJECTS)"); } else { - project->values("TARGETA").append(project->first("DESTDIR") + "lib" + project->first("TARGET") + ".a"); + project->values("TARGETA").append(project->first("DESTDIR") + project->first("QMAKE_PREFIX_STATICLIB") + + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_STATICLIB")); if(project->isActiveConfig("compile_libtool")) project->values("TARGET_la") = QStringList(project->first("DESTDIR") + "lib" + project->first("TARGET") + Option::libtool_ext); @@ -1045,7 +1068,8 @@ void UnixMakefileGenerator::init2() project->first("VER_MAJ")); project->values("TARGET") = project->values("TARGET_x"); } else if (!project->isEmpty("QMAKE_AIX_SHLIB")) { - project->values("TARGET_").append("lib" + project->first("TARGET") + ".a"); + project->values("TARGET_").append(project->first("QMAKE_PREFIX_STATICLIB") + project->first("TARGET") + + "." + project->first("QMAKE_EXTENSION_STATICLIB")); if(project->isActiveConfig("lib_version_first")) { project->values("TARGET_x").append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + @@ -1074,6 +1098,10 @@ void UnixMakefileGenerator::init2() project->first("VER_PAT")); } project->values("TARGET") = project->values("TARGET_x.y.z"); + } else if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) { + project->values("TARGET_").append(project->first("TARGET") + "." + + project->first("QMAKE_EXTENSION_SHLIB")); + project->values("TARGET") = project->values("TARGET_"); } else { project->values("TARGET_").append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB")); diff --git a/qmake/option.cpp b/qmake/option.cpp index b41e39d..d7c5397 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -410,6 +410,7 @@ Option::init(int argc, char **argv) Option::res_ext = ".res"; #else Option::dirlist_sep = ":"; + Option::shellPath = QStringList("sh"); #endif Option::sysenv_mod = "QMAKE_ENV_"; Option::field_sep = ' '; diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 5654a18..a80eed4 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -8,7 +8,7 @@ symbian: { TARGET.CAPABILITY = All -Tcb TARGET.UID3 = 0x200267C2 - webkitlibs.sources = QtWebKit.dll + webkitlibs.sources = $$QMAKE_LIBDIR_QT/QtWebKit.dll webkitlibs.path = /sys/bin vendorinfo = \ "; Localised Vendor name" \ @@ -24,9 +24,12 @@ symbian: { DEPLOYMENT += webkitlibs webkitbackup - # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target. - # Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000. - MMP_RULES += "LINKEROPTION armcc --rw-base 0xE00000" + symbian-abld|symbian-sbsv2 { + # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target. + # Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000. + QMAKE_LFLAGS.ARMCC += --rw-base 0xE00000 + CONFIG += do_not_build_as_thumb + } } include($$PWD/../WebKit.pri) @@ -3417,7 +3420,7 @@ CONFIG(QTDIR_build):isEqual(QT_MAJOR_VERSION, 4):greaterThan(QT_MINOR_VERSION, 4 symbian { shared { contains(CONFIG, def_files) { - defFilePath=../WebKit/qt/symbian + DEF_FILE=../WebKit/qt/symbian } } } diff --git a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp index cf69723..fd604a0 100644 --- a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp @@ -53,7 +53,7 @@ #include "runtime_root.h" #include "QWebPageClient.h" #include <QKeyEvent> -#include <QPixmap.h> +#include <QPixmap> #include <QRegion> #include <QVector> #include <QWidget> diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index df9a463..500cde6 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -48,7 +48,7 @@ symbian: { pu_header = "; Partial upgrade package for testing QtCore changes without reinstalling everything" \ "$${LITERAL_HASH}{\"Qt corelib\"}, (0x2001E61C), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU" partial_upgrade.pkg_prerules = pu_header vendorinfo - partial_upgrade.sources = qtcore.dll + partial_upgrade.sources = $$QMAKE_LIBDIR_QT/QtCore.dll partial_upgrade.path = c:/sys/bin DEPLOYMENT = partial_upgrade $$DEPLOYMENT } diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index c8f836a..dfa2c17 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -58,6 +58,11 @@ #include <stdarg.h> #include <string.h> +#ifndef QT_NO_EXCEPTIONS +# include <string> +# include <exception> +#endif + #if !defined(Q_OS_WINCE) # include <errno.h> # if defined(Q_CC_MSVC) diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 2ed0e46..ef448b1 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -74,7 +74,7 @@ win32 { SOURCES += io/qsettings_mac.cpp io/qfilesystemwatcher_fsevents.cpp } - linux-*:{ + linux-*:!symbian { SOURCES += \ io/qfilesystemwatcher_inotify.cpp \ io/qfilesystemwatcher_dnotify.cpp diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 728c316..aa1c7d9 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -62,21 +62,25 @@ static const int QFILE_WRITEBUFFER_SIZE = 16384; static QByteArray locale_encode(const QString &f) { -#ifndef Q_OS_DARWIN - return f.toLocal8Bit(); -#else +#if defined(Q_OS_DARWIN) // Mac always expects UTF-8... and decomposed... return f.normalized(QString::NormalizationForm_D).toUtf8(); +#elif defined(Q_OS_SYMBIAN) + return f.toUtf8(); +#else + return f.toLocal8Bit(); #endif } static QString locale_decode(const QByteArray &f) { -#ifndef Q_OS_DARWIN - return QString::fromLocal8Bit(f); -#else +#if defined(Q_OS_DARWIN) // Mac always gives us UTF-8 and decomposed, we want that composed... return QString::fromUtf8(f).normalized(QString::NormalizationForm_C); +#elif defined(Q_OS_SYMBIAN) + return QString::fromUtf8(f); +#else + return QString::fromLocal8Bit(f); #endif } diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 6df00d6..3dcc1ad 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -55,7 +55,7 @@ #include <stdlib.h> #include <limits.h> #if defined(Q_OS_SYMBIAN) -# include <syslimits.h> +# include <sys/syslimits.h> # include <f32file.h> # include <pathinfo.h> # include "private/qcore_symbian_p.h" diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index adc87fb..8902f7d 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -66,7 +66,7 @@ #include "qstring.h" #include "qprocess.h" #include "qprocess_p.h" -#include "qeventdispatcher_symbian_p.h" +#include "private/qeventdispatcher_symbian_p.h" #include <private/qthread_p.h> #include <qmutex.h> diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 6d33c8b..8e76e9e 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1411,8 +1411,12 @@ QString QResourceFileEngine::fileName(FileName file) const } else if(file == PathName || file == AbsolutePathName) { const QString path = (file == AbsolutePathName) ? d->resource.absoluteFilePath() : d->resource.fileName(); const int slash = path.lastIndexOf(QLatin1Char('/')); - if (slash != -1) - return path.left(slash); + if (slash == -1) + return QLatin1String(":"); + else if (slash <= 1) + return QLatin1String(":/"); + return path.left(slash); + } else if(file == CanonicalName || file == CanonicalPathName) { const QString absoluteFilePath = d->resource.absoluteFilePath(); if(file == CanonicalPathName) { diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 30af6fa..ce9ed58 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -518,19 +518,15 @@ int QMetaType::registerTypedef(const char* typeName, int aliasId) idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(), normalizedTypeName.size()); - if (idx) { - Q_ASSERT(idx == aliasId); + if (idx) return idx; - } - if (!idx) { - QCustomTypeInfo inf; - inf.typeName = normalizedTypeName; - inf.alias = aliasId; - inf.constr = 0; - inf.destr = 0; - ct->append(inf); - } + QCustomTypeInfo inf; + inf.typeName = normalizedTypeName; + inf.alias = aliasId; + inf.constr = 0; + inf.destr = 0; + ct->append(inf); return aliasId; } diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 389e6e7..68f34ca 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2033,6 +2033,8 @@ void QObjectPrivate::setParent_helper(QObject *o) } } } + if (!wasDeleted && declarativeData) + declarativeData->parentChanged(q, o); } /*! diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index cc5bf97..20e3da1 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -90,6 +90,7 @@ class Q_CORE_EXPORT QDeclarativeData public: virtual ~QDeclarativeData(); virtual void destroyed(QObject *) = 0; + virtual void parentChanged(QObject *, QObject *) = 0; }; class Q_CORE_EXPORT QObjectPrivate : public QObjectData diff --git a/src/corelib/kernel/qsystemsemaphore_symbian.cpp b/src/corelib/kernel/qsystemsemaphore_symbian.cpp index c252dd5..8cef611 100644 --- a/src/corelib/kernel/qsystemsemaphore_symbian.cpp +++ b/src/corelib/kernel/qsystemsemaphore_symbian.cpp @@ -44,7 +44,7 @@ #include "qcoreapplication.h" #include <qdebug.h> -#include <qcore_symbian_p.h> +#include "qcore_symbian_p.h" #include <e32cmn.h> QT_BEGIN_NAMESPACE diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 591fb3d..7c584b4d 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,4 +1,32 @@ ============================================================================= +The changes below are pre Qt 4.7.0 beta + +PathView: offset property now uses range 0-1.0 rather than 0-100 +ListView, GridView::positionViewAtIndex() gained a 'mode' parameter +Removed Qt.playSound (replaced by SoundEffect element) +Removed Qt.closestAngle (use RotationAnimation instead) +Removed NumberFormatter +Removed DateTimeFormatter (use Qt.formatDateTime() instead) +Using WebView now requires "import org.webkit 1.0" +Using Particles now requires "import Qt.labs.particles 1.0" +AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) + +C++ API +------- +QDeclarativeContext::addDefaultObject() has been replaced with +QDeclarativeContext::setContextObject() + +Behavior and Animation syntax +----------------------------- +Previously animations and behaviors could be "assigned" to properties like this: + Item { x: Behavior {}; y: NumberAnimation {} } +To make it more obvious that these are not regular value assignments a new "on" +syntax has been introduced: + Item { Behavior on x {}; NumberAnimation on y {} } +Only the syntax has changed, the behavior is identical. + + +============================================================================= The changes below are pre Qt 4.7.0 alpha Flickable: renamed viewportWidth -> contentWidth @@ -6,33 +34,14 @@ Flickable: renamed viewportHeight -> contentHeight Flickable: renamed viewportX -> contentX Flickable: renamed viewportY -> contentY Removed Flickable.reportedVelocitySmoothing -Removed Qt.playSound (replaced by SoundEffect element) -Removed NumberFormatter -Removed DateTimeFormatter (use Qt.formatDateTime() instead) Renamed MouseRegion -> MouseArea Connection: syntax and rename: Connection { sender: a; signal: foo(); script: xxx } Connection { sender: a; signal: bar(); script: yyy } becomes: Connections { target: a; onFoo: xxx; onBar: yyy } -Using WebView now requires "import org.webkit 1.0" - -QmlView -------- -The API of QmlView has been narrowed and its role as a convenience class -reinforced. -- remove addItem() -- remove clearItems() - use 'delete root()' -- remove reset() -- resizeContent -> enum ResizeMode { SizeViewToRootObject, SizeRootObjectToView } -- remove setQml(), qml() -- rename setUrl(), ur() to setSource(), source() -- root() -> rootObject(), returns QGraphicsObject rather than QmlGraphicsItem -- remove quit() signal -> use quit() signal of engine() -- initialSize() signal removed -- Added status() to determine status of the internal QmlComponent -sectionExpression has been replaced by section.property, section.criteria +ListView::sectionExpression has been replaced by section.property, section.criteria ListModel --------- @@ -42,29 +51,45 @@ ListModel - foo: true is now a bool (not string "true") - foo: false is now a bool (not string "false" == true!) -C++ API -------- -QML_DEFINE_... definition macros, previously global macros, are replaced by -QML_REGISTER_... registration macros, which must be called explicitly. C++ API users -should also consider using the QmlExtensionPlugin (previously named QmlModulePlugin) -as a cleaner mechanism for publishing libraries of QML types, or the upcoming -application plugin features of the qmlviewer / qmlruntime / qml. - PropertyAnimation ------------------ matchProperties and matchTargets have been renamed back to properties and targets. The semantics are explained in the PropertyAnimation::properties documentation and the animation overview documentation. -Behavior and Animation syntax ------------------------------ +Easing curves and their parameters are now specified via dot properties: +* easing.type : enum +* easing.amplitude : real +* easing.overshoot : real +* easing.period : real +For example: +PropertyAnimation { properties: "y"; easing.type: "InOutElastic"; easing.amplitude: 2.0; easing.period: 1.5 } + +C++ API +------- +QML_DEFINE_... definition macros, previously global macros, are replaced by +qmlRegisterType registration functions, which must be called explicitly. +C++ API users should also consider using the QmlExtensionPlugin (previously +named QmlModulePlugin) as a cleaner mechanism for publishing libraries of QML +types, or the upcoming application plugin features of the qmlviewer / +qmlruntime / qml. + +QmlView +------- +The API of QmlView has been narrowed and its role as a convenience class +reinforced. +- remove addItem() +- remove clearItems() - use 'delete root()' +- remove reset() +- resizeContent -> enum ResizeMode { SizeViewToRootObject, SizeRootObjectToView } +- remove setQml(), qml() +- rename setUrl(), ur() to setSource(), source() +- root() -> rootObject(), returns QGraphicsObject rather than QmlGraphicsItem +- remove quit() signal -> use quit() signal of engine() +- initialSize() signal removed +- Added status() to determine status of the internal QmlComponent +- removed execute() - setSource() will also execute the QML. -Previously animations and behaviors could be "assigned" to properties like this: - Item { x: Behavior {}; y: NumberAnimation {} } -To make it more obvious that these are not regular value assignments a new "on" -syntax has been introduced: - Item { Behavior on x {}; NumberAnimation on y {} } -Only the syntax has changed, the behavior is identical. ============================================================================= The changes below are pre-4.6.0 release. diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri index 3ff92b1..d30651b 100644 --- a/src/declarative/graphicsitems/graphicsitems.pri +++ b/src/declarative/graphicsitems/graphicsitems.pri @@ -48,7 +48,6 @@ HEADERS += \ $$PWD/qdeclarativevisualitemmodel_p.h \ $$PWD/qdeclarativelistview_p.h \ $$PWD/qdeclarativegraphicsobjectcontainer_p.h \ - $$PWD/qdeclarativeparticles_p.h \ $$PWD/qdeclarativelayoutitem_p.h \ $$PWD/qdeclarativeitemchangelistener_p.h \ $$PWD/qdeclarativeeffects.cpp @@ -82,5 +81,4 @@ SOURCES += \ $$PWD/qdeclarativevisualitemmodel.cpp \ $$PWD/qdeclarativelistview.cpp \ $$PWD/qdeclarativegraphicsobjectcontainer.cpp \ - $$PWD/qdeclarativeparticles.cpp \ - $$PWD/qdeclarativelayoutitem.cpp \ + $$PWD/qdeclarativelayoutitem.cpp diff --git a/src/declarative/graphicsitems/qdeclarativeanchors_p.h b/src/declarative/graphicsitems/qdeclarativeanchors_p.h index 0b97e8c..1961fdd 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors_p.h +++ b/src/declarative/graphicsitems/qdeclarativeanchors_p.h @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QDeclarativeAnchorsPrivate; -class QDeclarativeAnchorLine; +struct QDeclarativeAnchorLine; class Q_DECLARATIVE_EXPORT QDeclarativeAnchors : public QObject { Q_OBJECT diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp index 20b1de3..2c2e034 100644 --- a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp @@ -247,9 +247,25 @@ void QDeclarativeAnimatedImage::setSource(const QUrl &url) emit statusChanged(d->status); } +#define ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION 16 + void QDeclarativeAnimatedImage::movieRequestFinished() { Q_D(QDeclarativeAnimatedImage); + + d->redirectCount++; + if (d->redirectCount < ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION) { + QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = d->reply->url().resolved(redirect.toUrl()); + d->reply->deleteLater(); + d->reply = 0; + setSource(url); + return; + } + } + d->redirectCount=0; + d->_movie = new QMovie(d->reply); if (!d->_movie->isValid()){ qWarning() << "Error Reading Animated Image File " << d->url; diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h b/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h index 39bb3e5..273c1d6 100644 --- a/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h @@ -66,7 +66,7 @@ class QDeclarativeAnimatedImagePrivate : public QDeclarativeImagePrivate public: QDeclarativeAnimatedImagePrivate() - : playing(true), paused(false), preset_currentframe(0), _movie(0), reply(0) + : playing(true), paused(false), preset_currentframe(0), _movie(0), reply(0), redirectCount(0) { } @@ -75,6 +75,7 @@ public: int preset_currentframe; QMovie *_movie; QNetworkReply *reply; + int redirectCount; }; QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp index de16668..a7534b8 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp @@ -191,7 +191,7 @@ void QDeclarativeBorderImage::load() update(); } else { d->status = Loading; - if (d->url.path().endsWith(QLatin1String(".sci"))) { + if (d->url.path().endsWith(QLatin1String("sci"))) { #ifndef QT_NO_LOCALFILE_OPTIMIZED_QML QString lf = toLocalFileOrQrc(d->url); if (!lf.isEmpty()) { @@ -400,9 +400,23 @@ void QDeclarativeBorderImage::requestFinished() update(); } +#define BORDERIMAGE_MAX_REDIRECT 16 + void QDeclarativeBorderImage::sciRequestFinished() { Q_D(QDeclarativeBorderImage); + + d->redirectCount++; + if (d->redirectCount < BORDERIMAGE_MAX_REDIRECT) { + QVariant redirect = d->sciReply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = d->sciReply->url().resolved(redirect.toUrl()); + setSource(url); + return; + } + } + d->redirectCount=0; + if (d->sciReply->error() != QNetworkReply::NoError) { d->status = Error; d->sciReply->deleteLater(); diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h b/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h index b9cf73a..82b9ebf 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h @@ -68,7 +68,8 @@ public: : border(0), sciReply(0), sciPendingPixmapCache(false), horizontalTileMode(QDeclarativeBorderImage::Stretch), - verticalTileMode(QDeclarativeBorderImage::Stretch) + verticalTileMode(QDeclarativeBorderImage::Stretch), + redirectCount(0) { } @@ -90,6 +91,7 @@ public: bool sciPendingPixmapCache; QDeclarativeBorderImage::TileMode horizontalTileMode; QDeclarativeBorderImage::TileMode verticalTileMode; + int redirectCount; }; QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 67068a0..9ccb3b6 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -264,6 +264,7 @@ void QDeclarativeFlickablePrivate::fixupY() void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) { + Q_Q(QDeclarativeFlickable); if (data.move.value() > minExtent || maxExtent > minExtent) { timeline.reset(data.move); if (data.move.value() != minExtent) { @@ -273,6 +274,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4); } else { data.move.setValue(minExtent); + q->viewportMoved(); } } //emit flickingChanged(); @@ -284,6 +286,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4); } else { data.move.setValue(maxExtent); + q->viewportMoved(); } //emit flickingChanged(); } else { diff --git a/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp b/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp index 0323a59..20524b6 100644 --- a/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp +++ b/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp @@ -41,6 +41,8 @@ #include "qdeclarativefocuspanel_p.h" +#include "qdeclarativeitem_p.h" + #include <QtGui/qgraphicsscene.h> #include <QEvent> @@ -65,7 +67,8 @@ QT_BEGIN_NAMESPACE QDeclarativeFocusPanel::QDeclarativeFocusPanel(QDeclarativeItem *parent) : QDeclarativeItem(parent) { - setFlag(ItemIsPanel); + Q_D(QDeclarativeItem); + d->flags |= QGraphicsItem::ItemIsPanel; } QDeclarativeFocusPanel::~QDeclarativeFocusPanel() diff --git a/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h b/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h index 1ad8b6e..d9ca0b0 100644 --- a/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h +++ b/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h @@ -66,6 +66,7 @@ protected: private: Q_DISABLE_COPY(QDeclarativeFocusPanel) + Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeItem) }; QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativefocusscope.cpp b/src/declarative/graphicsitems/qdeclarativefocusscope.cpp index 384a47b..484df13 100644 --- a/src/declarative/graphicsitems/qdeclarativefocusscope.cpp +++ b/src/declarative/graphicsitems/qdeclarativefocusscope.cpp @@ -41,6 +41,8 @@ #include "qdeclarativefocusscope_p.h" +#include "qdeclarativeitem_p.h" + QT_BEGIN_NAMESPACE /*! @@ -62,7 +64,8 @@ QT_BEGIN_NAMESPACE QDeclarativeFocusScope::QDeclarativeFocusScope(QDeclarativeItem *parent) : QDeclarativeItem(parent) { - setFlag(QGraphicsItem::ItemIsFocusScope); + Q_D(QDeclarativeItem); + d->flags |= QGraphicsItem::ItemIsFocusScope; } QDeclarativeFocusScope::~QDeclarativeFocusScope() diff --git a/src/declarative/graphicsitems/qdeclarativefocusscope_p.h b/src/declarative/graphicsitems/qdeclarativefocusscope_p.h index cd480b4..c65a07c 100644 --- a/src/declarative/graphicsitems/qdeclarativefocusscope_p.h +++ b/src/declarative/graphicsitems/qdeclarativefocusscope_p.h @@ -54,6 +54,7 @@ QT_MODULE(Declarative) class Q_DECLARATIVE_EXPORT QDeclarativeFocusScope : public QDeclarativeItem { Q_OBJECT + Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeItem) public: QDeclarativeFocusScope(QDeclarativeItem *parent=0); virtual ~QDeclarativeFocusScope(); diff --git a/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp b/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp index 1977817..eb5b6ce 100644 --- a/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp +++ b/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp @@ -65,12 +65,12 @@ public: if (graphicsObject && graphicsObject->isWidget()) { if (!on) { graphicsObject->removeEventFilter(q); - QObject::disconnect(q, SIGNAL(widthChanged()), q, SLOT(_q_updateSize())); - QObject::disconnect(q, SIGNAL(heightChanged()), q, SLOT(_q_updateSize())); + QObject::disconnect(q, SIGNAL(widthChanged(qreal)), q, SLOT(_q_updateSize())); + QObject::disconnect(q, SIGNAL(heightChanged(qreal)), q, SLOT(_q_updateSize())); } else { graphicsObject->installEventFilter(q); - QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(_q_updateSize())); - QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(_q_updateSize())); + QObject::connect(q, SIGNAL(widthChanged(qreal)), q, SLOT(_q_updateSize())); + QObject::connect(q, SIGNAL(heightChanged(qreal)), q, SLOT(_q_updateSize())); } } } diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 60ffbe2..93f8d06 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -81,6 +81,10 @@ public: item->setPos(QPointF(row, col)); } } + bool contains(int x, int y) const { + return (x >= item->x() && x < item->x() + view->cellWidth() && + y >= item->y() && y < item->y() + view->cellHeight()); + } QDeclarativeItem *item; QDeclarativeGridView *view; @@ -97,7 +101,7 @@ class QDeclarativeGridViewPrivate : public QDeclarativeFlickablePrivate public: QDeclarativeGridViewPrivate() : currentItem(0), flow(QDeclarativeGridView::LeftToRight) - , visiblePos(0), visibleIndex(0) , currentIndex(-1) + , visibleIndex(0) , currentIndex(-1) , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1) , highlightRangeStart(0), highlightRangeEnd(0), highlightRange(QDeclarativeGridView::NoHighlightRange) , highlightComponent(0), highlight(0), trackedItem(0) @@ -115,7 +119,7 @@ public: void updateGrid(); void scheduleLayout(); - void layout(bool removed=false); + void layout(); void updateUnrequestedIndexes(); void updateUnrequestedPositions(); void updateTrackedItem(); @@ -274,7 +278,7 @@ public: || newGeometry.width() != oldGeometry.width()) { if (q->isComponentComplete()) { updateGrid(); - layout(); + scheduleLayout(); } } } @@ -305,7 +309,6 @@ public: QHash<QDeclarativeItem*,int> unrequestedItems; FxGridItem *currentItem; QDeclarativeGridView::Flow flow; - int visiblePos; int visibleIndex; int currentIndex; int cellWidth; @@ -350,7 +353,6 @@ void QDeclarativeGridViewPrivate::clear() for (int i = 0; i < visibleItems.count(); ++i) releaseItem(visibleItems.at(i)); visibleItems.clear(); - visiblePos = 0; visibleIndex = 0; releaseItem(currentItem); currentItem = 0; @@ -536,11 +538,11 @@ void QDeclarativeGridViewPrivate::scheduleLayout() Q_Q(QDeclarativeGridView); if (!layoutScheduled) { layoutScheduled = true; - QMetaObject::invokeMethod(q, "layout", Qt::QueuedConnection); + QCoreApplication::postEvent(q, new QEvent(QEvent::User), Qt::HighEventPriority); } } -void QDeclarativeGridViewPrivate::layout(bool removed) +void QDeclarativeGridViewPrivate::layout() { Q_Q(QDeclarativeGridView); layoutScheduled = false; @@ -549,8 +551,6 @@ void QDeclarativeGridViewPrivate::layout(bool removed) qreal colPos = visibleItems.first()->colPos(); int col = visibleIndex % columns; if (colPos != col * colSize()) { - if (removed) - rowPos -= rowSize(); colPos = col * colSize(); visibleItems.first()->setPosition(colPos, rowPos); } @@ -748,21 +748,26 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m if (currentItem && currentItem->rowPos() - position() != highlightRangeStart) { qreal pos = currentItem->rowPos() - highlightRangeStart; timeline.reset(data.move); - if (fixupDuration) + if (fixupDuration) { timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else + } else { data.move.setValue(-pos); + q->viewportMoved(); + } vTime = timeline.time(); } } else if (snapMode != QDeclarativeGridView::NoSnap) { - qreal pos = qMax(qMin(snapPosAt(position()) - highlightRangeStart, -maxExtent), -minExtent); - qreal dist = qAbs(data.move + pos); + qreal pos = -snapPosAt(-(data.move.value() - highlightRangeStart)) + highlightRangeStart; + pos = qMin(qMax(pos, maxExtent), minExtent); + qreal dist = qAbs(data.move.value() - pos); if (dist > 0) { timeline.reset(data.move); - if (fixupDuration) - timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else - data.move.setValue(-pos); + if (fixupDuration) { + timeline.move(data.move, pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); + } else { + data.move.setValue(pos); + q->viewportMoved(); + } vTime = timeline.time(); } } else { @@ -788,7 +793,7 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m if (FxGridItem *item = firstVisibleItem()) maxDistance = qAbs(item->rowPos() + data.move.value()); } else if (data.move.value() < minExtent) { - maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity, vSize):0)); + maxDistance = qAbs(minExtent - data.move.value()); } if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) data.flickTarget = minExtent; @@ -797,7 +802,7 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m qreal pos = snapPosAt(-data.move.value()) + rowSize(); maxDistance = qAbs(pos + data.move.value()); } else if (data.move.value() > maxExtent) { - maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity, vSize):0); + maxDistance = qAbs(maxExtent - data.move.value()); } if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) data.flickTarget = maxExtent; @@ -816,7 +821,8 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m qreal maxAccel = v2 / (2.0f * maxDistance); qreal overshootDist = 0.0; if (maxAccel < accel) { - qreal dist = v2 / (accel * 2.0); + // + rowSize()/4 to encourage moving at least one item in the flick direction + qreal dist = v2 / (accel * 2.0) + rowSize()/4; if (v > 0) dist = -dist; data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; @@ -1421,6 +1427,17 @@ void QDeclarativeGridView::setSnapMode(SnapMode mode) } } +bool QDeclarativeGridView::event(QEvent *event) +{ + Q_D(QDeclarativeGridView); + if (event->type() == QEvent::User) { + d->layout(); + return true; + } + + return QDeclarativeFlickable::event(event); +} + void QDeclarativeGridView::viewportMoved() { Q_D(QDeclarativeGridView); @@ -1488,7 +1505,7 @@ qreal QDeclarativeGridView::maxYExtent() const return QDeclarativeFlickable::maxYExtent(); qreal extent; if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) - extent = -(d->rowPosAt(count()-1) - d->highlightRangeEnd); + extent = -(d->endPosition() - d->highlightRangeEnd); else extent = -(d->endPosition() - height()); const qreal minY = minYExtent(); @@ -1515,7 +1532,7 @@ qreal QDeclarativeGridView::maxXExtent() const return QDeclarativeFlickable::maxXExtent(); qreal extent; if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) - extent = -(d->rowPosAt(count()-1) - d->highlightRangeEnd); + extent = -(d->endPosition() - d->highlightRangeEnd); else extent = -(d->endPosition() - height()); const qreal minX = minXExtent(); @@ -1651,46 +1668,105 @@ void QDeclarativeGridView::moveCurrentIndexRight() } /*! - \qmlmethod GridView::positionViewAtIndex(int index) + \qmlmethod GridView::positionViewAtIndex(int index, PositionMode mode) + + Positions the view such that the \a index is at the position specified by + \a mode: + + \list + \o Beginning - position item at the top (or left for TopToBottom flow) of the view. + \o Center- position item in the center of the view. + \o End - position item at bottom (or right for horizontal orientation) of the view. + \o Visible - if any part of the item is visible then take no action, otherwise + bring the item into view. + \o Contain - ensure the entire item is visible. If the item is larger than + the view the item is positioned at the top (or left for TopToBottom flow) of the view. + \endlist - Positions the view such that the \a index is at the top (or left for horizontal orientation) of the view. If positioning the view at the index would cause empty space to be displayed at - the end of the view, the view will be positioned at the end. + the beginning or end of the view, the view will be positioned at the boundary. It is not recommended to use contentX or contentY to position the view at a particular index. This is unreliable since removing items from the start - of the list does not cause all other items to be repositioned. + of the view does not cause all other items to be repositioned. The correct way to bring an item into view is with positionViewAtIndex. */ -void QDeclarativeGridView::positionViewAtIndex(int index) +void QDeclarativeGridView::positionViewAtIndex(int index, int mode) { Q_D(QDeclarativeGridView); if (!d->isValid() || index < 0 || index >= d->model->count()) return; + if (mode < Beginning || mode > Contain) + return; - qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent(); + qreal pos = d->position(); FxGridItem *item = d->visibleItem(index); - if (item) { - // Already created - just move to top of view - int pos = qMin(item->rowPos(), maxExtent); - d->setPosition(pos); - } else { - int pos = d->rowPosAt(index); + if (!item) { + int itemPos = d->rowPosAt(index); // save the currently visible items in case any of them end up visible again QList<FxGridItem*> oldVisible = d->visibleItems; d->visibleItems.clear(); d->visibleIndex = index - index % d->columns; - d->setPosition(pos); - // setPosition() will cause refill. Adjust if we have moved beyond range - if (d->position() > maxExtent) - d->setPosition(maxExtent); + d->setPosition(itemPos); // now release the reference to all the old visible items. for (int i = 0; i < oldVisible.count(); ++i) d->releaseItem(oldVisible.at(i)); + item = d->visibleItem(index); + } + if (item) { + qreal itemPos = item->rowPos(); + switch (mode) { + case Beginning: + pos = itemPos; + break; + case Center: + pos = itemPos - (d->size() - d->rowSize())/2; + break; + case End: + pos = itemPos - d->size() + d->rowSize(); + break; + case Visible: + if (itemPos > pos + d->size()) + pos = itemPos - d->size() + d->rowSize(); + else if (item->endRowPos() < pos) + pos = itemPos; + break; + case Contain: + if (item->endRowPos() > pos + d->size()) + pos = itemPos - d->size() + d->rowSize(); + if (itemPos < pos) + pos = itemPos; + } + qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent(); + pos = qMin(pos, maxExtent); + qreal minExtent = d->flow == QDeclarativeGridView::LeftToRight ? -minYExtent() : -minXExtent(); + pos = qMax(pos, minExtent); + d->setPosition(pos); } d->fixupPosition(); } +/*! + \qmlmethod int GridView::indexAt(int x, int y) + + Returns the index of the visible item containing the point \a x, \a y in content + coordinates. If there is no item at the point specified, or the item is + not visible -1 is returned. + + If the item is outside the visible area, -1 is returned, regardless of + whether an item will exist at that point when scrolled into view. +*/ +int QDeclarativeGridView::indexAt(int x, int y) const +{ + Q_D(const QDeclarativeGridView); + for (int i = 0; i < d->visibleItems.count(); ++i) { + const FxGridItem *listItem = d->visibleItems.at(i); + if(listItem->contains(x, y)) + return listItem->index; + } + + return -1; +} void QDeclarativeGridView::componentComplete() { @@ -1763,7 +1839,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) { Q_D(QDeclarativeGridView); if (!d->visibleItems.count() || d->model->count() <= 1) { - refill(); + d->scheduleLayout(); d->updateCurrent(qMax(0, qMin(d->currentIndex, d->model->count()-1))); emit countChanged(); return; @@ -1792,8 +1868,9 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) d->currentIndex += count; if (d->currentItem) d->currentItem->index = d->currentIndex; + emit currentIndexChanged(); } - d->layout(); + d->scheduleLayout(); emit countChanged(); return; } @@ -1823,9 +1900,21 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) } } + // Update the indexes of the following visible items. + for (int i = 0; i < d->visibleItems.count(); ++i) { + FxGridItem *listItem = d->visibleItems.at(i); + if (listItem->index != -1 && listItem->index >= modelIndex) + listItem->index += count; + } + + bool addedVisible = false; QList<FxGridItem*> added; int i = 0; while (i < insertCount && rowPos <= to + d->rowSize()*(d->columns - (colPos/d->colSize()))/qreal(d->columns)) { + if (!addedVisible) { + d->scheduleLayout(); + addedVisible = true; + } FxGridItem *item = d->createItem(modelIndex + i); d->visibleItems.insert(index, item); item->setPosition(colPos, rowPos); @@ -1846,6 +1935,15 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) } } + // update visibleIndex + d->visibleIndex = 0; + for (QList<FxGridItem*>::Iterator it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) { + if ((*it)->index != -1) { + d->visibleIndex = (*it)->index; + break; + } + } + if (d->currentIndex >= modelIndex) { // adjust current item index d->currentIndex += count; @@ -1853,18 +1951,13 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) d->currentItem->index = d->currentIndex; d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex)); } - } - // Update the indexes of the following visible items. - for (; index < d->visibleItems.count(); ++index) { - FxGridItem *listItem = d->visibleItems.at(index); - if (listItem->index != -1) - listItem->index += count; + emit currentIndexChanged(); } // everything is in order now - emit add() signal for (int j = 0; j < added.count(); ++j) added.at(j)->attached->emitAdd(); - d->layout(); + emit countChanged(); } @@ -1880,8 +1973,10 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) FxGridItem *item = *it; if (item->index == -1 || item->index < modelIndex) { // already removed, or before removed items - if (item->index < modelIndex) + if (item->index < modelIndex && !removedVisible) { + d->scheduleLayout(); removedVisible = true; + } ++it; } else if (item->index >= modelIndex + count) { // after removed items @@ -1889,7 +1984,10 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) ++it; } else { // removed item - removedVisible = true; + if (!removedVisible) { + d->scheduleLayout(); + removedVisible = true; + } item->attached->emitRemove(); if (item->attached->delayRemove()) { item->index = -1; @@ -1907,6 +2005,7 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) d->currentIndex -= count; if (d->currentItem) d->currentItem->index -= count; + emit currentIndexChanged(); } else if (currentRemoved) { // current item has been removed. d->releaseItem(d->currentItem); @@ -1916,6 +2015,7 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) } // update visibleIndex + d->visibleIndex = 0; for (it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) { if ((*it)->index != -1) { d->visibleIndex = (*it)->index; @@ -1923,27 +2023,16 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) } } - if (removedVisible) { - if (d->visibleItems.isEmpty()) { - d->visibleIndex = 0; - d->setPosition(0); - refill(); - } else { - // Correct the positioning of the items - d->scheduleLayout(); - } + if (removedVisible && d->visibleItems.isEmpty()) { + d->timeline.clear(); + d->setPosition(0); + if (d->model->count() == 0) + update(); } emit countChanged(); } -void QDeclarativeGridView::layout() -{ - Q_D(QDeclarativeGridView); - if (d->layoutScheduled) - d->layout(); -} - void QDeclarativeGridView::destroyRemoved() { Q_D(QDeclarativeGridView); @@ -2055,7 +2144,7 @@ void QDeclarativeGridView::itemsMoved(int from, int to, int count) d->releaseItem(item); } - d->layout(removedBeforeVisible); + d->layout(); } void QDeclarativeGridView::modelReset() diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index 787c04c..90f13d2 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -137,6 +137,12 @@ public: SnapMode snapMode() const; void setSnapMode(SnapMode mode); + enum PositionMode { Beginning, Center, End, Visible, Contain }; + Q_ENUMS(PositionMode); + + Q_INVOKABLE void positionViewAtIndex(int index, int mode); + Q_INVOKABLE int indexAt(int x, int y) const; + static QDeclarativeGridViewAttached *qmlAttachedProperties(QObject *); public Q_SLOTS: @@ -144,7 +150,6 @@ public Q_SLOTS: void moveCurrentIndexDown(); void moveCurrentIndexLeft(); void moveCurrentIndexRight(); - void positionViewAtIndex(int index); Q_SIGNALS: void countChanged(); @@ -164,6 +169,7 @@ Q_SIGNALS: void snapModeChanged(); protected: + virtual bool event(QEvent *event); virtual void viewportMoved(); virtual qreal minYExtent() const; virtual qreal maxYExtent() const; @@ -181,7 +187,6 @@ private Q_SLOTS: void destroyRemoved(); void createdItem(int index, QDeclarativeItem *item); void destroyingItem(QDeclarativeItem *item); - void layout(); private: void refill(); @@ -192,7 +197,7 @@ class QDeclarativeGridViewAttached : public QObject Q_OBJECT public: QDeclarativeGridViewAttached(QObject *parent) - : QObject(parent), m_isCurrent(false), m_delayRemove(false) {} + : QObject(parent), m_view(0), m_isCurrent(false), m_delayRemove(false) {} ~QDeclarativeGridViewAttached() {} Q_PROPERTY(QDeclarativeGridView *view READ view CONSTANT) diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index c7d7a4c..4ba80ad 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -273,7 +273,7 @@ void QDeclarativeContents::calcHeight() m_height = qMax(bottom - top, qreal(0.0)); if (m_height != oldheight || m_y != oldy) - emit rectChanged(); + emit rectChanged(rectF()); } //TODO: optimization: only check sender(), if there is one @@ -301,7 +301,7 @@ void QDeclarativeContents::calcWidth() m_width = qMax(right - left, qreal(0.0)); if (m_width != oldwidth || m_x != oldx) - emit rectChanged(); + emit rectChanged(rectF()); } void QDeclarativeContents::setItem(QDeclarativeItem *item) @@ -313,11 +313,11 @@ void QDeclarativeContents::setItem(QDeclarativeItem *item) QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i)); if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects? continue; - connect(child, SIGNAL(heightChanged()), this, SLOT(calcHeight())); + connect(child, SIGNAL(heightChanged(qreal)), this, SLOT(calcHeight())); connect(child, SIGNAL(yChanged()), this, SLOT(calcHeight())); - connect(child, SIGNAL(widthChanged()), this, SLOT(calcWidth())); + connect(child, SIGNAL(widthChanged(qreal)), this, SLOT(calcWidth())); connect(child, SIGNAL(xChanged()), this, SLOT(calcWidth())); - connect(this, SIGNAL(rectChanged()), m_item, SIGNAL(childrenRectChanged())); + connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF))); } calcHeight(); @@ -1662,7 +1662,7 @@ void QDeclarativeItem::setClip(bool c) if (clip() == c) return; setFlag(ItemClipsChildrenToShape, c); - emit clipChanged(); + emit clipChanged(c); } /*! @@ -1802,11 +1802,11 @@ void QDeclarativeItem::geometryChanged(const QRectF &newGeometry, if (newGeometry.x() != oldGeometry.x()) emit xChanged(); if (newGeometry.width() != oldGeometry.width()) - emit widthChanged(); + emit widthChanged(newGeometry.width()); if (newGeometry.y() != oldGeometry.y()) emit yChanged(); if (newGeometry.height() != oldGeometry.height()) - emit heightChanged(); + emit heightChanged(newGeometry.height()); for(int ii = 0; ii < d->changeListeners.count(); ++ii) { const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii); @@ -2068,7 +2068,6 @@ void QDeclarativeItem::setBaselineOffset(qreal offset) return; d->_baselineOffset = offset; - emit baselineOffsetChanged(); for(int ii = 0; ii < d->changeListeners.count(); ++ii) { const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii); @@ -2078,6 +2077,7 @@ void QDeclarativeItem::setBaselineOffset(qreal offset) anchor->updateVerticalAnchors(); } } + emit baselineOffsetChanged(offset); } /*! @@ -2224,7 +2224,7 @@ void QDeclarativeItem::setKeepMouseGrab(bool keep) } /*! - \qmlmethod object Item::mapFromItem(Item item, int x, int y) + \qmlmethod object Item::mapFromItem(Item item, real x, real y) Maps the point (\a x, \a y), which is in \a item's coordinate system, to this item's coordinate system, and returns an object with \c x and \c y @@ -2233,7 +2233,7 @@ void QDeclarativeItem::setKeepMouseGrab(bool keep) If \a item is a \c null value, this maps the point from the coordinate system of the root QML view. */ -QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, int x, int y) const +QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, qreal x, qreal y) const { QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject(); QDeclarativeItem *itemObj = qobject_cast<QDeclarativeItem*>(item.toQObject()); @@ -2244,13 +2244,13 @@ QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, int x, int // If QGraphicsItem::mapFromItem() is called with 0, behaves the same as mapFromScene() QPointF p = qobject_cast<QGraphicsItem*>(this)->mapFromItem(itemObj, x, y); - sv.setProperty("x", p.x()); - sv.setProperty("y", p.y()); + sv.setProperty(QLatin1String("x"), p.x()); + sv.setProperty(QLatin1String("y"), p.y()); return sv; } /*! - \qmlmethod object Item::mapToItem(Item item, int x, int y) + \qmlmethod object Item::mapToItem(Item item, real x, real y) Maps the point (\a x, \a y), which is in this item's coordinate system, to \a item's coordinate system, and returns an object with \c x and \c y @@ -2259,7 +2259,7 @@ QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, int x, int If \a item is a \c null value, this maps \a x and \a y to the coordinate system of the root QML view. */ -QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, int x, int y) const +QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qreal y) const { QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject(); QDeclarativeItem *itemObj = qobject_cast<QDeclarativeItem*>(item.toQObject()); @@ -2270,23 +2270,15 @@ QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, int x, int y) // If QGraphicsItem::mapToItem() is called with 0, behaves the same as mapToScene() QPointF p = qobject_cast<QGraphicsItem*>(this)->mapToItem(itemObj, x, y); - sv.setProperty("x", p.x()); - sv.setProperty("y", p.y()); + sv.setProperty(QLatin1String("x"), p.x()); + sv.setProperty(QLatin1String("y"), p.y()); return sv; } -/*! - \internal - - This function emits the \e focusChanged signal. - - Subclasses overriding this function should call up - to their base class. -*/ -void QDeclarativeItem::focusChanged(bool flag) +void QDeclarativeItemPrivate::focusChanged(bool flag) { - Q_UNUSED(flag); - emit focusChanged(); + Q_Q(QDeclarativeItem); + emit q->focusChanged(flag); } /*! \internal */ @@ -2579,14 +2571,16 @@ QPointF QDeclarativeItemPrivate::computeTransformOrigin() const /*! \internal */ bool QDeclarativeItem::sceneEvent(QEvent *event) { + Q_D(QDeclarativeItem); if (event->type() == QEvent::KeyPress) { QKeyEvent *k = static_cast<QKeyEvent *>(event); - if ((k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) && !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { keyPressEvent(static_cast<QKeyEvent *>(event)); if (!event->isAccepted()) return QGraphicsItem::sceneEvent(event); + else + return true; } else { return QGraphicsItem::sceneEvent(event); } @@ -2595,7 +2589,7 @@ bool QDeclarativeItem::sceneEvent(QEvent *event) if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) { - focusChanged(hasFocus()); + d->focusChanged(hasFocus()); } return rv; } @@ -2608,7 +2602,7 @@ QVariant QDeclarativeItem::itemChange(GraphicsItemChange change, Q_D(const QDeclarativeItem); switch (change) { case ItemParentHasChanged: - emit parentChanged(); + emit parentChanged(parentItem()); break; case ItemChildAddedChange: case ItemChildRemovedChange: @@ -2721,7 +2715,7 @@ void QDeclarativeItem::setSmooth(bool smooth) if (d->smooth == smooth) return; d->smooth = smooth; - emit smoothChanged(); + emit smoothChanged(smooth); update(); } diff --git a/src/declarative/graphicsitems/qdeclarativeitem.h b/src/declarative/graphicsitems/qdeclarativeitem.h index 2053eba..c88b1db 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.h +++ b/src/declarative/graphicsitems/qdeclarativeitem.h @@ -42,8 +42,8 @@ #ifndef QDECLARATIVEITEM_H #define QDECLARATIVEITEM_H -#include <qdeclarative.h> -#include <qdeclarativecomponent.h> +#include <QtDeclarative/qdeclarative.h> +#include <QtDeclarative/qdeclarativecomponent.h> #include <QtCore/QObject> #include <QtCore/QList> @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QDeclarativeState; -class QDeclarativeAnchorLine; +struct QDeclarativeAnchorLine; class QDeclarativeTransition; class QDeclarativeKeyEvent; class QDeclarativeAnchors; @@ -161,8 +161,8 @@ public: bool keepMouseGrab() const; void setKeepMouseGrab(bool); - Q_INVOKABLE QScriptValue mapFromItem(const QScriptValue &item, int x, int y) const; - Q_INVOKABLE QScriptValue mapToItem(const QScriptValue &item, int x, int y) const; + Q_INVOKABLE QScriptValue mapFromItem(const QScriptValue &item, qreal x, qreal y) const; + Q_INVOKABLE QScriptValue mapToItem(const QScriptValue &item, qreal x, qreal y) const; QDeclarativeAnchorLine left() const; QDeclarativeAnchorLine right() const; @@ -173,18 +173,18 @@ public: QDeclarativeAnchorLine baseline() const; Q_SIGNALS: - void widthChanged(); - void heightChanged(); + void widthChanged(qreal); + void heightChanged(qreal); void childrenChanged(); - void childrenRectChanged(); - void baselineOffsetChanged(); + void childrenRectChanged(const QRectF &); + void baselineOffsetChanged(qreal); void stateChanged(const QString &); - void focusChanged(); - void wantsFocusChanged(); - void parentChanged(); + void focusChanged(bool); + void wantsFocusChanged(bool); + void parentChanged(QDeclarativeItem *); void transformOriginChanged(TransformOrigin); - void smoothChanged(); - void clipChanged(); + void smoothChanged(bool); + void clipChanged(bool); protected: bool isComponentComplete() const; @@ -199,7 +199,6 @@ protected: virtual void classBegin(); virtual void componentComplete(); - virtual void focusChanged(bool); virtual void keyPressEvent(QKeyEvent *event); virtual void keyReleaseEvent(QKeyEvent *event); virtual void inputMethodEvent(QInputMethodEvent *); diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index e424970..55df063 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -91,7 +91,7 @@ public Q_SLOTS: void calcWidth(); Q_SIGNALS: - void rectChanged(); + void rectChanged(QRectF); private: QDeclarativeItem *m_item; @@ -101,7 +101,7 @@ private: qreal m_height; }; -class QDeclarativeItemPrivate : public QGraphicsItemPrivate +class Q_DECLARATIVE_EXPORT QDeclarativeItemPrivate : public QGraphicsItemPrivate { Q_DECLARE_PUBLIC(QDeclarativeItem) @@ -240,7 +240,7 @@ public: // Reimplemented from QGraphicsItemPrivate virtual void subFocusItemChange() { - emit q_func()->wantsFocusChanged(); + emit q_func()->wantsFocusChanged(subFocusItem != 0); } // Reimplemented from QGraphicsItemPrivate @@ -255,9 +255,11 @@ public: } } + virtual void focusChanged(bool); + static int consistentTime; static QTime currentTime(); - static void Q_DECLARATIVE_EXPORT setConsistentTime(int t); + static void setConsistentTime(int t); static void start(QTime &); static int elapsed(QTime &); static int restart(QTime &); diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp index 25660f8..1a48cbd 100644 --- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp @@ -65,7 +65,6 @@ #include "qdeclarativelistview_p.h" #include "qdeclarativeloader_p.h" #include "qdeclarativemousearea_p.h" -#include "qdeclarativeparticles_p.h" #include "qdeclarativepath_p.h" #include "qdeclarativepathview_p.h" #include "qdeclarativerectangle_p.h" @@ -82,76 +81,72 @@ void QDeclarativeItemModule::defineModule() { - QML_REGISTER_TYPE(Qt,4,6,AnimatedImage,QDeclarativeAnimatedImage); - QML_REGISTER_TYPE(Qt,4,6,Blur,QGraphicsBlurEffect); - QML_REGISTER_TYPE(Qt,4,6,BorderImage,QDeclarativeBorderImage); - QML_REGISTER_TYPE(Qt,4,6,Colorize,QGraphicsColorizeEffect); - QML_REGISTER_TYPE(Qt,4,6,Column,QDeclarativeColumn); - QML_REGISTER_TYPE(Qt,4,6,Drag,QDeclarativeDrag); - QML_REGISTER_TYPE(Qt,4,6,DropShadow,QGraphicsDropShadowEffect); - QML_REGISTER_TYPE(Qt,4,6,Flickable,QDeclarativeFlickable); - QML_REGISTER_TYPE(Qt,4,6,Flipable,QDeclarativeFlipable); - QML_REGISTER_TYPE(Qt,4,6,Flow,QDeclarativeFlow); - QML_REGISTER_TYPE(Qt,4,6,FocusPanel,QDeclarativeFocusPanel); - QML_REGISTER_TYPE(Qt,4,6,FocusScope,QDeclarativeFocusScope); - QML_REGISTER_TYPE(Qt,4,6,Gradient,QDeclarativeGradient); - QML_REGISTER_TYPE(Qt,4,6,GradientStop,QDeclarativeGradientStop); - QML_REGISTER_TYPE(Qt,4,6,GraphicsObjectContainer,QDeclarativeGraphicsObjectContainer); - QML_REGISTER_TYPE(Qt,4,6,Grid,QDeclarativeGrid); - QML_REGISTER_TYPE(Qt,4,6,GridView,QDeclarativeGridView); - QML_REGISTER_TYPE(Qt,4,6,Image,QDeclarativeImage); - QML_REGISTER_TYPE(Qt,4,6,Item,QDeclarativeItem); - QML_REGISTER_TYPE(Qt,4,6,KeyNavigation,QDeclarativeKeyNavigationAttached); - QML_REGISTER_TYPE(Qt,4,6,Keys,QDeclarativeKeysAttached); - QML_REGISTER_TYPE(Qt,4,6,LayoutItem,QDeclarativeLayoutItem); - QML_REGISTER_TYPE(Qt,4,6,ListView,QDeclarativeListView); - QML_REGISTER_TYPE(Qt,4,6,Loader,QDeclarativeLoader); - QML_REGISTER_TYPE(Qt,4,6,MouseArea,QDeclarativeMouseArea); - QML_REGISTER_TYPE(Qt,4,6,Opacity,QGraphicsOpacityEffect); - QML_REGISTER_TYPE(Qt,4,6,ParticleMotion,QDeclarativeParticleMotion); - QML_REGISTER_TYPE(Qt,4,6,ParticleMotionGravity,QDeclarativeParticleMotionGravity); - QML_REGISTER_TYPE(Qt,4,6,ParticleMotionLinear,QDeclarativeParticleMotionLinear); - QML_REGISTER_TYPE(Qt,4,6,ParticleMotionWander,QDeclarativeParticleMotionWander); - QML_REGISTER_TYPE(Qt,4,6,Particles,QDeclarativeParticles); - QML_REGISTER_TYPE(Qt,4,6,Path,QDeclarativePath); - QML_REGISTER_TYPE(Qt,4,6,PathAttribute,QDeclarativePathAttribute); - QML_REGISTER_TYPE(Qt,4,6,PathCubic,QDeclarativePathCubic); - QML_REGISTER_TYPE(Qt,4,6,PathLine,QDeclarativePathLine); - QML_REGISTER_TYPE(Qt,4,6,PathPercent,QDeclarativePathPercent); - QML_REGISTER_TYPE(Qt,4,6,PathQuad,QDeclarativePathQuad); - QML_REGISTER_TYPE(Qt,4,6,PathView,QDeclarativePathView); - QML_REGISTER_TYPE(Qt,4,6,Pen,QDeclarativePen); - QML_REGISTER_TYPE(Qt,4,6,QIntValidator,QIntValidator); + qmlRegisterType<QDeclarativeAnimatedImage>("Qt",4,6,"AnimatedImage"); + qmlRegisterType<QGraphicsBlurEffect>("Qt",4,6,"Blur"); + qmlRegisterType<QDeclarativeBorderImage>("Qt",4,6,"BorderImage"); + qmlRegisterType<QGraphicsColorizeEffect>("Qt",4,6,"Colorize"); + qmlRegisterType<QDeclarativeColumn>("Qt",4,6,"Column"); + qmlRegisterType<QDeclarativeDrag>("Qt",4,6,"Drag"); + qmlRegisterType<QGraphicsDropShadowEffect>("Qt",4,6,"DropShadow"); + qmlRegisterType<QDeclarativeFlickable>("Qt",4,6,"Flickable"); + qmlRegisterType<QDeclarativeFlipable>("Qt",4,6,"Flipable"); + qmlRegisterType<QDeclarativeFlow>("Qt",4,6,"Flow"); + qmlRegisterType<QDeclarativeFocusPanel>("Qt",4,6,"FocusPanel"); + qmlRegisterType<QDeclarativeFocusScope>("Qt",4,6,"FocusScope"); + qmlRegisterType<QDeclarativeGradient>("Qt",4,6,"Gradient"); + qmlRegisterType<QDeclarativeGradientStop>("Qt",4,6,"GradientStop"); + qmlRegisterType<QDeclarativeGraphicsObjectContainer>("Qt",4,6,"GraphicsObjectContainer"); + qmlRegisterType<QDeclarativeGrid>("Qt",4,6,"Grid"); + qmlRegisterType<QDeclarativeGridView>("Qt",4,6,"GridView"); + qmlRegisterType<QDeclarativeImage>("Qt",4,6,"Image"); + qmlRegisterType<QDeclarativeItem>("Qt",4,6,"Item"); + qmlRegisterType<QDeclarativeKeyNavigationAttached>("Qt",4,6,"KeyNavigation"); + qmlRegisterType<QDeclarativeKeysAttached>("Qt",4,6,"Keys"); + qmlRegisterType<QDeclarativeLayoutItem>("Qt",4,6,"LayoutItem"); + qmlRegisterType<QDeclarativeListView>("Qt",4,6,"ListView"); + qmlRegisterType<QDeclarativeLoader>("Qt",4,6,"Loader"); + qmlRegisterType<QDeclarativeMouseArea>("Qt",4,6,"MouseArea"); + qmlRegisterType<QGraphicsOpacityEffect>("Qt",4,6,"Opacity"); + qmlRegisterType<QDeclarativePath>("Qt",4,6,"Path"); + qmlRegisterType<QDeclarativePathAttribute>("Qt",4,6,"PathAttribute"); + qmlRegisterType<QDeclarativePathCubic>("Qt",4,6,"PathCubic"); + qmlRegisterType<QDeclarativePathLine>("Qt",4,6,"PathLine"); + qmlRegisterType<QDeclarativePathPercent>("Qt",4,6,"PathPercent"); + qmlRegisterType<QDeclarativePathQuad>("Qt",4,6,"PathQuad"); + qmlRegisterType<QDeclarativePathView>("Qt",4,6,"PathView"); + qmlRegisterType<QDeclarativePen>("Qt",4,6,"Pen"); + qmlRegisterType<QIntValidator>("Qt",4,6,"QIntValidator"); #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) - QML_REGISTER_TYPE(Qt,4,7,QDoubleValidator,QDoubleValidator); - QML_REGISTER_TYPE(Qt,4,7,QRegExpValidator,QRegExpValidator); + qmlRegisterType<QDoubleValidator>("Qt",4,7,"QDoubleValidator"); + qmlRegisterType<QRegExpValidator>("Qt",4,7,"QRegExpValidator"); #endif - QML_REGISTER_TYPE(Qt,4,6,Rectangle,QDeclarativeRectangle); - QML_REGISTER_TYPE(Qt,4,6,Repeater,QDeclarativeRepeater); - QML_REGISTER_TYPE(Qt,4,6,Rotation,QGraphicsRotation); - QML_REGISTER_TYPE(Qt,4,6,Row,QDeclarativeRow); - QML_REGISTER_TYPE(Qt,4,6,Scale,QGraphicsScale); - QML_REGISTER_TYPE(Qt,4,6,Text,QDeclarativeText); - QML_REGISTER_TYPE(Qt,4,6,TextEdit,QDeclarativeTextEdit); - QML_REGISTER_TYPE(Qt,4,6,TextInput,QDeclarativeTextInput); - QML_REGISTER_TYPE(Qt,4,6,ViewSection,QDeclarativeViewSection); - QML_REGISTER_TYPE(Qt,4,6,VisibleArea,QDeclarativeFlickableVisibleArea); - QML_REGISTER_TYPE(Qt,4,6,VisualDataModel,QDeclarativeVisualDataModel); - QML_REGISTER_TYPE(Qt,4,6,VisualItemModel,QDeclarativeVisualItemModel); + qmlRegisterType<QDeclarativeRectangle>("Qt",4,6,"Rectangle"); + qmlRegisterType<QDeclarativeRepeater>("Qt",4,6,"Repeater"); + qmlRegisterType<QGraphicsRotation>("Qt",4,6,"Rotation"); + qmlRegisterType<QDeclarativeRow>("Qt",4,6,"Row"); + qmlRegisterType<QGraphicsScale>("Qt",4,6,"Scale"); + qmlRegisterType<QDeclarativeText>("Qt",4,6,"Text"); + qmlRegisterType<QDeclarativeTextEdit>("Qt",4,6,"TextEdit"); + qmlRegisterType<QDeclarativeTextInput>("Qt",4,6,"TextInput"); + qmlRegisterType<QDeclarativeViewSection>("Qt",4,6,"ViewSection"); + qmlRegisterType<QDeclarativeFlickableVisibleArea>("Qt",4,6,"VisibleArea"); + qmlRegisterType<QDeclarativeVisualDataModel>("Qt",4,6,"VisualDataModel"); + qmlRegisterType<QDeclarativeVisualItemModel>("Qt",4,6,"VisualItemModel"); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeAnchors); - QML_REGISTER_NOCREATE_TYPE(QGraphicsEffect); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeKeyEvent); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeMouseEvent); - QML_REGISTER_NOCREATE_TYPE(QGraphicsObject); - QML_REGISTER_NOCREATE_TYPE(QGraphicsTransform); - QML_REGISTER_NOCREATE_TYPE(QDeclarativePathElement); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeCurve); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeScaleGrid); - QML_REGISTER_NOCREATE_TYPE(QValidator); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeVisualModel); - QML_REGISTER_NOCREATE_TYPE(QAction); + qmlRegisterType<QDeclarativeAnchors>(); + qmlRegisterType<QGraphicsEffect>(); + qmlRegisterType<QDeclarativeKeyEvent>(); + qmlRegisterType<QDeclarativeMouseEvent>(); + qmlRegisterType<QGraphicsObject>(); + qmlRegisterType<QGraphicsWidget>(); + qmlRegisterType<QGraphicsTransform>(); + qmlRegisterType<QDeclarativePathElement>(); + qmlRegisterType<QDeclarativeCurve>(); + qmlRegisterType<QDeclarativeScaleGrid>(); + qmlRegisterType<QValidator>(); + qmlRegisterType<QDeclarativeVisualModel>(); + qmlRegisterType<QAction>(); #ifdef QT_WEBKIT_LIB - QML_REGISTER_NOCREATE_TYPE(QDeclarativeWebSettings); + qmlRegisterType<QDeclarativeWebSettings>(); #endif } diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index d54bb70..84281c8 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -129,6 +129,10 @@ public: item->setX(pos); } } + bool contains(int x, int y) const { + return (x >= item->x() && x < item->x() + item->width() && + y >= item->y() && y < item->y() + item->height()); + } QDeclarativeItem *item; QDeclarativeItem *section; @@ -158,7 +162,7 @@ public: , bufferMode(NoBuffer) , ownModel(false), wrap(false), autoHighlight(true), haveHighlightRange(false) , correctFlick(true), inFlickCorrection(false), lazyRelease(false) - , deferredRelease(false), minExtentDirty(true), maxExtentDirty(true) + , deferredRelease(false), layoutScheduled(false), minExtentDirty(true), maxExtentDirty(true) {} void init(); @@ -393,9 +397,8 @@ public: QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry); if (item != viewport) { if ((orient == QDeclarativeListView::Vertical && newGeometry.height() != oldGeometry.height()) - || newGeometry.width() != oldGeometry.width()) { - layout(); - fixupPosition(); + || (orient == QDeclarativeListView::Horizontal && newGeometry.width() != oldGeometry.width())) { + scheduleLayout(); } } } @@ -414,6 +417,7 @@ public: } void refill(qreal from, qreal to, bool doBuffer = false); + void scheduleLayout(); void layout(); void updateUnrequestedIndexes(); void updateUnrequestedPositions(); @@ -480,6 +484,7 @@ public: bool inFlickCorrection : 1; bool lazyRelease : 1; bool deferredRelease : 1; + bool layoutScheduled : 1; mutable bool minExtentDirty : 1; mutable bool maxExtentDirty : 1; }; @@ -557,7 +562,7 @@ void QDeclarativeListViewPrivate::releaseItem(FxListItem *item) return; if (trackedItem == item) { const char *notifier1 = orient == QDeclarativeListView::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged()); - const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged()) : SIGNAL(widthChanged()); + const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged(qreal)) : SIGNAL(widthChanged(qreal)); QObject::disconnect(trackedItem->item, notifier1, q, SLOT(trackedPositionChanged())); QObject::disconnect(trackedItem->item, notifier2, q, SLOT(trackedPositionChanged())); trackedItem = 0; @@ -680,9 +685,19 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) lazyRelease = false; } +void QDeclarativeListViewPrivate::scheduleLayout() +{ + Q_Q(QDeclarativeListView); + if (!layoutScheduled) { + layoutScheduled = true; + QCoreApplication::postEvent(q, new QEvent(QEvent::User), Qt::HighEventPriority); + } +} + void QDeclarativeListViewPrivate::layout() { Q_Q(QDeclarativeListView); + layoutScheduled = false; updateSections(); if (!visibleItems.isEmpty()) { int oldEnd = visibleItems.last()->endPosition(); @@ -748,7 +763,7 @@ void QDeclarativeListViewPrivate::updateTrackedItem() FxListItem *oldTracked = trackedItem; const char *notifier1 = orient == QDeclarativeListView::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged()); - const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged()) : SIGNAL(widthChanged()); + const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged(qreal)) : SIGNAL(widthChanged(qreal)); if (trackedItem && item != trackedItem) { QObject::disconnect(trackedItem->item, notifier1, q, SLOT(trackedPositionChanged())); @@ -1082,10 +1097,12 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m if (currentItem && currentItem->position() - position() != highlightRangeStart) { qreal pos = currentItem->position() - highlightRangeStart; timeline.reset(data.move); - if (fixupDuration) + if (fixupDuration) { timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else + } else { data.move.setValue(-pos); + q->viewportMoved(); + } vTime = timeline.time(); } } else if (snapMode != QDeclarativeListView::NoSnap) { @@ -1094,10 +1111,12 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m qreal dist = qAbs(data.move + pos); if (dist > 0) { timeline.reset(data.move); - if (fixupDuration) + if (fixupDuration) { timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else + } else { data.move.setValue(-pos); + q->viewportMoved(); + } vTime = timeline.time(); } } @@ -1124,7 +1143,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m if (FxListItem *item = firstVisibleItem()) maxDistance = qAbs(item->position() + data.move.value()); } else if (data.move.value() < minExtent) { - maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity, vSize):0)); + maxDistance = qAbs(minExtent - data.move.value()); } if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange) data.flickTarget = minExtent; @@ -1133,7 +1152,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m if (FxListItem *item = nextVisibleItem()) maxDistance = qAbs(item->position() + data.move.value()); } else if (data.move.value() > maxExtent) { - maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity, vSize):0); + maxDistance = qAbs(maxExtent - data.move.value()); } if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange) data.flickTarget = maxExtent; @@ -1156,7 +1175,8 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m qreal v2 = v * v; qreal maxAccel = v2 / (2.0f * maxDistance); if (maxAccel < accel) { - qreal dist = v2 / (accel * 2.0); + // + averageSize/4 to encourage moving at least one item in the flick direction + qreal dist = v2 / (accel * 2.0) + averageSize/4; if (v > 0) dist = -dist; data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; @@ -1944,6 +1964,17 @@ void QDeclarativeListView::setHeader(QDeclarativeComponent *header) } } +bool QDeclarativeListView::event(QEvent *event) +{ + Q_D(QDeclarativeListView); + if (event->type() == QEvent::User) { + d->layout(); + return true; + } + + return QDeclarativeFlickable::event(event); +} + void QDeclarativeListView::viewportMoved() { Q_D(QDeclarativeListView); @@ -1956,10 +1987,11 @@ void QDeclarativeListView::viewportMoved() if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { // reposition highlight qreal pos = d->highlight->position(); - if (pos > d->position() + d->highlightRangeEnd - 1 - d->highlight->size()) - pos = d->position() + d->highlightRangeEnd - 1 - d->highlight->size(); - if (pos < d->position() + d->highlightRangeStart) - pos = d->position() + d->highlightRangeStart; + qreal viewPos = qRound(d->position()); + if (pos > viewPos + d->highlightRangeEnd - 1 - d->highlight->size()) + pos = viewPos + d->highlightRangeEnd - 1 - d->highlight->size(); + if (pos < viewPos + d->highlightRangeStart) + pos = viewPos + d->highlightRangeStart; d->highlight->setPosition(pos); // update current index @@ -2032,7 +2064,7 @@ qreal QDeclarativeListView::maxYExtent() const return height(); if (d->maxExtentDirty) { if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) - d->maxExtent = -(d->positionAt(count()-1) - d->highlightRangeEnd); + d->maxExtent = -(d->endPosition() - d->highlightRangeEnd); else d->maxExtent = -(d->endPosition() - height() + 1); if (d->footer) @@ -2069,7 +2101,7 @@ qreal QDeclarativeListView::maxXExtent() const return width(); if (d->maxExtentDirty) { if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) - d->maxExtent = -(d->positionAt(count()-1) - d->highlightRangeEnd); + d->maxExtent = -(d->endPosition() - d->highlightRangeEnd); else d->maxExtent = -(d->endPosition() - width() + 1); if (d->footer) @@ -2151,11 +2183,23 @@ void QDeclarativeListView::decrementCurrentIndex() } /*! - \qmlmethod ListView::positionViewAtIndex(int index) + \qmlmethod ListView::positionViewAtIndex(int index, PositionMode mode) + + Positions the view such that the \a index is at the position specified by + \a mode: + + \list + \o Beginning - position item at the top (or left for horizontal orientation) of the view. + \o Center- position item in the center of the view. + \o End - position item at bottom (or right for horizontal orientation) of the view. + \o Visible - if any part of the item is visible then take no action, otherwise + bring the item into view. + \o Contain - ensure the entire item is visible. If the item is larger than + the view the item is positioned at the top (or left for horizontal orientation) of the view. + \endlist - Positions the view such that the \a index is at the top (or left for horizontal orientation) of the view. If positioning the view at the index would cause empty space to be displayed at - the end of the view, the view will be positioned at the end. + the beginning or end of the view, the view will be positioned at the boundary. It is not recommended to use contentX or contentY to position the view at a particular index. This is unreliable since removing items from the start @@ -2163,36 +2207,83 @@ void QDeclarativeListView::decrementCurrentIndex() the actual start of the view can vary based on the size of the delegates. The correct way to bring an item into view is with positionViewAtIndex. */ -void QDeclarativeListView::positionViewAtIndex(int index) +void QDeclarativeListView::positionViewAtIndex(int index, int mode) { Q_D(QDeclarativeListView); if (!d->isValid() || index < 0 || index >= d->model->count()) return; + if (mode < Beginning || mode > Contain) + return; - qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent(); + qreal pos = d->position(); FxListItem *item = d->visibleItem(index); - if (item) { - // Already created - just move to top of view - int pos = qMin(item->position(), maxExtent); - d->setPosition(pos); - } else { - int pos = d->positionAt(index); + if (!item) { + int itemPos = d->positionAt(index); // save the currently visible items in case any of them end up visible again QList<FxListItem*> oldVisible = d->visibleItems; d->visibleItems.clear(); - d->visiblePos = pos; + d->visiblePos = itemPos; d->visibleIndex = index; - d->setPosition(pos); - // setPosition() will cause refill. Adjust if we have moved beyond range. - if (d->position() > maxExtent) - d->setPosition(maxExtent); + d->setPosition(itemPos); // now release the reference to all the old visible items. for (int i = 0; i < oldVisible.count(); ++i) d->releaseItem(oldVisible.at(i)); + item = d->visibleItem(index); + } + if (item) { + const qreal itemPos = item->position(); + switch (mode) { + case Beginning: + pos = itemPos; + break; + case Center: + pos = itemPos - (d->size() - item->size())/2; + break; + case End: + pos = itemPos - d->size() + item->size(); + break; + case Visible: + if (itemPos > pos + d->size()) + pos = itemPos - d->size() + item->size(); + else if (item->endPosition() < pos) + pos = itemPos; + break; + case Contain: + if (item->endPosition() > pos + d->size()) + pos = itemPos - d->size() + item->size(); + if (itemPos < pos) + pos = itemPos; + } + qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent(); + pos = qMin(pos, maxExtent); + qreal minExtent = d->orient == QDeclarativeListView::Vertical ? -minYExtent() : -minXExtent(); + pos = qMax(pos, minExtent); + d->setPosition(pos); } d->fixupPosition(); } +/*! + \qmlmethod int ListView::indexAt(int x, int y) + + Returns the index of the visible item containing the point \a x, \a y in content + coordinates. If there is no item at the point specified, or the item is + not visible -1 is returned. + + If the item is outside the visible area, -1 is returned, regardless of + whether an item will exist at that point when scrolled into view. +*/ +int QDeclarativeListView::indexAt(int x, int y) const +{ + Q_D(const QDeclarativeListView); + for (int i = 0; i < d->visibleItems.count(); ++i) { + const FxListItem *listItem = d->visibleItems.at(i); + if(listItem->contains(x, y)) + return listItem->index; + } + + return -1; +} void QDeclarativeListView::componentComplete() { @@ -2273,7 +2364,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) d->updateUnrequestedIndexes(); d->moveReason = QDeclarativeListViewPrivate::Other; if (!d->visibleItems.count() || d->model->count() <= 1) { - d->layout(); + d->scheduleLayout(); d->updateCurrent(qMax(0, qMin(d->currentIndex, d->model->count()-1))); emit countChanged(); return; @@ -2303,8 +2394,9 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) d->currentIndex += count; if (d->currentItem) d->currentItem->index = d->currentIndex; + emit currentIndexChanged(); } - d->layout(); + d->scheduleLayout(); emit countChanged(); return; } @@ -2327,7 +2419,10 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) int i = 0; int from = d->position() - d->buffer; for (i = count-1; i >= 0 && pos > from; --i) { - addedVisible = true; + if (!addedVisible) { + d->scheduleLayout(); + addedVisible = true; + } FxListItem *item = d->createItem(modelIndex + i); d->visibleItems.insert(insertionIdx, item); pos -= item->size() + d->spacing; @@ -2354,7 +2449,10 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) int i = 0; int to = d->buffer+d->position()+d->size()-1; for (i = 0; i < count && pos <= to; ++i) { - addedVisible = true; + if (!addedVisible) { + d->scheduleLayout(); + addedVisible = true; + } FxListItem *item = d->createItem(modelIndex + i); d->visibleItems.insert(index, item); item->setPosition(pos); @@ -2377,6 +2475,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) d->currentItem->index = d->currentIndex; d->currentItem->setPosition(d->currentItem->position() + diff); } + emit currentIndexChanged(); } // Update the indexes of the following visible items. for (; index < d->visibleItems.count(); ++index) { @@ -2390,8 +2489,6 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) for (int j = 0; j < added.count(); ++j) added.at(j)->attached->emitAdd(); - if (addedVisible) - d->layout(); emit countChanged(); } @@ -2417,7 +2514,10 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) ++it; } else { // removed item - removedVisible = true; + if (!removedVisible) { + d->scheduleLayout(); + removedVisible = true; + } item->attached->emitRemove(); if (item->attached->delayRemove()) { item->index = -1; @@ -2442,6 +2542,7 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) d->currentIndex -= count; if (d->currentItem) d->currentItem->index -= count; + emit currentIndexChanged(); } else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) { // current item has been removed. d->currentItem->attached->setIsCurrentItem(false); @@ -2459,20 +2560,13 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) } } - if (removedVisible) { - if (d->visibleItems.isEmpty()) { - d->visibleIndex = 0; - d->visiblePos = d->header ? d->header->size() : 0; - d->timeline.clear(); - d->setPosition(0); - if (d->model->count() == 0) - update(); - else - refill(); - } else { - // Correct the positioning of the items - d->layout(); - } + if (removedVisible && d->visibleItems.isEmpty()) { + d->visibleIndex = 0; + d->visiblePos = d->header ? d->header->size() : 0; + d->timeline.clear(); + d->setPosition(0); + if (d->model->count() == 0) + update(); } emit countChanged(); diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h index d66ac2b..3635b39 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview_p.h +++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h @@ -191,10 +191,15 @@ public: static QDeclarativeListViewAttached *qmlAttachedProperties(QObject *); + enum PositionMode { Beginning, Center, End, Visible, Contain }; + Q_ENUMS(PositionMode); + + Q_INVOKABLE void positionViewAtIndex(int index, int mode); + Q_INVOKABLE int indexAt(int x, int y) const; + public Q_SLOTS: void incrementCurrentIndex(); void decrementCurrentIndex(); - void positionViewAtIndex(int index); Q_SIGNALS: void countChanged(); @@ -219,6 +224,7 @@ Q_SIGNALS: void footerChanged(); protected: + virtual bool event(QEvent *event); virtual void viewportMoved(); virtual qreal minYExtent() const; virtual qreal maxYExtent() const; diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index b0499d7..6dbcd16 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -155,6 +155,8 @@ void QDeclarativeLoaderPrivate::initResize() QDeclarativeLoader::QDeclarativeLoader(QDeclarativeItem *parent) : QDeclarativeItem(*(new QDeclarativeLoaderPrivate), parent) { + Q_D(QDeclarativeItem); + d->flags |= QGraphicsItem::ItemIsFocusScope; } /*! @@ -273,7 +275,7 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() if (component) { QDeclarativeContext *ctxt = new QDeclarativeContext(qmlContext(q)); - ctxt->addDefaultObject(q); + ctxt->setContextObject(q); if (!component->errors().isEmpty()) { qWarning() << component->errors(); @@ -346,12 +348,13 @@ QDeclarativeLoader::Status QDeclarativeLoader::status() const } /*! - \qmlproperty real Loader::progress +\qmlproperty real Loader::progress - This property holds the progress of QML data loading, from 0.0 (nothing loaded) - to 1.0 (finished). +This property holds the progress of loading QML data from the network, from +0.0 (nothing loaded) to 1.0 (finished). Most QML files are quite small, so +this value will rapidly change from 0 to 1. - \sa status +\sa status */ qreal QDeclarativeLoader::progress() const { diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index ec7aa62..26242bc 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -58,12 +58,12 @@ QDeclarativeDrag::~QDeclarativeDrag() { } -QDeclarativeItem *QDeclarativeDrag::target() const +QGraphicsObject *QDeclarativeDrag::target() const { return _target; } -void QDeclarativeDrag::setTarget(QDeclarativeItem *t) +void QDeclarativeDrag::setTarget(QGraphicsObject *t) { if (_target == t) return; @@ -383,7 +383,6 @@ void QDeclarativeMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event) } d->dragged = false; setHovered(true); - d->start = event->pos(); d->startScene = event->scenePos(); // we should only start timer if pressAndHold is connected to. if (d->isConnected("pressAndHold(QDeclarativeMouseEvent*)")) diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p.h index 33422e2..db49b57 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p.h @@ -55,7 +55,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeDrag : public QObject Q_OBJECT Q_ENUMS(Axis) - Q_PROPERTY(QDeclarativeItem *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QGraphicsObject *target READ target WRITE setTarget NOTIFY targetChanged) Q_PROPERTY(Axis axis READ axis WRITE setAxis NOTIFY axisChanged) Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged) Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax NOTIFY maximumXChanged) @@ -67,8 +67,8 @@ public: QDeclarativeDrag(QObject *parent=0); ~QDeclarativeDrag(); - QDeclarativeItem *target() const; - void setTarget(QDeclarativeItem *); + QGraphicsObject *target() const; + void setTarget(QGraphicsObject *); enum Axis { XAxis=0x01, YAxis=0x02, XandYAxis=0x03 }; Axis axis() const; @@ -92,7 +92,7 @@ Q_SIGNALS: void maximumYChanged(); private: - QDeclarativeItem *_target; + QGraphicsObject *_target; Axis _axis; qreal _xmin; qreal _xmax; diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h index d4871f2..88206cd 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h @@ -101,7 +101,6 @@ public: bool dragY : 1; bool dragged : 1; QDeclarativeDrag *drag; - QPointF start; QPointF startScene; qreal startX; qreal startY; diff --git a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp index ab6007a..28a93d2 100644 --- a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp +++ b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp @@ -211,8 +211,8 @@ QDeclarativePaintedItem::~QDeclarativePaintedItem() */ void QDeclarativePaintedItem::init() { - connect(this,SIGNAL(widthChanged()),this,SLOT(clearCache())); - connect(this,SIGNAL(heightChanged()),this,SLOT(clearCache())); + connect(this,SIGNAL(widthChanged(qreal)),this,SLOT(clearCache())); + connect(this,SIGNAL(heightChanged(qreal)),this,SLOT(clearCache())); connect(this,SIGNAL(visibleChanged()),this,SLOT(clearCache())); } diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index cc17157..b9c8971 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -354,7 +354,7 @@ void QDeclarativePathView::setCurrentIndex(int idx) /*! \qmlproperty real PathView::offset - The offset specifies how far along the path the items are from their initial positions. + The offset specifies how far along the path (0.0-1.0) the items are from their initial positions. */ qreal QDeclarativePathView::offset() const { @@ -373,9 +373,9 @@ void QDeclarativePathViewPrivate::setOffset(qreal o) { Q_Q(QDeclarativePathView); if (_offset != o) { - _offset = qmlMod(o, qreal(100.0)); + _offset = qmlMod(o, qreal(1.0)); if (_offset < 0) - _offset = 100.0 + _offset; + _offset = 1.0 + _offset; q->refill(); } } @@ -503,7 +503,7 @@ QPointF QDeclarativePathViewPrivate::pointNear(const QPointF &point, qreal *near } if (nearPercent) - *nearPercent = nearPc / 10.0; + *nearPercent = nearPc / 1000.0; return nearPoint; } @@ -559,10 +559,10 @@ void QDeclarativePathView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if (diff) { setOffset(d->_offset + diff); - if (diff > 50) - diff -= 100; - else if (diff < -50) - diff += 100; + if (diff > 0.5) + diff -= 1.0; + else if (diff < -0.5) + diff += 1.0; d->lastElapsed = QDeclarativeItemPrivate::restart(d->lastPosTime); d->lastDist = diff; @@ -579,15 +579,15 @@ void QDeclarativePathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *) qreal elapsed = qreal(d->lastElapsed + QDeclarativeItemPrivate::elapsed(d->lastPosTime)) / 1000.; qreal velocity = elapsed > 0. ? d->lastDist / elapsed : 0; - if (d->model && d->model->count() && qAbs(velocity) > 5) { - if (velocity > 100) - velocity = 100; - else if (velocity < -100) - velocity = -100; - qreal inc = qmlMod(d->_offset - d->snapPos, qreal(100.0 / d->model->count())); - qreal dist = qAbs(velocity/2 - qmlMod(velocity/2, qreal(100.0 / d->model->count()) - inc)); + if (d->model && d->model->count() && qAbs(velocity) > 0.05) { + if (velocity > 1.5) + velocity = 1.5; + else if (velocity < -1.5) + velocity = -1.5; + qreal inc = qmlMod(d->_offset - d->snapPos, qreal(1.0 / d->model->count())); + qreal dist = qAbs(velocity/2 - qmlMod(velocity/2, qreal(1.0 / d->model->count()) - inc)); d->moveOffset.setValue(d->_offset); - d->tl.accel(d->moveOffset, velocity, 10, dist); + d->tl.accel(d->moveOffset, velocity, 0.1, dist); d->tl.callback(QDeclarativeTimeLineCallback(&d->moveOffset, d->fixOffsetCallback, d)); } else { d->fixOffset(); @@ -676,10 +676,10 @@ void QDeclarativePathView::componentComplete() itemIndex += d->pathOffset; itemIndex %= d->items.count(); - qreal targetOffset = qmlMod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), qreal(100.0)); + qreal targetOffset = qmlMod(1.0 + d->snapPos - qreal(itemIndex) / d->items.count(), qreal(1.0)); if (targetOffset < 0) - targetOffset = 100.0 + targetOffset; + targetOffset = 1.0 + targetOffset; if (targetOffset != d->_offset) { d->moveOffset.setValue(targetOffset); } @@ -712,8 +712,8 @@ void QDeclarativePathViewPrivate::regenerate() } items.append(item); item->setZValue(i); - qreal percent = i * (100. / numItems) + _offset; - percent = qAbs(qmlMod(percent, qreal(100.0))/100.0); + qreal percent = qreal(i) / numItems + _offset; + percent = qAbs(qmlMod(percent, qreal(1.0))); updateItem(item, percent); model->completeItem(); if (currentIndex == index) { @@ -745,10 +745,10 @@ void QDeclarativePathView::refill() QList<qreal> positions; for (int i=0; i<d->items.count(); i++){ - qreal percent = i * (100. / d->items.count()); + qreal percent = qreal(i) / d->items.count(); percent = percent + d->_offset; - percent = qmlMod(percent, qreal(100.0)); - positions << qAbs(percent/100.0); + percent = qmlMod(percent, qreal(1.0)); + positions << qAbs(percent); } if (d->pathItems==-1) { @@ -843,10 +843,10 @@ void QDeclarativePathView::itemsInserted(int modelIndex, int count) int itemIndex = (d->currentIndex - d->firstIndex + d->model->count())%d->model->count(); itemIndex += d->pathOffset; itemIndex %= d->items.count(); - qreal targetOffset = qmlMod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), qreal(100.0)); + qreal targetOffset = qmlMod(1.0 + d->snapPos - qreal(itemIndex) / d->items.count(), qreal(1.0)); if (targetOffset < 0) - targetOffset = 100.0 + targetOffset; + targetOffset = 1.0 + targetOffset; if (targetOffset != d->_offset) d->moveOffset.setValue(targetOffset); } @@ -880,10 +880,10 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count) int itemIndex = (d->currentIndex - d->firstIndex + d->model->count())%d->model->count(); itemIndex += d->pathOffset; itemIndex %= d->items.count(); - qreal targetOffset = qmlMod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), qreal(100.0)); + qreal targetOffset = qmlMod(1.0 + d->snapPos - qreal(itemIndex) / d->items.count(), qreal(1.0)); if (targetOffset < 0) - targetOffset = 100.0 + targetOffset; + targetOffset = 1.0 + targetOffset; if (targetOffset != d->_offset) d->moveOffset.setValue(targetOffset); } @@ -919,15 +919,15 @@ int QDeclarativePathViewPrivate::calcCurrentIndex() { int current = -1; if (model && items.count()) { - _offset = qmlMod(_offset, qreal(100.0)); + _offset = qmlMod(_offset, qreal(1.0)); if (_offset < 0) - _offset += 100.0; + _offset += 1.0; if (pathItems == -1) { - qreal delta = qmlMod(_offset - snapPos, qreal(100.0)); + qreal delta = qmlMod(_offset - snapPos, qreal(1.0)); if (delta < 0) - delta = 100.0 + delta; - int ii = model->count() - qRound(delta * model->count() / 100); + delta = 1.0 + delta; + int ii = model->count() - qRound(delta * model->count()); if (ii < 0) ii = 0; current = ii; @@ -935,10 +935,10 @@ int QDeclarativePathViewPrivate::calcCurrentIndex() qreal bestDiff=1e9; int bestI=-1; for (int i=0; i<items.count(); i++){ - qreal percent = i * (100. / items.count()); + qreal percent = qreal(i) / items.count(); percent = percent + _offset; - percent = qmlMod(percent, qreal(100.0)); - qreal diff = qAbs(snapPos - (percent/100.0)); + percent = qmlMod(percent, qreal(1.0)); + qreal diff = qAbs(snapPos - percent); if (diff < bestDiff){ bestDiff = diff; bestI = i; @@ -1017,10 +1017,10 @@ void QDeclarativePathViewPrivate::snapToCurrent() itemIndex = itemIndex - model->count() + items.count(); } itemIndex %= items.count(); - qreal targetOffset = qmlMod(100 + (snapPos*100) - 100.0 * itemIndex / items.count(), qreal(100.0)); + qreal targetOffset = qmlMod(1.0 + snapPos - qreal(itemIndex) / items.count(), qreal(1.0)); if (targetOffset < 0) - targetOffset = 100.0 + targetOffset; + targetOffset = 1.0 + targetOffset; if (targetOffset == _offset && rounds == 0) return; @@ -1031,24 +1031,24 @@ void QDeclarativePathViewPrivate::snapToCurrent() if (rounds!=0){ //Compensate if the targetOffset would bring the target in from off the screen qreal distance = targetOffset - _offset; - if (distance <= -50) + if (distance <= -0.5) rounds--; - if (distance > 50) + if (distance > 0.5) rounds++; - tl.move(moveOffset, targetOffset + 100.0*(-rounds), QEasingCurve(QEasingCurve::InOutQuad), - int(100*items.count()*qMax((qreal)(2.0/items.count()),(qreal)qAbs(rounds)))); + tl.move(moveOffset, targetOffset -rounds, QEasingCurve(QEasingCurve::InOutQuad), + int(items.count()*qMax((qreal)(2.0/items.count()),(qreal)qAbs(rounds)))); tl.callback(QDeclarativeTimeLineCallback(&moveOffset, fixOffsetCallback, this)); return; } - if (targetOffset - _offset > 50.0) { - qreal distance = 100 - targetOffset + _offset; + if (targetOffset - _offset > 0.5) { + qreal distance = 1 - targetOffset + _offset; tl.move(moveOffset, 0.0, QEasingCurve(QEasingCurve::OutQuad), int(200 * _offset / distance)); - tl.set(moveOffset, 100.0); - tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InQuad), int(200 * (100-targetOffset) / distance)); - } else if (targetOffset - _offset <= -50.0) { - qreal distance = 100 - _offset + targetOffset; - tl.move(moveOffset, 100.0, QEasingCurve(QEasingCurve::OutQuad), int(200 * (100-_offset) / distance)); + tl.set(moveOffset, 1.0); + tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InQuad), int(200 * (1.0-targetOffset) / distance)); + } else if (targetOffset - _offset <= -0.5) { + qreal distance = 1 - _offset + targetOffset; + tl.move(moveOffset, 1.0, QEasingCurve(QEasingCurve::OutQuad), int(200 * (1.0-_offset) / distance)); tl.set(moveOffset, 0.0); tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InQuad), int(200 * targetOffset / distance)); } else { diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h index 4083ab5..62f7d95 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h @@ -66,11 +66,6 @@ QT_BEGIN_NAMESPACE -typedef struct PathViewItem{ - int index; - QDeclarativeItem* item; -}PathViewItem; - class QDeclarativeOpenMetaObjectType; class QDeclarativePathViewAttached; class QDeclarativePathViewPrivate : public QDeclarativeItemPrivate diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index 1212e89..0f59a70 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -212,19 +212,22 @@ void QDeclarativeBasePositioner::prePositioning() QList<QGraphicsItem *> children = d->QGraphicsItemPrivate::children; qSort(children.begin(), children.end(), d->insertionOrder); + QPODVector<PositionedItem,8> oldItems; + positionedItems.copyAndClear(oldItems); for (int ii = 0; ii < children.count(); ++ii) { QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(ii)); if (!child) continue; PositionedItem *item = 0; PositionedItem posItem(child); - int wIdx = positionedItems.find(posItem); + int wIdx = oldItems.find(posItem); if (wIdx < 0) { d->watchChanges(child); positionedItems.append(posItem); item = &positionedItems[positionedItems.count()-1]; } else { - item = &positionedItems[wIdx]; + item = &oldItems[wIdx]; + positionedItems.append(*item); } if (child->opacity() <= 0.0 || !child->isVisible()) { item->isVisible = false; diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp index e4cd499..b9696c8 100644 --- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp +++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp @@ -296,6 +296,8 @@ void QDeclarativeRepeater::clear() void QDeclarativeRepeater::regenerate() { Q_D(QDeclarativeRepeater); + if (!isComponentComplete()) + return; clear(); @@ -312,23 +314,65 @@ void QDeclarativeRepeater::regenerate() } } -void QDeclarativeRepeater::itemsInserted(int, int) +void QDeclarativeRepeater::itemsInserted(int index, int count) { - regenerate(); + Q_D(QDeclarativeRepeater); + if (!isComponentComplete()) + return; + for (int i = 0; i < count; ++i) { + int modelIndex = index + i; + QDeclarativeItem *item = d->model->item(modelIndex); + if (item) { + item->setParent(parentItem()); + if (modelIndex < d->deletables.count()) + item->stackBefore(d->deletables.at(modelIndex)); + else + item->stackBefore(this); + d->deletables.insert(modelIndex, item); + } + } } -void QDeclarativeRepeater::itemsRemoved(int, int) +void QDeclarativeRepeater::itemsRemoved(int index, int count) { - regenerate(); + Q_D(QDeclarativeRepeater); + if (!isComponentComplete()) + return; + while (count--) { + QDeclarativeItem *item = d->deletables.takeAt(index); + if (item) { + item->setParentItem(this); + d->model->release(item); + } + } } -void QDeclarativeRepeater::itemsMoved(int,int,int) +void QDeclarativeRepeater::itemsMoved(int from, int to, int count) { - regenerate(); + Q_D(QDeclarativeRepeater); + if (!isComponentComplete()) + return; + QList<QDeclarativeItem*> removed; + int removedCount = count; + while (removedCount--) + removed << d->deletables.takeAt(from); + for (int i = 0; i < count; ++i) + d->deletables.insert(to + i, removed.at(i)); + for (int i = 0; i < d->model->count(); ++i) { + if (i < from && i < to) + continue; + QDeclarativeItem *item = d->deletables.at(i); + if (i < d->deletables.count()-1) + item->stackBefore(d->deletables.at(i+1)); + else + item->stackBefore(this); + } } void QDeclarativeRepeater::modelReset() { + if (!isComponentComplete()) + return; regenerate(); } diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index be73b39..dbae47d 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -760,17 +760,11 @@ void QDeclarativeTextEdit::keyReleaseEvent(QKeyEvent *event) QDeclarativePaintedItem::keyReleaseEvent(event); } -/*! - \overload - Handles changing of the focus property. Focus is applied to the control - even if the edit does not have active focus. This is because things - like KeyProxy can give the behavior of focus even when hasFocus() isn't - true. -*/ -void QDeclarativeTextEdit::focusChanged(bool hasFocus) +void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus) { - setCursorVisible(hasFocus); - QDeclarativeItem::focusChanged(hasFocus); + Q_Q(QDeclarativeTextEdit); + q->setCursorVisible(hasFocus); + QDeclarativeItemPrivate::focusChanged(hasFocus); } /*! diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h index 6183b1d..b1682c4 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h @@ -215,8 +215,6 @@ protected: void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *); - void focusChanged(bool); - // mouse filter? void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h index 002fac4..dd2a29d 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h @@ -80,6 +80,7 @@ public: void updateDefaultTextOption(); void relayoutDocument(); void updateSelection(); + void focusChanged(bool); QString text; QFont font; diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 3382628..01167dc 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -636,12 +636,12 @@ int QDeclarativeTextInput::xToPos(int x) return d->control->xToPos(x - d->hscroll); } -void QDeclarativeTextInput::focusChanged(bool hasFocus) +void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus) { - Q_D(QDeclarativeTextInput); - d->focused = hasFocus; - setCursorVisible(hasFocus); - QDeclarativeItem::focusChanged(hasFocus); + Q_Q(QDeclarativeTextInput); + focused = hasFocus; + q->setCursorVisible(hasFocus); + QDeclarativeItemPrivate::focusChanged(hasFocus); } void QDeclarativeTextInput::keyPressEvent(QKeyEvent* ev) @@ -834,6 +834,9 @@ void QDeclarativeTextInputPrivate::init() oldValidity = control->hasAcceptableInput(); lastSelectionStart = 0; lastSelectionEnd = 0; + QPalette p = control->palette(); + selectedTextColor = p.color(QPalette::HighlightedText); + selectionColor = p.color(QPalette::Highlight); } void QDeclarativeTextInput::cursorPosChanged() diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h index f690ae2..6a61c2d 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h @@ -199,8 +199,6 @@ protected: void keyPressEvent(QKeyEvent* ev); bool event(QEvent *e); - void focusChanged(bool hasFocus); - public Q_SLOTS: void selectAll(); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h index 3d28f40..5d17a55 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h @@ -83,6 +83,7 @@ public: void init(); void startCreatingCursor(); + void focusChanged(bool hasFocus); QLineControl* control; diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 6bad4da..6341764 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -196,7 +196,7 @@ QVariant QDeclarativeVisualItemModel::evaluate(int index, const QString &express return QVariant(); QDeclarativeContext *ccontext = qmlContext(this); QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext); - ctxt->addDefaultObject(d->children.at(index)); + ctxt->setContextObject(d->children.at(index)); QDeclarativeExpression e(ctxt, expression, objectContext); QVariant value = e.value(); delete ctxt; @@ -991,7 +991,7 @@ QDeclarativeItem *QDeclarativeVisualDataModel::item(int index, const QByteArray QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext); QDeclarativeVisualDataModelData *data = new QDeclarativeVisualDataModelData(index, this); ctxt->setContextProperty(QLatin1String("model"), data); - ctxt->addDefaultObject(data); + ctxt->setContextObject(data); nobj = d->m_delegate->beginCreate(ctxt); if (complete) d->m_delegate->completeCreate(); @@ -1104,7 +1104,7 @@ QVariant QDeclarativeVisualDataModel::evaluate(int index, const QString &express if (!ccontext) ccontext = qmlContext(this); QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext); QDeclarativeVisualDataModelData *data = new QDeclarativeVisualDataModelData(index, this); - ctxt->addDefaultObject(data); + ctxt->setContextObject(data); QDeclarativeExpression e(ctxt, expression, objectContext); value = e.value(); delete data; diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp index 34163a4..6404be3 100644 --- a/src/declarative/qml/parser/qdeclarativejslexer.cpp +++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp @@ -56,9 +56,11 @@ #include <stdio.h> #include <string.h> -QT_QML_BEGIN_NAMESPACE - +QT_BEGIN_NAMESPACE extern double qstrtod(const char *s00, char const **se, bool *ok); +QT_END_NAMESPACE + +QT_QML_BEGIN_NAMESPACE #define shiftWindowsLineBreak() \ do { \ diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h index 77b7484..dfdef11 100644 --- a/src/declarative/qml/qdeclarative.h +++ b/src/declarative/qml/qdeclarative.h @@ -99,7 +99,7 @@ int qmlRegisterType() qRegisterMetaType<T *>(pointerName.constData()), qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()), - 0, + 0, 0, 0, 0, 0, 0, &T::staticMetaObject, @@ -131,7 +131,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c qRegisterMetaType<T *>(pointerName.constData()), qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()), - QDeclarativePrivate::create<T>, + sizeof(T), QDeclarativePrivate::createInto<T>, uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, @@ -163,7 +163,7 @@ int qmlRegisterExtendedType() qRegisterMetaType<T *>(pointerName.constData()), qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()), - 0, + 0, 0, 0, 0, 0, 0, &T::staticMetaObject, @@ -203,7 +203,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, qRegisterMetaType<T *>(pointerName.constData()), qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()), - QDeclarativePrivate::create<T>, + sizeof(T), QDeclarativePrivate::createInto<T>, uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, @@ -256,7 +256,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, qRegisterMetaType<T *>(pointerName.constData()), qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()), - QDeclarativePrivate::create<T>, + sizeof(T), QDeclarativePrivate::createInto<T>, uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, @@ -275,18 +275,6 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, return QDeclarativePrivate::registerType(type); } -#define QML_REGISTER_INTERFACE(INTERFACE) \ - qmlRegisterInterface<INTERFACE>(#INTERFACE) - -#define QML_REGISTER_EXTENDED_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, CLASS, EXTENSION) \ - qmlRegisterExtendedType<CLASS,EXTENSION>(#URI, VERSION_MAJ, VERSION_MIN, #NAME) - -#define QML_REGISTER_TYPE(URI,VMAJ,VMIN,NAME,CLASS) \ - qmlRegisterType<CLASS>(#URI, VMAJ, VMIN, #NAME) - -#define QML_REGISTER_NOCREATE_TYPE(CLASS) \ - qmlRegisterType<CLASS>() - class QDeclarativeContext; class QDeclarativeEngine; Q_DECLARATIVE_EXPORT void qmlExecuteDeferred(QObject *); diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index 88ca5cd..090bd5b 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -79,14 +79,25 @@ QDeclarativeBindingPrivate::QDeclarativeBindingPrivate() { } -QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj, QDeclarativeContext *ctxt, const QString &url, int lineNumber, QObject *parent) +QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj, + QDeclarativeContextData *ctxt, const QString &url, int lineNumber, + QObject *parent) : QDeclarativeExpression(ctxt, data, rc, obj, url, lineNumber, *new QDeclarativeBindingPrivate) { setParent(parent); setNotifyOnValueChanged(true); } -QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContext *ctxt, QObject *parent) +QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContext *ctxt, + QObject *parent) +: QDeclarativeExpression(QDeclarativeContextData::get(ctxt), str, obj, *new QDeclarativeBindingPrivate) +{ + setParent(parent); + setNotifyOnValueChanged(true); +} + +QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContextData *ctxt, + QObject *parent) : QDeclarativeExpression(ctxt, str, obj, *new QDeclarativeBindingPrivate) { setParent(parent); @@ -181,8 +192,8 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) } if (data->error.isValid()) { - QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine())? - QDeclarativeEnginePrivate::get(data->context()->engine()):0; + QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine)? + QDeclarativeEnginePrivate::get(data->context()->engine):0; if (!data->addError(p)) qWarning().nospace() << qPrintable(this->error().toString()); } else { @@ -223,7 +234,7 @@ void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteF int QDeclarativeBinding::propertyIndex() { Q_D(QDeclarativeBinding); - return d->bindingData()->property.index(); + return QDeclarativePropertyPrivate::bindingIndex(d->bindingData()->property); } bool QDeclarativeBinding::enabled() const @@ -259,23 +270,57 @@ void QDeclarativeAbstractBinding::addToObject(QObject *object) { Q_ASSERT(object); + if (m_object == object) + return; + + int index = propertyIndex(); + removeFromObject(); Q_ASSERT(!m_prevBinding); - QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, true); - m_nextBinding = data->bindings; - if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; - m_prevBinding = &data->bindings; - data->bindings = this; m_object = object; + QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, true); + + if (index & 0xFF000000) { + // Value type + + int coreIndex = index & 0xFFFFFF; + + // Find the value type proxy (if there is one) + QDeclarativeValueTypeProxyBinding *proxy = 0; + if (data->hasBindingBit(coreIndex)) { + QDeclarativeAbstractBinding *b = data->bindings; + while (b && b->propertyIndex() != coreIndex) + b = b->m_nextBinding; + Q_ASSERT(b && b->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy); + proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(b); + } + + if (!proxy) + proxy = new QDeclarativeValueTypeProxyBinding(object, coreIndex); + proxy->addToObject(object); + + m_nextBinding = proxy->m_bindings; + if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; + m_prevBinding = &proxy->m_bindings; + proxy->m_bindings = this; - data->setBindingBit(m_object, propertyIndex()); + } else { + m_nextBinding = data->bindings; + if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; + m_prevBinding = &data->bindings; + data->bindings = this; + + data->setBindingBit(m_object, index); + } } void QDeclarativeAbstractBinding::removeFromObject() { if (m_prevBinding) { + int index = propertyIndex(); + Q_ASSERT(m_object); *m_prevBinding = m_nextBinding; @@ -283,8 +328,14 @@ void QDeclarativeAbstractBinding::removeFromObject() m_prevBinding = 0; m_nextBinding = 0; - QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(m_object, false); - if (data) data->clearBindingBit(propertyIndex()); + if (index & 0xFF000000) { + // Value type - we don't remove the proxy from the object. It will sit their happily + // doing nothing for ever more. + } else { + QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(m_object, false); + if (data) data->clearBindingBit(index); + } + m_object = 0; } } @@ -305,4 +356,88 @@ void QDeclarativeAbstractBinding::setEnabled(bool e, QDeclarativePropertyPrivate if (e) m_mePtr = 0; } +QDeclarativeValueTypeProxyBinding::QDeclarativeValueTypeProxyBinding(QObject *o, int index) +: m_object(o), m_index(index), m_bindings(0) +{ +} + +QDeclarativeValueTypeProxyBinding::~QDeclarativeValueTypeProxyBinding() +{ + while (m_bindings) { + QDeclarativeAbstractBinding *binding = m_bindings; + binding->setEnabled(false, 0); + binding->destroy(); + } +} + +void QDeclarativeValueTypeProxyBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags) +{ + if (e) { + addToObject(m_object); + + QDeclarativeAbstractBinding *bindings = m_bindings; + m_bindings = 0; + recursiveEnable(bindings, flags); + } else { + removeFromObject(); + + QDeclarativeAbstractBinding *bindings = m_bindings; + m_bindings = 0; + recursiveDisable(bindings); + } +} + +void QDeclarativeValueTypeProxyBinding::recursiveEnable(QDeclarativeAbstractBinding *b, QDeclarativePropertyPrivate::WriteFlags flags) +{ + if (!b) + return; + + QDeclarativeAbstractBinding *next = b->m_nextBinding; + b->m_prevBinding = 0; + b->m_nextBinding = 0; + Q_ASSERT(b->m_mePtr == 0); + b->m_mePtr = &b; + + recursiveEnable(next, flags); + + if (b) + b->setEnabled(true, flags); +} + +void QDeclarativeValueTypeProxyBinding::recursiveDisable(QDeclarativeAbstractBinding *b) +{ + if (!b) + return; + + recursiveDisable(b->m_nextBinding); + + b->setEnabled(false, 0); + + Q_ASSERT(b->m_prevBinding == 0); + Q_ASSERT(b->m_nextBinding == 0); + b->m_nextBinding = m_bindings; + if (b->m_nextBinding) b->m_nextBinding->m_prevBinding = &b->m_nextBinding; + b->m_prevBinding = &m_bindings; + m_bindings = b; +} + +int QDeclarativeValueTypeProxyBinding::propertyIndex() +{ + return m_index; +} + +void QDeclarativeValueTypeProxyBinding::update(QDeclarativePropertyPrivate::WriteFlags) +{ +} + +QDeclarativeAbstractBinding *QDeclarativeValueTypeProxyBinding::binding(int propertyIndex) +{ + QDeclarativeAbstractBinding *binding = m_bindings; + + while (binding && binding->propertyIndex() != propertyIndex) + binding = binding->m_nextBinding; + + return binding; +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h index 1a714f0..56f1715 100644 --- a/src/declarative/qml/qdeclarativebinding_p.h +++ b/src/declarative/qml/qdeclarativebinding_p.h @@ -68,12 +68,14 @@ class Q_DECLARATIVE_EXPORT QDeclarativeAbstractBinding { public: QDeclarativeAbstractBinding(); - virtual ~QDeclarativeAbstractBinding(); virtual void destroy(); virtual QString expression() const; + enum Type { PropertyBinding, ValueTypeProxy }; + virtual Type bindingType() const { return PropertyBinding; } + void setEnabled(bool e) { setEnabled(e, QDeclarativePropertyPrivate::DontRemoveBinding); } virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags) = 0; virtual int propertyIndex() = 0; @@ -85,11 +87,13 @@ public: void removeFromObject(); protected: + virtual ~QDeclarativeAbstractBinding(); void clear(); private: + friend class QDeclarativeDeclarativeData; - friend class QDeclarativeProperty; + friend class QDeclarativeValueTypeProxyBinding; friend class QDeclarativePropertyPrivate; friend class QDeclarativeVME; @@ -99,6 +103,32 @@ private: QDeclarativeAbstractBinding *m_nextBinding; }; +class QDeclarativeValueTypeProxyBinding : public QDeclarativeAbstractBinding +{ +public: + QDeclarativeValueTypeProxyBinding(QObject *o, int coreIndex); + + virtual Type bindingType() const { return ValueTypeProxy; } + + virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags); + virtual int propertyIndex(); + virtual void update(QDeclarativePropertyPrivate::WriteFlags); + + QDeclarativeAbstractBinding *binding(int propertyIndex); + +protected: + ~QDeclarativeValueTypeProxyBinding(); + +private: + void recursiveEnable(QDeclarativeAbstractBinding *, QDeclarativePropertyPrivate::WriteFlags); + void recursiveDisable(QDeclarativeAbstractBinding *); + + friend class QDeclarativeAbstractBinding; + QObject *m_object; + int m_index; + QDeclarativeAbstractBinding *m_bindings; +}; + class QDeclarativeContext; class QDeclarativeBindingPrivate; class Q_DECLARATIVE_EXPORT QDeclarativeBinding : public QDeclarativeExpression, public QDeclarativeAbstractBinding @@ -106,9 +136,9 @@ class Q_DECLARATIVE_EXPORT QDeclarativeBinding : public QDeclarativeExpression, Q_OBJECT public: QDeclarativeBinding(const QString &, QObject *, QDeclarativeContext *, QObject *parent=0); - QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContext *, const QString &, int, - QObject *parent); - ~QDeclarativeBinding(); + QDeclarativeBinding(const QString &, QObject *, QDeclarativeContextData *, QObject *parent=0); + QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContextData *, + const QString &, int, QObject *parent); void setTarget(const QDeclarativeProperty &); QDeclarativeProperty property() const; @@ -125,6 +155,7 @@ public Q_SLOTS: void update() { update(QDeclarativePropertyPrivate::DontRemoveBinding); } protected: + ~QDeclarativeBinding(); void emitValueChanged(); private: diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index 17937fd..1acca2f 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -48,12 +48,17 @@ #include <private/qdeclarativejsast_p.h> #include <private/qdeclarativejsengine_p.h> #include <private/qdeclarativeexpression_p.h> +#include <QtCore/qcoreapplication.h> #include <QtCore/qdebug.h> #include <QtCore/qnumeric.h> #include <private/qdeclarativeanchors_p_p.h> +#include <private/qdeclarativeglobal_p.h> QT_BEGIN_NAMESPACE +DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL); +DEFINE_BOOL_CONFIG_OPTION(qmlDisableOptimizer, QML_DISABLE_OPTIMIZER); + using namespace QDeclarativeJS; namespace { @@ -124,24 +129,7 @@ public: QDeclarativeCompiledBindingsPrivate *parent; }; - struct Subscription { - struct Signal { - QDeclarativeGuard<QObject> source; - int notifyIndex; - }; - - enum { InvalidType, SignalType, IdType } type; - inline Subscription(); - inline ~Subscription(); - bool isSignal() const { return type == SignalType; } - bool isId() const { return type == IdType; } - inline Signal *signal(); - inline QDeclarativeContextPrivate::IdNotifier *id(); - union { - char signalData[sizeof(Signal)]; - char idData[sizeof(QDeclarativeContextPrivate::IdNotifier)]; - }; - }; + typedef QDeclarativeNotifierEndpoint Subscription; Subscription *subscriptions; QScriptDeclarativeClass::PersistentIdentifier *identifiers; @@ -154,18 +142,18 @@ public: static int methodCount; void init(); - void run(int instr, QDeclarativeContextPrivate *context, + void run(int instr, QDeclarativeContextData *context, QDeclarativeDelayedError *error, QObject *scope, QObject *output); inline void unsubscribe(int subIndex); - inline void subscribeId(QDeclarativeContextPrivate *p, int idIndex, int subIndex); + inline void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex); inline void subscribe(QObject *o, int notifyIndex, int subIndex); QDeclarativePropertyCache::Data *findproperty(QObject *obj, - const QScriptDeclarativeClass::Identifier &name, - QDeclarativeEnginePrivate *enginePriv, - QDeclarativePropertyCache::Data &local); + const QScriptDeclarativeClass::Identifier &name, + QDeclarativeEnginePrivate *enginePriv, + QDeclarativePropertyCache::Data &local); bool findproperty(QObject *obj, Register *output, QDeclarativeEnginePrivate *enginePriv, @@ -174,7 +162,7 @@ public: bool isTerminal); void findgeneric(Register *output, // value output int subIdx, // Subscription index in config - QDeclarativeContextPrivate *context, // Context to search in + QDeclarativeContextData *context, // Context to search in const QScriptDeclarativeClass::Identifier &name, bool isTerminal); }; @@ -190,21 +178,9 @@ QDeclarativeCompiledBindingsPrivate::~QDeclarativeCompiledBindingsPrivate() delete [] identifiers; identifiers = 0; } -QDeclarativeCompiledBindingsPrivate::Subscription::Subscription() -: type(InvalidType) -{ -} - -QDeclarativeCompiledBindingsPrivate::Subscription::~Subscription() -{ - if (type == SignalType) ((Signal *)signalData)->~Signal(); - else if (type == IdType) ((QDeclarativeContextPrivate::IdNotifier *)idData)->~IdNotifier(); -} - - int QDeclarativeCompiledBindingsPrivate::methodCount = -1; -QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContext *context) +QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context) : QObject(*(new QDeclarativeCompiledBindingsPrivate)) { Q_D(QDeclarativeCompiledBindings); @@ -248,7 +224,6 @@ void QDeclarativeCompiledBindingsPrivate::Binding::setEnabled(bool e, QDeclarati { if (e) { addToObject(target); - update(flags); } else { removeFromObject(); } @@ -276,8 +251,8 @@ void QDeclarativeCompiledBindingsPrivate::Binding::destroy() { enabled = false; removeFromObject(); - parent->q_func()->release(); clear(); + parent->q_func()->release(); } int QDeclarativeCompiledBindings::qt_metacall(QMetaObject::Call c, int id, void **) @@ -303,47 +278,51 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) if (!binding->enabled) return; - if (binding->updating) - qWarning("ERROR: Circular binding"); - QDeclarativeContext *context = q->QDeclarativeAbstractExpression::context(); + QDeclarativeContextData *context = q->QDeclarativeAbstractExpression::context(); if (!context) { qWarning("QDeclarativeCompiledBindings: Attempted to evaluate an expression in an invalid context"); return; } - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(context); + if (!context->engine) + return; + + if (binding->updating) { + QString name; + if (binding->property & 0xFFFF0000) { + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); + + QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; + Q_ASSERT(vt); + + name = QLatin1String(binding->target->metaObject()->property(binding->property & 0xFFFF).name()); + name.append(QLatin1String(".")); + name.append(QLatin1String(vt->metaObject()->property(binding->property >> 24).name())); + } else { + name = QLatin1String(binding->target->metaObject()->property(binding->property).name()); + } + qmlInfo(binding->target) << QCoreApplication::translate("QDeclarativeCompiledBindings", "Binding loop detected for property \"%1\"").arg(name); + return; + } + + binding->updating = true; if (binding->property & 0xFFFF0000) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(cp->engine); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; Q_ASSERT(vt); vt->read(binding->target, binding->property & 0xFFFF); QObject *target = vt; - run(binding->index, cp, binding, binding->scope, target); + run(binding->index, context, binding, binding->scope, target); vt->write(binding->target, binding->property & 0xFFFF, QDeclarativePropertyPrivate::DontRemoveBinding); } else { - run(binding->index, cp, binding, binding->scope, binding->target); + run(binding->index, context, binding, binding->scope, binding->target); } -} - -QDeclarativeCompiledBindingsPrivate::Subscription::Signal *QDeclarativeCompiledBindingsPrivate::Subscription::signal() -{ - if (type == IdType) ((QDeclarativeContextPrivate::IdNotifier *)idData)->~IdNotifier(); - if (type != SignalType) new (signalData) Signal; - type = SignalType; - return (Signal *)signalData; -} - -QDeclarativeContextPrivate::IdNotifier *QDeclarativeCompiledBindingsPrivate::Subscription::id() -{ - if (type == SignalType) ((Signal *)signalData)->~Signal(); - if (type != IdType) new (idData) QDeclarativeContextPrivate::IdNotifier; - type = IdType; - return (QDeclarativeContextPrivate::IdNotifier *)idData; + binding->updating = false; } namespace { @@ -653,26 +632,11 @@ struct QDeclarativeBindingCompilerPrivate void QDeclarativeCompiledBindingsPrivate::unsubscribe(int subIndex) { - Q_Q(QDeclarativeCompiledBindings); - QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); - if (sub->isSignal()) { - QDeclarativeCompiledBindingsPrivate::Subscription::Signal *s = sub->signal(); - if (s->source) -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) - QMetaObject::disconnectOne(s->source, s->notifyIndex, - q, methodCount + subIndex); -#else - // QTBUG-6781 - QMetaObject::disconnect(s->source, s->notifyIndex, - q, methodCount + subIndex); -#endif - } else if (sub->isId()) { - sub->id()->clear(); - } + sub->disconnect(); } -void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextPrivate *p, int idIndex, int subIndex) +void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex) { Q_Q(QDeclarativeCompiledBindings); @@ -680,15 +644,9 @@ void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextPrivate if (p->idValues[idIndex]) { QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); - QDeclarativeContextPrivate::IdNotifier *i = sub->id(); - - i->next = p->idValues[idIndex].bindings; - i->prev = &p->idValues[idIndex].bindings; - p->idValues[idIndex].bindings = i; - if (i->next) i->next->prev = &i->next; - - i->target = q; - i->methodIndex = methodCount + subIndex; + sub->target = q; + sub->targetMethod = methodCount + subIndex; + sub->connect(&p->idValues[idIndex].bindings); } } @@ -697,27 +655,12 @@ void QDeclarativeCompiledBindingsPrivate::subscribe(QObject *o, int notifyIndex, Q_Q(QDeclarativeCompiledBindings); QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); - - if (sub->isId()) - unsubscribe(subIndex); - - QDeclarativeCompiledBindingsPrivate::Subscription::Signal *s = sub->signal(); - if (o != s->source || notifyIndex != s->notifyIndex) { - if (s->source) -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) - QMetaObject::disconnectOne(s->source, s->notifyIndex, - q, methodCount + subIndex); -#else - // QTBUG-6781 - QMetaObject::disconnect(s->source, s->notifyIndex, - q, methodCount + subIndex); -#endif - s->source = o; - s->notifyIndex = notifyIndex; - if (s->source && s->notifyIndex != -1) - QMetaObject::connect(s->source, s->notifyIndex, q, - methodCount + subIndex, Qt::DirectConnection); - } + sub->target = q; + sub->targetMethod = methodCount + subIndex; + if (o) + sub->connect(o, notifyIndex); + else + sub->disconnect(); } // Conversion functions - these MUST match the QtScript expression path @@ -767,7 +710,7 @@ inline static bool toBool(Register *reg, int type, bool *ok = 0) } } -inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextPrivate *context, bool *ok = 0) +inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextData *context, bool *ok = 0) { if (ok) *ok = true; @@ -811,9 +754,9 @@ static QObject *variantToQObject(const QVariant &value, bool *ok) } bool QDeclarativeCompiledBindingsPrivate::findproperty(QObject *obj, Register *output, - QDeclarativeEnginePrivate *enginePriv, - int subIdx, const QScriptDeclarativeClass::Identifier &name, - bool isTerminal) + QDeclarativeEnginePrivate *enginePriv, + int subIdx, const QScriptDeclarativeClass::Identifier &name, + bool isTerminal) { if (!obj) { output->setUndefined(); @@ -884,10 +827,10 @@ bool QDeclarativeCompiledBindingsPrivate::findproperty(QObject *obj, Register *o } void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, - int subIdx, - QDeclarativeContextPrivate *context, - const QScriptDeclarativeClass::Identifier &name, - bool isTerminal) + int subIdx, + QDeclarativeContextData *context, + const QScriptDeclarativeClass::Identifier &name, + bool isTerminal) { QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(context->engine); @@ -898,14 +841,17 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, if (contextPropertyIndex != -1) { - if (subIdx != -1) - subscribe(QDeclarativeContextPrivate::get(context), contextPropertyIndex + context->notifyIndex, subIdx); - if (contextPropertyIndex < context->idValueCount) { output->setQObject(context->idValues[contextPropertyIndex]); output->settype(QMetaType::QObjectStar); + + if (subIdx != -1) + subscribeId(context, contextPropertyIndex, subIdx); + } else { - const QVariant &value = context->propertyValues.at(contextPropertyIndex); + QDeclarativeContextPrivate *cp = context->asQDeclarativeContextPrivate(); + const QVariant &value = cp->propertyValues.at(contextPropertyIndex); + if (isTerminal) { new (output->typeDataPtr()) QVariant(value); output->settype(qMetaTypeId<QVariant>()); @@ -916,6 +862,11 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, else { output->settype(QMetaType::QObjectStar); } return; } + + if (subIdx != -1) + subscribe(context->asQDeclarativeContext(), contextPropertyIndex + cp->notifyIndex, subIdx); + + } return; @@ -928,18 +879,14 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, } } - if (QObject *root = context->defaultObjects.isEmpty()?0:context->defaultObjects.first()) { + if (QObject *root = context->contextObject) { if (findproperty(root, output, enginePriv, subIdx, name, isTerminal)) return; } - if (context->parent) { - context = QDeclarativeContextPrivate::get(context->parent); - } else { - context = 0; - } + context = context->parent; } output->setUndefined(); @@ -958,7 +905,7 @@ void QDeclarativeCompiledBindingsPrivate::init() } static void throwException(int id, QDeclarativeDelayedError *error, - Program *program, QDeclarativeContextPrivate *context, + Program *program, QDeclarativeContextData *context, const QString &description = QString()) { error->error.setUrl(context->url); @@ -1120,8 +1067,8 @@ static void dumpInstruction(const Instr *instr) } void QDeclarativeCompiledBindingsPrivate::run(int instrIndex, - QDeclarativeContextPrivate *context, QDeclarativeDelayedError *error, - QObject *scope, QObject *output) + QDeclarativeContextData *context, QDeclarativeDelayedError *error, + QObject *scope, QObject *output) { error->removeError(); @@ -1169,7 +1116,7 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex, break; case Instr::LoadRoot: - registers[instr->load.reg].setQObject(context->defaultObjects.at(0)); + registers[instr->load.reg].setQObject(context->contextObject); break; case Instr::LoadAttached: @@ -1455,7 +1402,7 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex, // name is not present in the current context or it would have been // found during the static compile findgeneric(registers + instr->find.reg, instr->find.subscribeIndex, - QDeclarativeContextPrivate::get(context->parent), + context->parent, identifiers[instr->find.name].identifier, instr->common.type == Instr::FindGenericTerminal); break; @@ -1612,6 +1559,9 @@ bool QDeclarativeBindingCompilerPrivate::compile(QDeclarativeJS::AST::Node *node return false; if (type.unknownType) { + if (!qmlExperimental()) + return false; + if (destination->type != QMetaType::QReal && destination->type != QVariant::String && destination->type != QMetaType::Bool && @@ -1895,7 +1845,7 @@ bool QDeclarativeBindingCompilerPrivate::parseName(AST::Node *node, Result &type if (!fetch(type, component->metaObject(), reg, d1Idx, subscribeName, nameNodes.at(ii))) return false; - } else { + } else if (qmlExperimental()) { Instr find; if (nameParts.count() == 1) find.common.type = Instr::FindGenericTerminal; @@ -2051,7 +2001,11 @@ bool QDeclarativeBindingCompilerPrivate::numberArith(Result &type, const Result int lhsTmp = -1; int rhsTmp = -1; + if (lhs.unknownType) { + if (!qmlExperimental()) + return false; + lhsTmp = acquireReg(); Instr conv; @@ -2062,6 +2016,9 @@ bool QDeclarativeBindingCompilerPrivate::numberArith(Result &type, const Result } if (rhs.unknownType) { + if (!qmlExperimental()) + return false; + rhsTmp = acquireReg(); Instr conv; @@ -2107,6 +2064,9 @@ bool QDeclarativeBindingCompilerPrivate::stringArith(Result &type, const Result int rhsTmp = -1; if (lhs.unknownType) { + if (!qmlExperimental()) + return false; + lhsTmp = acquireReg(Instr::CleanupString); Instr convert; @@ -2117,6 +2077,9 @@ bool QDeclarativeBindingCompilerPrivate::stringArith(Result &type, const Result } if (rhs.unknownType) { + if (!qmlExperimental()) + return false; + rhsTmp = acquireReg(Instr::CleanupString); Instr convert; @@ -2637,6 +2600,12 @@ int QDeclarativeBindingCompiler::compile(const Expression &expression, QDeclarat { if (!expression.expression.asAST()) return false; + if (!qmlExperimental() && expression.property->isValueTypeSubProperty) + return -1; + + if (qmlDisableOptimizer()) + return -1; + d->context = expression.context; d->component = expression.component; d->destination = expression.property; diff --git a/src/declarative/qml/qdeclarativecompiledbindings_p.h b/src/declarative/qml/qdeclarativecompiledbindings_p.h index 2e24371..84a5df9 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings_p.h +++ b/src/declarative/qml/qdeclarativecompiledbindings_p.h @@ -95,7 +95,7 @@ class QDeclarativeCompiledBindingsPrivate; class QDeclarativeCompiledBindings : public QObject, public QDeclarativeAbstractExpression, public QDeclarativeRefCount { public: - QDeclarativeCompiledBindings(const char *program, QDeclarativeContext *context); + QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context); virtual ~QDeclarativeCompiledBindings(); QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property); diff --git a/src/declarative/qml/qdeclarativecompileddata.cpp b/src/declarative/qml/qdeclarativecompileddata.cpp index bdf16a3..dfbf453 100644 --- a/src/declarative/qml/qdeclarativecompileddata.cpp +++ b/src/declarative/qml/qdeclarativecompileddata.cpp @@ -199,20 +199,6 @@ void QDeclarativeCompiledData::clear() cachedPrograms[ii] = 0; } - -QObject *QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContext *ctxt, const QBitField &bindings) const -{ - if (type) { - QObject *rv = type->create(); - if (rv) - QDeclarativeEngine::setContextForObject(rv, ctxt); - return rv; - } else { - Q_ASSERT(component); - return QDeclarativeComponentPrivate::get(component)->create(ctxt, bindings); - } -} - const QMetaObject *QDeclarativeCompiledData::TypeReference::metaObject() const { if (type) { diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index ef1032b..42d2950 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -82,7 +82,7 @@ QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP); DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATISTICS_DUMP); -DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL); +DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP); using namespace QDeclarativeParser; @@ -825,7 +825,9 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt) if (isCustomParser && !customProps.isEmpty()) { QDeclarativeCustomParser *cp = output->types.at(obj->type).type->customParser(); cp->clearErrors(); + cp->compiler = this; obj->custom = cp->compile(customProps); + cp->compiler = 0; foreach (QDeclarativeError err, cp->errors()) { err.setUrl(output->url); exceptions << err; @@ -1711,16 +1713,6 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop, COMPILE_CHECK(checkValidId(idValue, val)); - // We disallow id's that conflict with import prefixes and types - QDeclarativeEnginePrivate::ImportedNamespace *ns = 0; - QDeclarativeType *type = 0; - QDeclarativeEnginePrivate::get(engine)->resolveType(unit->imports, val.toUtf8(), - &type, 0, 0, 0, &ns); - if (type) - COMPILE_EXCEPTION(idValue, QCoreApplication::translate("QDeclarativeCompiler","id conflicts with type name")); - if (ns) - COMPILE_EXCEPTION(idValue, QCoreApplication::translate("QDeclarativeCompiler","id conflicts with namespace prefix")); - if (compileState.ids.contains(val)) COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","id is not unique")); @@ -1850,6 +1842,7 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type, QMetaProperty p = type->metaObject()->property(idx); prop->index = idx; prop->type = p.userType(); + prop->isValueTypeSubProperty = true; if (prop->value) COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Property assignment expected")); @@ -2183,6 +2176,27 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop return true; } +// Similar logic to above, but not knowing target property. +int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const +{ + int dot = script.indexOf('.'); + if (dot > 0) { + QDeclarativeType *type = 0; + QDeclarativeEnginePrivate::get(engine)->resolveType(unit->imports, script.left(dot), &type, 0, 0, 0, 0); + if (!type) + return -1; + const QMetaObject *mo = type->metaObject(); + const char *key = script.constData() + dot+1; + int i = mo->enumeratorCount(); + while (i--) { + int v = mo->enumerator(i).keyToValue(key); + if (v >= 0) + return v; + } + } + return -1; +} + // Ensures that the dynamic meta specification on obj is valid bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) { @@ -2712,7 +2726,9 @@ bool QDeclarativeCompiler::completeComponentBuild() QDeclarativeBindingCompiler bindingCompiler; - for (QHash<QDeclarativeParser::Value*,BindingReference>::Iterator iter = compileState.bindings.begin(); iter != compileState.bindings.end(); ++iter) { + for (QHash<QDeclarativeParser::Value*,BindingReference>::Iterator iter = compileState.bindings.begin(); + iter != compileState.bindings.end(); ++iter) { + BindingReference &binding = *iter; expr.context = binding.bindingContext.object; @@ -2720,18 +2736,13 @@ bool QDeclarativeCompiler::completeComponentBuild() expr.expression = binding.expression; expr.imports = unit->imports; - if (qmlExperimental()) { - int index = bindingCompiler.compile(expr, QDeclarativeEnginePrivate::get(engine)); - if (index != -1) { - qWarning() << "Accepted for optimization:" << qPrintable(expr.expression.asScript()); - binding.dataType = BindingReference::Experimental; - binding.compiledIndex = index; - componentStat.optimizedBindings++; - continue; - } else { - qWarning() << "Rejected for optimization:" << qPrintable(expr.expression.asScript()); - } - } + int index = bindingCompiler.compile(expr, QDeclarativeEnginePrivate::get(engine)); + if (index != -1) { + binding.dataType = BindingReference::Experimental; + binding.compiledIndex = index; + componentStat.optimizedBindings++; + continue; + } binding.dataType = BindingReference::QtScript; @@ -2768,7 +2779,8 @@ bool QDeclarativeCompiler::completeComponentBuild() if (bindingCompiler.isValid()) { compileState.compiledBindingData = bindingCompiler.program(); - QDeclarativeBindingCompiler::dump(compileState.compiledBindingData); + if (bindingsDump()) + QDeclarativeBindingCompiler::dump(compileState.compiledBindingData); } saveComponentState(); diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index cca42e2..a81259b 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -72,6 +72,7 @@ QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QDeclarativeComponent; class QDeclarativeContext; +class QDeclarativeContextData; class QScriptProgram; class Q_AUTOTEST_EXPORT QDeclarativeCompiledData : public QDeclarativeRefCount, public QDeclarativeCleanup @@ -95,7 +96,7 @@ public: QDeclarativeComponent *component; QDeclarativeRefCount *ref; - QObject *createInstance(QDeclarativeContext *, const QBitField &) const; + QObject *createInstance(QDeclarativeContextData *, const QBitField &) const; const QMetaObject *metaObject() const; }; QList<TypeReference> types; @@ -160,6 +161,8 @@ public: static QMetaMethod findSignalByName(const QMetaObject *, const QByteArray &name); + int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum + private: static void reset(QDeclarativeCompiledData *); diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index d6bb216..a280d7e 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -404,23 +404,9 @@ QDeclarativeContext *QDeclarativeComponent::creationContext() const { Q_D(const QDeclarativeComponent); if(d->creationContext) - return d->creationContext; - QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(this); - if (ddata) - return ddata->context; - else - return 0; -} + return d->creationContext->asQDeclarativeContext(); -/*! - \internal - Sets the QDeclarativeContext the component was created in. This is only - desirable for components created in QML script. -*/ -void QDeclarativeComponent::setCreationContext(QDeclarativeContext* c) -{ - Q_D(QDeclarativeComponent); - d->creationContext = c; + return qmlContext(this); } /*! @@ -512,7 +498,6 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q { } - /*! \internal A version of create which returns a scriptObject, for use in script @@ -526,7 +511,9 @@ QScriptValue QDeclarativeComponent::createObject() return QScriptValue(); } QObject* ret = create(ctxt); - return QDeclarativeEnginePrivate::qmlScriptObject(ret, d->engine); + QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine); + QDeclarativeDeclarativeData::get(ret, true)->setImplicitDestructible(); + return priv->objectClass->newQObject(ret, QMetaType::QObjectStar); } /*! @@ -541,19 +528,19 @@ QObject *QDeclarativeComponent::create(QDeclarativeContext *context) { Q_D(QDeclarativeComponent); - return d->create(context, QBitField()); + if (!context) + context = d->engine->rootContext(); + + QObject *rv = beginCreate(context); + completeCreate(); + return rv; } -QObject *QDeclarativeComponentPrivate::create(QDeclarativeContext *context, - const QBitField &bindings) +QObject *QDeclarativeComponentPrivate::create(QDeclarativeContextData *context, + const QBitField &bindings) { if (!context) - context = engine->rootContext(); - - if (context->engine() != engine) { - qWarning("QDeclarativeComponent::create(): Must create component in context from the same QDeclarativeEngine"); - return 0; - } + context = QDeclarativeContextData::get(engine->rootContext()); QObject *rv = beginCreate(context, bindings); completeCreate(); @@ -586,11 +573,17 @@ QObject *QDeclarativeComponentPrivate::create(QDeclarativeContext *context, QObject *QDeclarativeComponent::beginCreate(QDeclarativeContext *context) { Q_D(QDeclarativeComponent); - return d->beginCreate(context, QBitField()); + QObject *rv = d->beginCreate(context?QDeclarativeContextData::get(context):0, QBitField()); + if (rv) { + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(rv); + Q_ASSERT(ddata); + ddata->indestructible = true; + } + return rv; } QObject * -QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QBitField &bindings) +QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, const QBitField &bindings) { Q_Q(QDeclarativeComponent); if (!context) { @@ -598,7 +591,7 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QB return 0; } - if (context->engine() != engine) { + if (context->engine != engine) { qWarning("QDeclarativeComponent::beginCreate(): Must create component in context from the same QDeclarativeEngine"); return 0; } @@ -615,29 +608,24 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QB QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *contextPriv = - static_cast<QDeclarativeContextPrivate *>(QObjectPrivate::get(context)); - QDeclarativeContext *ctxt = new QDeclarativeContext(context, 0, true); - static_cast<QDeclarativeContextPrivate*>(ctxt->d_func())->url = cc->url; - static_cast<QDeclarativeContextPrivate*>(ctxt->d_func())->imports = cc->importCache; + QDeclarativeContextData *ctxt = new QDeclarativeContextData; + ctxt->isInternal = true; + ctxt->url = cc->url; + ctxt->imports = cc->importCache; cc->importCache->addref(); + ctxt->setParent(context); QObject *rv = begin(ctxt, ep, cc, start, count, &state, bindings); - if (rv) { - QDeclarative_setParent_noEvent(ctxt, rv); - } else { - delete ctxt; - } + if (rv && !context->isInternal && ep->isDebugging) + context->asQDeclarativeContextPrivate()->instances.append(rv); - if (rv && !contextPriv->isInternal && ep->isDebugging) - contextPriv->instances.append(rv); return rv; } -QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv, - QDeclarativeCompiledData *component, int start, int count, - ConstructionState *state, const QBitField &bindings) +QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, + QDeclarativeCompiledData *component, int start, int count, + ConstructionState *state, const QBitField &bindings) { bool isRoot = !enginePriv->inBeginCreate; enginePriv->inBeginCreate = true; @@ -667,8 +655,8 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContext *ctxt, QDeclar return rv; } -void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeContext *, QDeclarativeEnginePrivate *enginePriv, - QObject *object, ConstructionState *state) +void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeContextData *, QDeclarativeEnginePrivate *enginePriv, + QObject *object, ConstructionState *state) { bool isRoot = !enginePriv->inBeginCreate; enginePriv->inBeginCreate = true; diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h index aec0480..13a243e 100644 --- a/src/declarative/qml/qdeclarativecomponent.h +++ b/src/declarative/qml/qdeclarativecomponent.h @@ -104,7 +104,6 @@ public: void loadUrl(const QUrl &url); void setData(const QByteArray &, const QUrl &baseUrl); - void setCreationContext(QDeclarativeContext*); QDeclarativeContext *creationContext() const; static QDeclarativeComponentAttached *qmlAttachedProperties(QObject *); diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 3155813..649fce5 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -81,8 +81,8 @@ class QDeclarativeComponentPrivate : public QObjectPrivate public: QDeclarativeComponentPrivate() : typeData(0), progress(0.), start(-1), count(-1), cc(0), engine(0), creationContext(0) {} - QObject *create(QDeclarativeContext *context, const QBitField &); - QObject *beginCreate(QDeclarativeContext *, const QBitField &); + QObject *create(QDeclarativeContextData *, const QBitField &); + QObject *beginCreate(QDeclarativeContextData *, const QBitField &); void completeCreate(); QDeclarativeCompositeTypeData *typeData; @@ -108,15 +108,15 @@ public: }; ConstructionState state; - static QObject *begin(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv, + static QObject *begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, QDeclarativeCompiledData *component, int start, int count, ConstructionState *state, const QBitField &bindings = QBitField()); - static void beginDeferred(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv, + static void beginDeferred(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, QObject *object, ConstructionState *state); static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state); QDeclarativeEngine *engine; - QDeclarativeContext *creationContext; + QDeclarativeContextData *creationContext; void clear(); diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index b90a598..5014323 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -154,7 +154,7 @@ QDeclarativeCompositeTypeData::TypeReference::TypeReference() } QDeclarativeCompositeTypeManager::QDeclarativeCompositeTypeManager(QDeclarativeEngine *e) -: engine(e) +: engine(e), redirectCount(0) { } @@ -172,6 +172,10 @@ QDeclarativeCompositeTypeManager::~QDeclarativeCompositeTypeManager() QDeclarativeCompositeTypeData *QDeclarativeCompositeTypeManager::get(const QUrl &url) { + Redirects::Iterator redir = redirects.find(url); + if (redir != redirects.end()) + return get(*redir); + QDeclarativeCompositeTypeData *unit = components.value(url); if (!unit) { @@ -219,6 +223,8 @@ void QDeclarativeCompositeTypeManager::clearCache() } } +#define TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION 16 + void QDeclarativeCompositeTypeManager::replyFinished() { QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); @@ -226,6 +232,26 @@ void QDeclarativeCompositeTypeManager::replyFinished() QDeclarativeCompositeTypeData *unit = components.value(reply->url()); Q_ASSERT(unit); + redirectCount++; + if (redirectCount < TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION) { + QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = reply->url().resolved(redirect.toUrl()); + redirects.insert(reply->url(),url); + unit->imports.setBaseUrl(url); + components.remove(reply->url()); + components.insert(url, unit); + reply->deleteLater(); + reply = engine->networkAccessManager()->get(QNetworkRequest(url)); + QObject::connect(reply, SIGNAL(finished()), + this, SLOT(replyFinished())); + QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + return; + } + } + redirectCount = 0; + if (reply->error() != QNetworkReply::NoError) { QString errorDescription; // ### - Fill in error @@ -256,6 +282,24 @@ void QDeclarativeCompositeTypeManager::resourceReplyFinished() QDeclarativeCompositeTypeResource *resource = resources.value(reply->url()); Q_ASSERT(resource); + redirectCount++; + if (redirectCount < TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION) { + QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = reply->url().resolved(redirect.toUrl()); + redirects.insert(reply->url(),url); + resource->url = url.toString(); + resources.remove(reply->url()); + resources.insert(url, resource); + reply->deleteLater(); + reply = engine->networkAccessManager()->get(QNetworkRequest(url)); + QObject::connect(reply, SIGNAL(finished()), + this, SLOT(resourceReplyFinished())); + return; + } + } + redirectCount = 0; + if (reply->error() != QNetworkReply::NoError) { resource->status = QDeclarativeCompositeTypeResource::Error; @@ -271,12 +315,17 @@ void QDeclarativeCompositeTypeManager::resourceReplyFinished() reply->deleteLater(); } +// XXX this beyonds in QUrl::toLocalFile() +// WARNING, there is a copy of this function in qdeclarativeengine.cpp static QString toLocalFileOrQrc(const QUrl& url) { - QString r = url.toLocalFile(); - if (r.isEmpty() && url.scheme() == QLatin1String("qrc")) - r = QLatin1Char(':') + url.path(); - return r; + if (url.scheme() == QLatin1String("qrc")) { + if (url.authority().isEmpty()) + return QLatin1Char(':') + url.path(); + qWarning() << "Invalid url:" << url.toString() << "authority" << url.authority() << "not known."; + return QString(); + } + return url.toLocalFile(); } void QDeclarativeCompositeTypeManager::loadResource(QDeclarativeCompositeTypeResource *resource) @@ -461,18 +510,21 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData int waiting = 0; + + foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { - QString qmldir; + QString qmldircontentnetwork; if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) { QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString(); for (int ii = 0; ii < unit->resources.count(); ++ii) { if (unit->resources.at(ii)->url == importUrl) { - qmldir = QString::fromUtf8(unit->resources.at(ii)->data); + qmldircontentnetwork = QString::fromUtf8(unit->resources.at(ii)->data); break; } } } + int vmaj = -1; int vmin = -1; if (!imp.version.isEmpty()) { @@ -487,7 +539,7 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } if (!QDeclarativeEnginePrivate::get(engine)-> - addToImport(&unit->imports, qmldir, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) + addToImport(&unit->imports, qmldircontentnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) { QDeclarativeError error; error.setUrl(unit->imports.baseUrl()); @@ -500,6 +552,27 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } } + /* + For local urls, add an implicit import "." as first lookup. This will also trigger + the loading of the qmldir and the import of any native types from available plugins. + */ + { + + QString qmldircontentnetwork; + if (QDeclarativeCompositeTypeResource *resource + = resources.value(unit->imports.baseUrl().resolved(QUrl(QLatin1String("./qmldir"))))) + qmldircontentnetwork = QString::fromUtf8(resource->data); + + QDeclarativeEnginePrivate::get(engine)-> + addToImport(&unit->imports, + qmldircontentnetwork, + QLatin1String("."), + QString(), + -1, -1, + QDeclarativeScriptParser::Import::File); + } + + QList<QDeclarativeScriptParser::TypeReference*> types = unit->data.referencedTypes(); for (int ii = 0; ii < types.count(); ++ii) { @@ -546,6 +619,10 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData continue; } + Redirects::Iterator redir = redirects.find(url); + if (redir != redirects.end()) + url = *redir; + QDeclarativeCompositeTypeData *urlUnit = components.value(url); if (!urlUnit) { diff --git a/src/declarative/qml/qdeclarativecompositetypemanager_p.h b/src/declarative/qml/qdeclarativecompositetypemanager_p.h index 03d16b8..a572e0c 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager_p.h +++ b/src/declarative/qml/qdeclarativecompositetypemanager_p.h @@ -109,6 +109,9 @@ private: Components components; typedef QHash<QUrl, QDeclarativeCompositeTypeResource *> Resources; Resources resources; + typedef QHash<QUrl, QUrl> Redirects; + Redirects redirects; + int redirectCount; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index f70e143..782c0d7 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -58,83 +58,13 @@ QT_BEGIN_NAMESPACE QDeclarativeContextPrivate::QDeclarativeContextPrivate() -: parent(0), engine(0), isInternal(false), propertyNames(0), - notifyIndex(-1), highPriorityCount(0), imports(0), expressions(0), contextObjects(0), - idValues(0), idValueCount(0), optimizedBindings(0) +: data(0), notifyIndex(-1) { } -void QDeclarativeContextPrivate::addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject) -{ - Q_Q(QDeclarativeContext); - - if (!engine) - return; - - QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); - QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); - - QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); - - scriptContext->pushScope(enginePriv->contextClass->newContext(q, scopeObject)); - scriptContext->pushScope(enginePriv->globalClass->globalObject()); - - QScriptValue scope = scriptEngine->newObject(); - scriptContext->setActivationObject(scope); - scriptContext->pushScope(scope); - - for (int ii = 0; ii < script.codes.count(); ++ii) { - scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii)); - - if (scriptEngine->hasUncaughtException()) { - QDeclarativeError error; - QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); - qWarning().nospace() << qPrintable(error.toString()); - } - } - - scriptEngine->popContext(); - - scripts.append(scope); -} - -void QDeclarativeContextPrivate::destroyed(ContextGuard *guard) -{ - Q_Q(QDeclarativeContext); - - // process of being deleted (which is *probably* why obj has been destroyed - // anyway), as we're about to get deleted which will invalidate all the - // expressions that could depend on us - QObject *parent = q->parent(); - if (parent && QObjectPrivate::get(parent)->wasDeleted) - return; - - while(guard->bindings) { - QObject *o = guard->bindings->target; - int mi = guard->bindings->methodIndex; - guard->bindings->clear(); - if (o) o->qt_metacall(QMetaObject::InvokeMetaMethod, mi, 0); - } - - for (int ii = 0; ii < idValueCount; ++ii) { - if (&idValues[ii] == guard) { - QMetaObject::activate(q, ii + notifyIndex, 0); - return; - } - } -} - -void QDeclarativeContextPrivate::init() -{ - Q_Q(QDeclarativeContext); - - if (parent) - parent->d_func()->childContexts.insert(q); -} - /*! \class QDeclarativeContext - \since 4.7 + \since 4.7 \brief The QDeclarativeContext class defines a context within a QML engine. \mainclass @@ -177,7 +107,7 @@ void QDeclarativeContextPrivate::init() MyDataSet myDataSet; QDeclarativeEngine engine; QDeclarativeContext context(engine.rootContext()); - context.addDefaultObject(&myDataSet); + context.setContextObject(&myDataSet); QDeclarativeComponent component(&engine, "ListView { model=myModel }"); component.create(&context); @@ -221,8 +151,9 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeEngine *e, bool) : QObject(*(new QDeclarativeContextPrivate)) { Q_D(QDeclarativeContext); - d->engine = e; - d->init(); + d->data = new QDeclarativeContextData(this); + + d->data->engine = e; } /*! @@ -233,10 +164,9 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeEngine *engine, QObject *pa : QObject(*(new QDeclarativeContextPrivate), parent) { Q_D(QDeclarativeContext); - QDeclarativeContext *parentContext = engine?engine->rootContext():0; - d->parent = parentContext; - d->engine = parentContext->engine(); - d->init(); + d->data = new QDeclarativeContextData(this); + + d->data->setParent(engine?QDeclarativeContextData::get(engine->rootContext()):0); } /*! @@ -247,22 +177,19 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QOb : QObject(*(new QDeclarativeContextPrivate), parent) { Q_D(QDeclarativeContext); - d->parent = parentContext; - d->engine = parentContext->engine(); - d->init(); + d->data = new QDeclarativeContextData(this); + + d->data->setParent(parentContext?QDeclarativeContextData::get(parentContext):0); } /*! \internal */ -QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QObject *parent, bool) -: QObject(*(new QDeclarativeContextPrivate), parent) +QDeclarativeContext::QDeclarativeContext(QDeclarativeContextData *data) +: QObject(*(new QDeclarativeContextPrivate), 0) { Q_D(QDeclarativeContext); - d->parent = parentContext; - d->engine = parentContext->engine(); - d->isInternal = true; - d->init(); + d->data = data; } /*! @@ -275,78 +202,9 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QOb QDeclarativeContext::~QDeclarativeContext() { Q_D(QDeclarativeContext); - if (d->parent) - d->parent->d_func()->childContexts.remove(this); - - for (QSet<QDeclarativeContext *>::ConstIterator iter = d->childContexts.begin(); - iter != d->childContexts.end(); - ++iter) { - (*iter)->d_func()->invalidateEngines(); - (*iter)->d_func()->parent = 0; - } - - QDeclarativeAbstractExpression *expression = d->expressions; - while (expression) { - QDeclarativeAbstractExpression *nextExpression = expression->m_nextExpression; - - expression->m_context = 0; - expression->m_prevExpression = 0; - expression->m_nextExpression = 0; - - expression = nextExpression; - } - - while (d->contextObjects) { - QDeclarativeDeclarativeData *co = d->contextObjects; - d->contextObjects = d->contextObjects->nextContextObject; - - co->context = 0; - co->nextContextObject = 0; - co->prevContextObject = 0; - } - - if (d->propertyNames) - d->propertyNames->release(); - - if (d->imports) - d->imports->release(); - - if (d->optimizedBindings) - d->optimizedBindings->release(); - - delete [] d->idValues; -} - -void QDeclarativeContextPrivate::invalidateEngines() -{ - if (!engine) - return; - engine = 0; - for (QSet<QDeclarativeContext *>::ConstIterator iter = childContexts.begin(); - iter != childContexts.end(); - ++iter) { - (*iter)->d_func()->invalidateEngines(); - } -} - -/* -Refreshes all expressions that could possibly depend on this context. -Refreshing flushes all context-tree dependent caches in the expressions, and should occur every -time the context tree *structure* (not values) changes. -*/ -void QDeclarativeContextPrivate::refreshExpressions() -{ - for (QSet<QDeclarativeContext *>::ConstIterator iter = childContexts.begin(); - iter != childContexts.end(); - ++iter) { - (*iter)->d_func()->refreshExpressions(); - } - QDeclarativeAbstractExpression *expression = expressions; - while (expression) { - expression->refresh(); - expression = expression->m_nextExpression; - } + if (!d->data->isInternal) + d->data->destroy(); } /*! @@ -356,7 +214,7 @@ void QDeclarativeContextPrivate::refreshExpressions() QDeclarativeEngine *QDeclarativeContext::engine() const { Q_D(const QDeclarativeContext); - return d->engine; + return d->data->engine; } /*! @@ -366,17 +224,33 @@ QDeclarativeEngine *QDeclarativeContext::engine() const QDeclarativeContext *QDeclarativeContext::parentContext() const { Q_D(const QDeclarativeContext); - return d->parent; + return d->data->parent?d->data->parent->asQDeclarativeContext():0; +} + +/*! + Return the context object, or 0 if there is no context object. +*/ +QObject *QDeclarativeContext::contextObject() const +{ + Q_D(const QDeclarativeContext); + return d->data->contextObject; } /*! - Add \a defaultObject to this context. The object will be added after - any existing default objects. + Set the context \a object. */ -void QDeclarativeContext::addDefaultObject(QObject *defaultObject) +void QDeclarativeContext::setContextObject(QObject *object) { Q_D(QDeclarativeContext); - d->defaultObjects.prepend(defaultObject); + + QDeclarativeContextData *data = d->data; + + if (data->isInternal) { + qWarning("QDeclarativeContext: Cannot set context object for internal context."); + return; + } + + data->contextObject = object; } /*! @@ -388,50 +262,36 @@ void QDeclarativeContext::setContextProperty(const QString &name, const QVariant if (d->notifyIndex == -1) d->notifyIndex = this->metaObject()->methodCount(); - if (d->engine) { + QDeclarativeContextData *data = d->data; + + if (data->isInternal) { + qWarning("QDeclarativeContext: Cannot set property on internal context."); + return; + } + + if (data->engine) { bool ok; - QObject *o = QDeclarativeEnginePrivate::get(d->engine)->toQObject(value, &ok); + QObject *o = QDeclarativeEnginePrivate::get(data->engine)->toQObject(value, &ok); if (ok) { setContextProperty(name, o); return; } } - if (!d->propertyNames) d->propertyNames = new QDeclarativeIntegerCache(d->engine); + if (!data->propertyNames) data->propertyNames = new QDeclarativeIntegerCache(data->engine); - int idx = d->propertyNames->value(name); + int idx = data->propertyNames->value(name); if (idx == -1) { - d->propertyNames->add(name, d->idValueCount + d->propertyValues.count()); + data->propertyNames->add(name, data->idValueCount + d->propertyValues.count()); d->propertyValues.append(value); - d->refreshExpressions(); + data->refreshExpressions(); } else { d->propertyValues[idx] = value; QMetaObject::activate(this, idx + d->notifyIndex, 0); } } -void QDeclarativeContextPrivate::setIdProperty(int idx, QObject *obj) -{ - if (notifyIndex == -1) { - Q_Q(QDeclarativeContext); - notifyIndex = q->metaObject()->methodCount(); - } - - idValues[idx].priv = this; - idValues[idx] = obj; -} - -void QDeclarativeContextPrivate::setIdPropertyData(QDeclarativeIntegerCache *data) -{ - Q_ASSERT(!propertyNames); - propertyNames = data; - propertyNames->addref(); - - idValueCount = data->count(); - idValues = new ContextGuard[idValueCount]; -} - /*! Set the \a value of the \a name property on this context. @@ -443,14 +303,21 @@ void QDeclarativeContext::setContextProperty(const QString &name, QObject *value if (d->notifyIndex == -1) d->notifyIndex = this->metaObject()->methodCount(); - if (!d->propertyNames) d->propertyNames = new QDeclarativeIntegerCache(d->engine); - int idx = d->propertyNames->value(name); + QDeclarativeContextData *data = d->data; + + if (data->isInternal) { + qWarning("QDeclarativeContext: Cannot set property on internal context."); + return; + } + + if (!data->propertyNames) data->propertyNames = new QDeclarativeIntegerCache(data->engine); + int idx = data->propertyNames->value(name); if (idx == -1) { - d->propertyNames->add(name, d->idValueCount + d->propertyValues.count()); + data->propertyNames->add(name, data->idValueCount + d->propertyValues.count()); d->propertyValues.append(QVariant::fromValue(value)); - d->refreshExpressions(); + data->refreshExpressions(); } else { d->propertyValues[idx] = QVariant::fromValue(value); QMetaObject::activate(this, idx + d->notifyIndex, 0); @@ -466,26 +333,27 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const Q_D(const QDeclarativeContext); QVariant value; int idx = -1; - if (d->propertyNames) - idx = d->propertyNames->value(name); + + QDeclarativeContextData *data = d->data; + + if (data->propertyNames) + idx = data->propertyNames->value(name); if (idx == -1) { QByteArray utf8Name = name.toUtf8(); - for (int ii = d->defaultObjects.count() - 1; ii >= 0; --ii) { - QObject *obj = d->defaultObjects.at(ii); + if (data->contextObject) { + QObject *obj = data->contextObject; QDeclarativePropertyCache::Data local; - QDeclarativePropertyCache::Data *property = QDeclarativePropertyCache::property(d->engine, obj, name, local); + QDeclarativePropertyCache::Data *property = + QDeclarativePropertyCache::property(data->engine, obj, name, local); - if (property) { - value = obj->metaObject()->property(property->coreIndex).read(obj); - break; - } + if (property) value = obj->metaObject()->property(property->coreIndex).read(obj); } if (!value.isValid() && parentContext()) value = parentContext()->contextProperty(name); } else { if (idx >= d->propertyValues.count()) - value = QVariant::fromValue(d->idValues[idx - d->propertyValues.count()].data()); + value = QVariant::fromValue(data->idValues[idx - d->propertyValues.count()].data()); else value = d->propertyValues[idx]; } @@ -502,20 +370,26 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const QUrl QDeclarativeContext::resolvedUrl(const QUrl &src) { Q_D(QDeclarativeContext); - QDeclarativeContext *ctxt = this; + return d->data->resolvedUrl(src); +} + +QUrl QDeclarativeContextData::resolvedUrl(const QUrl &src) +{ + QDeclarativeContextData *ctxt = this; + if (src.isRelative() && !src.isEmpty()) { if (ctxt) { while(ctxt) { - if(ctxt->d_func()->url.isValid()) + if(ctxt->url.isValid()) break; else - ctxt = ctxt->parentContext(); + ctxt = ctxt->parent; } if (ctxt) - return ctxt->d_func()->url.resolved(src); - else if (d->engine) - return d->engine->baseUrl().resolved(src); + return ctxt->url.resolved(src); + else if (engine) + return engine->baseUrl().resolved(src); } return QUrl(); } else { @@ -523,6 +397,7 @@ QUrl QDeclarativeContext::resolvedUrl(const QUrl &src) } } + /*! Explicitly sets the url resolvedUrl() will use for relative references to \a baseUrl. @@ -533,7 +408,9 @@ QUrl QDeclarativeContext::resolvedUrl(const QUrl &src) */ void QDeclarativeContext::setBaseUrl(const QUrl &baseUrl) { - d_func()->url = baseUrl; + Q_D(QDeclarativeContext); + + d->data->url = baseUrl; } /*! @@ -542,12 +419,13 @@ void QDeclarativeContext::setBaseUrl(const QUrl &baseUrl) */ QUrl QDeclarativeContext::baseUrl() const { - const QDeclarativeContext* p = this; - while (p && p->d_func()->url.isEmpty()) { - p = p->parentContext(); - } - if (p) - return p->d_func()->url; + Q_D(const QDeclarativeContext); + const QDeclarativeContextData* data = d->data; + while (data && data->url.isEmpty()) + data = data->parent; + + if (data) + return data->url; else return QUrl(); } @@ -578,4 +456,215 @@ QObject *QDeclarativeContextPrivate::context_at(QDeclarativeListProperty<QObject } } + +QDeclarativeContextData::QDeclarativeContextData() +: parent(0), engine(0), isInternal(false), publicContext(0), propertyNames(0), contextObject(0), + imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0), + contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), linkedContext(0) +{ +} + +QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt) +: parent(0), engine(0), isInternal(false), publicContext(ctxt), propertyNames(0), contextObject(0), + imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0), + contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), linkedContext(0) +{ +} + +void QDeclarativeContextData::destroy() +{ + if (linkedContext) + linkedContext->destroy(); + + if (prevChild) { + *prevChild = nextChild; + if (nextChild) nextChild->prevChild = prevChild; + nextChild = 0; + prevChild = 0; + } + + QDeclarativeContextData *child = childContexts; + while (child) { + QDeclarativeContextData *next = child->nextChild; + + child->invalidateEngines(); + child->parent = 0; + child->nextChild = 0; + child->prevChild = 0; + + child = next; + } + childContexts = 0; + + QDeclarativeAbstractExpression *expression = expressions; + while (expression) { + QDeclarativeAbstractExpression *nextExpression = expression->m_nextExpression; + + expression->m_context = 0; + expression->m_prevExpression = 0; + expression->m_nextExpression = 0; + + expression = nextExpression; + } + expressions = 0; + + while (contextObjects) { + QDeclarativeDeclarativeData *co = contextObjects; + contextObjects = contextObjects->nextContextObject; + + co->context = 0; + co->outerContext = 0; + co->nextContextObject = 0; + co->prevContextObject = 0; + } + + QDeclarativeGuardedContextData *contextGuard = contextGuards; + while (contextGuard) { + QDeclarativeGuardedContextData *next = contextGuard->m_next; + contextGuard->m_next = 0; + contextGuard->m_prev = 0; + contextGuard->m_contextData = 0; + contextGuard = next; + } + contextGuards = 0; + + if (propertyNames) + propertyNames->release(); + + if (imports) + imports->release(); + + if (optimizedBindings) + optimizedBindings->release(); + + delete [] idValues; + + if (isInternal) + delete publicContext; + + delete this; +} + +void QDeclarativeContextData::setParent(QDeclarativeContextData *p) +{ + if (p) { + parent = p; + engine = p->engine; + nextChild = p->childContexts; + if (nextChild) nextChild->prevChild = &nextChild; + prevChild = &p->childContexts; + p->childContexts = this; + } +} + +void QDeclarativeContextData::invalidateEngines() +{ + if (!engine) + return; + engine = 0; + + QDeclarativeContextData *child = childContexts; + while (child) { + child->invalidateEngines(); + child = child->nextChild; + } +} + +/* +Refreshes all expressions that could possibly depend on this context. Refreshing flushes all +context-tree dependent caches in the expressions, and should occur every time the context tree + *structure* (not values) changes. +*/ +void QDeclarativeContextData::refreshExpressions() +{ + QDeclarativeContextData *child = childContexts; + while (child) { + child->refreshExpressions(); + child = child->nextChild; + } + + QDeclarativeAbstractExpression *expression = expressions; + while (expression) { + expression->refresh(); + expression = expression->m_nextExpression; + } +} + +void QDeclarativeContextData::addObject(QObject *o) +{ + QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(o, true); + + Q_ASSERT(data->context == 0); + + data->context = this; + data->outerContext = this; + + data->nextContextObject = contextObjects; + if (data->nextContextObject) + data->nextContextObject->prevContextObject = &data->nextContextObject; + data->prevContextObject = &contextObjects; + contextObjects = data; +} + +void QDeclarativeContextData::addScript(const QDeclarativeParser::Object::ScriptBlock &script, + QObject *scopeObject) +{ + if (!engine) + return; + + QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); + QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); + + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->contextClass->newContext(this, scopeObject)); + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + for (int ii = 0; ii < script.codes.count(); ++ii) { + scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii)); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + } + + scriptEngine->popContext(); + + scripts.append(scope); +} + +void QDeclarativeContextData::setIdProperty(int idx, QObject *obj) +{ + idValues[idx] = obj; + idValues[idx].context = this; +} + +void QDeclarativeContextData::setIdPropertyData(QDeclarativeIntegerCache *data) +{ + Q_ASSERT(!propertyNames); + propertyNames = data; + propertyNames->addref(); + + idValueCount = data->count(); + idValues = new ContextGuard[idValueCount]; +} + +QDeclarativeContext *QDeclarativeContextData::asQDeclarativeContext() +{ + if (!publicContext) + publicContext = new QDeclarativeContext(this); + return publicContext; +} + +QDeclarativeContextPrivate *QDeclarativeContextData::asQDeclarativeContextPrivate() +{ + return QDeclarativeContextPrivate::get(asQDeclarativeContext()); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h index 0fb9bee..a349628 100644 --- a/src/declarative/qml/qdeclarativecontext.h +++ b/src/declarative/qml/qdeclarativecontext.h @@ -58,6 +58,7 @@ class QDeclarativeEngine; class QDeclarativeRefCount; class QDeclarativeContextPrivate; class QDeclarativeCompositeTypeData; +class QDeclarativeContextData; class Q_DECLARATIVE_EXPORT QDeclarativeContext : public QObject { @@ -72,11 +73,12 @@ public: QDeclarativeEngine *engine() const; QDeclarativeContext *parentContext() const; - void addDefaultObject(QObject *); - void setContextProperty(const QString &, QObject *); - void setContextProperty(const QString &, const QVariant &); + QObject *contextObject() const; + void setContextObject(QObject *); QVariant contextProperty(const QString &) const; + void setContextProperty(const QString &, QObject *); + void setContextProperty(const QString &, const QVariant &); QUrl resolvedUrl(const QUrl &); @@ -95,7 +97,8 @@ private: friend class QDeclarativeComponentPrivate; friend class QDeclarativeScriptPrivate; friend class QDeclarativeBoundSignalProxy; - QDeclarativeContext(QDeclarativeContext *parent, QObject *objParent, bool); + friend class QDeclarativeContextData; + QDeclarativeContext(QDeclarativeContextData *); QDeclarativeContext(QDeclarativeEngine *, bool); }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index 8297280..d74aa33 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -56,9 +56,11 @@ #include "qdeclarativecontext.h" #include "qdeclarativedeclarativedata_p.h" -#include "qdeclarativeengine_p.h" #include "qdeclarativeintegercache_p.h" #include "qdeclarativetypenamecache_p.h" +#include "qdeclarativenotifier_p.h" +#include "qdeclarativelist.h" +#include "qdeclarativeparser_p.h" #include <QtCore/qhash.h> #include <QtScript/qscriptvalue.h> @@ -77,6 +79,7 @@ class QDeclarativeExpressionPrivate; class QDeclarativeAbstractExpression; class QDeclarativeBinding_Id; class QDeclarativeCompiledBindings; +class QDeclarativeContextData; class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate { @@ -84,110 +87,182 @@ class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate public: QDeclarativeContextPrivate(); - QDeclarativeContext *parent; + QDeclarativeContextData *data; + + QList<QVariant> propertyValues; + int notifyIndex; + + static QDeclarativeContextPrivate *get(QDeclarativeContext *context) { + return static_cast<QDeclarativeContextPrivate *>(QObjectPrivate::get(context)); + } + static QDeclarativeContext *get(QDeclarativeContextPrivate *context) { + return static_cast<QDeclarativeContext *>(context->q_func()); + } + + // Only used for debugging + QList<QPointer<QObject> > instances; + + static int context_count(QDeclarativeListProperty<QObject> *); + static QObject *context_at(QDeclarativeListProperty<QObject> *, int); +}; + +class QDeclarativeGuardedContextData; +class QDeclarativeContextData +{ +public: + QDeclarativeContextData(); + QDeclarativeContextData(QDeclarativeContext *); + void destroy(); + + // My parent context and engine + QDeclarativeContextData *parent; QDeclarativeEngine *engine; + void setParent(QDeclarativeContextData *); + void invalidateEngines(); + void refreshExpressions(); + + void addObject(QObject *); + + QUrl resolvedUrl(const QUrl &); + + // My containing QDeclarativeContext. If isInternal is true this owns publicContext. + // If internal is false publicContext owns this. + QDeclarativeContext *asQDeclarativeContext(); + QDeclarativeContextPrivate *asQDeclarativeContextPrivate(); bool isInternal; + QDeclarativeContext *publicContext; + // Property name cache QDeclarativeIntegerCache *propertyNames; - QList<QVariant> propertyValues; - int notifyIndex; - QObjectList defaultObjects; - int highPriorityCount; + // Context object + QObject *contextObject; + // Any script blocks that exist on this context QList<QScriptValue> scripts; - void addScript(const QDeclarativeParser::Object::ScriptBlock &, QObject *); + void addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject); + // Context base url QUrl url; + // List of imports that apply to this context QDeclarativeTypeNameCache *imports; - void init(); + // My children + QDeclarativeContextData *childContexts; - void invalidateEngines(); - void refreshExpressions(); - QSet<QDeclarativeContext *> childContexts; + // My peers in parent's childContexts list + QDeclarativeContextData *nextChild; + QDeclarativeContextData **prevChild; + // Expressions that use this context QDeclarativeAbstractExpression *expressions; + // Doubly-linked list of objects that are owned by this context QDeclarativeDeclarativeData *contextObjects; - struct IdNotifier - { - inline IdNotifier(); - inline ~IdNotifier(); - - inline void clear(); - - IdNotifier *next; - IdNotifier**prev; - QObject *target; - int methodIndex; - }; + // Doubly-linked list of context guards (XXX merge with contextObjects) + QDeclarativeGuardedContextData *contextGuards; + // id guards struct ContextGuard : public QDeclarativeGuard<QObject> { - inline ContextGuard(); - inline ContextGuard &operator=(QObject *obj); - inline virtual void objectDestroyed(QObject *); - - QDeclarativeContextPrivate *priv; - IdNotifier *bindings; + ContextGuard() : context(0) {} + inline ContextGuard &operator=(QObject *obj) + { QDeclarativeGuard<QObject>::operator=(obj); return *this; } + virtual void objectDestroyed(QObject *) { + if (!QObjectPrivate::get(context->contextObject)->wasDeleted) bindings.notify(); + } + QDeclarativeContextData *context; + QDeclarativeNotifier bindings; }; ContextGuard *idValues; int idValueCount; void setIdProperty(int, QObject *); void setIdPropertyData(QDeclarativeIntegerCache *); - void destroyed(ContextGuard *); - static QDeclarativeContextPrivate *get(QDeclarativeContext *context) { - return static_cast<QDeclarativeContextPrivate *>(QObjectPrivate::get(context)); - } - static QDeclarativeContext *get(QDeclarativeContextPrivate *context) { - return static_cast<QDeclarativeContext *>(context->q_func()); + // Optimized binding pointer + QDeclarativeCompiledBindings *optimizedBindings; + + // Linked contexts. this owns linkedContext. + QDeclarativeContextData *linkedContext; + + static QDeclarativeContextData *get(QDeclarativeContext *context) { + return QDeclarativeContextPrivate::get(context)->data; } - QDeclarativeCompiledBindings *optimizedBindings; +private: + ~QDeclarativeContextData() {} +}; - // Only used for debugging - QList<QPointer<QObject> > instances; +class QDeclarativeGuardedContextData +{ +public: + inline QDeclarativeGuardedContextData(); + inline QDeclarativeGuardedContextData(QDeclarativeContextData *); + inline ~QDeclarativeGuardedContextData(); - static int context_count(QDeclarativeListProperty<QObject> *); - static QObject *context_at(QDeclarativeListProperty<QObject> *, int); + inline void setContextData(QDeclarativeContextData *); + + inline QDeclarativeContextData *contextData(); + + inline operator QDeclarativeContextData*() const { return m_contextData; } + inline QDeclarativeContextData* operator->() const { return m_contextData; } + +private: + friend class QDeclarativeContextData; + + inline void clear(); + + QDeclarativeContextData *m_contextData; + QDeclarativeGuardedContextData *m_next; + QDeclarativeGuardedContextData **m_prev; }; -QDeclarativeContextPrivate::IdNotifier::IdNotifier() -: next(0), prev(0), target(0), methodIndex(-1) +QDeclarativeGuardedContextData::QDeclarativeGuardedContextData() +: m_contextData(0), m_next(0), m_prev(0) { } -QDeclarativeContextPrivate::IdNotifier::~IdNotifier() +QDeclarativeGuardedContextData::QDeclarativeGuardedContextData(QDeclarativeContextData *data) +: m_contextData(0), m_next(0), m_prev(0) { - clear(); + setContextData(data); } -void QDeclarativeContextPrivate::IdNotifier::clear() +QDeclarativeGuardedContextData::~QDeclarativeGuardedContextData() { - if (next) next->prev = prev; - if (prev) *prev = next; - next = 0; prev = 0; target = 0; - methodIndex = -1; + clear(); } -QDeclarativeContextPrivate::ContextGuard::ContextGuard() -: priv(0), bindings(0) +void QDeclarativeGuardedContextData::setContextData(QDeclarativeContextData *contextData) { + clear(); + + if (contextData) { + m_contextData = contextData; + m_next = contextData->contextGuards; + if (m_next) m_next->m_prev = &m_next; + m_prev = &contextData->contextGuards; + contextData->contextGuards = this; + } } -QDeclarativeContextPrivate::ContextGuard &QDeclarativeContextPrivate::ContextGuard::operator=(QObject *obj) +QDeclarativeContextData *QDeclarativeGuardedContextData::contextData() { - (QDeclarativeGuard<QObject>&)*this = obj; return *this; + return m_contextData; } -void QDeclarativeContextPrivate::ContextGuard::objectDestroyed(QObject *) -{ - priv->destroyed(this); +void QDeclarativeGuardedContextData::clear() +{ + if (m_prev) { + *m_prev = m_next; + if (m_next) m_next->m_prev = m_prev; + m_contextData = 0; + m_next = 0; + m_prev = 0; + } } QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp index 5fcf4e2..847d632 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp +++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp @@ -51,17 +51,17 @@ QT_BEGIN_NAMESPACE struct ContextData : public QScriptDeclarativeClass::Object { ContextData() : overrideObject(0), isSharedContext(true) {} - ContextData(QDeclarativeContext *c, QObject *o) : context(c), scopeObject(o), overrideObject(0), isSharedContext(false) {} - QDeclarativeGuard<QDeclarativeContext> context; + ContextData(QDeclarativeContextData *c, QObject *o) : context(c), scopeObject(o), overrideObject(0), isSharedContext(false) {} + QDeclarativeGuardedContextData context; QDeclarativeGuard<QObject> scopeObject; QObject *overrideObject; bool isSharedContext; - QDeclarativeContext *getContext(QDeclarativeEngine *engine) { + QDeclarativeContextData *getContext(QDeclarativeEngine *engine) { if (isSharedContext) { return QDeclarativeEnginePrivate::get(engine)->sharedContext; } else { - return context.data(); + return context.contextData(); } } @@ -80,7 +80,7 @@ struct ContextData : public QScriptDeclarativeClass::Object { */ QDeclarativeContextScriptClass::QDeclarativeContextScriptClass(QDeclarativeEngine *bindEngine) : QDeclarativeScriptClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine), - lastScopeObject(0), lastContext(0), lastData(0), lastPropertyIndex(-1), lastDefaultObject(-1) + lastScopeObject(0), lastContext(0), lastData(0), lastPropertyIndex(-1) { } @@ -88,7 +88,7 @@ QDeclarativeContextScriptClass::~QDeclarativeContextScriptClass() { } -QScriptValue QDeclarativeContextScriptClass::newContext(QDeclarativeContext *context, QObject *scopeObject) +QScriptValue QDeclarativeContextScriptClass::newContext(QDeclarativeContextData *context, QObject *scopeObject) { QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -102,7 +102,7 @@ QScriptValue QDeclarativeContextScriptClass::newSharedContext() return newObject(scriptEngine, this, new ContextData()); } -QDeclarativeContext *QDeclarativeContextScriptClass::contextFromValue(const QScriptValue &v) +QDeclarativeContextData *QDeclarativeContextScriptClass::contextFromValue(const QScriptValue &v) { if (scriptClass(v) != this) return 0; @@ -132,9 +132,8 @@ QDeclarativeContextScriptClass::queryProperty(Object *object, const Identifier & lastContext = 0; lastData = 0; lastPropertyIndex = -1; - lastDefaultObject = -1; - QDeclarativeContext *bindContext = ((ContextData *)object)->getContext(engine); + QDeclarativeContextData *bindContext = ((ContextData *)object)->getContext(engine); QObject *scopeObject = ((ContextData *)object)->getScope(engine); if (!bindContext) return 0; @@ -160,29 +159,28 @@ QDeclarativeContextScriptClass::queryProperty(Object *object, const Identifier & scopeObject = 0; // Only applies to the first context includeTypes = false; // Only applies to the first context if (rv) return rv; - bindContext = bindContext->parentContext(); + bindContext = bindContext->parent; } return 0; } QScriptClass::QueryFlags -QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, QObject *scopeObject, - const Identifier &name, - QScriptClass::QueryFlags flags, - bool includeTypes) +QDeclarativeContextScriptClass::queryProperty(QDeclarativeContextData *bindContext, QObject *scopeObject, + const Identifier &name, + QScriptClass::QueryFlags flags, + bool includeTypes) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext); - lastPropertyIndex = cp->propertyNames?cp->propertyNames->value(name):-1; + lastPropertyIndex = bindContext->propertyNames?bindContext->propertyNames->value(name):-1; if (lastPropertyIndex != -1) { lastContext = bindContext; return QScriptClass::HandlesReadAccess; } - if (includeTypes && cp->imports) { - QDeclarativeTypeNameCache::Data *data = cp->imports->data(name); + if (includeTypes && bindContext->imports) { + QDeclarativeTypeNameCache::Data *data = bindContext->imports->data(name); if (data) { lastData = data; @@ -191,8 +189,8 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, } } - for (int ii = 0; ii < cp->scripts.count(); ++ii) { - lastFunction = QScriptDeclarativeClass::function(cp->scripts.at(ii), name); + for (int ii = 0; ii < bindContext->scripts.count(); ++ii) { + lastFunction = QScriptDeclarativeClass::function(bindContext->scripts.at(ii), name); if (lastFunction.isValid()) { lastContext = bindContext; return QScriptClass::HandlesReadAccess; @@ -210,13 +208,13 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, } } - for (int ii = cp->defaultObjects.count() - 1; ii >= 0; --ii) { + if (bindContext->contextObject) { QScriptClass::QueryFlags rv = - ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext, + ep->objectClass->queryProperty(bindContext->contextObject, name, flags, bindContext, QDeclarativeObjectScriptClass::ImplicitObject | QDeclarativeObjectScriptClass::SkipAttachedProperties); if (rv) { - lastDefaultObject = ii; + lastScopeObject = bindContext->contextObject; lastContext = bindContext; return rv; } @@ -230,11 +228,10 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) { Q_UNUSED(object); - QDeclarativeContext *bindContext = lastContext; + QDeclarativeContextData *bindContext = lastContext; Q_ASSERT(bindContext); QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); if (lastScopeObject) { @@ -244,33 +241,33 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) } else if (lastData) { if (lastData->type) - return Value(scriptEngine, ep->typeNameClass->newObject(cp->defaultObjects.at(0), lastData->type)); + return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->type)); else - return Value(scriptEngine, ep->typeNameClass->newObject(cp->defaultObjects.at(0), lastData->typeNamespace)); + return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->typeNamespace)); } else if (lastPropertyIndex != -1) { QScriptValue rv; - if (lastPropertyIndex < cp->idValueCount) { - rv = ep->objectClass->newQObject(cp->idValues[lastPropertyIndex].data()); + if (lastPropertyIndex < bindContext->idValueCount) { + rv = ep->objectClass->newQObject(bindContext->idValues[lastPropertyIndex].data()); + + if (ep->captureProperties) + ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(&bindContext->idValues[lastPropertyIndex].bindings); } else { + QDeclarativeContextPrivate *cp = bindContext->asQDeclarativeContextPrivate(); const QVariant &value = cp->propertyValues.at(lastPropertyIndex); if (value.userType() == qMetaTypeId<QList<QObject*> >()) { - rv = ep->listClass->newList(QDeclarativeListProperty<QObject>(bindContext, (void*)lastPropertyIndex, 0, QDeclarativeContextPrivate::context_count, QDeclarativeContextPrivate::context_at), qMetaTypeId<QDeclarativeListProperty<QObject> >()); + rv = ep->listClass->newList(QDeclarativeListProperty<QObject>(bindContext->asQDeclarativeContext(), (void*)lastPropertyIndex, 0, QDeclarativeContextPrivate::context_count, QDeclarativeContextPrivate::context_at), qMetaTypeId<QDeclarativeListProperty<QObject> >()); } else { rv = ep->scriptValueFromVariant(value); } - } - if (ep->captureProperties) - ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext, -1, lastPropertyIndex + cp->notifyIndex); + if (ep->captureProperties) + ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext->asQDeclarativeContext(), -1, lastPropertyIndex + cp->notifyIndex); + } return Value(scriptEngine, rv); - } else if(lastDefaultObject != -1) { - - // Default object property - return ep->objectClass->property(cp->defaultObjects.at(lastDefaultObject), name); } else { @@ -283,20 +280,14 @@ void QDeclarativeContextScriptClass::setProperty(Object *object, const Identifie const QScriptValue &value) { Q_UNUSED(object); - Q_ASSERT(lastScopeObject || lastDefaultObject != -1); + Q_ASSERT(lastScopeObject); - QDeclarativeContext *bindContext = lastContext; + QDeclarativeContextData *bindContext = lastContext; Q_ASSERT(bindContext); QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext); - if (lastScopeObject) { - ep->objectClass->setProperty(lastScopeObject, name, value, bindContext); - } else { - ep->objectClass->setProperty(cp->defaultObjects.at(lastDefaultObject), name, value, - bindContext); - } + ep->objectClass->setProperty(lastScopeObject, name, value, bindContext); } QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontextscriptclass_p.h b/src/declarative/qml/qdeclarativecontextscriptclass_p.h index 4b0dca0..93e4b20 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass_p.h +++ b/src/declarative/qml/qdeclarativecontextscriptclass_p.h @@ -60,16 +60,17 @@ QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QDeclarativeContext; +class QDeclarativeContextData; class QDeclarativeContextScriptClass : public QDeclarativeScriptClass { public: QDeclarativeContextScriptClass(QDeclarativeEngine *); ~QDeclarativeContextScriptClass(); - QScriptValue newContext(QDeclarativeContext *, QObject * = 0); + QScriptValue newContext(QDeclarativeContextData *, QObject * = 0); QScriptValue newSharedContext(); - QDeclarativeContext *contextFromValue(const QScriptValue &); + QDeclarativeContextData *contextFromValue(const QScriptValue &); QObject *setOverrideObject(QScriptValue &, QObject *); protected: @@ -79,7 +80,7 @@ protected: virtual void setProperty(Object *, const Identifier &name, const QScriptValue &); private: - QScriptClass::QueryFlags queryProperty(QDeclarativeContext *, QObject *scopeObject, + QScriptClass::QueryFlags queryProperty(QDeclarativeContextData *, QObject *scopeObject, const Identifier &, QScriptClass::QueryFlags flags, bool includeTypes); @@ -87,10 +88,9 @@ private: QDeclarativeEngine *engine; QObject *lastScopeObject; - QDeclarativeContext *lastContext; + QDeclarativeContextData *lastContext; QDeclarativeTypeNameCache::Data *lastData; int lastPropertyIndex; - int lastDefaultObject; QScriptValue lastFunction; uint m_id; diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp index 67f0963..a3a511c 100644 --- a/src/declarative/qml/qdeclarativecustomparser.cpp +++ b/src/declarative/qml/qdeclarativecustomparser.cpp @@ -43,6 +43,7 @@ #include "qdeclarativecustomparser_p_p.h" #include "qdeclarativeparser_p.h" +#include "qdeclarativecompiler_p.h" #include <QtCore/qdebug.h> @@ -260,4 +261,15 @@ void QDeclarativeCustomParser::error(const QDeclarativeCustomParserNode& node, c exceptions << error; } +/*! + If \a script is a simply enum expression (eg. Text.AlignLeft), + returns the integer equivalent (eg. 1). + + Otherwise, returns -1. +*/ +int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const +{ + return compiler->evaluateEnum(script); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h index 99587a8..f9bf513 100644 --- a/src/declarative/qml/qdeclarativecustomparser_p.h +++ b/src/declarative/qml/qdeclarativecustomparser_p.h @@ -66,6 +66,8 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) +class QDeclarativeCompiler; + class QDeclarativeCustomParserPropertyPrivate; class Q_DECLARATIVE_EXPORT QDeclarativeCustomParserProperty { @@ -111,6 +113,7 @@ private: class Q_DECLARATIVE_EXPORT QDeclarativeCustomParser { public: + QDeclarativeCustomParser() : compiler(0) {} virtual ~QDeclarativeCustomParser() {} void clearErrors(); @@ -124,13 +127,18 @@ protected: void error(const QDeclarativeCustomParserProperty&, const QString& description); void error(const QDeclarativeCustomParserNode&, const QString& description); + int evaluateEnum(const QByteArray&) const; + private: QList<QDeclarativeError> exceptions; + QDeclarativeCompiler *compiler; + friend class QDeclarativeCompiler; }; +#if 0 #define QML_REGISTER_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, TYPE, CUSTOMTYPE) \ qmlRegisterCustomType<TYPE>(#URI, VERSION_MAJ, VERSION_MIN, #NAME, #TYPE, new CUSTOMTYPE) - +#endif QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativedeclarativedata_p.h b/src/declarative/qml/qdeclarativedeclarativedata_p.h index ae40130..d1d063a 100644 --- a/src/declarative/qml/qdeclarativedeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedeclarativedata_p.h @@ -63,18 +63,32 @@ class QDeclarativeCompiledData; class QDeclarativeAbstractBinding; class QDeclarativeContext; class QDeclarativePropertyCache; +class QDeclarativeContextData; class Q_AUTOTEST_EXPORT QDeclarativeDeclarativeData : public QDeclarativeData { public: - QDeclarativeDeclarativeData(QDeclarativeContext *ctxt = 0) - : context(ctxt), bindings(0), nextContextObject(0), prevContextObject(0), - bindingBitsSize(0), bindingBits(0), outerContext(0), lineNumber(0), - columnNumber(0), deferredComponent(0), deferredIdx(0), attachedProperties(0), - propertyCache(0), guards(0) {} + QDeclarativeDeclarativeData() + : ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), + context(0), outerContext(0), bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), + bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0), + attachedProperties(0), propertyCache(0), guards(0) {} virtual void destroyed(QObject *); + virtual void parentChanged(QObject *, QObject *); + + void setImplicitDestructible() { + if (!explicitIndestructibleSet) indestructible = false; + } + + quint32 ownMemory:1; + quint32 ownContext:1; + quint32 indestructible:1; + quint32 explicitIndestructibleSet:1; + quint32 dummy:28; + + QDeclarativeContextData *context; + QDeclarativeContextData *outerContext; - QDeclarativeContext *context; QDeclarativeAbstractBinding *bindings; // Linked list for QDeclarativeContext::contextObjects @@ -87,7 +101,6 @@ public: void clearBindingBit(int); void setBindingBit(QObject *obj, int); - QDeclarativeContext *outerContext; // Can't this be found from context? ushort lineNumber; ushort columnNumber; diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp index e730b92..b6d2115 100644 --- a/src/declarative/qml/qdeclarativedirparser.cpp +++ b/src/declarative/qml/qdeclarativedirparser.cpp @@ -151,13 +151,16 @@ bool QDeclarativeDirParser::parse() _plugins.append(entry); + } else if (sectionCount == 2) { + // No version specified (should only be used for relative qmldir files) + const Component entry(sections[0], sections[1], -1, -1); + _components.append(entry); } else if (sectionCount == 3) { const QString &version = sections[1]; const int dotIndex = version.indexOf(QLatin1Char('.')); if (dotIndex == -1) { qWarning() << "expected '.'"; // ### use reportError - } else if (version.indexOf(QLatin1Char('.'), dotIndex + 1) != -1) { qWarning() << "unexpected '.'"; // ### use reportError diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index c23b17c..800434a 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -146,12 +146,11 @@ static bool qt_QmlQtModule_registered = false; void QDeclarativeEnginePrivate::defineModule() { - QML_REGISTER_TYPE(Qt,4,6,Component,QDeclarativeComponent); - QML_REGISTER_TYPE(Qt,4,6,QtObject,QObject); - QML_REGISTER_TYPE(Qt,4,6,WorkerScript,QDeclarativeWorkerScript); - QML_REGISTER_TYPE(Qt,4,6,WorkerListModel,QDeclarativeWorkerListModel); + qmlRegisterType<QDeclarativeComponent>("Qt",4,6,"Component"); + qmlRegisterType<QObject>("Qt",4,6,"QtObject"); + qmlRegisterType<QDeclarativeWorkerScript>("Qt",4,6,"WorkerScript"); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeBinding); + qmlRegisterType<QDeclarativeBinding>(); } QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) @@ -190,7 +189,7 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url) { if (p) { - QDeclarativeContext *ctxt = QDeclarativeEnginePrivate::get(this)->getContext(context); + QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(this)->getContext(context); Q_ASSERT(ctxt); return ctxt->resolvedUrl(url); } @@ -243,7 +242,6 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr qtObject.setProperty(QLatin1String("formatDateTime"),newFunction(QDeclarativeEnginePrivate::formatDateTime, 2)); //misc methods - qtObject.setProperty(QLatin1String("closestAngle"), newFunction(QDeclarativeEnginePrivate::closestAngle, 2)); qtObject.setProperty(QLatin1String("openUrlExternally"),newFunction(QDeclarativeEnginePrivate::desktopOpenUrl, 1)); qtObject.setProperty(QLatin1String("md5"),newFunction(QDeclarativeEnginePrivate::md5, 1)); qtObject.setProperty(QLatin1String("btoa"),newFunction(QDeclarativeEnginePrivate::btoa, 1)); @@ -637,9 +635,9 @@ QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object) if (!data) return 0; else if (data->outerContext) - return data->outerContext; + return data->outerContext->asQDeclarativeContext(); else - return data->context; + return 0; } /*! @@ -660,12 +658,63 @@ void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContex return; } - data->context = context; - data->nextContextObject = context->d_func()->contextObjects; - if (data->nextContextObject) - data->nextContextObject->prevContextObject = &data->nextContextObject; - data->prevContextObject = &context->d_func()->contextObjects; - context->d_func()->contextObjects = data; + QDeclarativeContextData *contextData = QDeclarativeContextData::get(context); + contextData->addObject(object); +} + +/*! +\enum QDeclarativeEngine::ObjectOwnership + +Ownership controls whether or not QML automatically destroys the QObject when the object +is garbage collected by the JavaScript engine. The two ownership options are: + +\list +\o CppOwnership - The object is owned by C++ code, and will never be deleted by QML. The +JavaScript destroy() method cannot be used on objects with CppOwnership. This option +is similar to QScriptEngine::QtOwnership. + +\o JavaScriptOwnership - The object is owned by JavaScript. When the object is returned to QML +as the return value of a method call or property access, QML will delete the object if there +are no remaining JavaScript references to it and it has no QObject::parent(). This option +is similar to QScriptEngine::ScriptOwnership. +\endlist + +Generally an application doesn't need to set an object's ownership explicitly. QML uses +a heuristic to set the default object ownership. By default, an object that is created by +QML has JavaScriptOwnership. The exception to this are the root objects created by calling +QDeclarativeCompnent::create() or QDeclarativeComponent::beginCreate() which have +CppOwnership by default. The ownership of these root-level objects is considered to have +been transfered to the C++ caller. + +Objects not-created by QML have CppOwnership by default. The exception to this is objects +returned from a C++ method call. The ownership of these objects is passed to JavaScript. + +Calling setObjectOwnership() overrides the default ownership heuristic used by QML. +*/ + +/*! +Sets the \a ownership of \a object. +*/ +void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership) +{ + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, true); + if (!ddata) + return; + + ddata->indestructible = (ownership == CppOwnership)?true:false; + ddata->explicitIndestructibleSet = true; +} + +/*! +Returns the ownership of \a object. +*/ +QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object) +{ + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, false); + if (!ddata) + return CppOwnership; + else + return ddata->indestructible?CppOwnership:JavaScriptOwnership; } void qmlExecuteDeferred(QObject *object) @@ -674,7 +723,7 @@ void qmlExecuteDeferred(QObject *object) if (data && data->deferredComponent) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine); QDeclarativeComponentPrivate::ConstructionState state; QDeclarativeComponentPrivate::beginDeferred(data->context, ep, object, &state); @@ -775,7 +824,18 @@ void QDeclarativeDeclarativeData::destroyed(QObject *object) g->objectDestroyed(object); } - delete this; + if (ownContext) + context->destroy(); + + if (ownMemory) + delete this; + else + this->~QDeclarativeDeclarativeData(); +} + +void QDeclarativeDeclarativeData::parentChanged(QObject *, QObject *parent) +{ + if (!parent && scriptValue.isValid()) scriptValue = QScriptValue(); } bool QDeclarativeDeclarativeData::hasBindingBit(int bit) const @@ -832,7 +892,7 @@ QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object, /*! Returns the QDeclarativeContext for the executing QScript \a ctxt. */ -QDeclarativeContext *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt) +QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt) { QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3); Q_ASSERT(scopeNode.isValid()); @@ -840,15 +900,15 @@ QDeclarativeContext *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt) return contextClass->contextFromValue(scopeNode); } -QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, - QScriptEngine *engine) +QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine) { QDeclarativeEnginePrivate *activeEnginePriv = static_cast<QDeclarativeScriptEngine*>(engine)->p; QDeclarativeEngine* activeEngine = activeEnginePriv->q_func(); - QDeclarativeContext* context = activeEnginePriv->getContext(ctxt); + QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); Q_ASSERT(context); + if(ctxt->argumentCount() != 1) { return engine->nullValue(); }else{ @@ -857,7 +917,8 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, return engine->nullValue(); QUrl url = QUrl(context->resolvedUrl(QUrl(arg))); QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine); - c->setCreationContext(context); + QDeclarativeComponentPrivate::get(c)->creationContext = context; + QDeclarativeDeclarativeData::get(c, true)->setImplicitDestructible(); return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QDeclarativeComponent*>()); } } @@ -871,7 +932,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3) return engine->nullValue(); - QDeclarativeContext* context = activeEnginePriv->getContext(ctxt); + QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); Q_ASSERT(context); QString qml = ctxt->argument(0).toString(); @@ -909,7 +970,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS return engine->nullValue(); } - QObject *obj = component.create(context); + QObject *obj = component.create(context->asQDeclarativeContext()); if(component.isError()) { QList<QDeclarativeError> errors = component.errors(); @@ -928,7 +989,8 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS if(gobj && gparent) gobj->setParentItem(gparent); - return qmlScriptObject(obj, activeEngine); + QDeclarativeDeclarativeData::get(obj, true)->setImplicitDestructible(); + return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar); } QScriptValue QDeclarativeEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engine) @@ -1177,25 +1239,6 @@ QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptE return QScriptValue(); } -QScriptValue QDeclarativeEnginePrivate::closestAngle(QScriptContext *ctxt, QScriptEngine *e) -{ - if(ctxt->argumentCount() < 2) - return e->newVariant(QVariant(0.0)); - qreal a = ctxt->argument(0).toNumber(); - qreal b = ctxt->argument(1).toNumber(); - qreal ret = b; - qreal diff = b-a; - while(diff > 180.0){ - ret -= 360.0; - diff -= 360.0; - } - while(diff < -180.0){ - ret += 360.0; - diff += 360.0; - } - return e->newVariant(QVariant(ret)); -} - QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 2) @@ -1299,12 +1342,16 @@ QVariant QDeclarativeScriptClass::toVariant(QDeclarativeEngine *engine, const QS } // XXX this beyonds in QUrl::toLocalFile() +// WARNING, there is a copy of this function in qdeclarativecompositetypemanager.cpp static QString toLocalFileOrQrc(const QUrl& url) { - QString r = url.toLocalFile(); - if (r.isEmpty() && url.scheme() == QLatin1String("qrc")) - r = QLatin1Char(':') + url.path(); - return r; + if (url.scheme() == QLatin1String("qrc")) { + if (url.authority().isEmpty()) + return QLatin1Char(':') + url.path(); + qWarning() << "Invalid url:" << url.toString() << "authority" << url.authority() << "not known."; + return QString(); + } + return url.toLocalFile(); } ///////////////////////////////////////////////////////////// @@ -1316,7 +1363,7 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QList<bool> isLibrary; QList<QString> qmlDirContent; - bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return) const + bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return) { for (int i=0; i<urls.count(); ++i) { int vmaj = majversions.at(i); @@ -1326,14 +1373,10 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { qt += '/'; qt += type; - if (qmlImportTrace()) - qDebug() << "Look in" << qt; QDeclarativeType *t = QDeclarativeMetaType::qmlType(qt,vmaj,vmin); if (t) { if (vmajor) *vmajor = vmaj; if (vminor) *vminor = vmin; - if (qmlImportTrace()) - qDebug() << "Found" << qt; if (type_return) *type_return = t; return true; @@ -1341,15 +1384,9 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); QString qmldircontent = qmlDirContent.at(i); - if (vmaj>=0 || !qmldircontent.isEmpty()) { - // Check version file - XXX cache these in QDeclarativeEngine! - if (qmldircontent.isEmpty()) { - QFile qmldir(toLocalFileOrQrc(QUrl(urls.at(i)+QLatin1String("/qmldir")))); - if (qmldir.open(QIODevice::ReadOnly)) { - qmldircontent = QString::fromUtf8(qmldir.readAll()); - } - } + bool typeWasDeclaredInQmldir = false; + if (!qmldircontent.isEmpty()) { const QString typeName = QString::fromUtf8(type); QDeclarativeDirParser qmldirParser; @@ -1358,17 +1395,18 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { qmldirParser.parse(); foreach (const QDeclarativeDirParser::Component &c, qmldirParser.components()) { // ### TODO: cache the components - if (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion)) { - if (c.typeName == typeName) { + if (c.typeName == typeName) { + typeWasDeclaredInQmldir = true; + if (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion)) { if (url_return) *url_return = url.resolved(QUrl(c.fileName)); - return true; } } } + } - } else { + if (!typeWasDeclaredInQmldir && !isLibrary.at(i)) { // XXX search non-files too! (eg. zip files, see QT-524) QFileInfo f(toLocalFileOrQrc(url)); if (f.exists()) { @@ -1396,8 +1434,88 @@ public: QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded; - bool add(const QUrl& base, const QString& qmldircontent, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, const QStringList& importPath, QDeclarativeEngine *engine) + QString importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine) { + QFile file(absoluteFilePath); + QString dir = QFileInfo(file).path(); + QString qmldircontent; + if (file.open(QFile::ReadOnly)) { + qmldircontent = QString::fromUtf8(file.readAll()); + if (qmlImportTrace()) + qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath; + } + + if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { + qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); + + QDeclarativeDirParser qmldirParser; + qmldirParser.setSource(qmldircontent); + qmldirParser.parse(); + + foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { + QDir pluginDir(dir + QDir::separator() + plugin.path); + if (dir.startsWith(QLatin1Char(':'))) + pluginDir = QDir(QCoreApplication::applicationDirPath()); + QString resolvedFilePath = + QDeclarativeEnginePrivate::get(engine) + ->resolvePlugin(pluginDir, + plugin.name); + + if (!resolvedFilePath.isEmpty()) { + engine->importExtension(resolvedFilePath, uri); + } + } + } + return qmldircontent; + } + + QString resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine) { + QString dir = dir_arg; + if (dir.endsWith(QLatin1Char('/')) || dir.endsWith(QLatin1Char('\\'))) + dir.chop(1); + + QStringList paths; + + if (!base.isEmpty()) { + QString baseDir = QFileInfo(toLocalFileOrQrc(base)).path(); + paths += baseDir; + } + + QString applicationDirPath = QCoreApplication::applicationDirPath(); + if (!applicationDirPath.isEmpty()) + paths += applicationDirPath; + + paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath; +#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) + QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); +#else + QString builtinPath; +#endif + if (!builtinPath.isEmpty()) + paths += builtinPath; + + // add fileImportPath last, this is *not* search order. + paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath; + + QString stableRelativePath = dir; + foreach( QString path, paths) { + if (dir.startsWith(path)) { + stableRelativePath = dir.mid(path.length()+1); + break; + } + } + stableRelativePath.replace(QLatin1Char('/'), QLatin1Char('.')); + stableRelativePath.replace(QLatin1Char('\\'), QLatin1Char('.')); + return stableRelativePath; + } + + + + + bool add(const QUrl& base, const QString &qmldircontentnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine) + { + QString qmldircontent = qmldircontentnetwork; + QString uri = uri_arg; QDeclarativeEnginePrivate::ImportedNamespace *s; if (prefix.isEmpty()) { s = &unqualifiedset; @@ -1406,30 +1524,40 @@ public: if (!s) set.insert(prefix,(s=new QDeclarativeEnginePrivate::ImportedNamespace)); } + + + QString url = uri; if (importType == QDeclarativeScriptParser::Import::Library) { url.replace(QLatin1Char('.'), QLatin1Char('/')); bool found = false; - QString content; QString dir; + // user import paths QStringList paths; - // base.. - paths += QFileInfo(base.toLocalFile()).path(); - paths += importPath; + QString localFileOrQrc = toLocalFileOrQrc(base); + QString localFileOrQrcPath = QFileInfo(localFileOrQrc).path(); + paths += localFileOrQrcPath; + paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath; + + QString applicationDirPath = QCoreApplication::applicationDirPath(); + if (!applicationDirPath.isEmpty()) + paths += applicationDirPath; + paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath; -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) + #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); -#else + #else QString builtinPath; -#endif + #endif if (!builtinPath.isEmpty()) paths += builtinPath; foreach (const QString &p, paths) { dir = p+QLatin1Char('/')+url; + QFileInfo fi(dir+QLatin1String("/qmldir")); const QString absoluteFilePath = fi.absoluteFilePath(); @@ -1437,33 +1565,31 @@ public: found = true; url = QUrl::fromLocalFile(fi.absolutePath()).toString(); - - QFile file(absoluteFilePath); - if (file.open(QFile::ReadOnly)) - content = QString::fromUtf8(file.readAll()); - - if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { - qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); - - QDeclarativeDirParser qmldirParser; - qmldirParser.setSource(content); - qmldirParser.parse(); - - foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { - QString resolvedFilePath = QDeclarativeEnginePrivate::get(engine)->resolvePlugin(QDir(dir + QDir::separator() + plugin.path), - plugin.name); - - if (!resolvedFilePath.isEmpty()) - engine->importExtension(resolvedFilePath, uri); - } - } - + uri = resolvedUri(dir, engine); + qmldircontent = importExtension(absoluteFilePath, uri, engine); break; } } } else { + + if (importType == QDeclarativeScriptParser::Import::File && qmldircontent.isEmpty()) { + QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir"))); + QString localFileOrQrc = toLocalFileOrQrc(importUrl); + if (!localFileOrQrc.isEmpty()) { + uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine); + qmldircontent = importExtension(localFileOrQrc, + uri, + engine); + + if (uri.endsWith(QLatin1Char('/'))) + uri.chop(1); + } + } + url = base.resolved(QUrl(url)).toString(); + if (url.endsWith(QLatin1Char('/'))) + url.chop(1); } s->uris.prepend(uri); @@ -1493,12 +1619,18 @@ public: if (s) { if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return)) return true; - if (s->urls.count() == 1 && !s->isLibrary[0] && url_return) { + if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) { + // qualified, and only 1 url *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml"))); return true; } } + + + /* now comes really nasty code. It makes "private" types load in the remote case, but + it does this by breaking the import order. This must go. Instead private types must + be marked private in the qmldir. */ if (url_return) { *url_return = base.resolved(QUrl(QString::fromUtf8(type + ".qml"))); return true; @@ -1642,9 +1774,10 @@ QUrl QDeclarativeEnginePrivate::Imports::baseUrl() const type version mapping and possibly declarative extensions plugins. The engine searches in the base directory of the qml file, then - the paths added via addImportPath(), then the paths specified in the - \c QML_IMPORT_PATH environment variable, then the builtin \c ImportsPath from - QLibraryInfo. + the paths added via addImportPath(), then in the directory containing the + application executable (QCoreApplication::applicationDirPath()), + then the paths specified in the \c QML_IMPORT_PATH environment variable, then the + builtin \c ImportsPath from QLibraryInfo. */ void QDeclarativeEngine::addImportPath(const QString& path) @@ -1661,6 +1794,8 @@ void QDeclarativeEngine::addImportPath(const QString& path) */ bool QDeclarativeEngine::importExtension(const QString &fileName, const QString &uri) { + if (qmlImportTrace()) + qDebug() << "QDeclarativeEngine::importExtension" << uri << "from" << fileName; QFileInfo fileInfo(fileName); const QString absoluteFilePath = fileInfo.absoluteFilePath(); QPluginLoader loader(absoluteFilePath); @@ -1744,6 +1879,8 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString return fileInfo.absoluteFilePath(); } + if (qmlImportTrace()) + qDebug() << "QDeclarativeEngine::resolvePlugin: Could not resolve plugin" << baseName << "in" << dir.absolutePath(); return QString(); } @@ -1784,6 +1921,9 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString return resolvePlugin(dir, baseName, QStringList() +# ifdef QT_DEBUG + << QLatin1String("_debug.dylib") // try a qmake-style debug build first +# endif << QLatin1String(".dylib") << QLatin1String(".so") << QLatin1String(".bundle"), @@ -1830,12 +1970,12 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString The base URL must already have been set with Import::setBaseUrl(). */ -bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString& qmldircontent, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const +bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString &qmldircontentnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const { QDeclarativeEngine *engine = QDeclarativeEnginePrivate::get(const_cast<QDeclarativeEnginePrivate *>(this)); - bool ok = imports->d->add(imports->d->base,qmldircontent,uri,prefix,vmaj,vmin,importType,fileImportPath, engine); if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::addToImport(" << imports << uri << prefix << vmaj << '.' << vmin << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << ": " << ok; + qDebug().nospace() << "QDeclarativeEngine::addToImport " << imports << " " << uri << " " << vmaj << '.' << vmin << " " << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << " as " << prefix; + bool ok = imports->d->add(imports->d->base,qmldircontentnetwork, uri,prefix,vmaj,vmin,importType, engine); return ok; } @@ -1855,8 +1995,6 @@ bool QDeclarativeEnginePrivate::resolveType(const Imports& imports, const QByteA { ImportedNamespace* ns = imports.d->findNamespace(QString::fromUtf8(type)); if (ns) { - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::resolveType" << type << "is namespace for" << ns->urls; if (ns_return) *ns_return = ns; return true; @@ -1864,15 +2002,15 @@ bool QDeclarativeEnginePrivate::resolveType(const Imports& imports, const QByteA if (type_return || url_return) { if (imports.d->find(type,vmaj,vmin,type_return,url_return)) { if (qmlImportTrace()) { + if (type_return && *type_return && url_return && !url_return->isEmpty()) + qDebug() << "QDeclarativeEngine::resolveType" << type << '=' << (*type_return)->typeName() << *url_return; if (type_return && *type_return) qDebug() << "QDeclarativeEngine::resolveType" << type << '=' << (*type_return)->typeName(); - if (url_return) + if (url_return && !url_return->isEmpty()) qDebug() << "QDeclarativeEngine::resolveType" << type << '=' << *url_return; } return true; } - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::resolveType" << type << "not found"; } return false; } diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h index fd66358..19e81b6 100644 --- a/src/declarative/qml/qdeclarativeengine.h +++ b/src/declarative/qml/qdeclarativeengine.h @@ -98,6 +98,10 @@ public: static QDeclarativeContext *contextForObject(const QObject *); static void setContextForObject(QObject *, QDeclarativeContext *); + enum ObjectOwnership { CppOwnership, JavaScriptOwnership }; + static void setObjectOwnership(QObject *, ObjectOwnership); + static ObjectOwnership objectOwnership(QObject *); + Q_SIGNALS: void quit (); diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 459a325..f1b7b0e 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -61,6 +61,7 @@ #include "qdeclarative.h" #include "qdeclarativevaluetype_p.h" #include "qdeclarativecontext.h" +#include "qdeclarativecontext_p.h" #include "qdeclarativeexpression.h" #include "qdeclarativeproperty_p.h" #include "qdeclarativepropertycache_p.h" @@ -144,10 +145,13 @@ public: struct CapturedProperty { CapturedProperty(QObject *o, int c, int n) - : object(o), coreIndex(c), notifyIndex(n) {} + : object(o), coreIndex(c), notifier(0), notifyIndex(n) {} + CapturedProperty(QDeclarativeNotifier *n) + : object(0), coreIndex(-1), notifier(n), notifyIndex(-1) {} QObject *object; int coreIndex; + QDeclarativeNotifier *notifier; int notifyIndex; }; bool captureProperties; @@ -159,7 +163,7 @@ public: struct ImportedNamespace; QDeclarativeContextScriptClass *contextClass; - QDeclarativeContext *sharedContext; + QDeclarativeContextData *sharedContext; QObject *sharedScope; QDeclarativeObjectScriptClass *objectClass; QDeclarativeValueTypeScriptClass *valueTypeClass; @@ -276,7 +280,7 @@ public: QString resolvePlugin(const QDir &dir, const QString &baseName); - bool addToImport(Imports*, const QString& qmlDirContent,const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; + bool addToImport(Imports*, const QString& uri, const QString &qmldircontentnetwork, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, @@ -318,7 +322,6 @@ public: static QScriptValue darker(QScriptContext*, QScriptEngine*); static QScriptValue tint(QScriptContext*, QScriptEngine*); - static QScriptValue closestAngle(QScriptContext*, QScriptEngine*); static QScriptValue desktopOpenUrl(QScriptContext*, QScriptEngine*); static QScriptValue md5(QScriptContext*, QScriptEngine*); static QScriptValue btoa(QScriptContext*, QScriptEngine*); @@ -334,9 +337,10 @@ public: static QDeclarativeEngine *getEngine(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p->q_func(); } static QDeclarativeEnginePrivate *get(QDeclarativeEngine *e) { return e->d_func(); } static QDeclarativeEnginePrivate *get(QDeclarativeContext *c) { return (c && c->engine()) ? QDeclarativeEnginePrivate::get(c->engine()) : 0; } + static QDeclarativeEnginePrivate *get(QDeclarativeContextData *c) { return (c && c->engine) ? QDeclarativeEnginePrivate::get(c->engine) : 0; } static QDeclarativeEnginePrivate *get(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p; } static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); } - QDeclarativeContext *getContext(QScriptContext *); + QDeclarativeContextData *getContext(QScriptContext *); static void defineModule(); }; diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index 3e4acbe..a377b35 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -49,6 +49,7 @@ #include "qdeclarativebinding_p.h" #include "qdeclarativecontext_p.h" #include "qdeclarativewatcher_p.h" +#include "qdeclarativevaluetype_p.h" #include <QtCore/qdebug.h> #include <QtCore/qmetaobject.h> @@ -218,10 +219,9 @@ void QDeclarativeEngineDebugServer::buildObjectDump(QDataStream &message, message << fakeProperties[ii]; } -void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, - QDeclarativeContext *ctxt) +void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, QDeclarativeContext *ctxt) { - QDeclarativeContextPrivate *p = (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt); + QDeclarativeContextData *p = QDeclarativeContextData::get(ctxt); QString ctxtName = ctxt->objectName(); int ctxtId = QDeclarativeDebugService::idForObject(ctxt); @@ -230,35 +230,34 @@ void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, int count = 0; - for (QSet<QDeclarativeContext *>::ConstIterator iter = p->childContexts.begin(); - iter != p->childContexts.end(); ++iter) { - QDeclarativeContextPrivate *p = (QDeclarativeContextPrivate *)QObjectPrivate::get(*iter); - if (p->isInternal) - continue; - ++count; + QDeclarativeContextData *child = p->childContexts; + while (child) { + if (!child->isInternal) + ++count; + child = child->nextChild; } message << count; - for (QSet<QDeclarativeContext *>::ConstIterator iter = p->childContexts.begin(); - iter != p->childContexts.end(); ++iter) { - QDeclarativeContextPrivate *p = (QDeclarativeContextPrivate *)QObjectPrivate::get(*iter); - if (p->isInternal) - continue; - buildObjectList(message, *iter); + child = p->childContexts; + while (child) { + if (!child->isInternal) + buildObjectList(message, child->asQDeclarativeContext()); + child = child->nextChild; } // Clean deleted objects - for (int ii = 0; ii < p->instances.count(); ++ii) { - if (!p->instances.at(ii)) { - p->instances.removeAt(ii); + QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(ctxt); + for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) { + if (!ctxtPriv->instances.at(ii)) { + ctxtPriv->instances.removeAt(ii); --ii; } } - message << p->instances.count(); - for (int ii = 0; ii < p->instances.count(); ++ii) { - message << objectData(p->instances.at(ii)); + message << ctxtPriv->instances.count(); + for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) { + message << objectData(ctxtPriv->instances.at(ii)); } } @@ -267,8 +266,8 @@ QDeclarativeEngineDebugServer::objectData(QObject *object) { QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object); QDeclarativeObjectData rv; - if (ddata) { - rv.url = ddata->outerContext->baseUrl(); + if (ddata && ddata->outerContext) { + rv.url = ddata->outerContext->url; rv.lineNumber = ddata->lineNumber; rv.columnNumber = ddata->columnNumber; } else { diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 899f402..9eed345 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -95,11 +95,18 @@ QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate(QDeclarativeExpress QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate() { - if (data) { data->q = 0; data->release(); data = 0; } + if (data) { + delete [] data->guardList; + data->guardList = 0; + data->guardListLength = 0; + data->q = 0; + data->release(); + data = 0; + } } -void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, const QString &expr, - QObject *me) +void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr, + QObject *me) { data->expression = expr; @@ -107,8 +114,8 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, const QStrin data->me = me; } -void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr, QDeclarativeRefCount *rc, - QObject *me, const QString &url, int lineNumber) +void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr, QDeclarativeRefCount *rc, + QObject *me, const QString &url, int lineNumber) { data->url = url; data->line = lineNumber; @@ -127,7 +134,7 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr, bool isShared = progIdx & 0x80000000; progIdx &= 0x7FFFFFFF; - QDeclarativeEngine *engine = ctxt->engine(); + QDeclarativeEngine *engine = ctxt->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -167,10 +174,10 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr, data->me = me; } -QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContext *context, QObject *object, +QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object, const QString &program, QScriptValue *contextObject) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine); if (contextObject) { *contextObject = ep->contextClass->newContext(context, object); @@ -184,10 +191,11 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex return rv; } -QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContext *context, QObject *object, - const QScriptProgram &program, QScriptValue *contextObject) +QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object, + const QScriptProgram &program, + QScriptValue *contextObject) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine); if (contextObject) { *contextObject = ep->contextClass->newContext(context, object); @@ -219,10 +227,10 @@ QDeclarativeExpression::QDeclarativeExpression() } /*! \internal */ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, void *expr, - QDeclarativeRefCount *rc, QObject *me, - const QString &url, int lineNumber, - QDeclarativeExpressionPrivate &dd) +QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, void *expr, + QDeclarativeRefCount *rc, QObject *me, + const QString &url, int lineNumber, + QDeclarativeExpressionPrivate &dd) : QObject(dd, 0) { Q_D(QDeclarativeExpression); @@ -237,7 +245,18 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, void * the expression's execution. */ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const QString &expression, - QObject *scope) + QObject *scope) +: QObject(*new QDeclarativeExpressionPrivate, 0) +{ + Q_D(QDeclarativeExpression); + d->init(QDeclarativeContextData::get(ctxt), expression, scope); +} + +/*! + \internal +*/ +QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, const QString &expression, + QObject *scope) : QObject(*new QDeclarativeExpressionPrivate, 0) { Q_D(QDeclarativeExpression); @@ -245,8 +264,8 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const } /*! \internal */ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const QString &expression, - QObject *scope, QDeclarativeExpressionPrivate &dd) +QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, const QString &expression, + QObject *scope, QDeclarativeExpressionPrivate &dd) : QObject(dd, 0) { Q_D(QDeclarativeExpression); @@ -267,7 +286,7 @@ QDeclarativeExpression::~QDeclarativeExpression() QDeclarativeEngine *QDeclarativeExpression::engine() const { Q_D(const QDeclarativeExpression); - return d->data->context()?d->data->context()->engine():0; + return d->data->context()?d->data->context()->engine:0; } /*! @@ -277,7 +296,8 @@ QDeclarativeEngine *QDeclarativeExpression::engine() const QDeclarativeContext *QDeclarativeExpression::context() const { Q_D(const QDeclarativeExpression); - return d->data->context(); + QDeclarativeContextData *data = d->data->context(); + return data?data->asQDeclarativeContext():0; } /*! @@ -338,8 +358,7 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo #endif QDeclarativeExpressionData *data = this->data; - QDeclarativeContextPrivate *ctxtPriv = data->context()->d_func(); - QDeclarativeEngine *engine = data->context()->engine(); + QDeclarativeEngine *engine = data->context()->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -370,7 +389,7 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo data->expressionFunctionValid = true; } - QDeclarativeContext *oldSharedContext = 0; + QDeclarativeContextData *oldSharedContext = 0; QObject *oldSharedScope = 0; QObject *oldOverride = 0; if (data->isShared) { @@ -622,137 +641,96 @@ void QDeclarativeExpression::__q_notify() void QDeclarativeExpressionPrivate::clearGuards() { - Q_Q(QDeclarativeExpression); - - static int notifyIdx = -1; - if (notifyIdx == -1) - notifyIdx = - QDeclarativeExpression::staticMetaObject.indexOfMethod("__q_notify()"); - - for (int ii = 0; ii < data->guardListLength; ++ii) { - if (data->guardList[ii].data()) { -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) - QMetaObject::disconnectOne(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#else - // QTBUG-6781 - QMetaObject::disconnect(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#endif - } - } - - delete [] data->guardList; data->guardList = 0; + delete [] data->guardList; + data->guardList = 0; data->guardListLength = 0; } void QDeclarativeExpressionPrivate::updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties) { - //clearGuards(); Q_Q(QDeclarativeExpression); static int notifyIdx = -1; if (notifyIdx == -1) - notifyIdx = - QDeclarativeExpression::staticMetaObject.indexOfMethod("__q_notify()"); + notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("__q_notify()"); - QDeclarativeExpressionData::SignalGuard *newGuardList = 0; - - if (properties.count() != data->guardListLength) - newGuardList = new QDeclarativeExpressionData::SignalGuard[properties.count()]; + if (properties.count() != data->guardListLength) { + QDeclarativeNotifierEndpoint *newGuardList = + new QDeclarativeNotifierEndpoint[properties.count()]; + + for (int ii = 0; ii < qMin(data->guardListLength, properties.count()); ++ii) + data->guardList[ii].copyAndClear(newGuardList[ii]); + + delete [] data->guardList; + data->guardList = newGuardList; + data->guardListLength = properties.count(); + } bool outputWarningHeader = false; - int hit = 0; + bool noChanges = true; for (int ii = 0; ii < properties.count(); ++ii) { + QDeclarativeNotifierEndpoint &guard = data->guardList[ii]; const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii); - bool needGuard = true; - if (ii >= data->guardListLength) { - // New guard - } else if(data->guardList[ii].data() == property.object && - data->guardList[ii].notifyIndex == property.notifyIndex) { - // Cache hit - if (!data->guardList[ii].isDuplicate || - (data->guardList[ii].isDuplicate && hit == ii)) { - needGuard = false; - ++hit; - } - } else if(data->guardList[ii].data() && !data->guardList[ii].isDuplicate) { - // Cache miss -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) - QMetaObject::disconnectOne(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#else - // QTBUG-6781 - QMetaObject::disconnect(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#endif - } - /* else { - // Cache miss, but nothing to do - } */ - - if (needGuard) { - if (!newGuardList) { - newGuardList = new QDeclarativeExpressionData::SignalGuard[properties.count()]; - for (int jj = 0; jj < ii; ++jj) - newGuardList[jj] = data->guardList[jj]; - } + guard.target = q; + guard.targetMethod = notifyIdx; + + if (property.notifier != 0) { + + if (!noChanges && guard.isConnected(property.notifier)) { + // Nothing to do + + } else { + noChanges = false; - if (property.notifyIndex != -1) { bool existing = false; for (int jj = 0; !existing && jj < ii; ++jj) - existing = newGuardList[jj].data() == property.object && - newGuardList[jj].notifyIndex == property.notifyIndex; - - newGuardList[ii] = property.object; - newGuardList[ii].notifyIndex = property.notifyIndex; - if (existing) - newGuardList[ii].isDuplicate = true; - else - QMetaObject::connect(property.object, property.notifyIndex, - q, notifyIdx); - } else { - if (!outputWarningHeader) { - outputWarningHeader = true; - qWarning() << "QDeclarativeExpression: Expression" << q->expression() - << "depends on non-NOTIFYable properties:"; + if (data->guardList[jj].isConnected(property.notifier)) + existing = true; + + if (existing) { + // duplicate + guard.disconnect(); + } else { + guard.connect(property.notifier); } + } - const QMetaObject *metaObj = property.object->metaObject(); - QMetaProperty metaProp = metaObj->property(property.coreIndex); - qWarning().nospace() << " " << metaObj->className() - << "::" << metaProp.name(); + } else if (property.notifyIndex != -1) { + + if (!noChanges && guard.isConnected(property.object, property.notifyIndex)) { + // Nothing to do + + } else { + noChanges = false; + + bool existing = false; + for (int jj = 0; !existing && jj < ii; ++jj) + if (data->guardList[jj].isConnected(property.object, property.notifyIndex)) + existing = true; + + if (existing) { + // duplicate + guard.disconnect(); + } else { + guard.connect(property.object, property.notifyIndex); + } + } + + } else { + if (!outputWarningHeader) { + outputWarningHeader = true; + qWarning() << "QDeclarativeExpression: Expression" << q->expression() + << "depends on non-NOTIFYable properties:"; } - } else if (newGuardList) { - newGuardList[ii] = data->guardList[ii]; - } - } - for (int ii = properties.count(); ii < data->guardListLength; ++ii) { - if (data->guardList[ii].data() && !data->guardList[ii].isDuplicate) { -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) - QMetaObject::disconnectOne(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#else - // QTBUG-6781 - QMetaObject::disconnect(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#endif - } - } + const QMetaObject *metaObj = property.object->metaObject(); + QMetaProperty metaProp = metaObj->property(property.coreIndex); - if (newGuardList) { - if (data->guardList) delete [] data->guardList; - data->guardList = newGuardList; - data->guardListLength = properties.count(); + qWarning().nospace() << " " << metaObj->className() + << "::" << metaProp.name(); + } } } @@ -784,12 +762,12 @@ QDeclarativeAbstractExpression::~QDeclarativeAbstractExpression() } } -QDeclarativeContext *QDeclarativeAbstractExpression::context() const +QDeclarativeContextData *QDeclarativeAbstractExpression::context() const { return m_context; } -void QDeclarativeAbstractExpression::setContext(QDeclarativeContext *context) +void QDeclarativeAbstractExpression::setContext(QDeclarativeContextData *context) { if (m_prevExpression) { *m_prevExpression = m_nextExpression; @@ -802,13 +780,11 @@ void QDeclarativeAbstractExpression::setContext(QDeclarativeContext *context) m_context = context; if (m_context) { - QDeclarativeContextPrivate *cp = - static_cast<QDeclarativeContextPrivate *>(QObjectPrivate::get(m_context)); - m_nextExpression = cp->expressions; + m_nextExpression = m_context->expressions; if (m_nextExpression) m_nextExpression->m_prevExpression = &m_nextExpression; - m_prevExpression = &cp->expressions; - cp->expressions = this; + m_prevExpression = &context->expressions; + m_context->expressions = this; } } diff --git a/src/declarative/qml/qdeclarativeexpression.h b/src/declarative/qml/qdeclarativeexpression.h index 911d328..73a5793 100644 --- a/src/declarative/qml/qdeclarativeexpression.h +++ b/src/declarative/qml/qdeclarativeexpression.h @@ -58,6 +58,7 @@ class QDeclarativeRefCount; class QDeclarativeEngine; class QDeclarativeContext; class QDeclarativeExpressionPrivate; +class QDeclarativeContextData; class Q_DECLARATIVE_EXPORT QDeclarativeExpression : public QObject { Q_OBJECT @@ -91,18 +92,21 @@ Q_SIGNALS: void valueChanged(); protected: - QDeclarativeExpression(QDeclarativeContext *, const QString &, QObject *, - QDeclarativeExpressionPrivate &dd); - QDeclarativeExpression(QDeclarativeContext *, void *, QDeclarativeRefCount *rc, QObject *me, const QString &, - int, QDeclarativeExpressionPrivate &dd); + QDeclarativeExpression(QDeclarativeContextData *, const QString &, QObject *, + QDeclarativeExpressionPrivate &dd); + QDeclarativeExpression(QDeclarativeContextData *, void *, QDeclarativeRefCount *rc, + QObject *me, const QString &, int, QDeclarativeExpressionPrivate &dd); private Q_SLOTS: void __q_notify(); private: + QDeclarativeExpression(QDeclarativeContextData *, const QString &, QObject *); + Q_DECLARE_PRIVATE(QDeclarativeExpression) friend class QDeclarativeDebugger; friend class QDeclarativeContext; + friend class QDeclarativeVME; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index cd1729d..5adaa89 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -70,15 +70,16 @@ public: bool isValid() const; - QDeclarativeContext *context() const; - void setContext(QDeclarativeContext *); + QDeclarativeContextData *context() const; + void setContext(QDeclarativeContextData *); virtual void refresh(); private: friend class QDeclarativeContext; + friend class QDeclarativeContextData; friend class QDeclarativeContextPrivate; - QDeclarativeContext *m_context; + QDeclarativeContextData *m_context; QDeclarativeAbstractExpression **m_prevExpression; QDeclarativeAbstractExpression *m_nextExpression; }; @@ -129,24 +130,7 @@ public: QString url; // This is a QString for a reason. QUrls are slooooooow... int line; - struct SignalGuard : public QDeclarativeGuard<QObject> { - SignalGuard() : isDuplicate(false), notifyIndex(-1) {} - - SignalGuard &operator=(QObject *obj) { - QDeclarativeGuard<QObject>::operator=(obj); - return *this; - } - SignalGuard &operator=(const SignalGuard &o) { - QDeclarativeGuard<QObject>::operator=(o); - isDuplicate = o.isDuplicate; - notifyIndex = o.notifyIndex; - return *this; - } - - bool isDuplicate:1; - int notifyIndex:31; - }; - SignalGuard *guardList; + QDeclarativeNotifierEndpoint *guardList; int guardListLength; }; @@ -160,8 +144,8 @@ public: QDeclarativeExpressionPrivate(QDeclarativeExpressionData *); ~QDeclarativeExpressionPrivate(); - void init(QDeclarativeContext *, const QString &, QObject *); - void init(QDeclarativeContext *, void *, QDeclarativeRefCount *, QObject *, const QString &, int); + void init(QDeclarativeContextData *, const QString &, QObject *); + void init(QDeclarativeContextData *, void *, QDeclarativeRefCount *, QObject *, const QString &, int); QDeclarativeExpressionData *data; @@ -181,8 +165,8 @@ public: virtual void emitValueChanged(); static void exceptionToError(QScriptEngine *, QDeclarativeError &); - static QScriptValue evalInObjectScope(QDeclarativeContext *, QObject *, const QString &, QScriptValue * = 0); - static QScriptValue evalInObjectScope(QDeclarativeContext *, QObject *, const QScriptProgram &, QScriptValue * = 0); + static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QString &, QScriptValue * = 0); + static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QScriptProgram &, QScriptValue * = 0); }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeinfo.cpp b/src/declarative/qml/qdeclarativeinfo.cpp index 7dc61fd..5146bb6 100644 --- a/src/declarative/qml/qdeclarativeinfo.cpp +++ b/src/declarative/qml/qdeclarativeinfo.cpp @@ -43,6 +43,7 @@ #include "qdeclarativedeclarativedata_p.h" #include "qdeclarativecontext.h" +#include "qdeclarativecontext_p.h" #include "qdeclarativemetatype_p.h" #include <QCoreApplication> @@ -102,8 +103,8 @@ QDeclarativeInfo::QDeclarativeInfo(const QObject *object) QDeclarativeDeclarativeData *ddata = object?QDeclarativeDeclarativeData::get(object):0; pos += QLatin1String(" ("); if (ddata) { - if (ddata->outerContext) { - pos += ddata->outerContext->baseUrl().toString(); + if (ddata->outerContext && !ddata->outerContext->url.isEmpty()) { + pos += ddata->outerContext->url.toString(); pos += QLatin1Char(':'); pos += QString::number(ddata->lineNumber); pos += QLatin1Char(':'); diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index cf485fe..a23ff75 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -90,7 +90,7 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_STRING\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value); break; case QDeclarativeInstruction::StoreUrl: - qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_URL\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << primitives.at(instr->storeUrl.value); + qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_URL\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << urls.at(instr->storeUrl.value); break; case QDeclarativeInstruction::StoreColor: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_COLOR\t\t" << instr->storeColor.propertyIndex << "\t\t\t" << QString::number(instr->storeColor.value, 16); diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp index 50ab56b..b32e575 100644 --- a/src/declarative/qml/qdeclarativemetatype.cpp +++ b/src/declarative/qml/qdeclarativemetatype.cpp @@ -124,7 +124,10 @@ public: int m_version_maj; int m_version_min; int m_typeId; int m_listId; - QObject *(*m_newFunc)(); + + int m_allocationSize; + void (*m_newFunc)(void *); + const QMetaObject *m_baseMetaObject; QDeclarativeAttachedPropertiesFunc m_attachedPropertiesFunc; const QMetaObject *m_attachedPropertiesType; @@ -141,7 +144,7 @@ public: QDeclarativeTypePrivate::QDeclarativeTypePrivate() : m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0), - m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0), + m_allocationSize(0), m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0), m_parserStatusCast(-1), m_propertyValueSourceCast(-1), m_propertyValueInterceptorCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0), m_isSetup(false) { @@ -174,6 +177,7 @@ QDeclarativeType::QDeclarativeType(int index, const QDeclarativePrivate::Registe d->m_version_min = type.versionMinor; d->m_typeId = type.typeId; d->m_listId = type.listId; + d->m_allocationSize = type.objectSize; d->m_newFunc = type.create; d->m_baseMetaObject = type.metaObject; d->m_attachedPropertiesFunc = type.attachedPropertiesFunction; @@ -274,13 +278,29 @@ QObject *QDeclarativeType::create() const { d->init(); - QObject *rv = d->m_newFunc(); + QObject *rv = (QObject *)operator new(d->m_allocationSize); + d->m_newFunc(rv); + if (rv && !d->m_metaObjects.isEmpty()) (void *)new QDeclarativeProxyMetaObject(rv, &d->m_metaObjects); return rv; } +void QDeclarativeType::create(QObject **out, void **memory, size_t additionalMemory) const +{ + d->init(); + + QObject *rv = (QObject *)operator new(d->m_allocationSize + additionalMemory); + d->m_newFunc(rv); + + if (rv && !d->m_metaObjects.isEmpty()) + (void *)new QDeclarativeProxyMetaObject(rv, &d->m_metaObjects); + + *out = rv; + *memory = ((char *)rv) + d->m_allocationSize; +} + QDeclarativeCustomParser *QDeclarativeType::customParser() const { return d->m_customParser; diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h index cf8946d..1a36f10 100644 --- a/src/declarative/qml/qdeclarativemetatype_p.h +++ b/src/declarative/qml/qdeclarativemetatype_p.h @@ -111,6 +111,7 @@ public: bool availableInVersion(int vmajor, int vminor) const; QObject *create() const; + void create(QObject **, void **, size_t) const; QDeclarativeCustomParser *customParser() const; diff --git a/src/declarative/qml/qdeclarativenotifier.cpp b/src/declarative/qml/qdeclarativenotifier.cpp new file mode 100644 index 0000000..b12bf77 --- /dev/null +++ b/src/declarative/qml/qdeclarativenotifier.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativenotifier_p.h" + +QT_BEGIN_NAMESPACE + +void QDeclarativeNotifier::emitNotify(QDeclarativeNotifierEndpoint *endpoint) +{ + QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier(); + + QDeclarativeNotifierEndpoint **oldDisconnected = n->disconnected; + n->disconnected = &endpoint; + + if (n->next) + emitNotify(n->next); + + if (endpoint) { + void *args[] = { 0 }; + + QMetaObject::metacall(endpoint->target, QMetaObject::InvokeMetaMethod, + endpoint->targetMethod, args); + + if (endpoint) + endpoint->asNotifier()->disconnected = oldDisconnected; + } + + if (oldDisconnected) *oldDisconnected = endpoint; +} + +void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &other) +{ + other.disconnect(); + + other.target = target; + other.targetMethod = targetMethod; + + if (!isConnected()) + return; + + if (SignalType == type) { + Signal *other_s = other.toSignal(); + Signal *s = asSignal(); + + other_s->source = s->source; + other_s->sourceSignal = s->sourceSignal; + s->source = 0; + } else if(NotifierType == type) { + Notifier *other_n = other.toNotifier(); + Notifier *n = asNotifier(); + + other_n->notifier = n->notifier; + other_n->disconnected = n->disconnected; + if (other_n->disconnected) *other_n->disconnected = &other; + + if (n->next) { + other_n->next = n->next; + n->next->asNotifier()->prev = &other_n->next; + } + other_n->prev = n->prev; + *other_n->prev = &other; + + n->prev = 0; + n->next = 0; + n->disconnected = 0; + n->notifier = 0; + } +} + + +QT_END_NAMESPACE + diff --git a/src/declarative/qml/qdeclarativenotifier_p.h b/src/declarative/qml/qdeclarativenotifier_p.h new file mode 100644 index 0000000..2a9660d --- /dev/null +++ b/src/declarative/qml/qdeclarativenotifier_p.h @@ -0,0 +1,276 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVENOTIFIER_P_H +#define QDECLARATIVENOTIFIER_P_H + +#include "qdeclarativeguard_p.h" + +QT_BEGIN_NAMESPACE + +class QDeclarativeNotifierEndpoint; +class QDeclarativeNotifier +{ +public: + inline QDeclarativeNotifier(); + inline ~QDeclarativeNotifier(); + inline void notify(); + +private: + friend class QDeclarativeNotifierEndpoint; + + static void emitNotify(QDeclarativeNotifierEndpoint *); + QDeclarativeNotifierEndpoint *endpoints; +}; + +class QDeclarativeNotifierEndpoint +{ +public: + inline QDeclarativeNotifierEndpoint(); + inline QDeclarativeNotifierEndpoint(QObject *t, int m); + inline ~QDeclarativeNotifierEndpoint(); + + QObject *target; + int targetMethod; + + inline bool isConnected(); + inline bool isConnected(QObject *source, int sourceSignal); + inline bool isConnected(QDeclarativeNotifier *); + + inline void connect(QObject *source, int sourceSignal); + inline void connect(QDeclarativeNotifier *); + inline void disconnect(); + + void copyAndClear(QDeclarativeNotifierEndpoint &other); + +private: + friend class QDeclarativeNotifier; + + struct Signal { + QDeclarativeGuard<QObject> source; + int sourceSignal; + }; + + struct Notifier { + QDeclarativeNotifier *notifier; + QDeclarativeNotifierEndpoint **disconnected; + + QDeclarativeNotifierEndpoint *next; + QDeclarativeNotifierEndpoint **prev; + }; + + enum { InvalidType, SignalType, NotifierType } type; + union { + char signalData[sizeof(Signal)]; + char notifierData[sizeof(Notifier)]; + }; + + inline Notifier *toNotifier(); + inline Notifier *asNotifier(); + inline Signal *toSignal(); + inline Signal *asSignal(); +}; + +QDeclarativeNotifier::QDeclarativeNotifier() +: endpoints(0) +{ +} + +QDeclarativeNotifier::~QDeclarativeNotifier() +{ + QDeclarativeNotifierEndpoint *endpoint = endpoints; + while (endpoint) { + QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier(); + endpoint = n->next; + + n->next = 0; + n->prev = 0; + n->notifier = 0; + if (n->disconnected) *n->disconnected = 0; + n->disconnected = 0; + } + endpoints = 0; +} + +void QDeclarativeNotifier::notify() +{ + if (endpoints) emitNotify(endpoints); +} + +QDeclarativeNotifierEndpoint::QDeclarativeNotifierEndpoint() +: target(0), targetMethod(0), type(InvalidType) +{ +} + +QDeclarativeNotifierEndpoint::QDeclarativeNotifierEndpoint(QObject *t, int m) +: target(t), targetMethod(m), type(InvalidType) +{ +} + +QDeclarativeNotifierEndpoint::~QDeclarativeNotifierEndpoint() +{ + disconnect(); + if (SignalType == type) { + Signal *s = asSignal(); + s->~Signal(); + } +} + +bool QDeclarativeNotifierEndpoint::isConnected() +{ + if (SignalType == type) { + return asSignal()->source; + } else if (NotifierType == type) { + return asNotifier()->notifier; + } else { + return false; + } +} + +bool QDeclarativeNotifierEndpoint::isConnected(QObject *source, int sourceSignal) +{ + return SignalType == type && asSignal()->source == source && asSignal()->sourceSignal == sourceSignal; +} + +bool QDeclarativeNotifierEndpoint::isConnected(QDeclarativeNotifier *notifier) +{ + return NotifierType == type && asNotifier()->notifier == notifier; +} + +void QDeclarativeNotifierEndpoint::connect(QObject *source, int sourceSignal) +{ + Signal *s = toSignal(); + + if (s->source == source && s->sourceSignal == sourceSignal) + return; + + disconnect(); + + QMetaObject::connect(source, sourceSignal, target, targetMethod); + + s->source = source; + s->sourceSignal = sourceSignal; +} + +void QDeclarativeNotifierEndpoint::connect(QDeclarativeNotifier *notifier) +{ + Notifier *n = toNotifier(); + + if (n->notifier == notifier) + return; + + disconnect(); + + n->next = notifier->endpoints; + if (n->next) { n->next->asNotifier()->prev = &n->next; } + notifier->endpoints = this; + n->prev = ¬ifier->endpoints; + n->notifier = notifier; +} + +void QDeclarativeNotifierEndpoint::disconnect() +{ + if (type == SignalType) { + Signal *s = (Signal *)&signalData; + if (s->source) { + QMetaObject::disconnectOne(s->source, s->sourceSignal, target, targetMethod); + s->source = 0; + } + } else if (type == NotifierType) { + Notifier *n = asNotifier(); + + if (n->next) n->next->asNotifier()->prev = n->prev; + if (n->prev) *n->prev = n->next; + if (n->disconnected) *n->disconnected = 0; + n->next = 0; + n->prev = 0; + n->disconnected = 0; + n->notifier = 0; + } +} + +QDeclarativeNotifierEndpoint::Notifier *QDeclarativeNotifierEndpoint::toNotifier() +{ + if (NotifierType == type) + return asNotifier(); + + if (SignalType == type) { + disconnect(); + Signal *s = asSignal(); + s->~Signal(); + } + + Notifier *n = asNotifier(); + n->next = 0; + n->prev = 0; + n->disconnected = 0; + n->notifier = 0; + type = NotifierType; + return n; +} + +QDeclarativeNotifierEndpoint::Notifier *QDeclarativeNotifierEndpoint::asNotifier() +{ + return (Notifier *)(¬ifierData); +} + +QDeclarativeNotifierEndpoint::Signal *QDeclarativeNotifierEndpoint::toSignal() +{ + if (SignalType == type) + return asSignal(); + + disconnect(); + Signal *s = asSignal(); + new (s) Signal; + type = SignalType; + + return s; +} + +QDeclarativeNotifierEndpoint::Signal *QDeclarativeNotifierEndpoint::asSignal() +{ + return (Signal *)(&signalData); +} + +QT_END_NAMESPACE + +#endif // QDECLARATIVENOTIFIER_P_H + diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index e6f6e5f..84c9bef 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -59,6 +59,15 @@ QT_BEGIN_NAMESPACE struct ObjectData : public QScriptDeclarativeClass::Object { ObjectData(QObject *o, int t) : object(o), type(t) {} + + virtual ~ObjectData() { + if (object && !object->parent()) { + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, false); + if (ddata && !ddata->indestructible) + object->deleteLater(); + } + } + QDeclarativeGuard<QObject> object; int type; }; @@ -69,7 +78,7 @@ struct ObjectData : public QScriptDeclarativeClass::Object { QtScript for QML. */ QDeclarativeObjectScriptClass::QDeclarativeObjectScriptClass(QDeclarativeEngine *bindEngine) -: QDeclarativeScriptClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), +: QDeclarativeScriptClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), #if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) methods(bindEngine), #endif @@ -87,7 +96,7 @@ QDeclarativeObjectScriptClass::~QDeclarativeObjectScriptClass() { } -QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type) +QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type) { QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -96,7 +105,11 @@ QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, true); - if (!ddata->scriptValue.isValid()) { + if (!ddata) { + return scriptEngine->undefinedValue(); + } else if (!ddata->indestructible && !object->parent()) { + return newObject(scriptEngine, this, new ObjectData(object, type)); + } else if (!ddata->scriptValue.isValid()) { ddata->scriptValue = newObject(scriptEngine, this, new ObjectData(object, type)); return ddata->scriptValue; } else if (ddata->scriptValue.engine() == QDeclarativeEnginePrivate::getScriptEngine(engine)) { @@ -120,16 +133,16 @@ int QDeclarativeObjectScriptClass::objectType(const QScriptValue &value) const return ((ObjectData*)(o))->type; } -QScriptClass::QueryFlags -QDeclarativeObjectScriptClass::queryProperty(Object *object, const Identifier &name, +QScriptClass::QueryFlags +QDeclarativeObjectScriptClass::queryProperty(Object *object, const Identifier &name, QScriptClass::QueryFlags flags) { return queryProperty(toQObject(object), name, flags, 0); } -QScriptClass::QueryFlags -QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &name, - QScriptClass::QueryFlags flags, QDeclarativeContext *evalContext, +QScriptClass::QueryFlags +QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &name, + QScriptClass::QueryFlags flags, QDeclarativeContextData *evalContext, QueryHints hints) { Q_UNUSED(flags); @@ -147,12 +160,12 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam lastData = QDeclarativePropertyCache::property(engine, obj, name, local); if (lastData) - return QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess; + return QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess; if (!(hints & SkipAttachedProperties)) { if (!evalContext && context()) { // Global object, QScriptContext activation object, QDeclarativeContext object - QScriptValue scopeNode = scopeChainValue(context(), -3); + QScriptValue scopeNode = scopeChainValue(context(), -3); if (scopeNode.isValid()) { Q_ASSERT(scriptClass(scopeNode) == enginePrivate->contextClass); @@ -160,15 +173,11 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam } } - if (evalContext) { - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(evalContext); - - if (cp->imports) { - QDeclarativeTypeNameCache::Data *data = cp->imports->data(name); - if (data) { - lastTNData = data; - return QScriptClass::HandlesReadAccess; - } + if (evalContext && evalContext->imports) { + QDeclarativeTypeNameCache::Data *data = evalContext->imports->data(name); + if (data) { + lastTNData = data; + return QScriptClass::HandlesReadAccess; } } } @@ -228,7 +237,7 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) } } else { if (enginePriv->captureProperties && !(lastData->flags & QDeclarativePropertyCache::Data::IsConstant)) { - enginePriv->capturedProperties << + enginePriv->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(obj, lastData->coreIndex, lastData->notifyIndex); } @@ -293,17 +302,17 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) } } -void QDeclarativeObjectScriptClass::setProperty(Object *object, - const Identifier &name, +void QDeclarativeObjectScriptClass::setProperty(Object *object, + const Identifier &name, const QScriptValue &value) { return setProperty(toQObject(object), name, value); } -void QDeclarativeObjectScriptClass::setProperty(QObject *obj, - const Identifier &name, +void QDeclarativeObjectScriptClass::setProperty(QObject *obj, + const Identifier &name, const QScriptValue &value, - QDeclarativeContext *evalContext) + QDeclarativeContextData *evalContext) { Q_UNUSED(name); @@ -330,7 +339,7 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj, if (!evalContext && context()) { // Global object, QScriptContext activation object, QDeclarativeContext object - QScriptValue scopeNode = scopeChainValue(context(), -3); + QScriptValue scopeNode = scopeChainValue(context(), -3); if (scopeNode.isValid()) { Q_ASSERT(scriptClass(scopeNode) == enginePriv->contextClass); @@ -338,7 +347,8 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj, } } - QDeclarativeAbstractBinding *delBinding = QDeclarativePropertyPrivate::setBinding(obj, *lastData, 0); + QDeclarativeAbstractBinding *delBinding = + QDeclarativePropertyPrivate::setBinding(obj, lastData->coreIndex, -1, 0); if (delBinding) delBinding->destroy(); @@ -392,17 +402,30 @@ QScriptValue QDeclarativeObjectScriptClass::tostring(QScriptContext *context, QS QScriptValue QDeclarativeObjectScriptClass::destroy(QScriptContext *context, QScriptEngine *engine) { - QObject* obj = context->thisObject().toQObject(); - if(obj){ - int delay = 0; - if(context->argumentCount() > 0) - delay = context->argument(0).toInt32(); - if (delay > 0) - QTimer::singleShot(delay, obj, SLOT(deleteLater())); - else - obj->deleteLater(); - } - return engine->nullValue(); + QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine); + QScriptValue that = context->thisObject(); + + if (scriptClass(that) != p->objectClass) + return engine->undefinedValue(); + + ObjectData *data = (ObjectData *)p->objectClass->object(that); + if (!data->object) + return engine->undefinedValue(); + + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(data->object, false); + if (!ddata || ddata->indestructible) + return engine->currentContext()->throwError(QLatin1String("Invalid attempt to destroy() an indestructible object")); + + QObject *obj = data->object; + int delay = 0; + if (context->argumentCount() > 0) + delay = context->argument(0).toInt32(); + if (delay > 0) + QTimer::singleShot(delay, obj, SLOT(deleteLater())); + else + obj->deleteLater(); + + return engine->undefinedValue(); } QStringList QDeclarativeObjectScriptClass::propertyNames(Object *object) @@ -428,6 +451,14 @@ QStringList QDeclarativeObjectScriptClass::propertyNames(Object *object) return cache->propertyNames(); } +bool QDeclarativeObjectScriptClass::compare(Object *o1, Object *o2) +{ + ObjectData *d1 = (ObjectData *)o1; + ObjectData *d2 = (ObjectData *)o2; + + return d1 == d2 || d1->object == d2->object; +} + #if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) struct MethodData : public QScriptDeclarativeClass::Object { @@ -438,9 +469,11 @@ struct MethodData : public QScriptDeclarativeClass::Object { }; QDeclarativeObjectMethodScriptClass::QDeclarativeObjectMethodScriptClass(QDeclarativeEngine *bindEngine) -: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), +: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine) { + qRegisterMetaType<QList<QObject *> >("QList<QObject *>"); + setSupportsCall(true); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -483,7 +516,7 @@ QScriptValue QDeclarativeObjectMethodScriptClass::connect(QScriptContext *contex } else { qScriptConnect(data->object, signal.constData(), context->argument(0), context->argument(1)); } - + return engine->undefinedValue(); } @@ -508,14 +541,15 @@ QScriptValue QDeclarativeObjectMethodScriptClass::disconnect(QScriptContext *con } else { qScriptDisconnect(data->object, signal.constData(), context->argument(0), context->argument(1)); } - + return engine->undefinedValue(); } -QScriptClass::QueryFlags -QDeclarativeObjectMethodScriptClass::queryProperty(Object *, const Identifier &name, +QScriptClass::QueryFlags +QDeclarativeObjectMethodScriptClass::queryProperty(Object *, const Identifier &name, QScriptClass::QueryFlags flags) { + Q_UNUSED(flags); if (name == m_connectId.identifier || name == m_disconnectId.identifier) return QScriptClass::HandlesReadAccess; else @@ -548,10 +582,10 @@ struct MetaCallArgument { private: MetaCallArgument(const MetaCallArgument &); - + inline void cleanup(); - char *data[16]; + void *data[4]; int type; }; } @@ -566,23 +600,25 @@ MetaCallArgument::~MetaCallArgument() cleanup(); } -void MetaCallArgument::cleanup() +void MetaCallArgument::cleanup() { if (type == QMetaType::QString) { - ((QString *)data)->~QString(); + ((QString *)&data)->~QString(); } else if (type == -1 || type == qMetaTypeId<QVariant>()) { - ((QVariant *)data)->~QVariant(); + ((QVariant *)&data)->~QVariant(); } else if (type == qMetaTypeId<QScriptValue>()) { - ((QScriptValue *)data)->~QScriptValue(); + ((QScriptValue *)&data)->~QScriptValue(); + } else if (type == qMetaTypeId<QList<QObject *> >()) { + ((QList<QObject *> *)&data)->~QList<QObject *>(); } } void *MetaCallArgument::dataPtr() { - if (type == -1) + if (type == -1) return ((QVariant *)data)->data(); else - return (void *)data; + return (void *)&data; } void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) @@ -591,9 +627,9 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) if (callType == 0) return; QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); - + if (callType == qMetaTypeId<QScriptValue>()) { - new (data) QScriptValue(engine->undefinedValue()); + new (&data) QScriptValue(engine->undefinedValue()); type = callType; } else if (callType == QMetaType::Int || callType == QMetaType::UInt || @@ -602,17 +638,20 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) callType == QMetaType::Float) { type = callType; } else if (callType == QMetaType::QObjectStar) { - *((QObject **)data) = 0; + *((QObject **)&data) = 0; type = callType; } else if (callType == QMetaType::QString) { - new (data) QString(); + new (&data) QString(); type = callType; } else if (callType == qMetaTypeId<QVariant>()) { - type = qMetaTypeId<QVariant>(); - new (data) QVariant(); + type = callType; + new (&data) QVariant(); + } else if (callType == qMetaTypeId<QList<QObject *> >()) { + type = callType; + new (&data) QList<QObject *>(); } else { type = -1; - new (data) QVariant(callType, (void *)0); + new (&data) QVariant(callType, (void *)0); } } @@ -621,47 +660,50 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, if (type != 0) { cleanup(); type = 0; } if (callType == qMetaTypeId<QScriptValue>()) { - new (data) QScriptValue(value); + new (&data) QScriptValue(value); type = qMetaTypeId<QScriptValue>(); } else if (callType == QMetaType::Int) { - *((int *)data) = int(value.toInt32()); + *((int *)&data) = int(value.toInt32()); type = callType; } else if (callType == QMetaType::UInt) { - *((uint *)data) = uint(value.toUInt32()); + *((uint *)&data) = uint(value.toUInt32()); type = callType; } else if (callType == QMetaType::Bool) { - *((bool *)data) = value.toBool(); + *((bool *)&data) = value.toBool(); type = callType; } else if (callType == QMetaType::Double) { - *((double *)data) = double(value.toNumber()); + *((double *)&data) = double(value.toNumber()); type = callType; } else if (callType == QMetaType::Float) { - *((float *)data) = float(value.toNumber()); + *((float *)&data) = float(value.toNumber()); type = callType; } else if (callType == QMetaType::QString) { if (value.isNull() || value.isUndefined()) - new (data) QString(); + new (&data) QString(); else - new (data) QString(value.toString()); + new (&data) QString(value.toString()); type = callType; } else if (callType == QMetaType::QObjectStar) { - *((QObject **)data) = value.toQObject(); + *((QObject **)&data) = value.toQObject(); type = callType; } else if (callType == qMetaTypeId<QVariant>()) { - new (data) QVariant(QDeclarativeScriptClass::toVariant(engine, value)); + new (&data) QVariant(QDeclarativeScriptClass::toVariant(engine, value)); + type = callType; + } else if (callType == qMetaTypeId<QList<QObject*> >()) { + new (&data) QList<QObject *>(); // We don't support passing in QList<QObject*> type = callType; } else { - new (data) QVariant(); + new (&data) QVariant(); type = -1; QVariant v = QDeclarativeScriptClass::toVariant(engine, value); if (v.userType() == callType) { - *((QVariant *)data) = v; + *((QVariant *)&data) = v; } else if (v.canConvert((QVariant::Type)callType)) { - *((QVariant *)data) = v; - ((QVariant *)data)->convert((QVariant::Type)callType); + *((QVariant *)&data) = v; + ((QVariant *)&data)->convert((QVariant::Type)callType); } else { - *((QVariant *)data) = QVariant(callType, (void *)0); + *((QVariant *)&data) = QVariant(callType, (void *)0); } } } @@ -669,25 +711,38 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) { QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); - + if (type == qMetaTypeId<QScriptValue>()) { - return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)data)); + return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)&data)); } else if (type == QMetaType::Int) { - return QScriptDeclarativeClass::Value(engine, *((int *)data)); + return QScriptDeclarativeClass::Value(engine, *((int *)&data)); } else if (type == QMetaType::UInt) { - return QScriptDeclarativeClass::Value(engine, *((uint *)data)); + return QScriptDeclarativeClass::Value(engine, *((uint *)&data)); } else if (type == QMetaType::Bool) { - return QScriptDeclarativeClass::Value(engine, *((bool *)data)); + return QScriptDeclarativeClass::Value(engine, *((bool *)&data)); } else if (type == QMetaType::Double) { - return QScriptDeclarativeClass::Value(engine, *((double *)data)); + return QScriptDeclarativeClass::Value(engine, *((double *)&data)); } else if (type == QMetaType::Float) { - return QScriptDeclarativeClass::Value(engine, *((float *)data)); + return QScriptDeclarativeClass::Value(engine, *((float *)&data)); } else if (type == QMetaType::QString) { - return QScriptDeclarativeClass::Value(engine, *((QString *)data)); + return QScriptDeclarativeClass::Value(engine, *((QString *)&data)); } else if (type == QMetaType::QObjectStar) { - return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->objectClass->newQObject(*((QObject **)data))); + QObject *object = *((QObject **)&data); + QDeclarativeDeclarativeData::get(object, true)->setImplicitDestructible(); + QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); + return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object)); + } else if (type == qMetaTypeId<QList<QObject *> >()) { + QList<QObject *> &list = *(QList<QObject *>*)&data; + QScriptValue rv = engine->newArray(list.count()); + QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); + for (int ii = 0; ii < list.count(); ++ii) { + QObject *object = list.at(ii); + QDeclarativeDeclarativeData::get(object, true)->setImplicitDestructible(); + rv.setProperty(ii, priv->objectClass->newQObject(object)); + } + return QScriptDeclarativeClass::Value(engine, rv); } else if (type == -1 || type == qMetaTypeId<QVariant>()) { - return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)data))); + return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)&data))); } else { return QScriptDeclarativeClass::Value(); } @@ -706,21 +761,21 @@ QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass:: // ### Cache for (int ii = 0; ii < argTypeNames.count(); ++ii) { argTypes[ii] = QMetaType::type(argTypeNames.at(ii)); - if (argTypes[ii] == QVariant::Invalid) + if (argTypes[ii] == QVariant::Invalid) return Value(ctxt, ctxt->throwError(QString::fromLatin1("Unknown method parameter type: %1").arg(QLatin1String(argTypeNames.at(ii))))); } - if (argTypes.count() > ctxt->argumentCount()) + if (argTypes.count() > ctxt->argumentCount()) return Value(ctxt, ctxt->throwError(QLatin1String("Insufficient arguments"))); QVarLengthArray<MetaCallArgument, 9> args(argTypes.count() + 1); args[0].initAsType(method->data.propType, engine); - for (int ii = 0; ii < argTypes.count(); ++ii) + for (int ii = 0; ii < argTypes.count(); ++ii) args[ii + 1].fromScriptValue(argTypes[ii], engine, ctxt->argument(ii)); QVarLengthArray<void *, 9> argData(args.count()); - for (int ii = 0; ii < args.count(); ++ii) + for (int ii = 0; ii < args.count(); ++ii) argData[ii] = args[ii].dataPtr(); QMetaObject::metacall(method->object, QMetaObject::InvokeMetaMethod, method->data.coreIndex, argData.data()); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h index 04e760f..396b782 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h @@ -57,13 +57,14 @@ #include "qdeclarativetypenamecache_p.h" #include <private/qdeclarativescriptclass_p.h> +#include <QtScript/qscriptengine.h> QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QScriptContext; class QScriptEngine; -class QDeclarativeContext; +class QDeclarativeContextData; #if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) class Q_AUTOTEST_EXPORT QDeclarativeObjectMethodScriptClass : public QScriptDeclarativeClass @@ -99,6 +100,7 @@ public: ~QDeclarativeObjectScriptClass(); QScriptValue newQObject(QObject *, int type = QMetaType::QObjectStar); + QObject *toQObject(const QScriptValue &) const; int objectType(const QScriptValue &) const; @@ -110,14 +112,15 @@ public: QScriptClass::QueryFlags queryProperty(QObject *, const Identifier &, QScriptClass::QueryFlags flags, - QDeclarativeContext *evalContext, + QDeclarativeContextData *evalContext, QueryHints hints = 0); ScriptValue property(QObject *, const Identifier &); void setProperty(QObject *, const Identifier &name, const QScriptValue &, - QDeclarativeContext *evalContext = 0); + QDeclarativeContextData *evalContext = 0); virtual QStringList propertyNames(Object *); + virtual bool compare(Object *, Object *); protected: virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp index b0599ad..51f1660 100644 --- a/src/declarative/qml/qdeclarativeparser.cpp +++ b/src/declarative/qml/qdeclarativeparser.cpp @@ -207,13 +207,14 @@ QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o) } QDeclarativeParser::Property::Property() -: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false) +: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false), + isValueTypeSubProperty(false) { } QDeclarativeParser::Property::Property(const QByteArray &n) : parent(0), type(0), index(-1), value(0), name(n), isDefault(false), - isDeferred(false) + isDeferred(false), isValueTypeSubProperty(false) { } diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 5bf4b68..9dfb86b 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -351,6 +351,8 @@ namespace QDeclarativeParser // True if the setting of this property will be deferred. Set by the // QDeclarativeCompiler bool isDeferred; + // True if this property is a value-type psuedo-property + bool isValueTypeSubProperty; LocationSpan location; LocationRange listValueRange; diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h index 01369d4..bebe82c 100644 --- a/src/declarative/qml/qdeclarativeprivate.h +++ b/src/declarative/qml/qdeclarativeprivate.h @@ -73,6 +73,9 @@ namespace QDeclarativePrivate QObject *create() { return new T; } template<typename T> + void createInto(void *memory) { new (memory) T; } + + template<typename T> QObject *createParent(QObject *p) { return new T(p); } template<class From, class To, int N> @@ -172,7 +175,8 @@ namespace QDeclarativePrivate int typeId; int listId; - QObject *(*create)(); + int objectSize; + void (*create)(void *); const char *uri; int versionMajor; diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index 945d098..caa1acf 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -124,7 +124,7 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeContext *ct : d(new QDeclarativePropertyPrivate) { d->q = this; - d->context = ctxt; + d->context = ctxt?QDeclarativeContextData::get(ctxt):0; d->engine = ctxt?ctxt->engine():0; d->initDefault(obj); } @@ -177,7 +177,7 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QD : d(new QDeclarativePropertyPrivate) { d->q = this; - d->context = ctxt; + d->context = ctxt?QDeclarativeContextData::get(ctxt):0; d->engine = ctxt?ctxt->engine():0; d->initProperty(obj, name); if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; } @@ -204,7 +204,7 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name { if (!obj) return; - QDeclarativeTypeNameCache *typeNameCache = context?QDeclarativeContextPrivate::get(context)->imports:0; + QDeclarativeTypeNameCache *typeNameCache = context?context->imports:0; QStringList path = name.split(QLatin1Char('.')); if (path.isEmpty()) return; @@ -494,15 +494,13 @@ QDeclarativeProperty &QDeclarativeProperty::operator=(const QDeclarativeProperty */ bool QDeclarativeProperty::isWritable() const { - QDeclarativeProperty::PropertyTypeCategory category = propertyTypeCategory(); - if (!d->object) return false; - if (category == List) + if (d->core.flags & QDeclarativePropertyCache::Data::IsQList) //list return true; - else if (type() & SignalProperty) + else if (d->core.flags & QDeclarativePropertyCache::Data::IsFunction) //signal handler return false; - else if (d->core.isValid() && d->object) + else if (d->core.isValid()) //normal property return d->core.flags & QDeclarativePropertyCache::Data::IsWritable; else return false; @@ -598,7 +596,6 @@ QMetaMethod QDeclarativeProperty::method() const return QMetaMethod(); } - /*! Returns the binding associated with this property, or 0 if no binding exists. @@ -617,13 +614,18 @@ QDeclarativePropertyPrivate::binding(const QDeclarativeProperty &that) return 0; QDeclarativeAbstractBinding *binding = data->bindings; - while (binding) { - // ### This wont work for value types - if (binding->propertyIndex() == that.d->core.coreIndex) - return binding; + while (binding && binding->propertyIndex() != that.d->core.coreIndex) binding = binding->m_nextBinding; + + if (binding && that.d->valueType.valueTypeCoreIdx != -1) { + if (binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) { + QDeclarativeValueTypeProxyBinding *proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(binding); + + binding = proxy->binding(bindingIndex(that)); + } } - return 0; + + return binding; } /*! @@ -650,36 +652,36 @@ QDeclarativePropertyPrivate::setBinding(const QDeclarativeProperty &that, return 0; } - return that.d->setBinding(that.d->object, that.d->core, newBinding, flags); + return that.d->setBinding(that.d->object, that.d->core.coreIndex, + that.d->valueType.valueTypeCoreIdx, newBinding, flags); } QDeclarativeAbstractBinding * -QDeclarativePropertyPrivate::setBinding(QObject *object, const QDeclarativePropertyCache::Data &core, - QDeclarativeAbstractBinding *newBinding, WriteFlags flags) +QDeclarativePropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeIndex, + QDeclarativeAbstractBinding *newBinding, WriteFlags flags) { QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, 0 != newBinding); + QDeclarativeAbstractBinding *binding = 0; - if (data && data->hasBindingBit(core.coreIndex)) { - QDeclarativeAbstractBinding *binding = data->bindings; - while (binding) { - // ### This wont work for value types - if (binding->propertyIndex() == core.coreIndex) { - binding->setEnabled(false); + if (data && data->hasBindingBit(coreIndex)) { + binding = data->bindings; - if (newBinding) - newBinding->setEnabled(true, flags); + while (binding && binding->propertyIndex() != coreIndex) + binding = binding->m_nextBinding; + } - return binding; // ### QDeclarativeAbstractBinding; - } + if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) { + int index = coreIndex | (valueTypeIndex << 24); + binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index); + } - binding = binding->m_nextBinding; - } - } + if (binding) + binding->setEnabled(false); - if (newBinding) + if (newBinding) newBinding->setEnabled(true, flags); - return 0; + return binding; } /*! @@ -922,7 +924,7 @@ bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, Writ } bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePropertyCache::Data &property, - const QVariant &value, QDeclarativeContext *context, + const QVariant &value, QDeclarativeContextData *context, WriteFlags flags) { int coreIdx = property.coreIndex; @@ -1253,6 +1255,18 @@ int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty & return that.d->valueType.valueTypeCoreIdx; } +/*! + Returns the "property index" for use in bindings. The top 8 bits are the value type + offset, and 0 otherwise. The bottom 24-bits are the regular property index. +*/ +int QDeclarativePropertyPrivate::bindingIndex(const QDeclarativeProperty &that) +{ + int rv = that.d->core.coreIndex; + if (rv != -1 && that.d->valueType.valueTypeCoreIdx != -1) + rv = rv | (that.d->valueType.valueTypeCoreIdx << 24); + return rv; +} + struct SerializedData { bool isValueType; QDeclarativePropertyCache::Data core; @@ -1291,7 +1305,7 @@ QByteArray QDeclarativePropertyPrivate::saveProperty(const QMetaObject *metaObje } QDeclarativeProperty -QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QDeclarativeContext *ctxt) +QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QDeclarativeContextData *ctxt) { QDeclarativeProperty prop; @@ -1300,7 +1314,7 @@ QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QD prop.d->object = object; prop.d->context = ctxt; - prop.d->engine = ctxt?ctxt->engine():0; + prop.d->engine = ctxt->engine; const SerializedData *sd = (const SerializedData *)data.constData(); if (sd->isValueType) { diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h index c31e2d3..1bbee64 100644 --- a/src/declarative/qml/qdeclarativeproperty_p.h +++ b/src/declarative/qml/qdeclarativeproperty_p.h @@ -82,7 +82,7 @@ public: valueType(other.valueType) {} QDeclarativeProperty *q; - QDeclarativeContext *context; + QDeclarativeContextData *context; QDeclarativeEngine *engine; QDeclarativeGuard<QObject> object; @@ -109,15 +109,15 @@ public: static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags); static bool write(QObject *, const QDeclarativePropertyCache::Data &, const QVariant &, - QDeclarativeContext *, WriteFlags flags = 0); - static QDeclarativeAbstractBinding *setBinding(QObject *, const QDeclarativePropertyCache::Data &, + QDeclarativeContextData *, WriteFlags flags = 0); + static QDeclarativeAbstractBinding *setBinding(QObject *, int coreIndex, int valueTypeIndex /* -1 */, QDeclarativeAbstractBinding *, WriteFlags flags = DontRemoveBinding); static QByteArray saveValueType(const QMetaObject *, int, const QMetaObject *, int); static QByteArray saveProperty(const QMetaObject *, int); - static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContext *); + static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContextData *); static bool equal(const QMetaObject *, const QMetaObject *); static bool canConvert(const QMetaObject *from, const QMetaObject *to); @@ -133,6 +133,7 @@ public: QDeclarativeExpression *) ; static bool write(const QDeclarativeProperty &that, const QVariant &, WriteFlags); static int valueTypeCoreIndex(const QDeclarativeProperty &that); + static int bindingIndex(const QDeclarativeProperty &that); }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyPrivate::WriteFlags) diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 68e6e6b..bfbeff4 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -55,15 +55,16 @@ #include "qdeclarativerefcount_p.h" #include "qdeclarativecleanup_p.h" +#include "qdeclarativenotifier_p.h" #include <QtCore/qvector.h> #include <QtScript/private/qscriptdeclarativeclass_p.h> - QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QMetaProperty; + class QDeclarativePropertyCache : public QDeclarativeRefCount, public QDeclarativeCleanup { public: @@ -83,9 +84,9 @@ public: IsResettable = 0x00000004, // These are mutualy exclusive - IsFunction = 0x00000008, - IsQObjectDerived = 0x00000010, - IsEnumType = 0x00000020, + IsFunction = 0x00000010, + IsQObjectDerived = 0x00000020, + IsEnumType = 0x00000040, IsQList = 0x00000080, IsQmlBinding = 0x00000100, IsQScriptValue = 0x00000200, @@ -96,7 +97,7 @@ public: }; Q_DECLARE_FLAGS(Flags, Flag) - + bool isValid() const { return coreIndex != -1; } Flags flags; @@ -114,9 +115,9 @@ public: struct ValueTypeData { inline ValueTypeData(); inline bool operator==(const ValueTypeData &); - Data::Flags flags; // flags on the value type wrapper - int valueTypeCoreIdx; // The prop index of the access property on the value type wrapper - int valueTypePropType; // The QVariant::Type of access property on the value type wrapper + Data::Flags flags; // flags of the access property on the value type proxy object + int valueTypeCoreIdx; // The prop index of the access property on the value type proxy object + int valueTypePropType; // The QVariant::Type of access property on the value type proxy object }; void update(QDeclarativeEngine *, const QMetaObject *); diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index c070123..00e6704 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -61,7 +61,7 @@ int qmlRegisterValueTypeEnums(const char *qmlName) QDeclarativePrivate::RegisterType type = { 0, - qRegisterMetaType<T *>(pointerName.constData()), 0, 0, + qRegisterMetaType<T *>(pointerName.constData()), 0, 0, 0, "Qt", 4, 6, qmlName, &T::staticMetaObject, diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp index 9cb65f8..a567c38 100644 --- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp +++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp @@ -41,6 +41,8 @@ #include "qdeclarativevaluetypescriptclass_p.h" +#include "qdeclarativebinding_p.h" +#include "qdeclarativeproperty_p.h" #include "qdeclarativeengine_p.h" #include "qdeclarativeguard_p.h" @@ -115,6 +117,11 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier { QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj); + QDeclarativeAbstractBinding *delBinding = + QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, 0); + if (delBinding) + delBinding->destroy(); + QVariant v = QDeclarativeScriptClass::toVariant(engine, value); ref->type->read(ref->object, ref->property); diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 6a08674..4457404 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -100,9 +100,8 @@ struct ListInstance QDeclarativeListProperty<void> qListProperty; }; -QObject *QDeclarativeVME::run(QDeclarativeContext *ctxt, QDeclarativeCompiledData *comp, - int start, int count, - const QBitField &bindingSkipList) +QObject *QDeclarativeVME::run(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, + int start, int count, const QBitField &bindingSkipList) { QDeclarativeVMEStack<QObject *> stack; @@ -119,7 +118,7 @@ void QDeclarativeVME::runDeferred(QObject *object) if (!data || !data->context || !data->deferredComponent) return; - QDeclarativeContext *ctxt = data->context; + QDeclarativeContextData *ctxt = data->context; QDeclarativeCompiledData *comp = data->deferredComponent; int start = data->deferredIdx + 1; int count = data->deferredComponent->bytecode.at(data->deferredIdx).defer.deferCount; @@ -129,10 +128,11 @@ void QDeclarativeVME::runDeferred(QObject *object) run(stack, ctxt, comp, start, count, QBitField()); } -QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarativeContext *ctxt, - QDeclarativeCompiledData *comp, - int start, int count, - const QBitField &bindingSkipList) +QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, + QDeclarativeContextData *ctxt, + QDeclarativeCompiledData *comp, + int start, int count, + const QBitField &bindingSkipList) { Q_ASSERT(comp); Q_ASSERT(ctxt); @@ -152,8 +152,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati QDeclarativeVMEStack<ListInstance> qliststack; vmeErrors.clear(); - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine()); - QDeclarativeContextPrivate *cp = (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); int status = -1; //for dbus QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor; @@ -169,9 +168,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati if (instr.init.parserStatusSize) parserStatus = QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus>(instr.init.parserStatusSize); if (instr.init.contextCache != -1) - cp->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache)); + ctxt->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache)); if (instr.init.compiledBinding != -1) - cp->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt); + ctxt->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt); } break; @@ -188,6 +187,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati QObject *o = types.at(instr.create.type).createInstance(ctxt, bindings); + if (!o) { if(types.at(instr.create.type).component) vmeErrors << types.at(instr.create.type).component->errors(); @@ -197,6 +197,25 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(o); Q_ASSERT(ddata); + + if (stack.isEmpty()) { + if (ddata->context) { + Q_ASSERT(ddata->context != ctxt); + Q_ASSERT(ddata->outerContext); + Q_ASSERT(ddata->outerContext != ctxt); + QDeclarativeContextData *c = ddata->context; + while (c->linkedContext) c = c->linkedContext; + c->linkedContext = ctxt; + } else { + ctxt->addObject(o); + } + + ddata->ownContext = true; + } else if (!ddata->context) { + ctxt->addObject(o); + } + + ddata->setImplicitDestructible(); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; @@ -228,25 +247,31 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati case QDeclarativeInstruction::SetId: { QObject *target = stack.top(); - cp->setIdProperty(instr.setId.index, target); + ctxt->setIdProperty(instr.setId.index, target); } break; case QDeclarativeInstruction::SetDefault: { - QObject *target = stack.top(); - ctxt->addDefaultObject(target); + ctxt->contextObject = stack.top(); } break; case QDeclarativeInstruction::CreateComponent: { - QObject *qcomp = new QDeclarativeComponent(ctxt->engine(), comp, ii + 1, instr.createComponent.count, stack.isEmpty() ? 0 : stack.top()); + QObject *qcomp = new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, + stack.isEmpty() ? 0 : stack.top()); - QDeclarativeEngine::setContextForObject(qcomp, ctxt); - QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp); + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp, true); Q_ASSERT(ddata); + + ctxt->addObject(qcomp); + + if (stack.isEmpty()) + ddata->ownContext = true; + + ddata->setImplicitDestructible(); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; @@ -553,7 +578,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati case QDeclarativeInstruction::StoreScript: { QObject *target = stack.top(); - cp->addScript(scripts.at(instr.storeScript.value), target); + ctxt->addScript(scripts.at(instr.storeScript.value), target); } break; @@ -562,7 +587,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati QObject *target = stack.top(); QObject *scope = stack.at(stack.count() - 1 - instr.storeScriptString.scope); QDeclarativeScriptString ss; - ss.setContext(ctxt); + ss.setContext(ctxt->asQDeclarativeContext()); ss.setScopeObject(scope); ss.setScript(primitives.at(instr.storeScriptString.value)); @@ -618,7 +643,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati break; QDeclarativeAbstractBinding *binding = - cp->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property); + ctxt->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property); bindValues.append(binding); binding->m_mePtr = &bindValues.values[bindValues.count - 1]; binding->addToObject(target); @@ -819,7 +844,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati if (isError()) { if (!stack.isEmpty()) { - delete stack.at(0); + delete stack.at(0); // ### What about failures in deferred creation? + } else { + ctxt->destroy(); } QDeclarativeEnginePrivate::clear(bindValues); @@ -832,11 +859,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati if (parserStatus.count) ep->parserStatus << parserStatus; - if (stack.isEmpty()) - return 0; - else - return stack.top(); - return 0; + Q_ASSERT(stack.count() == 1); + return stack.top(); } bool QDeclarativeVME::isError() const @@ -849,4 +873,25 @@ QList<QDeclarativeError> QDeclarativeVME::errors() const return vmeErrors; } +QObject * +QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData *ctxt, + const QBitField &bindings) const +{ + if (type) { + QObject *rv = 0; + void *memory = 0; + + type->create(&rv, &memory, sizeof(QDeclarativeDeclarativeData)); + QDeclarativeDeclarativeData *ddata = new (memory) QDeclarativeDeclarativeData; + ddata->ownMemory = false; + QObjectPrivate::get(rv)->declarativeData = ddata; + + return rv; + } else { + Q_ASSERT(component); + return QDeclarativeComponentPrivate::get(component)->create(ctxt, bindings); + } +} + + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h index 951f6a7..1c6fd3c 100644 --- a/src/declarative/qml/qdeclarativevme_p.h +++ b/src/declarative/qml/qdeclarativevme_p.h @@ -65,13 +65,13 @@ class QObject; class QDeclarativeInstruction; class QDeclarativeCompiledData; class QDeclarativeCompiledData; -class QDeclarativeContext; +class QDeclarativeContextData; template<typename T, int N = 128> class QDeclarativeVMEStack { public: - QDeclarativeVMEStack() : index(-1), maxSize(N), data(fixedData) {} - ~QDeclarativeVMEStack() { if (data != fixedData) qFree(fixedData); } + QDeclarativeVMEStack() : index(-1), maxSize(N), data((T *)fixedData) {} + ~QDeclarativeVMEStack() { if (data != (T *)fixedData) qFree(data); } bool isEmpty() const { return index == -1; } const T &top() const { return data[index]; } @@ -83,7 +83,7 @@ public: private: void realloc() { maxSize += N; - if (data != fixedData) { + if (data != (T *)fixedData) { data = (T*)qRealloc(data, maxSize * sizeof(T)); } else { data = (T*)qMalloc(maxSize * sizeof(T)); @@ -92,7 +92,7 @@ private: int index; int maxSize; T *data; - T fixedData[N]; + char fixedData[N * sizeof(T)]; }; class QDeclarativeVME @@ -100,7 +100,7 @@ class QDeclarativeVME public: QDeclarativeVME(); - QObject *run(QDeclarativeContext *, QDeclarativeCompiledData *, + QObject *run(QDeclarativeContextData *, QDeclarativeCompiledData *, int start = -1, int count = -1, const QBitField & = QBitField()); void runDeferred(QObject *); @@ -109,8 +109,10 @@ public: QList<QDeclarativeError> errors() const; private: - QObject *run(QDeclarativeVMEStack<QObject *> &, QDeclarativeContext *, QDeclarativeCompiledData *, - int start, int count, const QBitField &); + QObject *run(QDeclarativeVMEStack<QObject *> &, + QDeclarativeContextData *, QDeclarativeCompiledData *, + int start, int count, + const QBitField &); QList<QDeclarativeError> vmeErrors; }; diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index d67c834..f9c99ee 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -55,11 +55,11 @@ QT_BEGIN_NAMESPACE QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj, - const QMetaObject *other, - const QDeclarativeVMEMetaData *meta, - QDeclarativeCompiledData *cdata) -: object(obj), compiledData(cdata), ctxt(qmlContext(obj)), metaData(meta), methods(0), - parent(0) + const QMetaObject *other, + const QDeclarativeVMEMetaData *meta, + QDeclarativeCompiledData *cdata) +: object(obj), compiledData(cdata), ctxt(QDeclarativeDeclarativeData::get(obj)->outerContext), + metaData(meta), methods(0), parent(0) { compiledData->addref(); @@ -115,7 +115,7 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) if (type != QVariant::Invalid) { if (valueIndex != -1) { - QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine()):0; + QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine):0; QDeclarativeValueType *valueType = 0; if (ep) valueType = ep->valueTypes[type]; else valueType = QDeclarativeValueTypeFactory::valueType(type); @@ -214,16 +214,17 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) *reinterpret_cast<void **>(a[0]) = 0; if (!ctxt) return -1; - QDeclarativeContextPrivate *ctxtPriv = - (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt); - QObject *target = ctxtPriv->idValues[d->contextIdx].data(); + QDeclarativeContext *context = ctxt->asQDeclarativeContext(); + QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context); + + QObject *target = ctxtPriv->data->idValues[d->contextIdx].data(); if (!target) return -1; if (c == QMetaObject::ReadProperty && !aConnected.testBit(id)) { int sigIdx = methodOffset + id + metaData->propertyCount; - QMetaObject::connect(ctxt, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx); + QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx); if (d->propertyIdx != -1) { QMetaProperty prop = @@ -262,10 +263,10 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) id -= plainSignals; if (id < metaData->methodCount) { - if (!ctxt->engine()) + if (!ctxt->engine) return -1; // We can't run the method - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); QScriptValue function = method(id); diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h index 37c0b7a..e11f6fa 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject_p.h +++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h @@ -63,6 +63,7 @@ #include "qdeclarativeguard_p.h" #include "qdeclarativecompiler_p.h" +#include "qdeclarativecontext_p.h" QT_BEGIN_NAMESPACE @@ -121,7 +122,7 @@ protected: private: QObject *object; QDeclarativeCompiledData *compiledData; - QDeclarativeGuard<QDeclarativeContext> ctxt; + QDeclarativeGuardedContextData ctxt; const QDeclarativeVMEMetaData *metaData; int propOffset; diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp index 784353a..10c0b54 100644 --- a/src/declarative/qml/qdeclarativeworkerscript.cpp +++ b/src/declarative/qml/qdeclarativeworkerscript.cpp @@ -40,7 +40,8 @@ ****************************************************************************/ #include "qdeclarativeworkerscript_p.h" - +#include "qdeclarativelistmodel_p.h" +#include "qdeclarativelistmodelworkeragent_p.h" #include "qdeclarativeengine_p.h" #include <QtCore/qcoreevent.h> @@ -104,6 +105,7 @@ private: class QDeclarativeWorkerScriptEnginePrivate : public QObject { + Q_OBJECT public: QDeclarativeWorkerScriptEnginePrivate(QDeclarativeEngine *eng); @@ -165,87 +167,6 @@ private: void processLoad(int, const QUrl &); }; -// Currently this will leak as no-one releases it in the worker thread -class QDeclarativeWorkerListModelAgent : public QObject -{ - Q_OBJECT - Q_PROPERTY(int count READ count) - -public: - QDeclarativeWorkerListModelAgent(QDeclarativeWorkerListModel *); - ~QDeclarativeWorkerListModelAgent(); - - void addref(); - void release(); - - int count() const; - - Q_INVOKABLE void clear(); - Q_INVOKABLE void remove(int index); - Q_INVOKABLE void append(const QScriptValue &); - Q_INVOKABLE void insert(int index, const QScriptValue&); - Q_INVOKABLE QScriptValue get(int index) const; - Q_INVOKABLE void set(int index, const QScriptValue &); - Q_INVOKABLE void sync(); - - struct VariantRef - { - VariantRef() : a(0) {} - VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); } - VariantRef(QDeclarativeWorkerListModelAgent *_a) : a(_a) { if (a) a->addref(); } - ~VariantRef() { if (a) a->release(); } - - VariantRef &operator=(const VariantRef &o) { - if (o.a) o.a->addref(); - if (a) a->release(); a = o.a; - return *this; - } - - QDeclarativeWorkerListModelAgent *a; - }; -protected: - virtual bool event(QEvent *); - -private: - friend class QDeclarativeWorkerScriptEnginePrivate; - friend class QDeclarativeWorkerListModel; - QScriptEngine *m_engine; - - struct Change { - enum { Inserted, Removed, Moved, Changed } type; - int index; // Inserted/Removed/Moved/Changed - int count; // Inserted/Removed/Moved/Changed - int to; // Moved - }; - - struct Data { - QHash<int, QString> roles; - QHash<QString, int> strings; - QList<QHash<int, QVariant> > values; - QList<Change> changes; - - void clearChange(); - void insertChange(int index, int count); - void removeChange(int index, int count); - void changedChange(int index, int count); - }; - Data data; - - struct Sync : public QEvent { - Sync() : QEvent(QEvent::User) {} - Data data; - }; - - QAtomicInt m_ref; - QDeclarativeWorkerListModel *m_model; -}; - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QDeclarativeWorkerListModelAgent::VariantRef); - -QT_BEGIN_NAMESPACE - QDeclarativeWorkerScriptEnginePrivate::QDeclarativeWorkerScriptEnginePrivate(QDeclarativeEngine *engine) : workerEngine(0), qmlengine(engine), m_nextId(0) { @@ -390,10 +311,15 @@ QVariant QDeclarativeWorkerScriptEnginePrivate::scriptValueToVariant(const QScri return QVariant(list); } else if (value.isQObject()) { - QDeclarativeWorkerListModel *lm = qobject_cast<QDeclarativeWorkerListModel *>(value.toQObject()); + QDeclarativeListModel *lm = qobject_cast<QDeclarativeListModel *>(value.toQObject()); if (lm) { - QDeclarativeWorkerListModelAgent::VariantRef v(lm->agent()); - return qVariantFromValue(v); + QDeclarativeListModelWorkerAgent *agent = lm->agent(); + if (agent) { + QDeclarativeListModelWorkerAgent::VariantRef v(agent); + return qVariantFromValue(v); + } else { + return QVariant(); + } } else { // No other QObject's are allowed to be sent return QVariant(); @@ -423,11 +349,11 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::variantToScriptValue(const Q return QScriptValue(value.toString()); } else if (value.userType() == QMetaType::QReal) { return QScriptValue(value.toReal()); - } else if (value.userType() == qMetaTypeId<QDeclarativeWorkerListModelAgent::VariantRef>()) { - QDeclarativeWorkerListModelAgent::VariantRef vr = qvariant_cast<QDeclarativeWorkerListModelAgent::VariantRef>(value); - if (vr.a->m_engine == 0) - vr.a->m_engine = engine; - else if (vr.a->m_engine != engine) + } else if (value.userType() == qMetaTypeId<QDeclarativeListModelWorkerAgent::VariantRef>()) { + QDeclarativeListModelWorkerAgent::VariantRef vr = qvariant_cast<QDeclarativeListModelWorkerAgent::VariantRef>(value); + if (vr.a->scriptEngine() == 0) + vr.a->setScriptEngine(engine); + else if (vr.a->scriptEngine() != engine) return engine->nullValue(); QScriptValue o = engine->newQObject(vr.a); o.setData(engine->newVariant(value)); // Keeps the agent ref so that it is cleaned up on gc @@ -619,8 +545,6 @@ void QDeclarativeWorkerScriptEngine::run() called, triggering the \tt WorkerScript.onMessage() handler in \tt source.js. This in turn sends a reply message that is then received by the \tt onMessage() handler of \tt myWorker. - - \sa WorkerListModel */ QDeclarativeWorkerScript::QDeclarativeWorkerScript(QObject *parent) : QObject(parent), m_engine(0), m_scriptId(-1) @@ -714,544 +638,7 @@ bool QDeclarativeWorkerScript::event(QEvent *event) } } -void QDeclarativeWorkerListModelAgent::Data::clearChange() -{ - changes.clear(); -} - -void QDeclarativeWorkerListModelAgent::Data::insertChange(int index, int count) -{ - Change c = { Change::Inserted, index, count, 0 }; - changes << c; -} - -void QDeclarativeWorkerListModelAgent::Data::removeChange(int index, int count) -{ - Change c = { Change::Removed, index, count, 0 }; - changes << c; -} - -void QDeclarativeWorkerListModelAgent::Data::changedChange(int index, int count) -{ - Change c = { Change::Changed, index, count, 0 }; - changes << c; -} - -QDeclarativeWorkerListModelAgent::QDeclarativeWorkerListModelAgent(QDeclarativeWorkerListModel *m) -: m_engine(0), m_ref(1), m_model(m) -{ - data.roles = m_model->m_roles; - data.strings = m_model->m_strings; - data.values = m_model->m_values; -} - -QDeclarativeWorkerListModelAgent::~QDeclarativeWorkerListModelAgent() -{ -} - -void QDeclarativeWorkerListModelAgent::addref() -{ - m_ref.ref(); -} - -void QDeclarativeWorkerListModelAgent::release() -{ - bool del = !m_ref.deref(); - - if (del) - delete this; -} - -int QDeclarativeWorkerListModelAgent::count() const -{ - return data.values.count(); -} - -void QDeclarativeWorkerListModelAgent::clear() -{ - data.clearChange(); - data.removeChange(0, data.values.count()); - data.values.clear(); -} - -void QDeclarativeWorkerListModelAgent::remove(int index) -{ - if (data.values.count() <= index) - return; - - data.values.removeAt(index); - data.removeChange(index, 1); -} - -void QDeclarativeWorkerListModelAgent::append(const QScriptValue &value) -{ - QHash<int, QVariant> row; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash<QString, int>::Iterator iter = data.strings.find(name); - if (iter == data.strings.end()) { - int role = data.roles.count(); - data.roles.insert(role, name); - iter = data.strings.insert(name, role); - } - row.insert(*iter, v); - } - - data.values.append(row); - data.insertChange(data.values.count() - 1, 1); -} - -void QDeclarativeWorkerListModelAgent::insert(int index, const QScriptValue &value) -{ - if (index > data.values.count()) - return; - - QHash<int, QVariant> row; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash<QString, int>::Iterator iter = data.strings.find(name); - if (iter == data.strings.end()) { - int role = data.roles.count(); - data.roles.insert(role, name); - iter = data.strings.insert(name, role); - } - row.insert(*iter, v); - } - - data.values.insert(index, row); - data.insertChange(index, 1); -} - -void QDeclarativeWorkerListModelAgent::set(int index, const QScriptValue &value) -{ - if (data.values.count() <= index) - return; - - QHash<int, QVariant> row; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash<QString, int>::Iterator iter = data.strings.find(name); - if (iter == data.strings.end()) { - int role = data.roles.count(); - data.roles.insert(role, name); - iter = data.strings.insert(name, role); - } - row.insert(*iter, v); - } - - if (data.values.at(index) != row) { - data.values[index] = row; - data.changedChange(index, 1); - } -} - -QScriptValue QDeclarativeWorkerListModelAgent::get(int index) const -{ - if (data.values.count() <= index) - return m_engine->undefinedValue(); - - QScriptValue rv = m_engine->newObject(); - - QHash<int, QVariant> row = data.values.at(index); - for (QHash<int, QVariant>::ConstIterator iter = row.begin(); iter != row.end(); ++iter) - rv.setProperty(data.roles.value(iter.key()), qScriptValueFromValue(m_engine, iter.value())); - - return rv; -} - -void QDeclarativeWorkerListModelAgent::sync() -{ - Sync *s = new Sync; - s->data = data; - data.changes.clear(); - QCoreApplication::postEvent(this, s); -} - -bool QDeclarativeWorkerListModelAgent::event(QEvent *e) -{ - if (e->type() == QEvent::User) { - Sync *s = static_cast<Sync *>(e); - - const QList<Change> &changes = s->data.changes; - - if (m_model) { - bool cc = m_model->m_values.count() != s->data.values.count(); - - m_model->m_roles = s->data.roles; - m_model->m_strings = s->data.strings; - m_model->m_values = s->data.values; - - for (int ii = 0; ii < changes.count(); ++ii) { - const Change &change = changes.at(ii); - switch (change.type) { - case Change::Inserted: - emit m_model->itemsInserted(change.index, change.count); - break; - case Change::Removed: - emit m_model->itemsRemoved(change.index, change.count); - break; - case Change::Moved: - emit m_model->itemsMoved(change.index, change.to, change.count); - break; - case Change::Changed: - emit m_model->itemsMoved(change.index, change.to, change.count); - break; - } - } - - if (cc) - emit m_model->countChanged(); - } - } - - return QObject::event(e); -} - -/*! - \qmlclass WorkerListModel QDeclarativeWorkerListModel - \brief The WorkerListModel element provides a threaded list model. - - Use WorkerListModel together with WorkerScript to define a list model - that is controlled by a separate thread. This is useful if list modification - operations are synchronous and take some time: using WorkerListModel - moves these operations to a different thread and avoids blocking of the - main GUI thread. - - The thread that creates the WorkerListModel can modify the model for any - initial set-up requirements. However, once the model has been modified by - the associated WorkerScript, the model can only be modified by that worker - script and becomes read-only to all other threads. - - Here is an example application that uses WorkerScript to append the - current time to a WorkerListModel: - - \snippet examples/declarative/workerlistmodel/timedisplay.qml 0 - - The included file, \tt dataloader.js, looks like this: - - \snippet examples/declarative/workerlistmodel/dataloader.js 0 - - The application's \tt Timer object periodically sends a message to the - worker script by calling \tt WorkerScript::sendMessage(). When this message - is received, \tt WorkerScript.onMessage() is invoked in - \tt dataloader.js, which appends the current time to the worker list - model. - - Note that unlike ListModel, WorkerListModel does not have \tt move() and - \tt setProperty() methods. - - \sa WorkerScript, ListModel -*/ -QDeclarativeWorkerListModel::QDeclarativeWorkerListModel(QObject *parent) -: QListModelInterface(parent), m_agent(0) -{ -} - -QDeclarativeWorkerListModel::~QDeclarativeWorkerListModel() -{ - if (m_agent) { - m_agent->m_model = 0; - m_agent->release(); - } -} - -/*! - \qmlmethod WorkerListModel::clear() - - Deletes all content from the model. The properties are cleared such that - different properties may be set on subsequent additions. - - \sa append() remove() -*/ -void QDeclarativeWorkerListModel::clear() -{ - if (m_agent) { - qmlInfo(this) << "List can only be modified from a WorkerScript"; - return; - } - - int count = m_values.count(); - m_values.clear(); - if (count) { - emit itemsRemoved(0, count); - emit countChanged(); - } -} - -/*! - \qmlmethod WorkerListModel::remove(int index) - - Deletes the content at \a index from the model. - - \sa clear() -*/ -void QDeclarativeWorkerListModel::remove(int index) -{ - if (m_agent) { - qmlInfo(this) << "List can only be modified from a WorkerScript"; - return; - } - - if (m_values.count() <= index) - return; - - m_values.removeAt(index); - emit itemsRemoved(index, 1); - emit countChanged(); -} - -/*! - \qmlmethod WorkerListModel::append(jsobject dict) - - Adds a new item to the end of the list model, with the - values in \a dict. - - \code - FruitModel.append({"cost": 5.95, "name":"Pizza"}) - \endcode - - \sa set() remove() -*/ -void QDeclarativeWorkerListModel::append(const QScriptValue &value) -{ - if (m_agent) { - qmlInfo(this) << "List can only be modified from a WorkerScript"; - return; - } - - QHash<int, QVariant> data; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash<QString, int>::Iterator iter = m_strings.find(name); - if (iter == m_strings.end()) { - int role = m_roles.count(); - m_roles.insert(role, name); - iter = m_strings.insert(name, role); - } - data.insert(*iter, v); - } - - m_values.append(data); - - emit itemsInserted(m_values.count() - 1, 1); - emit countChanged(); -} - -/*! - \qmlmethod WorkerListModel::insert(int index, jsobject dict) - - Adds a new item to the list model at position \a index, with the - values in \a dict. - - \code - FruitModel.insert(2, {"cost": 5.95, "name":"Pizza"}) - \endcode - - The \a index must be to an existing item in the list, or one past - the end of the list (equivalent to append). - - \sa set() append() -*/ -void QDeclarativeWorkerListModel::insert(int index, const QScriptValue &value) -{ - if (m_agent) { - qmlInfo(this) << "List can only be modified from a WorkerScript"; - return; - } - - if (index > m_values.count()) - return; - - QHash<int, QVariant> data; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash<QString, int>::Iterator iter = m_strings.find(name); - if (iter == m_strings.end()) { - int role = m_roles.count(); - m_roles.insert(role, name); - iter = m_strings.insert(name, role); - } - data.insert(*iter, v); - } - - m_values.insert(index, data); - emit itemsInserted(index, 1); - emit countChanged(); -} - -/*! - \qmlmethod object ListModel::get(int index) - - Returns the item at \a index in the list model. - - \code - FruitModel.append({"cost": 5.95, "name":"Jackfruit"}) - FruitModel.get(0).cost - \endcode - - The \a index must be an element in the list. - - Note that properties of the returned object that are themselves objects - will also be models, and this get() method is used to access elements: - - \code - FruitModel.append(..., "attributes": - [{"name":"spikes","value":"7mm"}, - {"name":"color","value":"green"}]); - FruitModel.get(0).attributes.get(1).value; // == "green" - \endcode - - \sa append() -*/ -QScriptValue QDeclarativeWorkerListModel::get(int index) const -{ - QDeclarativeEngine *engine = qmlEngine(this); - if (!engine || m_values.count() <= index) - return QScriptValue(); - - QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); - QScriptValue rv = scriptEngine->newObject(); - - QHash<int, QVariant> data = m_values.at(index); - for (QHash<int, QVariant>::ConstIterator iter = data.begin(); iter != data.end(); ++iter) - rv.setProperty(m_roles.value(iter.key()), qScriptValueFromValue(scriptEngine, iter.value())); - - return rv; -} - -/*! - \qmlmethod WorkerListModel::set(int index, jsobject dict) - - Changes the item at \a index in the list model with the - values in \a dict. Properties not appearing in \a valuemap - are left unchanged. - - \code - FruitModel.set(3, {"cost": 5.95, "name":"Pizza"}) - \endcode - - The \a index must be an element in the list. - - \sa append() -*/ -void QDeclarativeWorkerListModel::set(int index, const QScriptValue &value) -{ - if (m_agent) { - qmlInfo(this) << "List can only be modified from a WorkerScript"; - return; - } - - if (m_values.count() <= index) - return; - - QHash<int, QVariant> data; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash<QString, int>::Iterator iter = m_strings.find(name); - if (iter == m_strings.end()) { - int role = m_roles.count(); - m_roles.insert(role, name); - iter = m_strings.insert(name, role); - } - data.insert(*iter, v); - } - - if (m_values.at(index) != data) { - m_values[index] = data; - emit itemsChanged(index, 1, m_roles.keys()); - } -} - -/*! - \qmlmethod WorkerListModel::sync() - - Writes any unsaved changes to the list model. This must be called after - changes have been made to the list model in the worker script. - - Note that this method can only be called from the associated worker script. -*/ -void QDeclarativeWorkerListModel::sync() -{ - // This is really a dummy method to make it look like sync() exists in - // WorkerListModel (and not QDeclarativeWorkerListModelAgent) and to let - // us document sync(). - qmlInfo(this) << "sync() can only be called from a WorkerScript"; -} - -QDeclarativeWorkerListModelAgent *QDeclarativeWorkerListModel::agent() -{ - if (!m_agent) - m_agent = new QDeclarativeWorkerListModelAgent(this); - - return m_agent; -} - -QList<int> QDeclarativeWorkerListModel::roles() const -{ - return m_roles.keys(); -} - -QString QDeclarativeWorkerListModel::toString(int role) const -{ - return m_roles.value(role); -} - -/*! - \qmlproperty int ListModel::count - The number of data entries in the model. -*/ -int QDeclarativeWorkerListModel::count() const -{ - return m_values.count(); -} - -QHash<int,QVariant> QDeclarativeWorkerListModel::data(int index, const QList<int> &) const -{ - if (m_values.count() <= index) - return QHash<int, QVariant>(); - else - return m_values.at(index); -} - -QVariant QDeclarativeWorkerListModel::data(int index, int role) const -{ - if (m_values.count() <= index) - return QVariant(); - else - return m_values.at(index).value(role); -} - QT_END_NAMESPACE -#include "qdeclarativeworkerscript.moc" +#include <qdeclarativeworkerscript.moc> diff --git a/src/declarative/qml/qdeclarativeworkerscript_p.h b/src/declarative/qml/qdeclarativeworkerscript_p.h index 912eac9..6cce799 100644 --- a/src/declarative/qml/qdeclarativeworkerscript_p.h +++ b/src/declarative/qml/qdeclarativeworkerscript_p.h @@ -55,7 +55,6 @@ #include "qdeclarative.h" #include "qdeclarativeparserstatus.h" -#include <private/qlistmodelinterface_p.h> #include <QtCore/qthread.h> #include <QtScript/qscriptvalue.h> @@ -118,49 +117,9 @@ private: QUrl m_source; }; -class QDeclarativeWorkerListModelAgent; -class Q_DECLARATIVE_EXPORT QDeclarativeWorkerListModel : public QListModelInterface -{ - Q_OBJECT - Q_PROPERTY(int count READ count NOTIFY countChanged) - -public: - QDeclarativeWorkerListModel(QObject * = 0); - virtual ~QDeclarativeWorkerListModel(); - - Q_INVOKABLE void clear(); - Q_INVOKABLE void remove(int index); - Q_INVOKABLE void append(const QScriptValue &); - Q_INVOKABLE void insert(int index, const QScriptValue&); - Q_INVOKABLE QScriptValue get(int index) const; - Q_INVOKABLE void set(int index, const QScriptValue &); - Q_INVOKABLE void sync(); - - QDeclarativeWorkerListModelAgent *agent(); - - virtual QList<int> roles() const; - virtual QString toString(int role) const; - virtual int count() const; - virtual QHash<int,QVariant> data(int index, const QList<int> &roles = (QList<int>())) const; - virtual QVariant data(int index, int role) const; - -Q_SIGNALS: - void countChanged(); - -private: - friend class QDeclarativeWorkerListModelAgent; - - QHash<int, QString> m_roles; - QHash<QString, int> m_strings; - QList<QHash<int, QVariant> > m_values; - - QDeclarativeWorkerListModelAgent *m_agent; -}; - QT_END_NAMESPACE QML_DECLARE_TYPE(QDeclarativeWorkerScript); -QML_DECLARE_TYPE(QDeclarativeWorkerListModel); QT_END_HEADER diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp index 87cab85..58e67fa 100644 --- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp +++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp @@ -1245,7 +1245,7 @@ void QDeclarativeXMLHttpRequest::finished() if (m_redirectCount < XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION) { QVariant redirect = m_network->attribute(QNetworkRequest::RedirectionTargetAttribute); if (redirect.isValid()) { - QUrl url = redirect.toUrl(); + QUrl url = m_network->url().resolved(redirect.toUrl()); destroyNetwork(); requestFromUrl(url); return; diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index aa1a34b..49888c3 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -38,6 +38,7 @@ SOURCES += \ $$PWD/qdeclarativescript.cpp \ $$PWD/qdeclarativecleanup.cpp \ $$PWD/qdeclarativepropertycache.cpp \ + $$PWD/qdeclarativenotifier.cpp \ $$PWD/qdeclarativeintegercache.cpp \ $$PWD/qdeclarativetypenamecache.cpp \ $$PWD/qdeclarativescriptstring.cpp \ @@ -108,6 +109,7 @@ HEADERS += \ $$PWD/qdeclarativewatcher_p.h \ $$PWD/qdeclarativecleanup_p.h \ $$PWD/qdeclarativepropertycache_p.h \ + $$PWD/qdeclarativenotifier_p.h \ $$PWD/qdeclarativeintegercache_p.h \ $$PWD/qdeclarativetypenamecache_p.h \ $$PWD/qdeclarativescriptstring.h \ diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 81c548b..d47dcc5 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -132,7 +132,7 @@ QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(QDeclarativeAbstrac using the \c start() and \c stop() methods. By default, animations are not running. Though, when the animations are assigned to properties, - as property value sources, they are set to running by default. + as property value sources using the \e on syntax, they are set to running by default. */ bool QDeclarativeAbstractAnimation::isRunning() const { @@ -1877,13 +1877,17 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) } /*! - \qmlproperty QEasingCurve PropertyAnimation::easing - \brief the easing curve used for the transition. + \qmlproperty enum PropertyAnimation::easing.type + \qmlproperty real PropertyAnimation::easing.amplitude + \qmlproperty real PropertyAnimation::easing.overshoot + \qmlproperty real PropertyAnimation::easing.period + \brief the easing curve used for the animation. - For the easing you can specify the following parameters: type, amplitude, period and overshoot. + To specify an easing curve you need to specify at least the type. For some curves you can also specify + amplitude, period and/or overshoot (more details provided after the table). \qml - PropertyAnimation { properties: "y"; easing.type: "InOutElastc"; easing.amplitude: 2.0; easing.period: 1.5 } + PropertyAnimation { properties: "y"; easing.type: "InOutElastic"; easing.amplitude: 2.0; easing.period: 1.5 } \endqml Available types are: @@ -2447,12 +2451,15 @@ QDeclarativeParentAnimation::QDeclarativeParentAnimation(QObject *parent) QDeclarative_setParent_noEvent(d->topLevelGroup, this); d->startAction = new QActionAnimation; + QDeclarative_setParent_noEvent(d->startAction, d->topLevelGroup); d->topLevelGroup->addAnimation(d->startAction); d->ag = new QParallelAnimationGroup; + QDeclarative_setParent_noEvent(d->ag, d->topLevelGroup); d->topLevelGroup->addAnimation(d->ag); d->endAction = new QActionAnimation; + QDeclarative_setParent_noEvent(d->endAction, d->topLevelGroup); d->topLevelGroup->addAnimation(d->endAction); } @@ -2743,4 +2750,100 @@ QAbstractAnimation *QDeclarativeParentAnimation::qtAnimation() return d->topLevelGroup; } +/*! + \qmlclass AnchorAnimation QDeclarativeAnchorAnimation + \since 4.7 + \inherits Animation + \brief The AnchorAnimation element allows you to animate anchor changes. + + AnchorAnimation will animated any changes specified by a state's AnchorChanges. + In the following snippet we animate the addition of a right anchor to our item. + \qml + Item { + id: myItem + width: 100 + } + ... + State { + AnchorChanges { + target: myItem + anchors.right: container.right + } + } + ... + Transition { + //smoothly reanchor myItem and move into new position + AnchorAnimation {} + } + \endqml + + \sa AnchorChanges +*/ + +QDeclarativeAnchorAnimation::QDeclarativeAnchorAnimation(QObject *parent) +: QDeclarativeAbstractAnimation(*(new QDeclarativeAnchorAnimationPrivate), parent) +{ + Q_D(QDeclarativeAnchorAnimation); + d->va = new QDeclarativeBulkValueAnimator; + QDeclarative_setParent_noEvent(d->va, this); +} + +QDeclarativeAnchorAnimation::~QDeclarativeAnchorAnimation() +{ +} + +QAbstractAnimation *QDeclarativeAnchorAnimation::qtAnimation() +{ + Q_D(QDeclarativeAnchorAnimation); + return d->va; +} + +/*! + \qmlproperty list<Item> AnchorAnimation::targets + The items to reanchor. + + If no targets are specified all AnchorChanges will be + animated by the AnchorAnimation. +*/ +QDeclarativeListProperty<QDeclarativeItem> QDeclarativeAnchorAnimation::targets() +{ + Q_D(QDeclarativeAnchorAnimation); + return QDeclarativeListProperty<QDeclarativeItem>(this, d->targets); +} + +void QDeclarativeAnchorAnimation::transition(QDeclarativeStateActions &actions, + QDeclarativeProperties &modified, + TransitionDirection direction) +{ + Q_UNUSED(modified); + Q_D(QDeclarativeAnchorAnimation); + PropertyUpdater *data = new PropertyUpdater; + data->interpolatorType = QMetaType::QReal; + data->interpolator = d->interpolator; + + data->reverse = direction == Backward ? true : false; + data->fromSourced = false; + data->fromDefined = false; + + for (int ii = 0; ii < actions.count(); ++ii) { + QDeclarativeAction &action = actions[ii]; + if (action.event && action.event->typeName() == QLatin1String("AnchorChanges") + && (d->targets.isEmpty() || d->targets.contains(static_cast<QDeclarativeAnchorChanges*>(action.event)->object()))) { + data->actions << static_cast<QDeclarativeAnchorChanges*>(action.event)->additionalActions(); + } + } + + if (data->actions.count()) { + if (!d->rangeIsSet) { + d->va->setStartValue(qreal(0)); + d->va->setEndValue(qreal(1)); + d->rangeIsSet = true; + } + d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped); + d->va->setFromSourcedValue(&data->fromSourced); + } else { + delete data; + } +} + QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index af48309..eb339f6 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -480,6 +480,26 @@ protected: virtual QAbstractAnimation *qtAnimation(); }; +class QDeclarativeAnchorAnimationPrivate; +class QDeclarativeAnchorAnimation : public QDeclarativeAbstractAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QDeclarativeAnchorAnimation) + Q_PROPERTY(QDeclarativeListProperty<QDeclarativeItem> targets READ targets) + +public: + QDeclarativeAnchorAnimation(QObject *parent=0); + virtual ~QDeclarativeAnchorAnimation(); + + QDeclarativeListProperty<QDeclarativeItem> targets(); + +protected: + virtual void transition(QDeclarativeStateActions &actions, + QDeclarativeProperties &modified, + TransitionDirection direction); + virtual QAbstractAnimation *qtAnimation(); +}; + QT_END_NAMESPACE QML_DECLARE_TYPE(QDeclarativeAbstractAnimation) @@ -495,6 +515,7 @@ QML_DECLARE_TYPE(QDeclarativeParallelAnimation) QML_DECLARE_TYPE(QDeclarativeVector3dAnimation) QML_DECLARE_TYPE(QDeclarativeRotationAnimation) QML_DECLARE_TYPE(QDeclarativeParentAnimation) +QML_DECLARE_TYPE(QDeclarativeAnchorAnimation) QT_END_HEADER diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index ae82a90..0460312 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -393,6 +393,19 @@ public: QPointF computeTransformOrigin(QDeclarativeItem::TransformOrigin origin, qreal width, qreal height) const; }; +class QDeclarativeAnchorAnimationPrivate : public QDeclarativeAbstractAnimationPrivate +{ + Q_DECLARE_PUBLIC(QDeclarativeAnchorAnimation) +public: + QDeclarativeAnchorAnimationPrivate() : rangeIsSet(false), va(0), + interpolator(QVariantAnimationPrivate::getInterpolator(QMetaType::QReal)) {} + + bool rangeIsSet; + QDeclarativeBulkValueAnimator *va; + QVariantAnimation::Interpolator interpolator; + QList<QDeclarativeItem*> targets; +}; + QT_END_NAMESPACE #endif // QDECLARATIVEANIMATION_P_H diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp index 8f5f537..bf98d40 100644 --- a/src/declarative/util/qdeclarativefontloader.cpp +++ b/src/declarative/util/qdeclarativefontloader.cpp @@ -61,7 +61,7 @@ class QDeclarativeFontLoaderPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QDeclarativeFontLoader) public: - QDeclarativeFontLoaderPrivate() : reply(0), status(QDeclarativeFontLoader::Null) {} + QDeclarativeFontLoaderPrivate() : reply(0), status(QDeclarativeFontLoader::Null), redirectCount(0) {} void addFontToDatabase(const QByteArray &); @@ -69,6 +69,7 @@ public: QString name; QNetworkReply *reply; QDeclarativeFontLoader::Status status; + int redirectCount; }; @@ -206,15 +207,31 @@ QDeclarativeFontLoader::Status QDeclarativeFontLoader::status() const return d->status; } +#define FONTLOADER_MAXIMUM_REDIRECT_RECURSION 16 + void QDeclarativeFontLoader::replyFinished() { Q_D(QDeclarativeFontLoader); if (d->reply) { + d->redirectCount++; + if (d->redirectCount < FONTLOADER_MAXIMUM_REDIRECT_RECURSION) { + QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = d->reply->url().resolved(redirect.toUrl()); + d->reply->deleteLater(); + d->reply = 0; + setSource(url); + return; + } + } + d->redirectCount=0; + if (!d->reply->error()) { QByteArray ba = d->reply->readAll(); d->addFontToDatabase(ba); } else { d->status = Error; + qWarning() << "Cannot load font:" << d->reply->url(); emit statusChanged(); } d->reply->deleteLater(); diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index b968ca5..340e9ac 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#include "qdeclarativelistmodel_p.h" - +#include "qdeclarativelistmodel_p_p.h" +#include "qdeclarativelistmodelworkeragent_p.h" #include "qdeclarativeopenmetaobject_p.h" #include <qdeclarativecustomparser_p.h> @@ -66,8 +66,6 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM return (QDeclarativeListModelParser::ListInstruction *)((char *)this + sizeof(ListModelData)); } -static void dump(ModelNode *node, int ind); - /*! \qmlclass ListModel QDeclarativeListModel \since 4.7 @@ -96,9 +94,12 @@ static void dump(ModelNode *node, int ind); } \endcode - Roles (properties) must begin with a lower-case letter. The above example defines a + Roles (properties) must begin with a lower-case letter.The above example defines a ListModel containing three elements, with the roles "name" and "cost". + Values must be simple constants - either strings (quoted), bools (true, false), numbers, + or enum values (like Text.AlignHCenter). + The defined model can be used in views such as ListView: \code Component { @@ -169,6 +170,8 @@ static void dump(ModelNode *node, int ind); } \endcode + \section2 Modifying list models + The content of a ListModel may be created and modified using the clear(), append(), and set() methods. For example: @@ -193,252 +196,146 @@ static void dump(ModelNode *node, int ind); except by first clearing the model - whatever properties are first added are then the only permitted properties in the model. - \sa {qmlmodels}{Data Models} -*/ -class ModelObject : public QObject -{ - Q_OBJECT -public: - ModelObject(); + \section2 Using threaded list models with WorkerScript - void setValue(const QByteArray &name, const QVariant &val) - { - _mo->setValue(name, val); - } + ListModel can be used together with WorkerScript access a list model + from multiple threads. This is useful if list modifications are + synchronous and take some time: the list operations can be moved to a + different thread to avoid blocking of the main GUI thread. -private: - QDeclarativeOpenMetaObject *_mo; -}; + Here is an example that uses WorkerScript to periodically append the + current time to a list model: -struct ModelNode -{ - ModelNode(); - ~ModelNode(); + \snippet examples/declarative/listmodel-threaded/timedisplay.qml 0 - QList<QVariant> values; - QHash<QString, ModelNode *> properties; + The included file, \tt dataloader.js, looks like this: - QDeclarativeListModel *model(const QDeclarativeListModel *parent) { - if (!modelCache) { - modelCache = new QDeclarativeListModel; - QDeclarativeEngine::setContextForObject(modelCache,QDeclarativeEngine::contextForObject(parent)); + \snippet examples/declarative/listmodel-threaded/dataloader.js 0 - modelCache->_root = this; - } - return modelCache; - } + The application's \tt Timer object periodically sends a message to the + worker script by calling \tt WorkerScript::sendMessage(). When this message + is received, \tt WorkerScript.onMessage() is invoked in + \tt dataloader.js, which appends the current time to the list model. - ModelObject *object(const QDeclarativeListModel *parent) { - if (!objectCache) { - objectCache = new ModelObject(); - QHash<QString, ModelNode *>::iterator it; - for (it = properties.begin(); it != properties.end(); ++it) { - objectCache->setValue(it.key().toUtf8(), parent->valueForNode(*it)); - } - } - return objectCache; - } + Note the call to sync() from the \c WorkerScript.onMessage() handler. + Without this call, the changes made to the list are not reflected in the + list model in the main thread. - void setObjectValue(const QScriptValue& valuemap); - void setListValue(const QScriptValue& valuelist); + \section3 Limitations - void setProperty(const QString& prop, const QVariant& val) { - QHash<QString, ModelNode *>::const_iterator it = properties.find(prop); - if (it != properties.end()) { - (*it)->values[0] = val; - } else { - ModelNode *n = new ModelNode; - n->values << val; - properties.insert(prop,n); - } - if (objectCache) - objectCache->setValue(prop.toUtf8(), val); - } - - QDeclarativeListModel *modelCache; - ModelObject *objectCache; - bool isArray; -}; - -QT_END_NAMESPACE + If a list model is to be accessed from a WorkerScript, it \bold cannot + contain nested list data. So, the following model cannot be used from a WorkerScript + because of the list contained in the "attributes" property: -Q_DECLARE_METATYPE(ModelNode *) - -QT_BEGIN_NAMESPACE - -void ModelNode::setObjectValue(const QScriptValue& valuemap) { - QScriptValueIterator it(valuemap); - while (it.hasNext()) { - it.next(); - ModelNode *value = new ModelNode; - QScriptValue v = it.value(); - if (v.isArray()) { - value->isArray = true; - value->setListValue(v); - } else { - value->values << v.toVariant(); + \code + ListModel { + id: fruitModel + ListElement { + name: "Apple" + cost: 2.45 + attributes: [ + ListElement { description: "Core" }, + ListElement { description: "Deciduous" } + ] } - properties.insert(it.name(),value); } -} + \endcode -void ModelNode::setListValue(const QScriptValue& valuelist) { - int size = valuelist.property(QString::fromLatin1("length")).toInt32(); - values.clear(); - for (int i = 0; i < size; ++i) { - ModelNode *value = new ModelNode; - QScriptValue v = valuelist.property(i); - if (v.isArray()) { - value->isArray = true; - value->setListValue(v); - } else if (v.isObject()) { - value->setObjectValue(v); - } else { - value->values << v.toVariant(); - } - values.append(qVariantFromValue(value)); + In addition, the WorkerScript cannot add any nested list data to the model. - } -} + \sa {qmlmodels}{Data Models}, WorkerScript +*/ -ModelObject::ModelObject() -: _mo(new QDeclarativeOpenMetaObject(this)) +QDeclarativeListModel::QDeclarativeListModel(QObject *parent) +: QListModelInterface(parent), m_agent(0), m_nested(new NestedListModel(this)), m_flat(0), m_isWorkerCopy(false) { } -QDeclarativeListModel::QDeclarativeListModel(QObject *parent) -: QListModelInterface(parent), _rolesOk(false), _root(0) +QDeclarativeListModel::QDeclarativeListModel(bool workerCopy, QObject *parent) +: QListModelInterface(parent), m_agent(0), m_nested(0), m_flat(0), m_isWorkerCopy(workerCopy) { + if (workerCopy) + m_flat = new FlatListModel(this); + else + m_nested = new NestedListModel(this); } QDeclarativeListModel::~QDeclarativeListModel() { - delete _root; + delete m_nested; + delete m_flat; } -void QDeclarativeListModel::checkRoles() const +bool QDeclarativeListModel::flatten() { - if (_rolesOk || !_root) - return; + if (m_flat) + return true; - for (int ii = 0; ii < _root->values.count(); ++ii) { - ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(ii)); - if (node) { - foreach (const QString &role, node->properties.keys()) - addRole(role); - } + QList<int> roles = m_nested->roles(); + + QList<QHash<int, QVariant> > values; + bool hasNested = false; + for (int i=0; i<m_nested->count(); i++) { + values.append(m_nested->data(i, roles, &hasNested)); + if (hasNested) + return false; } - _rolesOk = true; + FlatListModel *flat = new FlatListModel(this); + flat->m_values = values; + + for (int i=0; i<roles.count(); i++) { + QString s = m_nested->toString(roles[i]); + flat->m_roles.insert(roles[i], s); + flat->m_strings.insert(s, roles[i]); + } + + m_flat = flat; + delete m_nested; + m_nested = 0; + return true; } -void QDeclarativeListModel::addRole(const QString &role) const +QDeclarativeListModelWorkerAgent *QDeclarativeListModel::agent() { - if (!roleStrings.contains(role)) - roleStrings << role; + if (m_agent) + return m_agent; + + if (!flatten()) { + qmlInfo(this) << "List contains nested list values and cannot be used from a worker script"; + return 0; + } + + m_agent = new QDeclarativeListModelWorkerAgent(this); + return m_agent; } QList<int> QDeclarativeListModel::roles() const { - checkRoles(); - QList<int> rv; - for (int ii = 0; ii < roleStrings.count(); ++ii) - rv << ii; - return rv; + return m_flat ? m_flat->roles() : m_nested->roles(); } QString QDeclarativeListModel::toString(int role) const { - checkRoles(); - if (role < roleStrings.count()) - return roleStrings.at(role); - else - return QString(); -} - -QVariant QDeclarativeListModel::valueForNode(ModelNode *node) const -{ - QObject *rv = 0; - - if (node->isArray) { - // List - rv = node->model(this); - } else { - if (!node->properties.isEmpty()) { - // Object - rv = node->object(this); - } else if (node->values.count() == 0) { - // Invalid - return QVariant(); - } else if (node->values.count() == 1) { - // Value - QVariant &var = node->values[0]; - ModelNode *valueNode = qvariant_cast<ModelNode *>(var); - if (valueNode) { - if (!valueNode->properties.isEmpty()) - rv = valueNode->object(this); - else - rv = valueNode->model(this); - } else { - return var; - } - } - } - - if (rv) - return QVariant::fromValue(rv); - else - return QVariant(); + return m_flat ? m_flat->toString(role) : m_nested->toString(role); } QHash<int,QVariant> QDeclarativeListModel::data(int index, const QList<int> &roles) const { - checkRoles(); - QHash<int, QVariant> rv; if (index >= count() || index < 0) - return rv; + return QHash<int, QVariant>(); - ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); - if (!node) - return rv; - - for (int ii = 0; ii < roles.count(); ++ii) { - const QString &roleString = roleStrings.at(roles.at(ii)); - - QHash<QString, ModelNode *>::ConstIterator iter = - node->properties.find(roleString); - if (iter != node->properties.end()) { - ModelNode *row = *iter; - rv.insert(roles.at(ii), valueForNode(row)); - } - } - - return rv; + return m_flat ? m_flat->data(index, roles) : m_nested->data(index, roles); } QVariant QDeclarativeListModel::data(int index, int role) const { - checkRoles(); - QVariant rv; if (index >= count() || index < 0) - return rv; - - ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); - if (!node) - return rv; - - const QString &roleString = roleStrings.at(role); - - QHash<QString, ModelNode *>::ConstIterator iter = - node->properties.find(roleString); - if (iter != node->properties.end()) { - ModelNode *row = *iter; - rv = valueForNode(row); - } + return QVariant(); - return rv; + return m_flat ? m_flat->data(index, role) : m_nested->data(index, role); } /*! @@ -447,8 +344,7 @@ QVariant QDeclarativeListModel::data(int index, int role) const */ int QDeclarativeListModel::count() const { - if (!_root) return 0; - return _root->values.count(); + return m_flat ? m_flat->count() : m_nested->count(); } /*! @@ -462,12 +358,15 @@ int QDeclarativeListModel::count() const void QDeclarativeListModel::clear() { int cleared = count(); - _rolesOk = false; - delete _root; - _root = 0; - roleStrings.clear(); - emit itemsRemoved(0,cleared); - emit countChanged(0); + if (m_flat) + m_flat->clear(); + else + m_nested->clear(); + + if (!m_isWorkerCopy) { + emit itemsRemoved(0, cleared); + emit countChanged(0); + } } /*! @@ -479,17 +378,20 @@ void QDeclarativeListModel::clear() */ void QDeclarativeListModel::remove(int index) { - if (!_root || index < 0 || index >= _root->values.count()) { + if (index < 0 || index >= count()) { qmlInfo(this) << tr("remove: index %1 out of range").arg(index); return; } - ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); - _root->values.removeAt(index); - if (node) - delete node; - emit itemsRemoved(index,1); - emit countChanged(_root->values.count()); + if (m_flat) + m_flat->remove(index); + else + m_nested->remove(index); + + if (!m_isWorkerCopy) { + emit itemsRemoved(index, 1); + emit countChanged(this->count()); + } } /*! @@ -513,20 +415,17 @@ void QDeclarativeListModel::insert(int index, const QScriptValue& valuemap) qmlInfo(this) << tr("insert: value is not an object"); return; } - if (!_root) - _root = new ModelNode; - if (index >= _root->values.count() || index<0) { - if (index == _root->values.count()) - append(valuemap); - else - qmlInfo(this) << tr("insert: index %1 out of range").arg(index); + + if (index < 0 || index > count()) { + qmlInfo(this) << tr("insert: index %1 out of range").arg(index); return; } - ModelNode *mn = new ModelNode; - mn->setObjectValue(valuemap); - _root->values.insert(index,qVariantFromValue(mn)); - emit itemsInserted(index,1); - emit countChanged(_root->values.count()); + + bool ok = m_flat ? m_flat->insert(index, valuemap) : m_nested->insert(index, valuemap); + if (ok && !m_isWorkerCopy) { + emit itemsInserted(index, 1); + emit countChanged(this->count()); + } } /*! @@ -551,9 +450,10 @@ void QDeclarativeListModel::move(int from, int to, int n) qmlInfo(this) << tr("move: out of range"); return; } - int origfrom=from; // preserve actual move, so any animations are correct - int origto=to; - int orign=n; + + int origfrom = from; + int origto = to; + int orign = n; if (from > to) { // Only move forwards - flip if backwards moving int tfrom = from; @@ -562,24 +462,14 @@ void QDeclarativeListModel::move(int from, int to, int n) to = tto+n; n = tfrom-tto; } - if (n==1) { - _root->values.move(from,to); - } else { - QList<QVariant> replaced; - int i=0; - QVariantList::const_iterator it=_root->values.begin(); it += from+n; - for (; i<to-from; ++i,++it) - replaced.append(*it); - i=0; - it=_root->values.begin(); it += from; - for (; i<n; ++i,++it) - replaced.append(*it); - QVariantList::const_iterator f=replaced.begin(); - QVariantList::iterator t=_root->values.begin(); t += from; - for (; f != replaced.end(); ++f, ++t) - *t = *f; - } - emit itemsMoved(origfrom,origto,orign); + + if (m_flat) + m_flat->move(from, to, n); + else + m_nested->move(from, to, n); + + if (!m_isWorkerCopy) + emit itemsMoved(origfrom, origto, orign); } /*! @@ -600,13 +490,8 @@ void QDeclarativeListModel::append(const QScriptValue& valuemap) qmlInfo(this) << tr("append: value is not an object"); return; } - if (!_root) - _root = new ModelNode; - ModelNode *mn = new ModelNode; - mn->setObjectValue(valuemap); - _root->values << qVariantFromValue(mn); - emit itemsInserted(count()-1,1); - emit countChanged(_root->values.count()); + + insert(count(), valuemap); } /*! @@ -640,15 +525,7 @@ QScriptValue QDeclarativeListModel::get(int index) const return 0; } - ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); - if (!node) - return 0; - QDeclarativeEngine *eng = qmlEngine(this); - if (!eng) { - qWarning("Cannot call QDeclarativeListModel::get() without a QDeclarativeEngine"); - return 0; - } - return QDeclarativeEnginePrivate::qmlScriptObject(node->object(this), eng); + return m_flat ? m_flat->get(index) : m_nested->get(index); } /*! @@ -672,27 +549,22 @@ void QDeclarativeListModel::set(int index, const QScriptValue& valuemap) qmlInfo(this) << tr("set: value is not an object"); return; } - if ( !_root || index > _root->values.count() || index < 0) { + if (count() == 0 || index > count() || index < 0) { qmlInfo(this) << tr("set: index %1 out of range").arg(index); return; } - if (index == _root->values.count()) + + if (index == count()) { append(valuemap); - else { - ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); + } else { QList<int> roles; - node->setObjectValue(valuemap); - QScriptValueIterator it(valuemap); - while (it.hasNext()) { - it.next(); - int r = roleStrings.indexOf(it.name()); - if (r<0) { - r = roleStrings.count(); - roleStrings << it.name(); - } - roles.append(r); - } - emit itemsChanged(index,1,roles); + if (m_flat) + m_flat->set(index, valuemap, &roles); + else + m_nested->set(index, valuemap, &roles); + + if (!m_isWorkerCopy) + emit itemsChanged(index, 1, roles); } } @@ -711,22 +583,33 @@ void QDeclarativeListModel::set(int index, const QScriptValue& valuemap) */ void QDeclarativeListModel::setProperty(int index, const QString& property, const QVariant& value) { - if ( !_root || index >= _root->values.count() || index < 0) { + if (count() == 0 || index >= count() || index < 0) { qmlInfo(this) << tr("set: index %1 out of range").arg(index); return; } - ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); - int r = roleStrings.indexOf(property); - if (r<0) { - r = roleStrings.count(); - roleStrings << property; - } + QList<int> roles; - roles.append(r); + if (m_flat) + m_flat->setProperty(index, property, value, &roles); + else + m_nested->setProperty(index, property, value, &roles); - if (node) - node->setProperty(property,value); - emit itemsChanged(index,1,roles); + if (!m_isWorkerCopy) + emit itemsChanged(index, 1, roles); +} + +/*! + \qmlmethod ListModel::sync() + + Writes any unsaved changes to the list model after it has been modified + from a worker script. +*/ +void QDeclarativeListModel::sync() +{ + // This is just a dummy method to make it look like sync() exists in + // ListModel (and not just QDeclarativeListModelWorkerAgent) and to let + // us document sync(). + qmlInfo(this) << "List sync() can only be called from a WorkerScript"; } bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data) @@ -736,7 +619,7 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser const QVariant &value = values.at(ii); if(value.userType() == qMetaTypeId<QDeclarativeCustomParserNode>()) { - QDeclarativeCustomParserNode node = + QDeclarativeCustomParserNode node = qvariant_cast<QDeclarativeCustomParserNode>(value); { @@ -783,7 +666,7 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser } else { - QDeclarativeParser::Variant variant = + QDeclarativeParser::Variant variant = qvariant_cast<QDeclarativeParser::Variant>(value); int ref = data.count(); @@ -798,10 +681,17 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser d += char(variant.asBoolean()); } else if (variant.isScript()) { if (definesEmptyList(variant.asScript())) { - d[0] = 0; // QDeclarativeParser::Variant::Invalid - marks empty list + d[0] = char(QDeclarativeParser::Variant::Invalid); // marks empty list } else { - error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value")); - return false; + QByteArray script = variant.asScript().toUtf8(); + int v = evaluateEnum(script); + if (v<0) { + error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value")); + return false; + } else { + d[0] = char(QDeclarativeParser::Variant::Number); + d += QByteArray::number(v); + } } } d.append('\0'); @@ -834,15 +724,15 @@ QByteArray QDeclarativeListModelParser::compile(const QList<QDeclarativeCustomPa } } - int size = sizeof(ListModelData) + - instr.count() * sizeof(ListInstruction) + + int size = sizeof(ListModelData) + + instr.count() * sizeof(ListInstruction) + data.count(); QByteArray rv; rv.resize(size); ListModelData *lmd = (ListModelData *)rv.data(); - lmd->dataOffset = sizeof(ListModelData) + + lmd->dataOffset = sizeof(ListModelData) + instr.count() * sizeof(ListInstruction); lmd->instrCount = instr.count(); for (int ii = 0; ii < instr.count(); ++ii) @@ -857,7 +747,7 @@ void QDeclarativeListModelParser::setCustomData(QObject *obj, const QByteArray & QDeclarativeListModel *rv = static_cast<QDeclarativeListModel *>(obj); ModelNode *root = new ModelNode; - rv->_root = root; + rv->m_nested->_root = root; QStack<ModelNode *> nodes; nodes << root; @@ -942,7 +832,490 @@ bool QDeclarativeListModelParser::definesEmptyList(const QString &s) \sa ListModel */ -static void dump(ModelNode *node, int ind) +FlatListModel::FlatListModel(QDeclarativeListModel *base) + : m_scriptEngine(0), m_listModel(base) +{ +} + +FlatListModel::~FlatListModel() +{ +} + +QHash<int,QVariant> FlatListModel::data(int index, const QList<int> &roles) const +{ + Q_ASSERT(index >= 0 && index < m_values.count()); + + QHash<int, QVariant> row; + for (int i=0; i<roles.count(); i++) { + int role = roles[i]; + if (m_values[index].contains(role)) + row.insert(role, m_values[index][role]); + } + return row; +} + +QVariant FlatListModel::data(int index, int role) const +{ + Q_ASSERT(index >= 0 && index < m_values.count()); + if (m_values[index].contains(role)) + return m_values[index][role]; + return QVariant(); +} + +QList<int> FlatListModel::roles() const +{ + return m_roles.keys(); +} + +QString FlatListModel::toString(int role) const +{ + if (m_roles.contains(role)) + return m_roles[role]; + return QString(); +} + +int FlatListModel::count() const +{ + return m_values.count(); +} + +void FlatListModel::clear() +{ + m_values.clear(); +} + +void FlatListModel::remove(int index) +{ + m_values.removeAt(index); +} + +bool FlatListModel::append(const QScriptValue &value) +{ + return insert(m_values.count(), value); +} + +bool FlatListModel::insert(int index, const QScriptValue &value) +{ + Q_ASSERT(index >= 0 && index <= m_values.count()); + + QHash<int, QVariant> row; + if (!addValue(value, &row, 0)) + return false; + + m_values.insert(index, row); + return true; +} + +QScriptValue FlatListModel::get(int index) const +{ + Q_ASSERT(index >= 0 && index < m_values.count()); + + QScriptEngine *scriptEngine = m_scriptEngine ? m_scriptEngine : QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(m_listModel)); + + if (!scriptEngine) + return 0; + + QScriptValue rv = scriptEngine->newObject(); + + QHash<int, QVariant> row = m_values.at(index); + for (QHash<int, QVariant>::ConstIterator iter = row.begin(); iter != row.end(); ++iter) + rv.setProperty(m_roles.value(iter.key()), qScriptValueFromValue(scriptEngine, iter.value())); + + return rv; +} + +void FlatListModel::set(int index, const QScriptValue &value, QList<int> *roles) +{ + Q_ASSERT(index >= 0 && index < m_values.count()); + + QHash<int, QVariant> row = m_values[index]; + if (addValue(value, &row, roles)) + m_values[index] = row; +} + +void FlatListModel::setProperty(int index, const QString& property, const QVariant& value, QList<int> *roles) +{ + Q_ASSERT(index >= 0 && index < m_values.count()); + + QHash<QString, int>::Iterator iter = m_strings.find(property); + int role; + if (iter == m_strings.end()) { + role = m_roles.count(); + m_roles.insert(role, property); + m_strings.insert(property, role); + } else { + role = iter.value(); + } + roles->append(role); + + m_values[index][role] = value; +} + +void FlatListModel::move(int from, int to, int n) +{ + if (n == 1) { + m_values.move(from, to); + } else { + QList<QHash<int, QVariant> > replaced; + int i=0; + QList<QHash<int, QVariant> >::ConstIterator it=m_values.begin(); it += from+n; + for (; i<to-from; ++i,++it) + replaced.append(*it); + i=0; + it=m_values.begin(); it += from; + for (; i<n; ++i,++it) + replaced.append(*it); + QList<QHash<int, QVariant> >::ConstIterator f=replaced.begin(); + QList<QHash<int, QVariant> >::Iterator t=m_values.begin(); t += from; + for (; f != replaced.end(); ++f, ++t) + *t = *f; + } +} + +bool FlatListModel::addValue(const QScriptValue &value, QHash<int, QVariant> *row, QList<int> *roles) +{ + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + if (it.value().isObject()) { + qmlInfo(m_listModel) << "Cannot add nested list values when modifying or after modification from a worker script"; + return false; + } + + QString name = it.name(); + QVariant v = it.value().toVariant(); + + QHash<QString, int>::Iterator iter = m_strings.find(name); + if (iter == m_strings.end()) { + int role = m_roles.count(); + m_roles.insert(role, name); + iter = m_strings.insert(name, role); + if (roles) + roles->append(role); + } + row->insert(*iter, v); + } + return true; +} + +NestedListModel::NestedListModel(QDeclarativeListModel *base) + : _root(0), m_listModel(base), _rolesOk(false) +{ +} + +NestedListModel::~NestedListModel() +{ + delete _root; +} + +QVariant NestedListModel::valueForNode(ModelNode *node, bool *hasNested) const +{ + QObject *rv = 0; + if (hasNested) + *hasNested = false; + + if (node->isArray) { + // List + rv = node->model(this); + if (hasNested) + *hasNested = true; + } else { + if (!node->properties.isEmpty()) { + // Object + rv = node->object(this); + } else if (node->values.count() == 0) { + // Invalid + return QVariant(); + } else if (node->values.count() == 1) { + // Value + QVariant &var = node->values[0]; + ModelNode *valueNode = qvariant_cast<ModelNode *>(var); + if (valueNode) { + if (!valueNode->properties.isEmpty()) + rv = valueNode->object(this); + else + rv = valueNode->model(this); + } else { + return var; + } + } + } + + if (rv) { + return QVariant::fromValue(rv); + } else { + return QVariant(); + } +} + +QHash<int,QVariant> NestedListModel::data(int index, const QList<int> &roles, bool *hasNested) const +{ + Q_ASSERT(_root && index >= 0 && index < _root->values.count()); + checkRoles(); + QHash<int, QVariant> rv; + + ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); + if (!node) + return rv; + + for (int ii = 0; ii < roles.count(); ++ii) { + const QString &roleString = roleStrings.at(roles.at(ii)); + + QHash<QString, ModelNode *>::ConstIterator iter = node->properties.find(roleString); + if (iter != node->properties.end()) { + ModelNode *row = *iter; + rv.insert(roles.at(ii), valueForNode(row, hasNested)); + } + } + + return rv; +} + +QVariant NestedListModel::data(int index, int role) const +{ + Q_ASSERT(_root && index >= 0 && index < _root->values.count()); + checkRoles(); + QVariant rv; + + ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); + if (!node) + return rv; + + const QString &roleString = roleStrings.at(role); + + QHash<QString, ModelNode *>::ConstIterator iter = node->properties.find(roleString); + if (iter != node->properties.end()) { + ModelNode *row = *iter; + rv = valueForNode(row); + } + + return rv; +} + +int NestedListModel::count() const +{ + if (!_root) return 0; + return _root->values.count(); +} + +void NestedListModel::clear() +{ + _rolesOk = false; + roleStrings.clear(); + + delete _root; + _root = 0; +} + +void NestedListModel::remove(int index) +{ + if (!_root) + return; + ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); + _root->values.removeAt(index); + if (node) + delete node; +} + +bool NestedListModel::insert(int index, const QScriptValue& valuemap) +{ + if (!_root) + _root = new ModelNode; + + ModelNode *mn = new ModelNode; + mn->setObjectValue(valuemap); + _root->values.insert(index,qVariantFromValue(mn)); + return true; +} + +void NestedListModel::move(int from, int to, int n) +{ + if (n==1) { + _root->values.move(from,to); + } else { + QList<QVariant> replaced; + int i=0; + QVariantList::const_iterator it=_root->values.begin(); it += from+n; + for (; i<to-from; ++i,++it) + replaced.append(*it); + i=0; + it=_root->values.begin(); it += from; + for (; i<n; ++i,++it) + replaced.append(*it); + QVariantList::const_iterator f=replaced.begin(); + QVariantList::iterator t=_root->values.begin(); t += from; + for (; f != replaced.end(); ++f, ++t) + *t = *f; + } +} + +bool NestedListModel::append(const QScriptValue& valuemap) +{ + if (!_root) + _root = new ModelNode; + ModelNode *mn = new ModelNode; + mn->setObjectValue(valuemap); + _root->values << qVariantFromValue(mn); + return true; +} + +QScriptValue NestedListModel::get(int index) const +{ + ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); + if (!node) + return 0; + QDeclarativeEngine *eng = qmlEngine(m_listModel); + if (!eng) { + qWarning("Cannot call QDeclarativeListModel::get() without a QDeclarativeEngine"); + return 0; + } + return QDeclarativeEnginePrivate::qmlScriptObject(node->object(this), eng); +} + +void NestedListModel::set(int index, const QScriptValue& valuemap, QList<int> *roles) +{ + Q_ASSERT(index >=0 && index < count()); + + ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); + node->setObjectValue(valuemap); + + QScriptValueIterator it(valuemap); + while (it.hasNext()) { + it.next(); + int r = roleStrings.indexOf(it.name()); + if (r < 0) { + r = roleStrings.count(); + roleStrings << it.name(); + } + roles->append(r); + } +} + +void NestedListModel::setProperty(int index, const QString& property, const QVariant& value, QList<int> *roles) +{ + Q_ASSERT(index >=0 && index < count()); + + ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); + node->setProperty(property, value); + + int r = roleStrings.indexOf(property); + if (r < 0) { + r = roleStrings.count(); + roleStrings << property; + } + roles->append(r); +} + +void NestedListModel::checkRoles() const +{ + if (_rolesOk || !_root) + return; + + for (int i = 0; i<_root->values.count(); ++i) { + ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(i)); + if (node) { + foreach (const QString &role, node->properties.keys()) { + if (!roleStrings.contains(role)) + roleStrings.append(role); + } + } + } + + _rolesOk = true; +} + +QList<int> NestedListModel::roles() const +{ + checkRoles(); + QList<int> rv; + for (int ii = 0; ii < roleStrings.count(); ++ii) + rv << ii; + return rv; +} + +QString NestedListModel::toString(int role) const +{ + checkRoles(); + if (role < roleStrings.count()) + return roleStrings.at(role); + else + return QString(); +} + + +ModelNode::ModelNode() +: modelCache(0), objectCache(0), isArray(false) +{ +} + +ModelNode::~ModelNode() +{ + ModelNode *node; + + QList<ModelNode *> nodeValues = properties.values(); + for (int ii = 0; ii < nodeValues.count(); ++ii) { + node = nodeValues[ii]; + if (node) { delete node; node = 0; } + } + + for (int ii = 0; ii < values.count(); ++ii) { + node = qvariant_cast<ModelNode *>(values.at(ii)); + if (node) { delete node; node = 0; } + } + + if (modelCache) { modelCache->m_nested->_root = 0/* ==this */; delete modelCache; modelCache = 0; } + if (objectCache) { delete objectCache; objectCache = 0; } +} + +void ModelNode::setObjectValue(const QScriptValue& valuemap) { + QScriptValueIterator it(valuemap); + while (it.hasNext()) { + it.next(); + ModelNode *value = new ModelNode; + QScriptValue v = it.value(); + if (v.isArray()) { + value->isArray = true; + value->setListValue(v); + } else { + value->values << v.toVariant(); + } + properties.insert(it.name(),value); + } +} + +void ModelNode::setListValue(const QScriptValue& valuelist) { + QScriptValueIterator it(valuelist); + values.clear(); + int size = valuelist.property(QLatin1String("length")).toInt32(); + for (int i=0; i<size; i++) { + ModelNode *value = new ModelNode; + QScriptValue v = valuelist.property(i); + if (v.isArray()) { + value->isArray = true; + value->setListValue(v); + } else if (v.isObject()) { + value->setObjectValue(v); + } else { + value->values << v.toVariant(); + } + values.append(qVariantFromValue(value)); + } +} + +void ModelNode::setProperty(const QString& prop, const QVariant& val) { + QHash<QString, ModelNode *>::const_iterator it = properties.find(prop); + if (it != properties.end()) { + (*it)->values[0] = val; + } else { + ModelNode *n = new ModelNode; + n->values << val; + properties.insert(prop,n); + } + if (objectCache) + objectCache->setValue(prop.toUtf8(), val); +} + +void ModelNode::dump(ModelNode *node, int ind) { QByteArray indentBa(ind * 4, ' '); const char *indent = indentBa.constData(); @@ -963,22 +1336,15 @@ static void dump(ModelNode *node, int ind) } } -ModelNode::ModelNode() -: modelCache(0), objectCache(0), isArray(false) +ModelObject::ModelObject() +: _mo(new QDeclarativeOpenMetaObject(this)) { } -ModelNode::~ModelNode() +void ModelObject::setValue(const QByteArray &name, const QVariant &val) { - qDeleteAll(properties); - for (int ii = 0; ii < values.count(); ++ii) { - ModelNode *node = qvariant_cast<ModelNode *>(values.at(ii)); - if (node) { delete node; node = 0; } - } - if (modelCache) { modelCache->_root = 0/* ==this */; delete modelCache; modelCache = 0; } - if (objectCache) { delete objectCache; } + _mo->setValue(name, val); } -QT_END_NAMESPACE -#include <qdeclarativelistmodel.moc> +QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativelistmodel_p.h b/src/declarative/util/qdeclarativelistmodel_p.h index 8eb6583..6a0426b 100644 --- a/src/declarative/util/qdeclarativelistmodel_p.h +++ b/src/declarative/util/qdeclarativelistmodel_p.h @@ -59,6 +59,9 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) +class FlatListModel; +class NestedListModel; +class QDeclarativeListModelWorkerAgent; struct ModelNode; class Q_DECLARATIVE_EXPORT QDeclarativeListModel : public QListModelInterface { @@ -83,20 +86,26 @@ public: Q_INVOKABLE void set(int index, const QScriptValue&); Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value); Q_INVOKABLE void move(int from, int to, int count); + Q_INVOKABLE void sync(); + + QDeclarativeListModelWorkerAgent *agent(); Q_SIGNALS: void countChanged(int); private: - QVariant valueForNode(ModelNode *) const; - mutable QStringList roleStrings; friend class QDeclarativeListModelParser; + friend class QDeclarativeListModelWorkerAgent; friend struct ModelNode; - void checkRoles() const; - void addRole(const QString &) const; - mutable bool _rolesOk; - ModelNode *_root; + QDeclarativeListModel(bool workerCopy, QObject *parent=0); + bool flatten(); + bool modifyCheck(); + + QDeclarativeListModelWorkerAgent *m_agent; + NestedListModel *m_nested; + FlatListModel *m_flat; + bool m_isWorkerCopy; }; // ### FIXME diff --git a/src/declarative/util/qdeclarativelistmodel_p_p.h b/src/declarative/util/qdeclarativelistmodel_p_p.h new file mode 100644 index 0000000..8041561 --- /dev/null +++ b/src/declarative/util/qdeclarativelistmodel_p_p.h @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVELISTMODEL_P_P_H +#define QDECLARATIVELISTMODEL_P_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 "qdeclarativelistmodel_p.h" + +#include "qdeclarative.h" +#include "qdeclarativeengine_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeOpenMetaObject; +class QScriptEngine; +class QDeclarativeListModelWorkerAgent; +struct ModelNode; + +class FlatListModel +{ +public: + FlatListModel(QDeclarativeListModel *base); + ~FlatListModel(); + + QHash<int,QVariant> data(int index, const QList<int> &roles) const; + QVariant data(int index, int role) const; + + QList<int> roles() const; + QString toString(int role) const; + + int count() const; + void clear(); + void remove(int index); + bool append(const QScriptValue&); + bool insert(int index, const QScriptValue&); + QScriptValue get(int index) const; + void set(int index, const QScriptValue&, QList<int> *roles); + void setProperty(int index, const QString& property, const QVariant& value, QList<int> *roles); + void move(int from, int to, int count); + +private: + friend class QDeclarativeListModelWorkerAgent; + friend class QDeclarativeListModel; + + bool addValue(const QScriptValue &value, QHash<int, QVariant> *row, QList<int> *roles); + + QScriptEngine *m_scriptEngine; + QHash<int, QString> m_roles; + QHash<QString, int> m_strings; + QList<QHash<int, QVariant> > m_values; + QDeclarativeListModel *m_listModel; +}; + +class NestedListModel +{ +public: + NestedListModel(QDeclarativeListModel *base); + ~NestedListModel(); + + QHash<int,QVariant> data(int index, const QList<int> &roles, bool *hasNested = 0) const; + QVariant data(int index, int role) const; + + QList<int> roles() const; + QString toString(int role) const; + + int count() const; + void clear(); + void remove(int index); + bool append(const QScriptValue&); + bool insert(int index, const QScriptValue&); + QScriptValue get(int index) const; + void set(int index, const QScriptValue&, QList<int> *roles); + void setProperty(int index, const QString& property, const QVariant& value, QList<int> *role); + void move(int from, int to, int count); + + QVariant valueForNode(ModelNode *, bool *hasNested = 0) const; + void checkRoles() const; + + ModelNode *_root; + QDeclarativeListModel *m_listModel; + +private: + mutable QStringList roleStrings; + mutable bool _rolesOk; +}; + + +class ModelObject : public QObject +{ + Q_OBJECT +public: + ModelObject(); + void setValue(const QByteArray &name, const QVariant &val); + +private: + QDeclarativeOpenMetaObject *_mo; +}; + +struct ModelNode +{ + ModelNode(); + ~ModelNode(); + + QList<QVariant> values; + QHash<QString, ModelNode *> properties; + + QDeclarativeListModel *model(const NestedListModel *model) { + if (!modelCache) { + modelCache = new QDeclarativeListModel; + QDeclarativeEngine::setContextForObject(modelCache,QDeclarativeEngine::contextForObject(model->m_listModel)); + modelCache->m_nested->_root = this; // ListModel defaults to nestable model + } + return modelCache; + } + + ModelObject *object(const NestedListModel *model) { + if (!objectCache) { + objectCache = new ModelObject(); + QHash<QString, ModelNode *>::iterator it; + for (it = properties.begin(); it != properties.end(); ++it) { + objectCache->setValue(it.key().toUtf8(), model->valueForNode(*it)); + } + } + return objectCache; + } + + + void setObjectValue(const QScriptValue& valuemap); + void setListValue(const QScriptValue& valuelist); + void setProperty(const QString& prop, const QVariant& val); + static void dump(ModelNode *node, int ind); + + QDeclarativeListModel *modelCache; + ModelObject *objectCache; + bool isArray; +}; + + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(ModelNode *) + +QT_END_HEADER + +#endif // QDECLARATIVELISTMODEL_P_P_H + diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp new file mode 100644 index 0000000..2951262 --- /dev/null +++ b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativelistmodelworkeragent_p.h" +#include "qdeclarativelistmodel_p_p.h" +#include "qdeclarativedeclarativedata_p.h" +#include "qdeclarativeengine_p.h" +#include "qdeclarativeinfo.h" + +#include <QtCore/qcoreevent.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qdebug.h> + + +QT_BEGIN_NAMESPACE + + +void QDeclarativeListModelWorkerAgent::Data::clearChange() +{ + changes.clear(); +} + +void QDeclarativeListModelWorkerAgent::Data::insertChange(int index, int count) +{ + Change c = { Change::Inserted, index, count, 0 }; + changes << c; +} + +void QDeclarativeListModelWorkerAgent::Data::removeChange(int index, int count) +{ + Change c = { Change::Removed, index, count, 0 }; + changes << c; +} + +void QDeclarativeListModelWorkerAgent::Data::moveChange(int index, int count, int to) +{ + Change c = { Change::Moved, index, count, to }; + changes << c; +} + +void QDeclarativeListModelWorkerAgent::Data::changedChange(int index, int count) +{ + Change c = { Change::Changed, index, count, 0 }; + changes << c; +} + +QDeclarativeListModelWorkerAgent::QDeclarativeListModelWorkerAgent(QDeclarativeListModel *model) +: m_engine(0), m_ref(1), m_orig(model), m_copy(new QDeclarativeListModel(true, this)) +{ + m_copy->m_flat->m_roles = m_orig->m_flat->m_roles; + m_copy->m_flat->m_strings = m_orig->m_flat->m_strings; + m_copy->m_flat->m_values = m_orig->m_flat->m_values; +} + +QDeclarativeListModelWorkerAgent::~QDeclarativeListModelWorkerAgent() +{ +} + +void QDeclarativeListModelWorkerAgent::setScriptEngine(QScriptEngine *eng) +{ + m_engine = eng; + if (m_copy->m_flat) + m_copy->m_flat->m_scriptEngine = eng; +} + +QScriptEngine *QDeclarativeListModelWorkerAgent::scriptEngine() const +{ + return m_engine; +} + +void QDeclarativeListModelWorkerAgent::addref() +{ + m_ref.ref(); +} + +void QDeclarativeListModelWorkerAgent::release() +{ + bool del = !m_ref.deref(); + + if (del) + delete this; +} + +int QDeclarativeListModelWorkerAgent::count() const +{ + return m_copy->count(); +} + +void QDeclarativeListModelWorkerAgent::clear() +{ + data.clearChange(); + data.removeChange(0, m_copy->count()); + m_copy->clear(); +} + +void QDeclarativeListModelWorkerAgent::remove(int index) +{ + int count = m_copy->count(); + m_copy->remove(index); + + if (m_copy->count() != count) + data.removeChange(index, 1); +} + +void QDeclarativeListModelWorkerAgent::append(const QScriptValue &value) +{ + int count = m_copy->count(); + m_copy->append(value); + + if (m_copy->count() != count) + data.insertChange(m_copy->count() - 1, 1); +} + +void QDeclarativeListModelWorkerAgent::insert(int index, const QScriptValue &value) +{ + int count = m_copy->count(); + m_copy->insert(index, value); + + if (m_copy->count() != count) + data.insertChange(index, 1); +} + +QScriptValue QDeclarativeListModelWorkerAgent::get(int index) const +{ + return m_copy->get(index); +} + +void QDeclarativeListModelWorkerAgent::set(int index, const QScriptValue &value) +{ + m_copy->set(index, value); + data.changedChange(index, 1); +} + +void QDeclarativeListModelWorkerAgent::setProperty(int index, const QString& property, const QVariant& value) +{ + m_copy->setProperty(index, property, value); + data.changedChange(index, 1); +} + +void QDeclarativeListModelWorkerAgent::move(int from, int to, int count) +{ + m_copy->move(from, to, count); + data.moveChange(from, to, count); +} + +void QDeclarativeListModelWorkerAgent::sync() +{ + Sync *s = new Sync; + s->data = data; + s->list = m_copy; + data.changes.clear(); + QCoreApplication::postEvent(this, s); +} + +bool QDeclarativeListModelWorkerAgent::event(QEvent *e) +{ + if (e->type() == QEvent::User) { + Sync *s = static_cast<Sync *>(e); + + const QList<Change> &changes = s->data.changes; + + if (m_copy) { + bool cc = m_copy->count() != s->list->count(); + + FlatListModel *orig = m_orig->m_flat; + FlatListModel *copy = s->list->m_flat; + if (!orig || !copy) { + qWarning("QML ListModel worker: sync() failed"); + return QObject::event(e); + } + orig->m_roles = copy->m_roles; + orig->m_strings = copy->m_strings; + orig->m_values = copy->m_values; + + for (int ii = 0; ii < changes.count(); ++ii) { + const Change &change = changes.at(ii); + switch (change.type) { + case Change::Inserted: + emit m_orig->itemsInserted(change.index, change.count); + break; + case Change::Removed: + emit m_orig->itemsRemoved(change.index, change.count); + break; + case Change::Moved: + emit m_orig->itemsMoved(change.index, change.to, change.count); + break; + case Change::Changed: + emit m_orig->itemsMoved(change.index, change.to, change.count); + break; + } + } + + if (cc) + emit m_orig->countChanged(m_copy->count()); + } + } + + return QObject::event(e); +} + +QT_END_NAMESPACE + diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent_p.h b/src/declarative/util/qdeclarativelistmodelworkeragent_p.h new file mode 100644 index 0000000..b6a643b --- /dev/null +++ b/src/declarative/util/qdeclarativelistmodelworkeragent_p.h @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVELISTMODELWORKERAGENT_P_H +#define QDECLARATIVELISTMODELWORKERAGENT_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 "qdeclarative.h" + +#include <QtScript/qscriptvalue.h> +#include <QtGui/qevent.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeListModel; + +// Currently this will leak as no-one releases it in the worker thread +class QDeclarativeListModelWorkerAgent : public QObject +{ + Q_OBJECT + Q_PROPERTY(int count READ count) + +public: + QDeclarativeListModelWorkerAgent(QDeclarativeListModel *); + ~QDeclarativeListModelWorkerAgent(); + + void setScriptEngine(QScriptEngine *eng); + QScriptEngine *scriptEngine() const; + + void addref(); + void release(); + + int count() const; + + Q_INVOKABLE void clear(); + Q_INVOKABLE void remove(int index); + Q_INVOKABLE void append(const QScriptValue &); + Q_INVOKABLE void insert(int index, const QScriptValue&); + Q_INVOKABLE QScriptValue get(int index) const; + Q_INVOKABLE void set(int index, const QScriptValue &); + Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value); + Q_INVOKABLE void move(int from, int to, int count); + Q_INVOKABLE void sync(); + + struct VariantRef + { + VariantRef() : a(0) {} + VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); } + VariantRef(QDeclarativeListModelWorkerAgent *_a) : a(_a) { if (a) a->addref(); } + ~VariantRef() { if (a) a->release(); } + + VariantRef &operator=(const VariantRef &o) { + if (o.a) o.a->addref(); + if (a) a->release(); a = o.a; + return *this; + } + + QDeclarativeListModelWorkerAgent *a; + }; +protected: + virtual bool event(QEvent *); + +private: + friend class QDeclarativeWorkerScriptEnginePrivate; + QScriptEngine *m_engine; + + struct Change { + enum { Inserted, Removed, Moved, Changed } type; + int index; // Inserted/Removed/Moved/Changed + int count; // Inserted/Removed/Moved/Changed + int to; // Moved + }; + + struct Data { + QList<Change> changes; + + void clearChange(); + void insertChange(int index, int count); + void removeChange(int index, int count); + void moveChange(int index, int count, int to); + void changedChange(int index, int count); + }; + Data data; + + struct Sync : public QEvent { + Sync() : QEvent(QEvent::User) {} + Data data; + QDeclarativeListModel *list; + }; + + QAtomicInt m_ref; + QDeclarativeListModel *m_orig; + QDeclarativeListModel *m_copy; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QDeclarativeListModelWorkerAgent::VariantRef); + +QT_END_HEADER + +#endif // QDECLARATIVEWORKERSCRIPT_P_H + diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index cfb25dd..942d5f6 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -137,7 +137,7 @@ class QDeclarativeImageRequestHandler : public QObject Q_OBJECT public: QDeclarativeImageRequestHandler(QDeclarativeImageReader *read, QDeclarativeEngine *eng) - : QObject(), accessManager(0), engine(eng), reader(read) + : QObject(), accessManager(0), engine(eng), reader(read), redirectCount(0) { QCoreApplication::postEvent(this, new QEvent(QEvent::User)); } @@ -162,18 +162,24 @@ private: QNetworkAccessManager *accessManager; QDeclarativeEngine *engine; QDeclarativeImageReader *reader; + int redirectCount; + + static int replyDownloadProgress; + static int replyFinished; + static int downloadProgress; + static int thisNetworkRequestDone; }; //=========================================================================== +int QDeclarativeImageRequestHandler::replyDownloadProgress = -1; +int QDeclarativeImageRequestHandler::replyFinished = -1; +int QDeclarativeImageRequestHandler::downloadProgress = -1; +int QDeclarativeImageRequestHandler::thisNetworkRequestDone = -1; + bool QDeclarativeImageRequestHandler::event(QEvent *event) { if (event->type() == QEvent::User) { - static int replyDownloadProgress = -1; - static int replyFinished = -1; - static int downloadProgress = -1; - static int thisNetworkRequestDone = -1; - if (replyDownloadProgress == -1) { replyDownloadProgress = QNetworkReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)"); replyFinished = QNetworkReply::staticMetaObject.indexOfSignal("finished()"); @@ -264,10 +270,33 @@ bool QDeclarativeImageRequestHandler::event(QEvent *event) return QObject::event(event); } +#define IMAGEREQUESTHANDLER_MAX_REDIRECT_RECURSION 16 + void QDeclarativeImageRequestHandler::networkRequestDone() { QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); QDeclarativePixmapReply *job = replies.take(reply); + + redirectCount++; + if (redirectCount < IMAGEREQUESTHANDLER_MAX_REDIRECT_RECURSION) { + QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = reply->url().resolved(redirect.toUrl()); + QNetworkRequest req(url); + req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); + + reply->deleteLater(); + reply = networkAccessManager()->get(req); + + QMetaObject::connect(reply, replyDownloadProgress, job, downloadProgress); + QMetaObject::connect(reply, replyFinished, this, thisNetworkRequestDone); + + replies.insert(reply, job); + return; + } + } + redirectCount=0; + if (job) { QImage image; QDeclarativeImageReaderEvent::ReadError error; diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index 9c2b1e6..8865e04 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -439,7 +439,8 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions() if (d->isExplicit) { a.toValue = d->expressions.at(ii).second->value(); } else { - QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->expressions.at(ii).second->expression(), object(), qmlContext(this)); + QDeclarativeBinding *newBinding = + new QDeclarativeBinding(d->expressions.at(ii).second->expression(), object(), qmlContext(this)); newBinding->setTarget(prop); a.toBinding = newBinding; a.deletableToBinding = true; diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index 1d70d33..802ff1c 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -96,21 +96,12 @@ void QDeclarativeActionEvent::reverse() { } -QList<QDeclarativeAction> QDeclarativeActionEvent::extraActions() -{ - return QList<QDeclarativeAction>(); -} - bool QDeclarativeActionEvent::changesBindings() { return false; } -void QDeclarativeActionEvent::clearForwardBindings() -{ -} - -void QDeclarativeActionEvent::clearReverseBindings() +void QDeclarativeActionEvent::clearBindings() { } @@ -368,47 +359,60 @@ void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransit for (int ii = 0; ii < applyList.count(); ++ii) { QDeclarativeAction &action = applyList[ii]; - bool found = false; - - int jj; if (action.event) { if (!action.event->isReversable()) continue; - for (jj = 0; jj < d->revertList.count(); ++jj) { + bool found = false; + for (int jj = 0; jj < d->revertList.count(); ++jj) { QDeclarativeActionEvent *event = d->revertList.at(jj).event; if (event && event->typeName() == action.event->typeName()) { if (action.event->override(event)) { found = true; + + if (action.event != d->revertList.at(jj).event) { + action.event->copyOriginals(d->revertList.at(jj).event); + + QDeclarativeSimpleAction r(action); + additionalReverts << r; + d->revertList.removeAt(jj); + } else if (action.event->isRewindable()) //###why needed? + action.event->saveCurrentValues(); + break; } } } - if (!found || action.event != d->revertList.at(jj).event) + if (!found) { action.event->saveOriginals(); - else if (action.event->isRewindable()) - action.event->saveCurrentValues(); + // Only need to revert the applyList action if the previous + // state doesn't have a higher priority revert already + QDeclarativeSimpleAction r(action); + additionalReverts << r; + } } else { + bool found = false; action.fromBinding = QDeclarativePropertyPrivate::binding(action.property); - for (jj = 0; jj < d->revertList.count(); ++jj) { + for (int jj = 0; jj < d->revertList.count(); ++jj) { if (d->revertList.at(jj).property == action.property) { found = true; + if (d->revertList.at(jj).binding != action.fromBinding) { + action.deleteFromBinding(); + } break; } } - } - if (!found) { - if (!action.restore) { - action.deleteFromBinding(); - } else { - // Only need to revert the applyList action if the previous - // state doesn't have a higher priority revert already - QDeclarativeSimpleAction r(action); - additionalReverts << r; + if (!found) { + if (!action.restore) { + action.deleteFromBinding(); + } else { + // Only need to revert the applyList action if the previous + // state doesn't have a higher priority revert already + QDeclarativeSimpleAction r(action); + additionalReverts << r; + } } - } else if (d->revertList.at(jj).binding != action.fromBinding) { - action.deleteFromBinding(); } } diff --git a/src/declarative/util/qdeclarativestate_p.h b/src/declarative/util/qdeclarativestate_p.h index 0c6e7a3..ee2b7e8 100644 --- a/src/declarative/util/qdeclarativestate_p.h +++ b/src/declarative/util/qdeclarativestate_p.h @@ -92,17 +92,15 @@ public: virtual bool isReversable(); virtual void reverse(); virtual void saveOriginals() {} + virtual void copyOriginals(QDeclarativeActionEvent *) {} virtual bool isRewindable() { return isReversable(); } virtual void rewind() {} virtual void saveCurrentValues() {} - - //virtual bool hasExtraActions(); - virtual QList<QDeclarativeAction> extraActions(); + virtual void saveTargetValues() {} virtual bool changesBindings(); - virtual void clearForwardBindings(); - virtual void clearReverseBindings(); + virtual void clearBindings(); virtual bool override(QDeclarativeActionEvent*other); }; diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 766d1bc..6f5bb66 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -403,6 +403,17 @@ void QDeclarativeParentChange::saveOriginals() d->origStackBefore = d->rewindStackBefore; } +void QDeclarativeParentChange::copyOriginals(QDeclarativeActionEvent *other) +{ + Q_D(QDeclarativeParentChange); + QDeclarativeParentChange *pc = static_cast<QDeclarativeParentChange*>(other); + + d->origParent = pc->d_func()->rewindParent; + d->origStackBefore = pc->d_func()->rewindStackBefore; + + saveCurrentValues(); +} + void QDeclarativeParentChange::execute() { Q_D(QDeclarativeParentChange); @@ -561,11 +572,17 @@ QString QDeclarativeStateChangeScript::typeName() const \qmlclass AnchorChanges QDeclarativeAnchorChanges \brief The AnchorChanges element allows you to change the anchors of an item in a state. - AnchorChanges will 'inject' \c x, \c y, \c width, and \c height changes into the transition, - so you can animate them as you would normally changes to these properties: + In the following example we change the top and bottom anchors of an item: + \qml + AnchorChanges { + target: content; top: window.top; bottom: window.bottom + } + \endqml + + AnchorChanges can be animated using AnchorAnimation. \qml //animate our anchor changes - NumberAnimation { targets: content; properties: "x,y,width,height" } + AnchorAnimation {} \endqml For more information on anchors see \l {anchor-layout}{Anchor Layouts}. @@ -578,10 +595,10 @@ class QDeclarativeAnchorChangesPrivate : public QObjectPrivate public: QDeclarativeAnchorChangesPrivate() : target(0) {} - QString name; QDeclarativeItem *target; QString resetString; QStringList resetList; + QDeclarativeAnchorLine left; QDeclarativeAnchorLine right; QDeclarativeAnchorLine horizontalCenter; @@ -610,6 +627,24 @@ public: qreal fromY; qreal fromWidth; qreal fromHeight; + + qreal toX; + qreal toY; + qreal toWidth; + qreal toHeight; + + qreal rewindX; + qreal rewindY; + qreal rewindWidth; + qreal rewindHeight; + + bool applyOrigLeft; + bool applyOrigRight; + bool applyOrigHCenter; + bool applyOrigTop; + bool applyOrigBottom; + bool applyOrigVCenter; + bool applyOrigBaseline; }; /*! @@ -762,6 +797,38 @@ void QDeclarativeAnchorChanges::execute() if (!d->target) return; + //incorporate any needed "reverts" + if (d->applyOrigLeft) + d->target->anchors()->setLeft(d->origLeft); + if (d->applyOrigRight) + d->target->anchors()->setRight(d->origRight); + if (d->applyOrigHCenter) + d->target->anchors()->setHorizontalCenter(d->origHCenter); + if (d->applyOrigTop) + d->target->anchors()->setTop(d->origTop); + if (d->applyOrigBottom) + d->target->anchors()->setBottom(d->origBottom); + if (d->applyOrigVCenter) + d->target->anchors()->setVerticalCenter(d->origVCenter); + if (d->applyOrigBaseline) + d->target->anchors()->setBaseline(d->origBaseline); + + //reset any anchors that have been specified + if (d->resetList.contains(QLatin1String("left"))) + d->target->anchors()->resetLeft(); + if (d->resetList.contains(QLatin1String("right"))) + d->target->anchors()->resetRight(); + if (d->resetList.contains(QLatin1String("horizontalCenter"))) + d->target->anchors()->resetHorizontalCenter(); + if (d->resetList.contains(QLatin1String("top"))) + d->target->anchors()->resetTop(); + if (d->resetList.contains(QLatin1String("bottom"))) + d->target->anchors()->resetBottom(); + if (d->resetList.contains(QLatin1String("verticalCenter"))) + d->target->anchors()->resetVerticalCenter(); + if (d->resetList.contains(QLatin1String("baseline"))) + d->target->anchors()->resetBaseline(); + //set any anchors that have been specified if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid) d->target->anchors()->setLeft(d->left); @@ -790,6 +857,22 @@ void QDeclarativeAnchorChanges::reverse() if (!d->target) return; + //reset any anchors set by the state + if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetLeft(); + if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetRight(); + if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetHorizontalCenter(); + if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetTop(); + if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetBottom(); + if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetVerticalCenter(); + if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetBaseline(); + //restore previous anchors if (d->origLeft.anchorLine != QDeclarativeAnchorLine::Invalid) d->target->anchors()->setLeft(d->origLeft); @@ -812,31 +895,33 @@ QString QDeclarativeAnchorChanges::typeName() const return QLatin1String("AnchorChanges"); } -QList<QDeclarativeAction> QDeclarativeAnchorChanges::extraActions() +QList<QDeclarativeAction> QDeclarativeAnchorChanges::additionalActions() { Q_D(QDeclarativeAnchorChanges); QList<QDeclarativeAction> extra; - //### try to be smarter about which ones we add. - // or short-circuit later on if they haven't actually changed. - // we shouldn't set explicit width if there wasn't one before. if (d->target) { QDeclarativeAction a; - a.fromValue = d->fromX; - a.property = QDeclarativeProperty(d->target, QLatin1String("x")); - extra << a; - - a.fromValue = d->fromY; - a.property = QDeclarativeProperty(d->target, QLatin1String("y")); - extra << a; - - a.fromValue = d->fromWidth; - a.property = QDeclarativeProperty(d->target, QLatin1String("width")); - extra << a; - - a.fromValue = d->fromHeight; - a.property = QDeclarativeProperty(d->target, QLatin1String("height")); - extra << a; + if (d->fromX != d->toX) { + a.property = QDeclarativeProperty(d->target, QLatin1String("x")); + a.toValue = d->toX; + extra << a; + } + if (d->fromY != d->toY) { + a.property = QDeclarativeProperty(d->target, QLatin1String("y")); + a.toValue = d->toY; + extra << a; + } + if (d->fromWidth != d->toWidth) { + a.property = QDeclarativeProperty(d->target, QLatin1String("width")); + a.toValue = d->toWidth; + extra << a; + } + if (d->fromHeight != d->toHeight) { + a.property = QDeclarativeProperty(d->target, QLatin1String("height")); + a.toValue = d->toHeight; + extra << a; + } } return extra; @@ -858,10 +943,52 @@ void QDeclarativeAnchorChanges::saveOriginals() d->origVCenter = d->target->anchors()->verticalCenter(); d->origBaseline = d->target->anchors()->baseline(); + d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop + = d->applyOrigBottom = d->applyOrigHCenter = d->applyOrigBaseline = false; + saveCurrentValues(); } -void QDeclarativeAnchorChanges::clearForwardBindings() +void QDeclarativeAnchorChanges::copyOriginals(QDeclarativeActionEvent *other) +{ + Q_D(QDeclarativeAnchorChanges); + QDeclarativeAnchorChanges *ac = static_cast<QDeclarativeAnchorChanges*>(other); + QDeclarativeAnchorChangesPrivate *acp = ac->d_func(); + + //probably also need to revert some things + d->applyOrigLeft = (acp->left.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("left"))); + + d->applyOrigRight = (acp->right.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("right"))); + + d->applyOrigHCenter = (acp->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("horizontalCenter"))); + + d->applyOrigTop = (acp->top.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("top"))); + + d->applyOrigBottom = (acp->bottom.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("bottom"))); + + d->applyOrigVCenter = (acp->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("verticalCenter"))); + + d->applyOrigBaseline = (acp->baseline.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("baseline"))); + + d->origLeft = ac->d_func()->origLeft; + d->origRight = ac->d_func()->origRight; + d->origHCenter = ac->d_func()->origHCenter; + d->origTop = ac->d_func()->origTop; + d->origBottom = ac->d_func()->origBottom; + d->origVCenter = ac->d_func()->origVCenter; + d->origBaseline = ac->d_func()->origBaseline; + + saveCurrentValues(); +} + +void QDeclarativeAnchorChanges::clearBindings() { Q_D(QDeclarativeAnchorChanges); d->fromX = d->target->x(); @@ -869,6 +996,22 @@ void QDeclarativeAnchorChanges::clearForwardBindings() d->fromWidth = d->target->width(); d->fromHeight = d->target->height(); + //reset any anchors with corresponding reverts + if (d->applyOrigLeft) + d->target->anchors()->resetLeft(); + if (d->applyOrigRight) + d->target->anchors()->resetRight(); + if (d->applyOrigHCenter) + d->target->anchors()->resetHorizontalCenter(); + if (d->applyOrigTop) + d->target->anchors()->resetTop(); + if (d->applyOrigBottom) + d->target->anchors()->resetBottom(); + if (d->applyOrigVCenter) + d->target->anchors()->resetVerticalCenter(); + if (d->applyOrigBaseline) + d->target->anchors()->resetBaseline(); + //reset any anchors that have been specified if (d->resetList.contains(QLatin1String("left"))) d->target->anchors()->resetLeft(); @@ -902,47 +1045,6 @@ void QDeclarativeAnchorChanges::clearForwardBindings() d->target->anchors()->resetBaseline(); } -void QDeclarativeAnchorChanges::clearReverseBindings() -{ - Q_D(QDeclarativeAnchorChanges); - d->fromX = d->target->x(); - d->fromY = d->target->y(); - d->fromWidth = d->target->width(); - d->fromHeight = d->target->height(); - - //reset any anchors that were set in the state - if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetLeft(); - if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetRight(); - if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetHorizontalCenter(); - if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetTop(); - if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetBottom(); - if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetVerticalCenter(); - if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetBaseline(); - - //reset any anchors that were set in the original state - if (d->origLeft.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetLeft(); - if (d->origRight.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetRight(); - if (d->origHCenter.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetHorizontalCenter(); - if (d->origTop.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetTop(); - if (d->origBottom.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetBottom(); - if (d->origVCenter.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetVerticalCenter(); - if (d->origBaseline.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetBaseline(); -} - bool QDeclarativeAnchorChanges::override(QDeclarativeActionEvent*other) { if (other->typeName() != QLatin1String("AnchorChanges")) @@ -975,6 +1077,11 @@ void QDeclarativeAnchorChanges::rewind() d->target->anchors()->setVerticalCenter(d->rewindVCenter); if (d->rewindBaseline.anchorLine != QDeclarativeAnchorLine::Invalid) d->target->anchors()->setBaseline(d->rewindBaseline); + + d->target->setX(d->rewindX); + d->target->setY(d->rewindY); + d->target->setWidth(d->rewindWidth); + d->target->setHeight(d->rewindHeight); } void QDeclarativeAnchorChanges::saveCurrentValues() @@ -987,6 +1094,20 @@ void QDeclarativeAnchorChanges::saveCurrentValues() d->rewindBottom = d->target->anchors()->bottom(); d->rewindVCenter = d->target->anchors()->verticalCenter(); d->rewindBaseline = d->target->anchors()->baseline(); + + d->rewindX = d->target->x(); + d->rewindY = d->target->y(); + d->rewindWidth = d->target->width(); + d->rewindHeight = d->target->height(); +} + +void QDeclarativeAnchorChanges::saveTargetValues() +{ + Q_D(QDeclarativeAnchorChanges); + d->toX = d->target->x(); + d->toY = d->target->y(); + d->toWidth = d->target->width(); + d->toHeight = d->target->height(); } #include <qdeclarativestateoperations.moc> diff --git a/src/declarative/util/qdeclarativestateoperations_p.h b/src/declarative/util/qdeclarativestateoperations_p.h index dd4248023..66a8717 100644 --- a/src/declarative/util/qdeclarativestateoperations_p.h +++ b/src/declarative/util/qdeclarativestateoperations_p.h @@ -107,6 +107,7 @@ public: virtual ActionList actions(); virtual void saveOriginals(); + virtual void copyOriginals(QDeclarativeActionEvent*); virtual void execute(); virtual bool isReversable(); virtual void reverse(); @@ -196,13 +197,15 @@ public: virtual void reverse(); virtual QString typeName() const; virtual bool override(QDeclarativeActionEvent*other); - virtual QList<QDeclarativeAction> extraActions(); virtual bool changesBindings(); virtual void saveOriginals(); - virtual void clearForwardBindings(); - virtual void clearReverseBindings(); + virtual void copyOriginals(QDeclarativeActionEvent*); + virtual void clearBindings(); virtual void rewind(); virtual void saveCurrentValues(); + + QList<QDeclarativeAction> additionalActions(); + virtual void saveTargetValues(); }; QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativetransitionmanager.cpp b/src/declarative/util/qdeclarativetransitionmanager.cpp index e1143fa..f07fb23 100644 --- a/src/declarative/util/qdeclarativetransitionmanager.cpp +++ b/src/declarative/util/qdeclarativetransitionmanager.cpp @@ -126,10 +126,7 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> & QDeclarativePropertyPrivate::setBinding(action.property, 0); // Disable current binding if (action.event && action.event->changesBindings()) { //### assume isReversable()? d->bindingsList << action; - if (action.reverseEvent) - action.event->clearReverseBindings(); - else - action.event->clearForwardBindings(); + action.event->clearBindings(); } } @@ -144,8 +141,6 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> & if (!d->bindingsList.isEmpty()) { - //### do extra actions here? - // Apply all the property and binding changes for (int ii = 0; ii < applyList.size(); ++ii) { const QDeclarativeAction &action = applyList.at(ii); @@ -158,17 +153,18 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> & action.event->reverse(); else action.event->execute(); - applyList << action.event->extraActions(); } } // Read all the end values for binding changes for (int ii = 0; ii < applyList.size(); ++ii) { QDeclarativeAction *action = &applyList[ii]; - if (action->event) + if (action->event) { + action->event->saveTargetValues(); continue; + } const QDeclarativeProperty &prop = action->property; - if (action->toBinding || !action->toValue.isValid()) { //### is this always right (used for exta actions) + if (action->toBinding || !action->toValue.isValid()) { action->toValue = prop.read(); } } @@ -177,15 +173,9 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> & foreach(const QDeclarativeAction &action, applyList) { if (action.event) { if (action.event->isReversable()) { - if (action.reverseEvent) { //reverse the reverse - action.event->clearForwardBindings(); - action.event->rewind(); - action.event->clearReverseBindings(); - } else { - action.event->clearReverseBindings(); - action.event->rewind(); - action.event->clearForwardBindings(); - } + action.event->clearBindings(); + action.event->rewind(); + action.event->clearBindings(); } continue; } diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index 65bfdc1..4d4678a 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -75,44 +75,48 @@ void QDeclarativeUtilModule::defineModule() { - QML_REGISTER_TYPE(Qt,4,6,AnchorChanges,QDeclarativeAnchorChanges); - QML_REGISTER_TYPE(Qt,4,6,Behavior,QDeclarativeBehavior); - QML_REGISTER_TYPE(Qt,4,6,Binding,QDeclarativeBind); - QML_REGISTER_TYPE(Qt,4,6,ColorAnimation,QDeclarativeColorAnimation); - QML_REGISTER_TYPE(Qt,4,6,Connections,QDeclarativeConnections); - QML_REGISTER_TYPE(Qt,4,6,EaseFollow,QDeclarativeEaseFollow);; - QML_REGISTER_TYPE(Qt,4,6,FontLoader,QDeclarativeFontLoader); - QML_REGISTER_TYPE(Qt,4,6,ListElement,QDeclarativeListElement); - QML_REGISTER_TYPE(Qt,4,6,NumberAnimation,QDeclarativeNumberAnimation); - QML_REGISTER_TYPE(Qt,4,6,Package,QDeclarativePackage); - QML_REGISTER_TYPE(Qt,4,6,ParallelAnimation,QDeclarativeParallelAnimation); - QML_REGISTER_TYPE(Qt,4,6,ParentAction,QDeclarativeParentAction); - QML_REGISTER_TYPE(Qt,4,6,ParentAnimation,QDeclarativeParentAnimation); - QML_REGISTER_TYPE(Qt,4,6,ParentChange,QDeclarativeParentChange); - QML_REGISTER_TYPE(Qt,4,6,PauseAnimation,QDeclarativePauseAnimation); - QML_REGISTER_TYPE(Qt,4,6,PropertyAction,QDeclarativePropertyAction); - QML_REGISTER_TYPE(Qt,4,6,PropertyAnimation,QDeclarativePropertyAnimation); - QML_REGISTER_TYPE(Qt,4,6,RotationAnimation,QDeclarativeRotationAnimation); - QML_REGISTER_TYPE(Qt,4,6,ScriptAction,QDeclarativeScriptAction); - QML_REGISTER_TYPE(Qt,4,6,SequentialAnimation,QDeclarativeSequentialAnimation); - QML_REGISTER_TYPE(Qt,4,6,SpringFollow,QDeclarativeSpringFollow); - QML_REGISTER_TYPE(Qt,4,6,StateChangeScript,QDeclarativeStateChangeScript); - QML_REGISTER_TYPE(Qt,4,6,StateGroup,QDeclarativeStateGroup); - QML_REGISTER_TYPE(Qt,4,6,State,QDeclarativeState); - QML_REGISTER_TYPE(Qt,4,6,SystemPalette,QDeclarativeSystemPalette); - QML_REGISTER_TYPE(Qt,4,6,Timer,QDeclarativeTimer); - QML_REGISTER_TYPE(Qt,4,6,Transition,QDeclarativeTransition); - QML_REGISTER_TYPE(Qt,4,6,Vector3dAnimation,QDeclarativeVector3dAnimation); + qmlRegisterType<QDeclarativeAnchorAnimation>("Qt",4,6,"AnchorAnimation"); + qmlRegisterType<QDeclarativeAnchorChanges>("Qt",4,6,"AnchorChanges"); + qmlRegisterType<QDeclarativeBehavior>("Qt",4,6,"Behavior"); + qmlRegisterType<QDeclarativeBind>("Qt",4,6,"Binding"); + qmlRegisterType<QDeclarativeColorAnimation>("Qt",4,6,"ColorAnimation"); + qmlRegisterType<QDeclarativeConnections>("Qt",4,6,"Connections"); + qmlRegisterType<QDeclarativeEaseFollow>("Qt",4,6,"EaseFollow"); + qmlRegisterType<QDeclarativeFontLoader>("Qt",4,6,"FontLoader"); + qmlRegisterType<QDeclarativeListElement>("Qt",4,6,"ListElement"); + qmlRegisterType<QDeclarativeNumberAnimation>("Qt",4,6,"NumberAnimation"); + qmlRegisterType<QDeclarativePackage>("Qt",4,6,"Package"); + qmlRegisterType<QDeclarativeParallelAnimation>("Qt",4,6,"ParallelAnimation"); + qmlRegisterType<QDeclarativeParentAction>("Qt",4,6,"ParentAction"); + qmlRegisterType<QDeclarativeParentAnimation>("Qt",4,6,"ParentAnimation"); + qmlRegisterType<QDeclarativeParentChange>("Qt",4,6,"ParentChange"); + qmlRegisterType<QDeclarativePauseAnimation>("Qt",4,6,"PauseAnimation"); + qmlRegisterType<QDeclarativePropertyAction>("Qt",4,6,"PropertyAction"); + qmlRegisterType<QDeclarativePropertyAnimation>("Qt",4,6,"PropertyAnimation"); + qmlRegisterType<QDeclarativeRotationAnimation>("Qt",4,6,"RotationAnimation"); + qmlRegisterType<QDeclarativeScriptAction>("Qt",4,6,"ScriptAction"); + qmlRegisterType<QDeclarativeSequentialAnimation>("Qt",4,6,"SequentialAnimation"); + qmlRegisterType<QDeclarativeSpringFollow>("Qt",4,6,"SpringFollow"); + qmlRegisterType<QDeclarativeStateChangeScript>("Qt",4,6,"StateChangeScript"); + qmlRegisterType<QDeclarativeStateGroup>("Qt",4,6,"StateGroup"); + qmlRegisterType<QDeclarativeState>("Qt",4,6,"State"); + qmlRegisterType<QDeclarativeSystemPalette>("Qt",4,6,"SystemPalette"); + qmlRegisterType<QDeclarativeTimer>("Qt",4,6,"Timer"); + qmlRegisterType<QDeclarativeTransition>("Qt",4,6,"Transition"); + qmlRegisterType<QDeclarativeVector3dAnimation>("Qt",4,6,"Vector3dAnimation"); #ifndef QT_NO_XMLPATTERNS - QML_REGISTER_TYPE(Qt,4,6,XmlListModel,QDeclarativeXmlListModel); - QML_REGISTER_TYPE(Qt,4,6,XmlRole,QDeclarativeXmlListModelRole); + qmlRegisterType<QDeclarativeXmlListModel>("Qt",4,6,"XmlListModel"); + qmlRegisterType<QDeclarativeXmlListModelRole>("Qt",4,6,"XmlRole"); #endif - QML_REGISTER_NOCREATE_TYPE(QDeclarativeAnchors); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeAbstractAnimation); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeStateOperation); + qmlRegisterType<QDeclarativeAnchors>(); + qmlRegisterType<QDeclarativeAbstractAnimation>(); + qmlRegisterType<QDeclarativeStateOperation>(); - QML_REGISTER_CUSTOM_TYPE(Qt, 4,6, ListModel, QDeclarativeListModel, QDeclarativeListModelParser); - QML_REGISTER_CUSTOM_TYPE(Qt, 4,6, PropertyChanges, QDeclarativePropertyChanges, QDeclarativePropertyChangesParser); - QML_REGISTER_CUSTOM_TYPE(Qt, 4,6, Connections, QDeclarativeConnections, QDeclarativeConnectionsParser); + qmlRegisterCustomType<QDeclarativeListModel>("Qt", 4,6, "ListModel", "QDeclarativeListModel", + new QDeclarativeListModelParser); + qmlRegisterCustomType<QDeclarativePropertyChanges>("Qt", 4, 6, "PropertyChanges", "QDeclarativePropertyChanges", + new QDeclarativePropertyChangesParser); + qmlRegisterCustomType<QDeclarativeConnections>("Qt", 4, 6, "Connections", "QDeclarativeConnections", + new QDeclarativeConnectionsParser); } diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 735a009..59a062a 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -298,6 +298,7 @@ QDeclarativeView::~QDeclarativeView() void QDeclarativeView::setSource(const QUrl& url) { d->source = url; + d->engine.setBaseUrl(url); d->execute(); } @@ -458,8 +459,8 @@ void QDeclarativeView::setRootObject(QObject *obj) QPerformanceLog::clear(); d->root = item; d->qmlRoot = item; - connect(item, SIGNAL(widthChanged()), this, SLOT(sizeChanged())); - connect(item, SIGNAL(heightChanged()), this, SLOT(sizeChanged())); + connect(item, SIGNAL(widthChanged(qreal)), this, SLOT(sizeChanged())); + connect(item, SIGNAL(heightChanged(qreal)), this, SLOT(sizeChanged())); if (d->initialSize.height() <= 0 && d->qmlRoot->width() > 0) d->initialSize.setWidth(d->qmlRoot->width()); if (d->initialSize.height() <= 0 && d->qmlRoot->height() > 0) diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 49dbb27..01ae2ed 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -61,6 +61,9 @@ QT_BEGIN_NAMESPACE + + + typedef QPair<int, int> QDeclarativeXmlListRange; /*! @@ -111,6 +114,9 @@ class QDeclarativeXmlQuery : public QThread { Q_OBJECT public: + QDeclarativeXmlQuery(QObject *parent=0) + : QThread(parent), m_quit(false), m_restart(false), m_abort(false), m_queryId(0) { + } ~QDeclarativeXmlQuery() { m_mutex.lock(); m_quit = true; @@ -120,11 +126,6 @@ public: wait(); } - static QDeclarativeXmlQuery *instance() { - static QDeclarativeXmlQuery *query = new QDeclarativeXmlQuery; - return query; - } - void abort() { QMutexLocker locker(&m_mutex); m_abort = true; @@ -163,11 +164,6 @@ public: return m_removedItemRanges; } -private: - QDeclarativeXmlQuery(QObject *parent=0) - : QThread(parent), m_quit(false), m_restart(false), m_abort(false), m_queryId(0) { - } - Q_SIGNALS: void queryCompleted(int queryId, int size); @@ -217,8 +213,6 @@ private: QList<QDeclarativeXmlListRange> m_removedItemRanges; }; -//Q_GLOBAL_STATIC(QDeclarativeXmlQuery, QDeclarativeXmlQuery::instance()); - void QDeclarativeXmlQuery::doQueryJob() { QString r; @@ -396,7 +390,7 @@ public: QDeclarativeXmlListModelPrivate() : isComponentComplete(true), size(-1), highestRole(Qt::UserRole) , reply(0), status(QDeclarativeXmlListModel::Null), progress(0.0) - , queryId(-1), roleObjects() {} + , queryId(-1), roleObjects(), redirectCount(0) {} bool isComponentComplete; QUrl src; @@ -410,6 +404,7 @@ public: QNetworkReply *reply; QDeclarativeXmlListModel::Status status; qreal progress; + QDeclarativeXmlQuery qmlXmlQuery; int queryId; QList<QDeclarativeXmlListModelRole *> roleObjects; static void append_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, QDeclarativeXmlListModelRole *role); @@ -417,6 +412,7 @@ public: static void removeAt_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, int i); static void insert_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, int i, QDeclarativeXmlListModelRole *role); QList<QList<QVariant> > data; + int redirectCount; }; @@ -493,7 +489,8 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla QDeclarativeXmlListModel::QDeclarativeXmlListModel(QObject *parent) : QListModelInterface(*(new QDeclarativeXmlListModelPrivate), parent) { - connect(QDeclarativeXmlQuery::instance(), SIGNAL(queryCompleted(int,int)), + Q_D(QDeclarativeXmlListModel); + connect(&d->qmlXmlQuery, SIGNAL(queryCompleted(int,int)), this, SLOT(queryCompleted(int,int))); } @@ -575,8 +572,8 @@ void QDeclarativeXmlListModel::setSource(const QUrl &src) { Q_D(QDeclarativeXmlListModel); if (d->src != src) { - reload(); d->src = src; + reload(); emit sourceChanged(); } } @@ -726,7 +723,7 @@ void QDeclarativeXmlListModel::reload() if (!d->isComponentComplete) return; - QDeclarativeXmlQuery::instance()->abort(); + d->qmlXmlQuery.abort(); d->queryId = -1; int count = d->size; @@ -758,7 +755,7 @@ void QDeclarativeXmlListModel::reload() } if (!d->xml.isEmpty()) { - d->queryId = QDeclarativeXmlQuery::instance()->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects); + d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects); d->progress = 1.0; d->status = Ready; emit progressChanged(d->progress); @@ -778,9 +775,25 @@ void QDeclarativeXmlListModel::reload() this, SLOT(requestProgress(qint64,qint64))); } +#define XMLLISTMODEL_MAX_REDIRECT 16 + void QDeclarativeXmlListModel::requestFinished() { Q_D(QDeclarativeXmlListModel); + + d->redirectCount++; + if (d->redirectCount < XMLLISTMODEL_MAX_REDIRECT) { + QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = d->reply->url().resolved(redirect.toUrl()); + d->reply->deleteLater(); + d->reply = 0; + setSource(url); + return; + } + } + d->redirectCount = 0; + if (d->reply->error() != QNetworkReply::NoError) { disconnect(d->reply, 0, this, 0); d->reply->deleteLater(); @@ -789,7 +802,7 @@ void QDeclarativeXmlListModel::requestFinished() } else { d->status = Ready; QByteArray data = d->reply->readAll(); - d->queryId = QDeclarativeXmlQuery::instance()->doQuery(d->query, d->namespaces, data, &d->roleObjects); + d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, data, &d->roleObjects); disconnect(d->reply, 0, this, 0); d->reply->deleteLater(); d->reply = 0; @@ -815,10 +828,10 @@ void QDeclarativeXmlListModel::queryCompleted(int id, int size) return; bool sizeChanged = size != d->size; d->size = size; - d->data = QDeclarativeXmlQuery::instance()->modelData(); + d->data = d->qmlXmlQuery.modelData(); - QList<QDeclarativeXmlListRange> removed = QDeclarativeXmlQuery::instance()->removedItemRanges(); - QList<QDeclarativeXmlListRange> inserted = QDeclarativeXmlQuery::instance()->insertedItemRanges(); + QList<QDeclarativeXmlListRange> removed = d->qmlXmlQuery.removedItemRanges(); + QList<QDeclarativeXmlListRange> inserted = d->qmlXmlQuery.insertedItemRanges(); for (int i=0; i<removed.count(); i++) emit itemsRemoved(removed[i].first, removed[i].second); diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index 26edecc..ddf00ea 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -27,7 +27,8 @@ SOURCES += \ $$PWD/qdeclarativepixmapcache.cpp \ $$PWD/qdeclarativebehavior.cpp \ $$PWD/qdeclarativefontloader.cpp \ - $$PWD/qdeclarativestyledtext.cpp + $$PWD/qdeclarativestyledtext.cpp \ + $$PWD/qdeclarativelistmodelworkeragent.cpp HEADERS += \ $$PWD/qdeclarativeutilmodule_p.h\ @@ -49,6 +50,7 @@ HEADERS += \ $$PWD/qdeclarativestategroup_p.h \ $$PWD/qdeclarativetransition_p.h \ $$PWD/qdeclarativelistmodel_p.h\ + $$PWD/qdeclarativelistmodel_p_p.h\ $$PWD/qdeclarativelistaccessor_p.h \ $$PWD/qdeclarativeopenmetaobject_p.h \ $$PWD/qdeclarativenullablevalue_p_p.h \ @@ -59,7 +61,9 @@ HEADERS += \ $$PWD/qdeclarativepixmapcache_p.h \ $$PWD/qdeclarativebehavior_p.h \ $$PWD/qdeclarativefontloader_p.h \ - $$PWD/qdeclarativestyledtext_p.h + $$PWD/qdeclarativestyledtext_p.h \ + $$PWD/qdeclarativelistmodelworkeragent_p.h \ + $$PWD/qdeclarativelistmodelworkeragent_p_p.h contains(QT_CONFIG, xmlpatterns) { QT+=xmlpatterns diff --git a/src/gui/dialogs/qerrormessage.cpp b/src/gui/dialogs/qerrormessage.cpp index 0bca811..7be7481 100644 --- a/src/gui/dialogs/qerrormessage.cpp +++ b/src/gui/dialogs/qerrormessage.cpp @@ -70,10 +70,10 @@ extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp #if defined(QT_SOFTKEYS_ENABLED) #include <qaction.h> +#endif #ifdef Q_WS_S60 #include "private/qt_s60_p.h" #endif -#endif QT_BEGIN_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index a39ccfd..483eb62 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -1315,6 +1315,8 @@ void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event) return; } + d->proxyIsGivingFocus = true; + switch (event->reason()) { case Qt::TabFocusReason: { if (QWidget *focusChild = d->findFocusChild(0, true)) @@ -1328,10 +1330,11 @@ void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event) default: if (d->widget && d->widget->focusWidget()) { d->widget->focusWidget()->setFocus(event->reason()); - return; } break; } + + d->proxyIsGivingFocus = false; } /*! diff --git a/src/gui/graphicsview/qgraphicsproxywidget_p.h b/src/gui/graphicsview/qgraphicsproxywidget_p.h index 60eb058..8aed363 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget_p.h +++ b/src/gui/graphicsview/qgraphicsproxywidget_p.h @@ -118,6 +118,7 @@ public: quint32 styleChangeMode : 2; quint32 paletteChangeMode : 2; quint32 focusFromWidgetToProxy : 1; + quint32 proxyIsGivingFocus : 1; }; QT_END_NAMESPACE diff --git a/src/gui/gui.pro b/src/gui/gui.pro index d46f3b4..52531a3 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -51,12 +51,14 @@ contains(DEFINES,QT_EVAL):include($$QT_SOURCE_TREE/src/corelib/eval.pri) QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist DEFINES += Q_INTERNAL_QAPP_SRC -symbian: { +symbian { TARGET.UID3=0x2001B2DD - # ro-section in gui can exceed default allocated space, so move rw-section a little further - QMAKE_LFLAGS.ARMCC += --rw-base 0x800000 - QMAKE_LFLAGS.GCCE += -Tdata 0xC00000 + symbian-abld:symbian-sbsv2 { + # ro-section in gui can exceed default allocated space, so move rw-section a little further + QMAKE_LFLAGS.ARMCC += --rw-base 0x800000 + QMAKE_LFLAGS.GCCE += -Tdata 0xC00000 + } # Partial upgrade SIS file vendorinfo = \ @@ -70,7 +72,7 @@ symbian: { pu_header = "; Partial upgrade package for testing QtGui changes without reinstalling everything" \ "$${LITERAL_HASH}{\"Qt gui\"}, (0x2001E61C), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU" partial_upgrade.pkg_prerules = pu_header vendorinfo - partial_upgrade.sources = qtgui.dll + partial_upgrade.sources = $$QMAKE_LIBDIR_QT/QtGui.dll partial_upgrade.path = c:/sys/bin DEPLOYMENT = partial_upgrade $$DEPLOYMENT } diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index c6ad345..dce5c6a 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -1217,13 +1217,13 @@ void QSortFilterProxyModelPrivate::_q_sourceAboutToBeReset() { Q_Q(QSortFilterProxyModel); q->beginResetModel(); - invalidatePersistentIndexes(); - clear_mapping(); } void QSortFilterProxyModelPrivate::_q_sourceReset() { Q_Q(QSortFilterProxyModel); + invalidatePersistentIndexes(); + clear_mapping(); // All internal structures are deleted in clear() q->endResetModel(); update_source_sort_column(); diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 101dafe..61ad79d 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1232,17 +1232,17 @@ bool QTreeView::viewportEvent(QEvent *event) int oldBranch = d->hoverBranch; d->hoverBranch = d->itemDecorationAt(he->pos()); if (oldBranch != d->hoverBranch) { - QModelIndex oldIndex = d->modelIndex(oldBranch), - newIndex = d->modelIndex(d->hoverBranch); - if (oldIndex != newIndex) { - QRect oldRect = visualRect(oldIndex); - QRect newRect = visualRect(newIndex); - oldRect.setLeft(oldRect.left() - d->indent); - newRect.setLeft(newRect.left() - d->indent); - //we need to paint the whole items (including the decoration) so that when the user - //moves the mouse over those elements they are updated - viewport()->update(oldRect); - viewport()->update(newRect); + //we need to paint the whole items (including the decoration) so that when the user + //moves the mouse over those elements they are updated + if (oldBranch >= 0) { + int y = d->coordinateForItem(oldBranch); + int h = d->itemHeight(oldBranch); + viewport()->update(QRect(0, y, viewport()->width(), h)); + } + if (d->hoverBranch >= 0) { + int y = d->coordinateForItem(d->hoverBranch); + int h = d->itemHeight(d->hoverBranch); + viewport()->update(QRect(0, y, viewport()->width(), h)); } } break; } diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 4a15cf2..27b490b 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -52,6 +52,7 @@ #include "qstring.h" #include "qdebug.h" #include "qimage.h" +#include "qcombobox.h" #include "private/qkeymapper_p.h" #include "private/qfont_p.h" #ifndef QT_NO_STYLE_S60 @@ -1254,11 +1255,13 @@ void qt_init(QApplicationPrivate * /* priv */, int) } #endif +#ifdef QT_KEYPAD_NAVIGATION if (touch) { QApplicationPrivate::navigationMode = Qt::NavigationModeNone; } else { QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional; } +#endif #ifndef QT_NO_CURSOR //Check if window server pointer cursors are supported or not @@ -1407,11 +1410,13 @@ void QApplicationPrivate::leaveModal_sys(QWidget *widget) void QApplicationPrivate::openPopup(QWidget *popup) { + if (popup && qobject_cast<QComboBox *>(popup->parentWidget())) + static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(ETrue); + if (!QApplicationPrivate::popupWidgets) QApplicationPrivate::popupWidgets = new QWidgetList; QApplicationPrivate::popupWidgets->append(popup); - // Cancel focus widget pointer capture and long tap timer if (QApplication::focusWidget()) { static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer(); @@ -1450,6 +1455,9 @@ void QApplicationPrivate::openPopup(QWidget *popup) void QApplicationPrivate::closePopup(QWidget *popup) { + if (popup && qobject_cast<QComboBox *>(popup->parentWidget())) + static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(EFalse); + if (!QApplicationPrivate::popupWidgets) return; QApplicationPrivate::popupWidgets->removeAll(popup); diff --git a/src/gui/kernel/qcursor_s60.cpp b/src/gui/kernel/qcursor_s60.cpp index 54a9176..68e079e 100644 --- a/src/gui/kernel/qcursor_s60.cpp +++ b/src/gui/kernel/qcursor_s60.cpp @@ -44,7 +44,7 @@ #include <private/qapplication_p.h> #include <coecntrl.h> #include <qcursor.h> -#include <qt_s60_p.h> +#include <private/qt_s60_p.h> #include <qbitmap.h> #include <w32std.h> #include <qapplication.h> diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e5310ea..af5fcd1 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -6171,6 +6171,8 @@ void QWidget::setFocus(Qt::FocusReason reason) previousProxyFocus = topData->proxyWidget->widget()->focusWidget(); if (previousProxyFocus && previousProxyFocus->focusProxy()) previousProxyFocus = previousProxyFocus->focusProxy(); + if (previousProxyFocus == this && !topData->proxyWidget->d_func()->proxyIsGivingFocus) + return; } } #endif diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index bea2b6e..bfeef72 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -704,28 +704,13 @@ bool QRegion::intersects(const QRegion ®ion) const } /*! + \fn bool QRegion::intersects(const QRect &rect) const \since 4.2 Returns true if this region intersects with \a rect, otherwise returns false. */ -bool QRegion::intersects(const QRect &rect) const -{ - if (isEmpty() || rect.isNull()) - return false; - const QRect r = rect.normalized(); - if (!rect_intersects(boundingRect(), r)) - return false; - if (rectCount() == 1) - return true; - - const QVector<QRect> myRects = rects(); - for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it) - if (rect_intersects(r, *it)) - return true; - return false; -} #if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN) /*! @@ -4349,5 +4334,24 @@ bool QRegion::operator==(const QRegion &r) const return EqualRegion(d->qt_rgn, r.d->qt_rgn); } +bool QRegion::intersects(const QRect &rect) const +{ + if (isEmptyHelper(d->qt_rgn) || rect.isNull()) + return false; + + const QRect r = rect.normalized(); + if (!rect_intersects(d->qt_rgn->extents, r)) + return false; + if (d->qt_rgn->numRects == 1) + return true; + + const QVector<QRect> myRects = rects(); + for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it) + if (rect_intersects(r, *it)) + return true; + return false; +} + + #endif QT_END_NAMESPACE diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 4a563ed..cf545be 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE // returns the highest number closest to v, which is a power of 2 // NB! assumes 32 bit ints -int qt_next_power_of_two(int v) +static inline int qt_next_power_of_two(int v) { v--; v |= v >> 1; diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index d05c7e4..b25dce5 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -44,8 +44,8 @@ #include <QtGui/qpaintdevice.h> #include <private/qwidget_p.h> #include "qwindowsurface_s60_p.h" -#include "qpixmap_s60_p.h" -#include "qt_s60_p.h" +#include <private/qpixmap_s60_p.h> +#include <private/qt_s60_p.h> #include "private/qdrawhelper_p.h" QT_BEGIN_NAMESPACE diff --git a/src/gui/s60framework/s60framework.pri b/src/gui/s60framework/s60framework.pri index 6080e6d..e177a33 100644 --- a/src/gui/s60framework/s60framework.pri +++ b/src/gui/s60framework/s60framework.pri @@ -9,6 +9,8 @@ minimalAppResource31 = \ "END" MMP_RULES += minimalAppResource31 +SYMBIAN_RESOURCES += s60framework/s60main.rss + SOURCES += s60framework/qs60mainapplication.cpp \ s60framework/qs60mainappui.cpp \ s60framework/qs60maindocument.cpp diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index bf5a62e..a2ebebb 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -104,11 +104,11 @@ const int QS60StylePrivate::m_numberOfLayouts = const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { // *** generated pixel metrics *** -{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, -{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, -{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1} +{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,0,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, +{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,0,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, +{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,0,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,0,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,0,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1} // *** End of generated data *** }; @@ -2475,6 +2475,9 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w { int retValue = -1; switch (sh) { + case SH_ComboBox_Popup: + retValue = true; + break; case SH_Table_GridLineColor: retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 2, 0).rgba()); break; @@ -2690,6 +2693,19 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple height - 2 * frameThickness); } break; + case SC_ComboBoxListBoxPopup: { + const QRect desktopContent = QApplication::desktop()->availableGeometry(); + + // take the size of this and position bottom above available area + QRect popupRect; + const int width = desktopContent.width() - pixelMetric(PM_LayoutRightMargin) - pixelMetric(PM_LayoutLeftMargin); + popupRect.setWidth(width); + popupRect.setHeight(desktopContent.height()); //combobox resets height anyway based on content + popupRect.setBottom(desktopContent.bottom()); + popupRect.translate(pixelMetric(PM_LayoutLeftMargin), 0); + ret = popupRect; + } + break; default: break; } @@ -2844,9 +2860,13 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con ret = menuItem->rect; if (element == SE_ItemViewItemDecoration) { - if (menuItem->direction == Qt::RightToLeft) - ret.translate(ret.width()-indicatorWidth, 0); - ret.setWidth(indicatorWidth); + if (menuItem->icon.isNull()) { + ret = QRect(); + } else { + if (menuItem->direction == Qt::RightToLeft) + ret.translate(ret.width()-indicatorWidth, 0); + ret.setWidth(indicatorWidth); + } } else { ret = menuItem->rect; if (!menuItem->icon.isNull()) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index dd9e69e..9b85c04 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -73,7 +73,7 @@ #endif #endif #ifdef Q_OS_SYMBIAN -#include "qt_s60_p.h" +#include <private/qt_s60_p.h> #endif #include <QMutexLocker> diff --git a/src/gui/text/qfont_s60.cpp b/src/gui/text/qfont_s60.cpp index 52c77d6..ccd17a2 100644 --- a/src/gui/text/qfont_s60.cpp +++ b/src/gui/text/qfont_s60.cpp @@ -40,8 +40,8 @@ ****************************************************************************/ #include "qfont.h" -#include "qt_s60_p.h" -#include "qpixmap_s60_p.h" +#include <private/qt_s60_p.h> +#include <private/qpixmap_s60_p.h> #include "qmutex.h" QT_BEGIN_NAMESPACE diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 87a73df..621f666 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -45,8 +45,8 @@ #include "qfontengine_s60_p.h" #include "qabstractfileengine.h" #include "qdesktopservices.h" -#include "qpixmap_s60_p.h" -#include "qt_s60_p.h" +#include <private/qpixmap_s60_p.h> +#include <private/qt_s60_p.h> #include "qendian.h" #include <private/qcore_symbian_p.h> #if defined(QT_NO_FREETYPE) diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri index 3074367..bd2af85 100644 --- a/src/gui/util/util.pri +++ b/src/gui/util/util.pri @@ -41,5 +41,12 @@ embedded { symbian { LIBS += -lsendas2 -letext -lapmime - contains(QT_CONFIG, s60): LIBS += -lplatformenv -lCommonUI + contains(QT_CONFIG, s60) { + LIBS += -lplatformenv + contains(CONFIG, is_using_gnupoc) { + LIBS += -lcommonui + } else { + LIBS += -lCommonUI + } + } } diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index f71d250..c16f18a 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -532,9 +532,11 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView) QStyleOptionComboBox opt = comboStyleOption(); const bool usePopup = combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo); #ifndef QT_NO_SCROLLBAR +#ifndef Q_WS_S60 if (usePopup) view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); #endif +#endif if (combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) || usePopup) { view->setMouseTracking(true); @@ -2417,24 +2419,44 @@ void QComboBox::showPopup() // Position horizontally. listRect.moveLeft(above.x()); +#ifndef Q_WS_S60 // Position vertically so the curently selected item lines up // with the combo box. const QRect currentItemRect = view()->visualRect(view()->currentIndex()); const int offset = listRect.top() - currentItemRect.top(); listRect.moveTop(above.y() + offset - listRect.top()); +#endif // Clamp the listRect height and vertical position so we don't expand outside the // available screen geometry.This may override the vertical position, but it is more // important to show as much as possible of the popup. const int height = !boundToScreen ? listRect.height() : qMin(listRect.height(), screen.height()); +#ifdef Q_WS_S60 + //popup needs to be stretched with screen minimum dimension + listRect.setHeight(qMin(screen.height(), screen.width())); +#else listRect.setHeight(height); +#endif + if (boundToScreen) { if (listRect.top() < screen.top()) listRect.moveTop(screen.top()); if (listRect.bottom() > screen.bottom()) listRect.moveBottom(screen.bottom()); } +#ifdef Q_WS_S60 + if (screen.width() < screen.height()) { + // in portait, menu should be positioned above softkeys + listRect.moveBottom(screen.bottom()); + } else { + // landscape, menu should be at the right and horizontally centered + listRect.setWidth(listRect.height()); + listRect.moveCenter(screen.center()); + (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : + listRect.setLeft(screen.left()); + } +#endif } else if (!boundToScreen || listRect.height() <= belowHeight) { listRect.moveTopLeft(below); } else if (listRect.height() <= aboveHeight) { @@ -2643,6 +2665,34 @@ void QComboBox::changeEvent(QEvent *e) if (d->lineEdit) d->updateLineEditGeometry(); d->setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem); + +#ifdef Q_WS_S60 + if (d->container) { + QStyleOptionComboBox opt; + initStyleOption(&opt); + + if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { + const QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this)); + + QRect listRect(style()->subControlRect(QStyle::CC_ComboBox, &opt, + QStyle::SC_ComboBoxListBoxPopup, this)); + listRect.setHeight(qMin(screen.height(), screen.width())); + + if (screen.width() < screen.height()) { + // in portait, menu should be positioned above softkeys + listRect.moveBottom(screen.bottom()); + } else { + // landscape, menu should be at the right and horizontally centered + listRect.setWidth(listRect.height()); + listRect.moveCenter(screen.center()); + (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : + listRect.setLeft(screen.left()); + } + d->container->setGeometry(listRect); + } + } +#endif + // ### need to update scrollers etc. as well here break; case QEvent::EnabledChange: diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h index 74dfdc9..92d85cc 100644 --- a/src/gui/widgets/qcombobox_p.h +++ b/src/gui/widgets/qcombobox_p.h @@ -270,7 +270,9 @@ protected: const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionMenuItem opt = getStyleOption(option, index); +#ifndef Q_WS_S60 painter->fillRect(option.rect, opt.palette.background()); +#endif mCombo->style()->drawControl(QStyle::CE_MenuItem, &opt, painter, mCombo); } QSize sizeHint(const QStyleOptionViewItem &option, diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp index 7224768..4a9cfed 100644 --- a/src/gui/widgets/qmenu_symbian.cpp +++ b/src/gui/widgets/qmenu_symbian.cpp @@ -48,7 +48,7 @@ #include <private/qapplication_p.h> #include <private/qmenu_p.h> #include <private/qmenubar_p.h> -#include <qt_s60_p.h> +#include <private/qt_s60_p.h> #include <QtCore/qlibrary.h> #ifdef Q_WS_S60 diff --git a/src/gui/widgets/qsplitter.cpp b/src/gui/widgets/qsplitter.cpp index 965094e..f4076eb 100644 --- a/src/gui/widgets/qsplitter.cpp +++ b/src/gui/widgets/qsplitter.cpp @@ -1276,7 +1276,6 @@ void QSplitter::childEvent(QChildEvent *c) if (!c->child()->isWidgetType()) return; QWidget *w = static_cast<QWidget*>(c->child()); - if (c->added() && !d->blockChildAdd && !w->isWindow() && !d->findWidget(w)) { d->insertWidget_helper(d->list.count(), w, false); } else if (c->polished() && !d->blockChildAdd) { @@ -1313,18 +1312,16 @@ void QSplitter::setRubberBand(int pos) const int rBord = 3; // customizable? int hw = handleWidth(); if (!d->rubberBand) { - d->rubberBand = new QRubberBand(QRubberBand::Line); + QBoolBlocker b(d->blockChildAdd); + d->rubberBand = new QRubberBand(QRubberBand::Line, this); // For accessibility to identify this special widget. d->rubberBand->setObjectName(QLatin1String("qt_rubberband")); } - if (d->orient == Qt::Horizontal) - d->rubberBand->setGeometry(QRect(QPoint(pos + hw / 2 - rBord, r.y()), - QSize(2 * rBord, r.height())).translated(mapToGlobal(QPoint()))); - else - d->rubberBand->setGeometry(QRect(QPoint(r.x(), pos + hw / 2 - rBord), - QSize(r.width(), 2 * rBord)).translated(mapToGlobal(QPoint()))); - if (!d->rubberBand->isVisible()) - d->rubberBand->show(); + + const QRect newGeom = d->orient == Qt::Horizontal ? QRect(QPoint(pos + hw / 2 - rBord, r.y()), QSize(2 * rBord, r.height())) + : QRect(QPoint(r.x(), pos + hw / 2 - rBord), QSize(r.width(), 2 * rBord)); + d->rubberBand->setGeometry(newGeom); + d->rubberBand->show(); } /*! @@ -1555,16 +1552,14 @@ QSize QSplitter::sizeHint() const ensurePolished(); int l = 0; int t = 0; - QObjectList childList = children(); - for (int i = 0; i < childList.size(); ++i) { - if (QWidget *w = qobject_cast<QWidget *>(childList.at(i))) { - if (w->isHidden()) - continue; - QSize s = w->sizeHint(); - if (s.isValid()) { - l += d->pick(s); - t = qMax(t, d->trans(s)); - } + for (int i = 0; i < d->list.size(); ++i) { + QWidget *w = d->list.at(i)->widget; + if (w->isHidden()) + continue; + QSize s = w->sizeHint(); + if (s.isValid()) { + l += d->pick(s); + t = qMax(t, d->trans(s)); } } return orientation() == Qt::Horizontal ? QSize(l, t) : QSize(t, l); diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri index 6883dd8..937b8d6 100644 --- a/src/gui/widgets/widgets.pri +++ b/src/gui/widgets/widgets.pri @@ -164,6 +164,6 @@ wince*: { !static: QMAKE_WRITE_DEFAULT_RC = 1 } -symbian*: { +symbian: { SOURCES += widgets/qmenu_symbian.cpp } diff --git a/src/imports/imports.pro b/src/imports/imports.pro index 8b47043..3886f5c 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -SUBDIRS += widgets +SUBDIRS += widgets particles contains(QT_CONFIG, webkit): SUBDIRS += webkit contains(QT_CONFIG, multimedia): SUBDIRS += multimedia diff --git a/src/imports/multimedia/multimedia.pro b/src/imports/multimedia/multimedia.pro index f7a1d1b..16b3ace 100644 --- a/src/imports/multimedia/multimedia.pro +++ b/src/imports/multimedia/multimedia.pro @@ -17,10 +17,10 @@ SOURCES += \ qdeclarativevideo.cpp \ qmetadatacontrolmetaobject.cpp -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/Qt/multimedia -target.path = $$TARGETPATH +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -qmldir.files += $$QT_BUILD_TREE/imports/Qt/multimedia/qmldir +qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH INSTALLS += target qmldir diff --git a/config.tests/unix/largefile/largefiletest.cpp b/src/imports/particles/particles.cpp index bf25de9..ae3f318 100644 --- a/config.tests/unix/largefile/largefiletest.cpp +++ b/src/imports/particles/particles.cpp @@ -1,10 +1,10 @@ /**************************************************************************** ** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the config.tests of the Qt Toolkit. +** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -39,35 +39,31 @@ ** ****************************************************************************/ -/* Sample program for configure to test Large File support on target -platforms. -*/ +#include <QtDeclarative/qdeclarativeextensionplugin.h> +#include <QtDeclarative/qdeclarative.h> -#define _LARGEFILE_SOURCE -#define _LARGE_FILES -#define _FILE_OFFSET_BITS 64 -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <assert.h> -#include <stdio.h> +#include "qdeclarativeparticles_p.h" -int main( int, char **argv ) +QT_BEGIN_NAMESPACE + +class QParticlesQmlModule : public QDeclarativeExtensionPlugin { -// check that off_t can hold 2^63 - 1 and perform basic operations... -#define OFF_T_64 (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - if (OFF_T_64 % 2147483647 != 1) - return 1; + Q_OBJECT +public: + virtual void registerTypes(const char *uri) + { + Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.particles")); + qmlRegisterType<QDeclarativeParticleMotion>(uri,1,0,"ParticleMotion"); + qmlRegisterType<QDeclarativeParticleMotionGravity>(uri,1,0,"ParticleMotionGravity"); + qmlRegisterType<QDeclarativeParticleMotionLinear>(uri,1,0,"ParticleMotionLinear"); + qmlRegisterType<QDeclarativeParticleMotionWander>(uri,1,0,"ParticleMotionWander"); + qmlRegisterType<QDeclarativeParticles>(uri,1,0,"Particles"); + } +}; + +QT_END_NAMESPACE + +#include "particles.moc" - // stat breaks on SCO OpenServer - struct stat buf; - stat( argv[0], &buf ); - if (!S_ISREG(buf.st_mode)) - return 2; +Q_EXPORT_PLUGIN2(particlesqmlmodule, QT_PREPEND_NAMESPACE(QParticlesQmlModule)); - FILE *file = fopen( argv[0], "r" ); - off_t offset = ftello( file ); - fseek( file, offset, SEEK_CUR ); - fclose( file ); - return 0; -} diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro new file mode 100644 index 0000000..02d9ea6 --- /dev/null +++ b/src/imports/particles/particles.pro @@ -0,0 +1,20 @@ +TARGET = particles +TARGETPATH = Qt/labs/particles +include(../qimportbase.pri) + +QT += declarative + +SOURCES += \ + qdeclarativeparticles.cpp \ + particles.cpp + +HEADERS += \ + qdeclarativeparticles_p.h + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir +qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +INSTALLS += target qmldir diff --git a/src/declarative/graphicsitems/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp index 593c80a..bb6669a 100644 --- a/src/declarative/graphicsitems/qdeclarativeparticles.cpp +++ b/src/imports/particles/qdeclarativeparticles.cpp @@ -41,13 +41,12 @@ #include "qdeclarativeparticles_p.h" -#include "qdeclarativeitem_p.h" +#include <private/qdeclarativeitem_p.h> -#include <qdeclarativepixmapcache_p.h> -#include <qfxperf_p_p.h> -#include <qdeclarativeanimation_p_p.h> +#include <private/qdeclarativepixmapcache_p.h> +#include <private/qfxperf_p_p.h> +#include <QtCore/QAbstractAnimation> -#include <QNetworkReply> #include <QPainter> #include <QtGui/qdrawutil.h> #include <QVarLengthArray> @@ -412,6 +411,20 @@ public: QDeclarativeParticlesPrivate* d; }; +//an animation that just gives a tick +template<class T, void (T::*method)(int)> +class TickAnimationProxy : public QAbstractAnimation +{ +public: + TickAnimationProxy(T *p, QObject *parent = 0) : QAbstractAnimation(parent), m_p(p) {} + virtual int duration() const { return -1; } +protected: + virtual void updateCurrentTime(int msec) { (m_p->*method)(msec); } + +private: + T *m_p; +}; + //--------------------------------------------------------------------------- class QDeclarativeParticlesPrivate : public QDeclarativeItemPrivate { @@ -464,7 +477,7 @@ public: QList<QPair<int, int> > bursts;//countLeft, emissionRate pairs QList<QDeclarativeParticle> particles; - QTickAnimationProxy<QDeclarativeParticlesPrivate, &QDeclarativeParticlesPrivate::tick> clock; + TickAnimationProxy<QDeclarativeParticlesPrivate, &QDeclarativeParticlesPrivate::tick> clock; }; diff --git a/src/declarative/graphicsitems/qdeclarativeparticles_p.h b/src/imports/particles/qdeclarativeparticles_p.h index 06acbb9..993796d 100644 --- a/src/declarative/graphicsitems/qdeclarativeparticles_p.h +++ b/src/imports/particles/qdeclarativeparticles_p.h @@ -42,7 +42,7 @@ #ifndef QDECLARATIVEPARTICLES_H #define QDECLARATIVEPARTICLES_H -#include "qdeclarativeitem.h" +#include <QtDeclarative/qdeclarativeitem.h> QT_BEGIN_HEADER @@ -52,7 +52,7 @@ QT_MODULE(Declarative) class QDeclarativeParticle; class QDeclarativeParticles; -class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotion : public QObject +class QDeclarativeParticleMotion : public QObject { Q_OBJECT public: @@ -63,7 +63,7 @@ public: virtual void destroy(QDeclarativeParticle &); }; -class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionLinear : public QDeclarativeParticleMotion +class QDeclarativeParticleMotionLinear : public QDeclarativeParticleMotion { Q_OBJECT public: @@ -73,7 +73,7 @@ public: virtual void advance(QDeclarativeParticle &, int interval); }; -class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionGravity : public QDeclarativeParticleMotion +class QDeclarativeParticleMotionGravity : public QDeclarativeParticleMotion { Q_OBJECT @@ -106,7 +106,7 @@ private: qreal _accel; }; -class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionWander : public QDeclarativeParticleMotion +class QDeclarativeParticleMotionWander : public QDeclarativeParticleMotion { Q_OBJECT public: @@ -142,7 +142,7 @@ Q_SIGNALS: void xvarianceChanged(); void yvarianceChanged(); void paceChanged(); - + private: QDeclarativeParticles *particles; qreal _xvariance; @@ -151,7 +151,7 @@ private: }; class QDeclarativeParticlesPrivate; -class Q_DECLARATIVE_EXPORT QDeclarativeParticles : public QDeclarativeItem +class QDeclarativeParticles : public QDeclarativeItem { Q_OBJECT diff --git a/src/imports/particles/qmldir b/src/imports/particles/qmldir new file mode 100644 index 0000000..15456bb --- /dev/null +++ b/src/imports/particles/qmldir @@ -0,0 +1 @@ +plugin particles diff --git a/src/imports/qimportbase.pri b/src/imports/qimportbase.pri index ea12356..91f6552 100644 --- a/src/imports/qimportbase.pri +++ b/src/imports/qimportbase.pri @@ -13,7 +13,7 @@ isEmpty(TARGET) { QMLDIRFILE = $${_PRO_FILE_PWD_}/qmldir copy2build.input = QMLDIRFILE copy2build.output = $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir -isEmpty(vcproj):copy2build.variable_out = PRE_TARGETDEPS +!contains(TEMPLATE_PREFIX, vc):copy2build.variable_out = PRE_TARGETDEPS copy2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} copy2build.name = COPY ${QMAKE_FILE_IN} copy2build.CONFIG += no_link diff --git a/src/imports/webkit/plugin.cpp b/src/imports/webkit/plugin.cpp index 799fe9e..e3d73ec 100644 --- a/src/imports/webkit/plugin.cpp +++ b/src/imports/webkit/plugin.cpp @@ -54,7 +54,7 @@ public: virtual void registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("org.webkit")); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeWebSettings); + qmlRegisterType<QDeclarativeWebSettings>(); qmlRegisterType<QDeclarativeWebView>(uri,1,0,"WebView"); } }; diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp index d78ba28..f8b2b88 100644 --- a/src/imports/webkit/qdeclarativewebview.cpp +++ b/src/imports/webkit/qdeclarativewebview.cpp @@ -80,6 +80,7 @@ public: rendering(true) { } + void focusChanged(bool); QUrl url; // page url might be different if it has not loaded yet QWebPage *page; @@ -378,11 +379,12 @@ QVariant QDeclarativeWebView::evaluateJavaScript(const QString &scriptSource) return this->page()->mainFrame()->evaluateJavaScript(scriptSource); } -void QDeclarativeWebView::focusChanged(bool hasFocus) +void QDeclarativeWebViewPrivate::focusChanged(bool hasFocus) { + Q_Q(QDeclarativeWebView); QFocusEvent e(hasFocus ? QEvent::FocusIn : QEvent::FocusOut); - page()->event(&e); - QDeclarativeItem::focusChanged(hasFocus); + q->page()->event(&e); + QDeclarativeItemPrivate::focusChanged(hasFocus); } void QDeclarativeWebView::initialLayout() diff --git a/src/imports/webkit/qdeclarativewebview_p.h b/src/imports/webkit/qdeclarativewebview_p.h index 145e74b..36b18a6 100644 --- a/src/imports/webkit/qdeclarativewebview_p.h +++ b/src/imports/webkit/qdeclarativewebview_p.h @@ -42,8 +42,6 @@ #ifndef QDECLARATIVEWEBVIEW_H #define QDECLARATIVEWEBVIEW_H -#include "webkitqmlplugin_export.h" - #include <private/qdeclarativepainteditem_p.h> #include <QtGui/QAction> @@ -64,7 +62,7 @@ class QDeclarativeWebViewPrivate; class QNetworkRequest; class QDeclarativeWebView; -class WEBKITQMLPLUGIN_EXPORT QDeclarativeWebPage : public QWebPage +class QDeclarativeWebPage : public QWebPage { Q_OBJECT public: @@ -88,7 +86,7 @@ class QDeclarativeWebViewAttached; //### TODO: browser plugins -class WEBKITQMLPLUGIN_EXPORT QDeclarativeWebView : public QDeclarativePaintedItem +class QDeclarativeWebView : public QDeclarativePaintedItem { Q_OBJECT @@ -239,7 +237,6 @@ protected: void keyReleaseEvent(QKeyEvent* event); virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); - virtual void focusChanged(bool); virtual bool sceneEvent(QEvent *event); QDeclarativeWebView *createWindow(QWebPage::WebWindowType type); diff --git a/src/imports/webkit/qdeclarativewebview_p_p.h b/src/imports/webkit/qdeclarativewebview_p_p.h index 3ad9e9a..258b472 100644 --- a/src/imports/webkit/qdeclarativewebview_p_p.h +++ b/src/imports/webkit/qdeclarativewebview_p_p.h @@ -42,8 +42,6 @@ #ifndef QDECLARATIVEWEBVIEW_P_H #define QDECLARATIVEWEBVIEW_P_H -#include "webkitqmlplugin_export.h" - #include <qdeclarative.h> #include <QtWebKit/QWebPage> @@ -54,7 +52,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) -class WEBKITQMLPLUGIN_EXPORT QDeclarativeWebSettings : public QObject { +class QDeclarativeWebSettings : public QObject { Q_OBJECT Q_PROPERTY(QString standardFontFamily READ standardFontFamily WRITE setStandardFontFamily) diff --git a/src/imports/webkit/webkit.pro b/src/imports/webkit/webkit.pro index fdc12cc..ef08efe 100644 --- a/src/imports/webkit/webkit.pro +++ b/src/imports/webkit/webkit.pro @@ -3,17 +3,15 @@ TARGETPATH = org/webkit include(../qimportbase.pri) QT += webkit declarative -DEFINES += WEBKITQMLPLUGIN_EXPORTS SOURCES += qdeclarativewebview.cpp plugin.cpp HEADERS += qdeclarativewebview_p.h \ - qdeclarativewebview_p_p.h \ - webkitqmlplugin_export.h + qdeclarativewebview_p_p.h -QTDIR_build:DESTDIR = $$TARGETPATH -target.path = $$TARGETPATH +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -qmldir.files += $$QT_BUILD_TREE/imports/org/webkit/qmldir +qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH INSTALLS += target qmldir diff --git a/src/imports/widgets/widgets.cpp b/src/imports/widgets/widgets.cpp index ec21cc4..bc18e8a 100644 --- a/src/imports/widgets/widgets.cpp +++ b/src/imports/widgets/widgets.cpp @@ -118,15 +118,15 @@ public: { Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.widgets")); - QML_REGISTER_INTERFACE(QGraphicsLayoutItem); - QML_REGISTER_INTERFACE(QGraphicsLayout); + qmlRegisterInterface<QGraphicsLayoutItem>("QGraphicsLayoutItem"); + qmlRegisterInterface<QGraphicsLayout>("QGraphicsLayout"); qmlRegisterType<QGraphicsLinearLayoutStretchItemObject>(uri,4,6,"QGraphicsLinearLayoutStretchItem"); qmlRegisterType<QGraphicsLinearLayoutObject>(uri,4,6,"QGraphicsLinearLayout"); qmlRegisterType<QGraphicsGridLayoutObject>(uri,4,6,"QGraphicsGridLayout"); qmlRegisterExtendedType<QGraphicsView, QGraphicsViewDeclarativeUI>(uri,4,6,"QGraphicsView"); qmlRegisterExtendedType<QGraphicsScene,QGraphicsSceneDeclarativeUI>(uri,4,6,"QGraphicsScene"); qmlRegisterExtendedType<QGraphicsWidget,QGraphicsWidgetDeclarativeUI>(uri,4,6,"QGraphicsWidget"); - QML_REGISTER_INTERFACE(QGraphicsItem); + qmlRegisterInterface<QGraphicsItem>("QGraphicsItem"); } }; diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro index 02223d7..aa09b3c 100644 --- a/src/imports/widgets/widgets.pro +++ b/src/imports/widgets/widgets.pro @@ -12,11 +12,10 @@ HEADERS += \ graphicswidgets_p.h \ graphicslayouts_p.h -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/Qt/widgets -target.path = $$TARGETPATH +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -# install qmldir file -qmldir.files += qmldir -qmldir.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH +qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir +qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH INSTALLS += target qmldir diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index d1e7615..adc69ee 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -132,6 +132,11 @@ public: } + inline void addVertex(const GLfloat x, const GLfloat y) + { + vertexArray.add(QGLPoint(x, y)); + } + void addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline = true); void clear(); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index b90f0c2..ad07d9d 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1706,23 +1706,23 @@ void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragmen QGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c); QGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c); - vertexCoordinateArray.lineToArray(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); - vertexCoordinateArray.lineToArray(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y); - vertexCoordinateArray.lineToArray(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); - vertexCoordinateArray.lineToArray(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); - vertexCoordinateArray.lineToArray(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y); - vertexCoordinateArray.lineToArray(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y); + vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y); + vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); QGLRect src(fragments[i].sourceLeft * dx, fragments[i].sourceTop * dy, (fragments[i].sourceLeft + fragments[i].width) * dx, (fragments[i].sourceTop + fragments[i].height) * dy); - textureCoordinateArray.lineToArray(src.right, src.bottom); - textureCoordinateArray.lineToArray(src.right, src.top); - textureCoordinateArray.lineToArray(src.left, src.top); - textureCoordinateArray.lineToArray(src.left, src.top); - textureCoordinateArray.lineToArray(src.left, src.bottom); - textureCoordinateArray.lineToArray(src.right, src.bottom); + textureCoordinateArray.addVertex(src.right, src.bottom); + textureCoordinateArray.addVertex(src.right, src.top); + textureCoordinateArray.addVertex(src.left, src.top); + textureCoordinateArray.addVertex(src.left, src.top); + textureCoordinateArray.addVertex(src.left, src.bottom); + textureCoordinateArray.addVertex(src.right, src.bottom); qreal opacity = fragments[i].opacity * q->state()->opacity; opacityArray << opacity << opacity << opacity << opacity << opacity << opacity; diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 44814cc..53f6b4c 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -459,10 +459,6 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL) if (type == QPixmapData::SgImage && pixmap) { RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap); - // when "0" used as argument then - // default display, context are used - if (!context) - context = qt_vg_create_context(0, QInternal::Pixmap); destroyImages(); prevSize = QSize(); @@ -500,7 +496,7 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) } const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; - EGLImageKHR eglImage = eglCreateImageKHR(context->display(), + EGLImageKHR eglImage = eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)sgImage, @@ -515,7 +511,7 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) vgImage = vgCreateEGLImageTargetKHR(eglImage); if(vgGetError() != VG_NO_ERROR) { cleanup(); - eglDestroyImageKHR(context->display(), eglImage); + eglDestroyImageKHR(QEgl::display(), eglImage); SgDriver::Close(); return; } @@ -529,7 +525,7 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) prevSize = QSize(w, h); setSerialNumber(++qt_vg_pixmap_serial); // release stuff - eglDestroyImageKHR(context->display(), eglImage); + eglDestroyImageKHR(QEgl::display(), eglImage); SgDriver::Close(); } else if (type == QPixmapData::FbsBitmap) { CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap); @@ -624,7 +620,7 @@ void* QVGPixmapData::toNativeType(NativeType type) } const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; - EGLImageKHR eglImage = eglCreateImageKHR(context->display(), + EGLImageKHR eglImage = eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)sgImage, @@ -637,7 +633,7 @@ void* QVGPixmapData::toNativeType(NativeType type) VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage); if(vgGetError() != VG_NO_ERROR) { - eglDestroyImageKHR(context->display(), eglImage); + eglDestroyImageKHR(QEgl::display(), eglImage); sgImage->Close(); SgDriver::Close(); return 0; @@ -653,7 +649,7 @@ void* QVGPixmapData::toNativeType(NativeType type) } // release stuff vgDestroyImage(dstVgImage); - eglDestroyImageKHR(context->display(), eglImage); + eglDestroyImageKHR(QEgl::display(), eglImage); SgDriver::Close(); return reinterpret_cast<void*>(sgImage); } else if (type == QPixmapData::FbsBitmap) { diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp index 693312a..9b55fd2 100644 --- a/src/openvg/qwindowsurface_vgegl.cpp +++ b/src/openvg/qwindowsurface_vgegl.cpp @@ -230,9 +230,9 @@ static QEglContext *createContext(QPaintDevice *device) // Set the swap interval for the display. QByteArray interval = qgetenv("QT_VG_SWAP_INTERVAL"); if (!interval.isEmpty()) - eglSwapInterval(context->display(), interval.toInt()); + eglSwapInterval(QEgl::display(), interval.toInt()); else - eglSwapInterval(context->display(), 1); + eglSwapInterval(QEgl::display(), 1); #ifdef EGL_RENDERABLE_TYPE // Has the user specified an explicit EGL configuration to use? @@ -246,16 +246,16 @@ static QEglContext *createContext(QPaintDevice *device) EGLint matching = 0; EGLConfig cfg; if (eglChooseConfig - (context->display(), properties, &cfg, 1, &matching) && + (QEgl::display(), properties, &cfg, 1, &matching) && matching > 0) { // Check that the selected configuration actually supports OpenVG // and then create the context with it. EGLint id = 0; EGLint type = 0; eglGetConfigAttrib - (context->display(), cfg, EGL_CONFIG_ID, &id); + (QEgl::display(), cfg, EGL_CONFIG_ID, &id); eglGetConfigAttrib - (context->display(), cfg, EGL_RENDERABLE_TYPE, &type); + (QEgl::display(), cfg, EGL_RENDERABLE_TYPE, &type); if (cfgId == id && (type & EGL_OPENVG_BIT) != 0) { context->setConfig(cfg); if (!context->createContext()) { @@ -334,7 +334,7 @@ static void qt_vg_destroy_shared_context(QVGSharedContext *shared) shared->engine = 0; shared->context->doneCurrent(); if (shared->surface != EGL_NO_SURFACE) { - eglDestroySurface(shared->context->display(), shared->surface); + eglDestroySurface(QEgl::display(), shared->surface); shared->surface = EGL_NO_SURFACE; } delete shared->context; @@ -412,7 +412,7 @@ EGLSurface qt_vg_shared_surface(void) attribs[4] = EGL_NONE; } shared->surface = eglCreatePbufferSurface - (shared->context->display(), shared->context->config(), attribs); + (QEgl::display(), shared->context->config(), attribs); } return shared->surface; } @@ -555,7 +555,7 @@ void QVGEGLWindowSurfaceVGImage::beginPaint(QWidget *widget) context->makeCurrent(mainSurface()); recreateBackBuffer = false; if (backBufferSurface != EGL_NO_SURFACE) { - eglDestroySurface(context->display(), backBufferSurface); + eglDestroySurface(QEgl::display(), backBufferSurface); backBufferSurface = EGL_NO_SURFACE; } if (backBuffer != VG_INVALID_HANDLE) { @@ -568,7 +568,7 @@ void QVGEGLWindowSurfaceVGImage::beginPaint(QWidget *widget) if (backBuffer != VG_INVALID_HANDLE) { // Create an EGL surface for rendering into the VGImage. backBufferSurface = eglCreatePbufferFromClientBuffer - (context->display(), EGL_OPENVG_IMAGE, + (QEgl::display(), EGL_OPENVG_IMAGE, (EGLClientBuffer)(backBuffer), context->config(), NULL); if (backBufferSurface == EGL_NO_SURFACE) { @@ -704,7 +704,7 @@ QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget) #if defined(QVG_DIRECT_TO_WINDOW) // Did we get a direct to window rendering surface? EGLint buffer = 0; - if (eglQueryContext(context->display(), context->context(), + if (eglQueryContext(QEgl::display(), context->context(), EGL_RENDER_BUFFER, &buffer) && buffer == EGL_SINGLE_BUFFER) { needToSwap = false; @@ -714,7 +714,7 @@ QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget) // Try to force the surface back buffer to preserve its contents. if (needToSwap) { eglGetError(); // Clear error state first. - eglSurfaceAttrib(context->display(), surface, + eglSurfaceAttrib(QEgl::display(), surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); if (eglGetError() != EGL_SUCCESS) { qWarning("QVG: could not enable preserved swap"); diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h index 30f51e1..98d4222 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.h +++ b/src/plugins/bearer/symbian/qnetworksession_impl.h @@ -58,7 +58,7 @@ #include <QDateTime> #include <e32base.h> -#include <CommDbConnPref.h> +#include <commdbconnpref.h> #include <es_sock.h> #include <rconnmon.h> #ifdef SNAP_FUNCTIONALITY_AVAILABLE diff --git a/src/plugins/graphicssystems/trace/trace.pro b/src/plugins/graphicssystems/trace/trace.pro index d548a6c..07472e2 100644 --- a/src/plugins/graphicssystems/trace/trace.pro +++ b/src/plugins/graphicssystems/trace/trace.pro @@ -4,6 +4,7 @@ include(../../qpluginbase.pri) QT += network QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/graphicssystems +symbian:TARGET.UID3 = 0x2002130E SOURCES = main.cpp qgraphicssystem_trace.cpp diff --git a/src/plugins/imageformats/tiff/tiff.pro b/src/plugins/imageformats/tiff/tiff.pro index 85f618f..3cb64ad 100644 --- a/src/plugins/imageformats/tiff/tiff.pro +++ b/src/plugins/imageformats/tiff/tiff.pro @@ -58,7 +58,7 @@ contains(QT_CONFIG, system-tiff) { ../../../3rdparty/libtiff/libtiff/tif_wince.c \ ../../../3rdparty/libtiff/libtiff/tif_win32.c } - symbian*: { + symbian: { SOURCES += ../../../3rdparty/libtiff/port/lfind.c } } diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 730fdc5..42fbf9e 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -SUBDIRS *= accessible imageformats sqldrivers iconengines script bearer +SUBDIRS *= imageformats sqldrivers iconengines script bearer unix:!symbian { contains(QT_CONFIG,iconv)|contains(QT_CONFIG,gnu-libiconv):SUBDIRS *= codecs } else { @@ -9,6 +9,7 @@ unix:!symbian { !embedded:SUBDIRS *= graphicssystems embedded:SUBDIRS *= gfxdrivers decorations mousedrivers kbddrivers !win32:!embedded:!mac:!symbian:SUBDIRS *= inputmethods +!symbian:SUBDIRS += accessible symbian:SUBDIRS += s60 contains(QT_CONFIG, phonon): SUBDIRS *= phonon contains(QT_CONFIG, multimedia): SUBDIRS *= audio mediaservices diff --git a/src/plugins/s60/3_2/3_2.pro b/src/plugins/s60/3_2/3_2.pro index 468197d..7700677 100644 --- a/src/plugins/s60/3_2/3_2.pro +++ b/src/plugins/s60/3_2/3_2.pro @@ -10,7 +10,12 @@ contains(S60_VERSION, 3.1) { SOURCES += ../src/qlocale_3_2.cpp \ ../src/qdesktopservices_3_2.cpp \ ../src/qcoreapplication_3_2.cpp - LIBS += -lDirectoryLocalizer -lefsrv + contains(CONFIG, is_using_gnupoc) { + LIBS += -ldirectorylocalizer + } else { + LIBS += -lDirectoryLocalizer + } + LIBS += -lefsrv INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE } diff --git a/src/plugins/s60/5_0/5_0.pro b/src/plugins/s60/5_0/5_0.pro index 86e3dc9..164dfaa 100644 --- a/src/plugins/s60/5_0/5_0.pro +++ b/src/plugins/s60/5_0/5_0.pro @@ -10,7 +10,12 @@ contains(S60_VERSION, 3.1) { SOURCES += ../src/qlocale_3_2.cpp \ ../src/qdesktopservices_3_2.cpp \ ../src/qcoreapplication_3_2.cpp - LIBS += -lDirectoryLocalizer -lefsrv + contains(CONFIG, is_using_gnupoc) { + LIBS += -ldirectorylocalizer + } else { + LIBS += -lDirectoryLocalizer + } + LIBS += -lefsrv INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE } diff --git a/src/plugins/s60/s60pluginbase.pri b/src/plugins/s60/s60pluginbase.pri index c1aa4ef..1a6f4a2 100644 --- a/src/plugins/s60/s60pluginbase.pri +++ b/src/plugins/s60/s60pluginbase.pri @@ -4,6 +4,8 @@ include(../qpluginbase.pri) CONFIG -= plugin +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/s60 + MMP_RULES += NOEXPORTLIBRARY defBlock = \ diff --git a/src/qbase.pri b/src/qbase.pri index 835ed0e..4a75565 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -104,7 +104,7 @@ symbian { # built in this exact environment. *Never* use this when building a version # for release. contains(CONFIG, def_files) { - defFilePath=../s60installs + DEF_FILE=../s60installs } } load(armcc_warnings) diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 841fce4..b2e873f 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -11,26 +11,37 @@ symbian: { TARGET.UID3 = 0x2001E61C VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} - qtresources.sources = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/s60main.rsc + symbian-abld|symbian-sbsv2 { + qtresources.sources = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/s60main.rsc + } else { + qtresources.sources = $$QMAKE_LIBDIR_QT/s60main.rsc + DESTDIR = $$QMAKE_LIBDIR_QT + } qtresources.path = c:$$APP_RESOURCE_DIR qtlibraries.sources = \ - QtCore.dll \ - QtXml.dll \ - QtGui.dll \ - QtNetwork.dll \ - QtTest.dll \ - QtSql.dll + $$QMAKE_LIBDIR_QT/QtCore.dll \ + $$QMAKE_LIBDIR_QT/QtXml.dll \ + $$QMAKE_LIBDIR_QT/QtGui.dll \ + $$QMAKE_LIBDIR_QT/QtNetwork.dll \ + $$QMAKE_LIBDIR_QT/QtTest.dll \ + $$QMAKE_LIBDIR_QT/QtSql.dll + + symbian-abld|symbian-sbsv2 { + pluginLocations = $${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET) + } else { + pluginLocations = $$QT_BUILD_TREE/plugins/s60 + } qts60plugindeployment = \ "IF package(0x1028315F)" \ - " \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_5_0.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0.dll\"" \ + " \"$$pluginLocations/qts60plugin_5_0.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0.dll\"" \ "ELSEIF package(0x102752AE)" \ - " \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_3_2.dll\" - \"c:\\sys\\bin\\qts60plugin_3_2.dll\"" \ + " \"$$pluginLocations/qts60plugin_3_2.dll\" - \"c:\\sys\\bin\\qts60plugin_3_2.dll\"" \ "ELSEIF package(0x102032BE)" \ - " \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_3_1.dll\" - \"c:\\sys\\bin\\qts60plugin_3_1.dll\"" \ + " \"$$pluginLocations/qts60plugin_3_1.dll\" - \"c:\\sys\\bin\\qts60plugin_3_1.dll\"" \ "ELSE" \ - " \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_5_0.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0.dll\"" \ + " \"$$pluginLocations/qts60plugin_5_0.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0.dll\"" \ "ENDIF" qtlibraries.pkg_postrules += qts60plugindeployment @@ -61,18 +72,18 @@ symbian: { } qtlibraries.pkg_prerules += "(0x2002af5f), 0, 5, 0, {\"sqlite3\"}" - !contains(QT_CONFIG, no-jpeg): imageformats_plugins.sources += qjpeg.dll - !contains(QT_CONFIG, no-gif): imageformats_plugins.sources += qgif.dll - !contains(QT_CONFIG, no-mng): imageformats_plugins.sources += qmng.dll - !contains(QT_CONFIG, no-tiff): imageformats_plugins.sources += qtiff.dll - !contains(QT_CONFIG, no-ico): imageformats_plugins.sources += qico.dll + !contains(QT_CONFIG, no-jpeg): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qjpeg.dll + !contains(QT_CONFIG, no-gif): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qgif.dll + !contains(QT_CONFIG, no-mng): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qmng.dll + !contains(QT_CONFIG, no-tiff): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qtiff.dll + !contains(QT_CONFIG, no-ico): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qico.dll imageformats_plugins.path = c:$$QT_PLUGINS_BASE_DIR/imageformats - codecs_plugins.sources = qcncodecs.dll qjpcodecs.dll qtwcodecs.dll qkrcodecs.dll + codecs_plugins.sources = $$QT_BUILD_TREE/plugins/codecs/qcncodecs.dll $$QT_BUILD_TREE/plugins/codecs/qjpcodecs.dll $$QT_BUILD_TREE/plugins/codecs/qtwcodecs.dll $$QT_BUILD_TREE/plugins/codecs/qkrcodecs.dll codecs_plugins.path = c:$$QT_PLUGINS_BASE_DIR/codecs contains(QT_CONFIG, phonon-backend) { - phonon_backend_plugins.sources += phonon_mmf.dll + phonon_backend_plugins.sources += $$QMAKE_LIBDIR_QT/phonon_mmf.dll phonon_backend_plugins.path = c:$$QT_PLUGINS_BASE_DIR/phonon_backend DEPLOYMENT += phonon_backend_plugins @@ -83,7 +94,7 @@ symbian: { qtbackup.path = c:/private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) bearer_plugins.path = c:$$QT_PLUGINS_BASE_DIR/bearer - bearer_plugins.sources += qsymbianbearer.dll + bearer_plugins.sources += $$QT_BUILD_TREE/plugins/bearer/qsymbianbearer.dll DEPLOYMENT += qtresources \ qtlibraries \ @@ -94,37 +105,37 @@ symbian: { bearer_plugins contains(QT_CONFIG, svg): { - qtlibraries.sources += QtSvg.dll - imageformats_plugins.sources += qsvg.dll - iconengines_plugins.sources = qsvgicon.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtSvg.dll + imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qsvg.dll + iconengines_plugins.sources = $$QT_BUILD_TREE/plugins/iconengines/qsvgicon.dll iconengines_plugins.path = c:$$QT_PLUGINS_BASE_DIR/iconengines DEPLOYMENT += iconengines_plugins } contains(QT_CONFIG, phonon): { - qtlibraries.sources += phonon.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/phonon.dll } contains(QT_CONFIG, script): { - qtlibraries.sources += QtScript.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtScript.dll } contains(QT_CONFIG, xmlpatterns): { - qtlibraries.sources += QtXmlPatterns.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtXmlPatterns.dll } contains(QT_CONFIG, declarative): { - qtlibraries.sources += QtDeclarative.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtDeclarative.dll } graphicssystems_plugins.path = c:$$QT_PLUGINS_BASE_DIR/graphicssystems contains(QT_CONFIG, openvg) { - qtlibraries.sources += QtOpenVG.dll - graphicssystems_plugins.sources += qvggraphicssystem.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtOpenVG.dll + graphicssystems_plugins.sources += $$QT_BUILD_TREE/plugins/graphicssystems/qvggraphicssystem.dll } contains(QT_CONFIG, multimedia) { - qtlibraries.sources += QtMultimedia.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtMultimedia.dll } BLD_INF_RULES.prj_exports += "qt.iby $$CORE_MW_LAYER_IBY_EXPORT_PATH(qt.iby)" diff --git a/src/s60main/s60main.pro b/src/s60main/s60main.pro index 25fb188..1ba105d 100644 --- a/src/s60main/s60main.pro +++ b/src/s60main/s60main.pro @@ -17,7 +17,7 @@ symbian { qts60main_mcrt0.cpp # s60main needs to be built in ARM mode for GCCE to work. - MMP_RULES+="ALWAYS_BUILD_AS_ARM" + CONFIG += do_not_build_as_thumb # staticlib should not have any lib depencies in s60 # This seems not to work, some hard coded libs are still added as dependency diff --git a/src/s60main/s60main.rsg b/src/s60main/s60main.rsg new file mode 100644 index 0000000..8cdf3ba --- /dev/null +++ b/src/s60main/s60main.rsg @@ -0,0 +1,3 @@ +#define R_DEFAULT_DOCUMENT_NAME 0x55567002 +#define R_QT_WRAPPERAPP_MENUBAR 0x55567004 +#define R_QT_WRAPPERAPP_MENU 0x55567005 diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index a753f59..acfb2a4 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -497,6 +497,11 @@ QScriptDeclarativeClass::Value QScriptDeclarativeClass::call(Object *object, return Value(); } +bool QScriptDeclarativeClass::compare(Object *o, Object *o2) +{ + return o == o2; +} + QStringList QScriptDeclarativeClass::propertyNames(Object *object) { Q_UNUSED(object); diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h index a187391..714a67c 100644 --- a/src/script/bridge/qscriptdeclarativeclass_p.h +++ b/src/script/bridge/qscriptdeclarativeclass_p.h @@ -130,6 +130,7 @@ public: virtual void setProperty(Object *, const Identifier &name, const QScriptValue &); virtual QScriptValue::PropertyFlags propertyFlags(Object *, const Identifier &); virtual Value call(Object *, QScriptContext *); + virtual bool compare(Object *, Object *); virtual QStringList propertyNames(Object *); diff --git a/src/script/bridge/qscriptdeclarativeobject.cpp b/src/script/bridge/qscriptdeclarativeobject.cpp index a45bfbb..6e08b83 100644 --- a/src/script/bridge/qscriptdeclarativeobject.cpp +++ b/src/script/bridge/qscriptdeclarativeobject.cpp @@ -168,6 +168,23 @@ bool DeclarativeObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecStat return QScriptObjectDelegate::hasInstance(object, exec, value, proto); } +bool DeclarativeObjectDelegate::compareToObject(QScriptObject *o, JSC::ExecState *exec, JSC::JSObject *o2) +{ + if (!o2->inherits(&QScriptObject::info)) + return false; + + QScriptObject *scriptObject = static_cast<QScriptObject*>(o2); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + return false; + + DeclarativeObjectDelegate *other = static_cast<DeclarativeObjectDelegate*>(delegate); + if (m_class != other->m_class) + return false; + else + return m_class->compare(m_object, other->m_object); +} + } // namespace QScript QT_END_NAMESPACE diff --git a/src/script/bridge/qscriptdeclarativeobject_p.h b/src/script/bridge/qscriptdeclarativeobject_p.h index 5024a71..beb5af0 100644 --- a/src/script/bridge/qscriptdeclarativeobject_p.h +++ b/src/script/bridge/qscriptdeclarativeobject_p.h @@ -95,6 +95,8 @@ public: virtual bool hasInstance(QScriptObject*, JSC::ExecState*, JSC::JSValue value, JSC::JSValue proto); + bool compareToObject(QScriptObject *, JSC::ExecState *, JSC::JSObject *); + private: QScriptDeclarativeClass *m_class; QScriptDeclarativeClass::Object *m_object; diff --git a/src/src.pro b/src/src.pro index 0fbce6b..0033942 100644 --- a/src/src.pro +++ b/src/src.pro @@ -6,7 +6,10 @@ win32:SRC_SUBDIRS += src_winmain wince*:{ SRC_SUBDIRS += src_corelib src_xml src_gui src_sql src_network src_testlib } else:symbian { - SRC_SUBDIRS += src_s60main src_corelib src_xml src_gui src_network src_sql src_testlib src_s60installs + SRC_SUBDIRS += src_s60main src_corelib src_xml src_gui src_network src_sql src_testlib + !symbian-abld:!symbian-sbsv2 { + include(tools/tools.pro) + } } else { SRC_SUBDIRS += src_corelib src_xml src_network src_gui src_sql src_testlib !vxworks:contains(QT_CONFIG, qt3support): SRC_SUBDIRS += src_qt3support @@ -31,6 +34,10 @@ contains(QT_CONFIG, multimedia): SRC_SUBDIRS += src_multimedia SRC_SUBDIRS += src_plugins contains(QT_CONFIG, declarative): SRC_SUBDIRS += src_imports +# s60installs need to be at the end, because projects.pro does an ordered build, +# and s60installs depends on all the others. +symbian:SRC_SUBDIRS += src_s60installs + src_s60main.subdir = $$QT_SOURCE_TREE/src/s60main src_s60main.target = sub-s60main src_s60installs.subdir = $$QT_SOURCE_TREE/src/s60installs @@ -83,7 +90,7 @@ src_declarative.subdir = $$QT_SOURCE_TREE/src/declarative src_declarative.target = sub-declarative #CONFIG += ordered -!wince*:!symbian:!ordered { +!wince*:!ordered { src_corelib.depends = src_tools_moc src_tools_rcc src_gui.depends = src_corelib src_tools_uic embedded: src_gui.depends += src_network @@ -106,6 +113,7 @@ src_declarative.target = sub-declarative src_tools_activeqt.depends = src_tools_idc src_gui src_declarative.depends = src_xml src_gui src_script src_network src_svg src_plugins.depends = src_gui src_sql src_svg src_multimedia + src_s60installs.depends = $$TOOLS_SUBDIRS $$SRC_SUBDIRS src_imports.depends = src_gui src_declarative contains(QT_CONFIG, webkit) { src_webkit.depends = src_gui src_sql src_network src_xml @@ -123,7 +131,7 @@ src_declarative.target = sub-declarative contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2): src_plugins.depends += src_opengl } -!symbian { + # This creates a sub-src rule sub_src_target.CONFIG = recursive sub_src_target.recurse = $$TOOLS_SUBDIRS $$SRC_SUBDIRS @@ -170,6 +178,5 @@ for(subname, SRC_SUBDIRS) { debug.depends = $$EXTRA_DEBUG_TARGETS release.depends = $$EXTRA_RELEASE_TARGETS QMAKE_EXTRA_TARGETS += debug release -} SUBDIRS += $$SRC_SUBDIRS diff --git a/src/tools/bootstrap/bootstrap.pri b/src/tools/bootstrap/bootstrap.pri index b3ee948..15e746a 100644 --- a/src/tools/bootstrap/bootstrap.pri +++ b/src/tools/bootstrap/bootstrap.pri @@ -42,12 +42,12 @@ hpux-acc*|hpuxi-acc* { } else { contains(CONFIG, debug_and_release_target) { CONFIG(debug, debug|release) { - LIBS+=-L$$QT_BUILD_TREE/src/tools/bootstrap/debug + QMAKE_LIBDIR += $$QT_BUILD_TREE/src/tools/bootstrap/debug } else { - LIBS+=-L$$QT_BUILD_TREE/src/tools/bootstrap/release + QMAKE_LIBDIR += $$QT_BUILD_TREE/src/tools/bootstrap/release } } else { - LIBS += -L$$QT_BUILD_TREE/src/tools/bootstrap + QMAKE_LIBDIR += $$QT_BUILD_TREE/src/tools/bootstrap } LIBS += -lbootstrap } @@ -62,3 +62,12 @@ mac { LIBS += -framework CoreServices } +# Make dummy "sis" and "freeze" target to keep recursive "make sis/freeze" working. +sis_target.target = sis +sis_target.commands = +sis_target.depends = first +QMAKE_EXTRA_TARGETS += sis_target +freeze_target.target = freeze +freeze_target.commands = +freeze_target.depends = first +QMAKE_EXTRA_TARGETS += freeze_target diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 0dbb90f..48dc444 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -113,3 +113,13 @@ contains(QT_CONFIG, zlib) { lib.CONFIG = dummy_install INSTALLS += lib + +# Make dummy "sis" and "freeze" target to keep recursive "make sis/freeze" working. +sis_target.target = sis +sis_target.commands = +sis_target.depends = first +QMAKE_EXTRA_TARGETS += sis_target +freeze_target.target = freeze +freeze_target.commands = +freeze_target.depends = first +QMAKE_EXTRA_TARGETS += freeze_target diff --git a/src/tools/tools.pro b/src/tools/tools.pro index 25527e3..cd7cd9b 100644 --- a/src/tools/tools.pro +++ b/src/tools/tools.pro @@ -20,7 +20,7 @@ src_tools_uic3.target = sub-uic3 src_tools_idc.subdir = $$QT_SOURCE_TREE/src/tools/idc src_tools_idc.target = sub-idc -!wince*:!symbian:!ordered { +!wince*:!ordered { # Set dependencies for each subdir src_tools_moc.depends = src_tools_bootstrap src_tools_rcc.depends = src_tools_bootstrap diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 0150515..1267e7e 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -625,6 +625,11 @@ private: bool cdata; bool nsProcessing; QXmlLocator *locator; + +#ifdef Q_OS_SYMBIAN + // Workaround crash in elf2e32 under Wine. + virtual void dummy() {} +#endif }; /************************************************************** diff --git a/templates/.gitattributes b/templates/.gitattributes new file mode 100644 index 0000000..6540c78 --- /dev/null +++ b/templates/.gitattributes @@ -0,0 +1 @@ +pkg_template.pkg -crlf diff --git a/templates/.gitignore b/templates/.gitignore new file mode 100644 index 0000000..1bb0965 --- /dev/null +++ b/templates/.gitignore @@ -0,0 +1 @@ +!*.pkg diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index 143fbad..36eade8 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -55,7 +55,6 @@ SUBDIRS += \ qpacketprotocol \ # Cover qdeclarativerepeater \ # Cover qdeclarativeworkerscript \ # Cover - qdeclarativeworkerlistmodel \ # Cover qdeclarativevaluetypes \ # Cover qdeclarativexmlhttprequest \ # Cover qdeclarativeimageprovider \ # Cover diff --git a/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp b/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp index 9d8ba6c..6b7d57f 100644 --- a/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp +++ b/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp @@ -373,7 +373,6 @@ void tst_qdeclarativeanchors::crash1() QString expect = "QML Text (" + source.toString() + ":4:5" + ") Possible anchor loop detected on fill."; QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); - QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); // XXX ideally, should be one message QDeclarativeView *view = new QDeclarativeView(source); qApp->processEvents(); diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml b/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml index 12b1b7b..5e1891a 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml +++ b/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml @@ -10,7 +10,7 @@ Rectangle { width: 100; height: 100 color: Qt.rgba(1,0,0) Behavior on x { - NumberAnimation { objectName: "MyAnim"; running: true } + NumberAnimation {id: myAnim; objectName: "MyAnim"; running: true } } } diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml b/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml index 6419a6b..11b2d3a 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml +++ b/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml @@ -8,8 +8,8 @@ Rectangle { width: 100; height: 100; color: "green" Behavior on x { objectName: "MyBehavior" - NumberAnimation { duration: 200 } - NumberAnimation { duration: 1000 } + NumberAnimation {id: na1; duration: 200 } + NumberAnimation {id: na2; duration: 1000 } } } MouseArea { diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml b/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml index c28fa9a..5e72bca 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml +++ b/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml @@ -8,7 +8,7 @@ Rectangle { width: 100; height: 100; color: "green" Behavior on x { objectName: "MyBehavior"; - NumberAnimation { duration: 500; } + NumberAnimation {id: na; duration: 500; } } } MouseArea { diff --git a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp index f0117f5..be20ba1 100644 --- a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp +++ b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp @@ -58,9 +58,10 @@ private slots: void engineMethod(); void parentContext(); void setContextProperty(); - void addDefaultObject(); + void setContextObject(); void destruction(); void idAsContextProperty(); + void readOnlyContexts(); private: QDeclarativeEngine engine; @@ -224,24 +225,6 @@ private: int _c; }; -class TestObject2 : public QObject -{ - Q_OBJECT - Q_PROPERTY(int b READ b NOTIFY bChanged) - -public: - TestObject2() : _b(10) {} - - int b() const { return _b; } - void setB(int b) { _b = b; emit bChanged(); } - -signals: - void bChanged(); - -private: - int _b; -}; - #define TEST_CONTEXT_PROPERTY(ctxt, name, value) \ { \ QDeclarativeComponent component(&engine); \ @@ -367,35 +350,31 @@ void tst_qdeclarativecontext::setContextProperty() } } -void tst_qdeclarativecontext::addDefaultObject() +void tst_qdeclarativecontext::setContextObject() { QDeclarativeContext ctxt(&engine); TestObject to; - TestObject2 to2; to.setA(2); to.setB(192); to.setC(18); - to2.setB(111999); - ctxt.addDefaultObject(&to2); - ctxt.addDefaultObject(&to); + ctxt.setContextObject(&to); ctxt.setContextProperty("c", QVariant(9)); // Static context properties TEST_CONTEXT_PROPERTY(&ctxt, a, QVariant(2)); - TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(111999)); + TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(192)); TEST_CONTEXT_PROPERTY(&ctxt, c, QVariant(9)); to.setA(12); to.setB(100); to.setC(7); - to2.setB(1612); ctxt.setContextProperty("c", QVariant(3)); TEST_CONTEXT_PROPERTY(&ctxt, a, QVariant(12)); - TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(1612)); + TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(100)); TEST_CONTEXT_PROPERTY(&ctxt, c, QVariant(3)); // Changes in context properties @@ -449,6 +428,36 @@ void tst_qdeclarativecontext::idAsContextProperty() delete obj; } +// Internal contexts should be read-only +void tst_qdeclarativecontext::readOnlyContexts() +{ + QDeclarativeComponent component(&engine); + component.setData("import Qt 4.6; QtObject { id: me }", QUrl()); + + QObject *obj = component.create(); + QVERIFY(obj); + + QDeclarativeContext *context = qmlContext(obj); + QVERIFY(context); + + QVERIFY(qvariant_cast<QObject*>(context->contextProperty("me")) == obj); + QVERIFY(context->contextObject() == obj); + + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeContext: Cannot set property on internal context."); + context->setContextProperty("hello", 12); + QVERIFY(context->contextProperty("hello") == QVariant()); + + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeContext: Cannot set property on internal context."); + context->setContextProperty("hello", obj); + QVERIFY(context->contextProperty("hello") == QVariant()); + + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeContext: Cannot set context object for internal context."); + context->setContextObject(0); + QVERIFY(context->contextObject() == obj); + + delete obj; +} + QTEST_MAIN(tst_qdeclarativecontext) #include "tst_qdeclarativecontext.moc" diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml new file mode 100644 index 0000000..72edf6e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml @@ -0,0 +1,5 @@ +import Qt 4.6 + +QtObject { + Component.onCompleted: { var a = getObject(); a = null; } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml new file mode 100644 index 0000000..5897e2a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml @@ -0,0 +1,6 @@ +import Qt 4.6 + +QtObject { + property int test: getObjects().length + property bool test2: getObjects()[0].trueProperty +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp index 6a04704..a3bcb6a 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp @@ -43,7 +43,7 @@ class BaseExtensionObject : public QObject { Q_OBJECT - Q_PROPERTY(int baseExtendedProperty READ extendedProperty WRITE setExtendedProperty NOTIFY extendedPropertyChanged); + Q_PROPERTY(int baseExtendedProperty READ extendedProperty WRITE setExtendedProperty NOTIFY extendedPropertyChanged) public: BaseExtensionObject(QObject *parent) : QObject(parent), m_value(0) {} @@ -59,7 +59,7 @@ private: class ExtensionObject : public QObject { Q_OBJECT - Q_PROPERTY(int extendedProperty READ extendedProperty WRITE setExtendedProperty NOTIFY extendedPropertyChanged); + Q_PROPERTY(int extendedProperty READ extendedProperty WRITE setExtendedProperty NOTIFY extendedPropertyChanged) public: ExtensionObject(QObject *parent) : QObject(parent), m_value(0) {} @@ -74,12 +74,12 @@ private: void registerTypes() { - QML_REGISTER_TYPE(Qt.test, 1,0, MyQmlObject,MyQmlObject); - QML_REGISTER_TYPE(Qt.test, 1,0, MyDeferredObject,MyDeferredObject); - QML_REGISTER_TYPE(Qt.test, 1,0, MyQmlContainer,MyQmlContainer); - QML_REGISTER_EXTENDED_TYPE(Qt.test, 1,0, MyBaseExtendedObject,MyBaseExtendedObject,BaseExtensionObject); - QML_REGISTER_EXTENDED_TYPE(Qt.test, 1,0, MyExtendedObject,MyExtendedObject,ExtensionObject); - QML_REGISTER_TYPE(Qt.test, 1,0, MyTypeObject, MyTypeObject); + qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObject"); + qmlRegisterType<MyDeferredObject>("Qt.test", 1,0, "MyDeferredObject"); + qmlRegisterType<MyQmlContainer>("Qt.test", 1,0, "MyQmlContainer"); + qmlRegisterExtendedType<MyBaseExtendedObject, BaseExtensionObject>("Qt.test", 1,0, "MyBaseExtendedObject"); + qmlRegisterExtendedType<MyExtendedObject, ExtensionObject>("Qt.test", 1,0, "MyExtendedObject"); + qmlRegisterType<MyTypeObject>("Qt.test", 1,0, "MyTypeObject"); } #include "testtypes.moc" diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h index a283e3f..72dc3bb 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h @@ -205,28 +205,20 @@ public slots: class MyDefaultObject1 : public QObject { Q_OBJECT - Q_PROPERTY(int horseLegs READ horseLegs CONSTANT); - Q_PROPERTY(int antLegs READ antLegs CONSTANT); + Q_PROPERTY(int horseLegs READ horseLegs CONSTANT) + Q_PROPERTY(int antLegs READ antLegs CONSTANT) + Q_PROPERTY(int emuLegs READ emuLegs CONSTANT) public: int horseLegs() const { return 4; } int antLegs() const { return 6; } -}; - -class MyDefaultObject2 : public QObject -{ - Q_OBJECT - Q_PROPERTY(int antLegs READ antLegs CONSTANT); - Q_PROPERTY(int emuLegs READ emuLegs CONSTANT); -public: - int antLegs() const { return 5; } // Had an accident int emuLegs() const { return 2; } }; class MyDefaultObject3 : public QObject { Q_OBJECT - Q_PROPERTY(int antLegs READ antLegs CONSTANT); - Q_PROPERTY(int humanLegs READ humanLegs CONSTANT); + Q_PROPERTY(int antLegs READ antLegs CONSTANT) + Q_PROPERTY(int humanLegs READ humanLegs CONSTANT) public: int antLegs() const { return 7; } // Mutant int humanLegs() const { return 2; } @@ -237,9 +229,9 @@ class MyDeferredObject : public QObject { Q_OBJECT Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged) - Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty); - Q_PROPERTY(QObject *objectProperty2 READ objectProperty2 WRITE setObjectProperty2); - Q_CLASSINFO("DeferredPropertyNames", "value,objectProperty,objectProperty2"); + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty) + Q_PROPERTY(QObject *objectProperty2 READ objectProperty2 WRITE setObjectProperty2) + Q_CLASSINFO("DeferredPropertyNames", "value,objectProperty,objectProperty2") public: MyDeferredObject() : m_value(0), m_object(0), m_object2(0) {} @@ -266,7 +258,7 @@ QML_DECLARE_TYPE(MyDeferredObject); class MyBaseExtendedObject : public QObject { Q_OBJECT -Q_PROPERTY(int baseProperty READ baseProperty WRITE setBaseProperty); +Q_PROPERTY(int baseProperty READ baseProperty WRITE setBaseProperty) public: MyBaseExtendedObject() : m_value(0) {} @@ -281,7 +273,7 @@ QML_DECLARE_TYPE(MyBaseExtendedObject); class MyExtendedObject : public MyBaseExtendedObject { Q_OBJECT -Q_PROPERTY(int coreProperty READ coreProperty WRITE setCoreProperty); +Q_PROPERTY(int coreProperty READ coreProperty WRITE setCoreProperty) public: MyExtendedObject() : m_value(0) {} @@ -299,34 +291,34 @@ class MyTypeObject : public QObject Q_ENUMS(MyEnum) Q_FLAGS(MyFlags) - Q_PROPERTY(QString id READ id WRITE setId); - Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty); - Q_PROPERTY(QDeclarativeComponent *componentProperty READ componentProperty WRITE setComponentProperty); - Q_PROPERTY(MyFlags flagProperty READ flagProperty WRITE setFlagProperty); - Q_PROPERTY(MyEnum enumProperty READ enumProperty WRITE setEnumProperty); - Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty); - Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty); - Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty); - Q_PROPERTY(qreal realProperty READ realProperty WRITE setRealProperty); - Q_PROPERTY(double doubleProperty READ doubleProperty WRITE setDoubleProperty); - Q_PROPERTY(float floatProperty READ floatProperty WRITE setFloatProperty); - Q_PROPERTY(QColor colorProperty READ colorProperty WRITE setColorProperty); - Q_PROPERTY(QDate dateProperty READ dateProperty WRITE setDateProperty); - Q_PROPERTY(QTime timeProperty READ timeProperty WRITE setTimeProperty); - Q_PROPERTY(QDateTime dateTimeProperty READ dateTimeProperty WRITE setDateTimeProperty); - Q_PROPERTY(QPoint pointProperty READ pointProperty WRITE setPointProperty); - Q_PROPERTY(QPointF pointFProperty READ pointFProperty WRITE setPointFProperty); - Q_PROPERTY(QSize sizeProperty READ sizeProperty WRITE setSizeProperty); - Q_PROPERTY(QSizeF sizeFProperty READ sizeFProperty WRITE setSizeFProperty); - Q_PROPERTY(QRect rectProperty READ rectProperty WRITE setRectProperty NOTIFY rectPropertyChanged); - Q_PROPERTY(QRect rectProperty2 READ rectProperty2 WRITE setRectProperty2); - Q_PROPERTY(QRectF rectFProperty READ rectFProperty WRITE setRectFProperty); - Q_PROPERTY(bool boolProperty READ boolProperty WRITE setBoolProperty); - Q_PROPERTY(QVariant variantProperty READ variantProperty WRITE setVariantProperty); - Q_PROPERTY(QVector3D vectorProperty READ vectorProperty WRITE setVectorProperty); - Q_PROPERTY(QUrl urlProperty READ urlProperty WRITE setUrlProperty); - - Q_PROPERTY(QDeclarativeScriptString scriptProperty READ scriptProperty WRITE setScriptProperty); + Q_PROPERTY(QString id READ id WRITE setId) + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty) + Q_PROPERTY(QDeclarativeComponent *componentProperty READ componentProperty WRITE setComponentProperty) + Q_PROPERTY(MyFlags flagProperty READ flagProperty WRITE setFlagProperty) + Q_PROPERTY(MyEnum enumProperty READ enumProperty WRITE setEnumProperty) + Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty) + Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty) + Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty) + Q_PROPERTY(qreal realProperty READ realProperty WRITE setRealProperty) + Q_PROPERTY(double doubleProperty READ doubleProperty WRITE setDoubleProperty) + Q_PROPERTY(float floatProperty READ floatProperty WRITE setFloatProperty) + Q_PROPERTY(QColor colorProperty READ colorProperty WRITE setColorProperty) + Q_PROPERTY(QDate dateProperty READ dateProperty WRITE setDateProperty) + Q_PROPERTY(QTime timeProperty READ timeProperty WRITE setTimeProperty) + Q_PROPERTY(QDateTime dateTimeProperty READ dateTimeProperty WRITE setDateTimeProperty) + Q_PROPERTY(QPoint pointProperty READ pointProperty WRITE setPointProperty) + Q_PROPERTY(QPointF pointFProperty READ pointFProperty WRITE setPointFProperty) + Q_PROPERTY(QSize sizeProperty READ sizeProperty WRITE setSizeProperty) + Q_PROPERTY(QSizeF sizeFProperty READ sizeFProperty WRITE setSizeFProperty) + Q_PROPERTY(QRect rectProperty READ rectProperty WRITE setRectProperty NOTIFY rectPropertyChanged) + Q_PROPERTY(QRect rectProperty2 READ rectProperty2 WRITE setRectProperty2) + Q_PROPERTY(QRectF rectFProperty READ rectFProperty WRITE setRectFProperty) + Q_PROPERTY(bool boolProperty READ boolProperty WRITE setBoolProperty) + Q_PROPERTY(QVariant variantProperty READ variantProperty WRITE setVariantProperty) + Q_PROPERTY(QVector3D vectorProperty READ vectorProperty WRITE setVectorProperty) + Q_PROPERTY(QUrl urlProperty READ urlProperty WRITE setUrlProperty) + + Q_PROPERTY(QDeclarativeScriptString scriptProperty READ scriptProperty WRITE setScriptProperty) public: MyTypeObject() diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 4838288..caefdbf 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -126,6 +126,8 @@ private slots: void attachedPropertyScope(); void scriptConnect(); void scriptDisconnect(); + void ownership(); + void qlistqobjectMethods(); void bug1(); @@ -348,7 +350,6 @@ void tst_qdeclarativeecmascript::basicExpressions() MyQmlObject object2; MyQmlObject object3; MyDefaultObject1 default1; - MyDefaultObject2 default2; MyDefaultObject3 default3; object1.setStringProperty("Object1"); object2.setStringProperty("Object2"); @@ -357,13 +358,12 @@ void tst_qdeclarativeecmascript::basicExpressions() QDeclarativeContext context(engine.rootContext()); QDeclarativeContext nestedContext(&context); - context.addDefaultObject(&default1); - context.addDefaultObject(&default2); + context.setContextObject(&default1); context.setContextProperty("a", QVariant(1944)); context.setContextProperty("b", QVariant("Milk")); context.setContextProperty("object", &object1); context.setContextProperty("objectOverride", &object2); - nestedContext.addDefaultObject(&default3); + nestedContext.setContextObject(&default3); nestedContext.setContextProperty("b", QVariant("Cow")); nestedContext.setContextProperty("objectOverride", &object3); nestedContext.setContextProperty("millipedeLegs", QVariant(100)); @@ -889,6 +889,7 @@ void tst_qdeclarativeecmascript::dynamicDestruction() } QVERIFY(!createdQmlObject); + QDeclarativeEngine::setObjectOwnership(object, QDeclarativeEngine::JavaScriptOwnership); QMetaObject::invokeMethod(object, "killMe"); QVERIFY(object); QTest::qWait(0); @@ -1636,7 +1637,7 @@ void tst_qdeclarativeecmascript::listToVariant() MyQmlContainer container; QDeclarativeContext context(engine.rootContext()); - context.addDefaultObject(&container); + context.setContextObject(&container); QObject *object = component.create(&context); QVERIFY(object != 0); @@ -1890,7 +1891,94 @@ void tst_qdeclarativeecmascript::scriptDisconnect() delete object; } +} + +class OwnershipObject : public QObject +{ + Q_OBJECT +public: + OwnershipObject() { object = new QObject; } + + QPointer<QObject> object; + +public slots: + QObject *getObject() { return object; } +}; + +void tst_qdeclarativeecmascript::ownership() +{ + OwnershipObject own; + QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext()); + context->setContextObject(&own); + + { + QDeclarativeComponent component(&engine, TEST_FILE("ownership.qml")); + + QVERIFY(own.object != 0); + + QObject *object = component.create(context); + QDeclarativeEnginePrivate::getScriptEngine(&engine)->collectGarbage(); + + QCoreApplication::processEvents(QEventLoop::DeferredDeletion); + + QVERIFY(own.object == 0); + + delete object; + } + + own.object = new QObject(&own); + + { + QDeclarativeComponent component(&engine, TEST_FILE("ownership.qml")); + + QVERIFY(own.object != 0); + + QObject *object = component.create(context); + QDeclarativeEnginePrivate::getScriptEngine(&engine)->collectGarbage(); + QCoreApplication::processEvents(QEventLoop::DeferredDeletion); + + QVERIFY(own.object != 0); + + delete object; + } +} + +class QListQObjectMethodsObject : public QObject +{ + Q_OBJECT +public: + QListQObjectMethodsObject() { + m_objects.append(new MyQmlObject()); + m_objects.append(new MyQmlObject()); + } + + ~QListQObjectMethodsObject() { + qDeleteAll(m_objects); + } + +public slots: + QList<QObject *> getObjects() { return m_objects; } + +private: + QList<QObject *> m_objects; +}; + +// Tests that returning a QList<QObject*> from a method works +void tst_qdeclarativeecmascript::qlistqobjectMethods() +{ + QListQObjectMethodsObject obj; + QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext()); + context->setContextObject(&obj); + + QDeclarativeComponent component(&engine, TEST_FILE("qlistqobjectMethods.qml")); + + QObject *object = component.create(context); + + QCOMPARE(object->property("test").toInt(), 2); + QCOMPARE(object->property("test2").toBool(), true); + + delete object; } QTEST_MAIN(tst_qdeclarativeecmascript) diff --git a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro index 0c736b4..3ba50be 100644 --- a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro +++ b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro @@ -1,8 +1,9 @@ load(qttest_p4) -contains(QT_CONFIG,declarative): QT += declarative gui +contains(QT_CONFIG,declarative): QT += declarative gui network macx:CONFIG -= app_bundle -SOURCES += tst_qdeclarativefontloader.cpp +HEADERS += ../shared/testhttpserver.h +SOURCES += tst_qdeclarativefontloader.cpp ../shared/testhttpserver.cpp # Define SRCDIR equal to test's source directory DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp index a9762df..375e801 100644 --- a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp +++ b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp @@ -43,6 +43,9 @@ #include <QtDeclarative/qdeclarativecomponent.h> #include <private/qdeclarativefontloader_p.h> #include "../../../shared/util.h" +#include "../shared/testhttpserver.h" + +#define SERVER_PORT 14445 class tst_qdeclarativefontloader : public QObject @@ -57,16 +60,21 @@ private slots: void localFont(); void failLocalFont(); void webFont(); + void redirWebFont(); void failWebFont(); private slots: private: QDeclarativeEngine engine; + TestHTTPServer server; }; -tst_qdeclarativefontloader::tst_qdeclarativefontloader() +tst_qdeclarativefontloader::tst_qdeclarativefontloader() : + server(SERVER_PORT) { + server.serveDirectory(SRCDIR "/data"); + Q_ASSERT(server.isValid()); } void tst_qdeclarativefontloader::noFont() @@ -126,21 +134,38 @@ void tst_qdeclarativefontloader::failLocalFont() void tst_qdeclarativefontloader::webFont() { - QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://www.princexml.com/fonts/steffmann/Starburst.ttf\" }"; + QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://localhost:14445/tarzeau_ocr_a.ttf\" }"; + QDeclarativeComponent component(&engine); + + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create()); + + QVERIFY(fontObject != 0); + QVERIFY(fontObject->source() != QUrl("")); + QTRY_COMPARE(fontObject->name(), QString("OCRA")); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); +} + +void tst_qdeclarativefontloader::redirWebFont() +{ + server.addRedirect("olddir/oldname.ttf","../tarzeau_ocr_a.ttf"); + + QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://localhost:14445/olddir/oldname.ttf\" }"; QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create()); QVERIFY(fontObject != 0); QVERIFY(fontObject->source() != QUrl("")); - QTRY_COMPARE(fontObject->name(), QString("Starburst")); + QTRY_COMPARE(fontObject->name(), QString("OCRA")); QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); } void tst_qdeclarativefontloader::failWebFont() { - QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://wrong.address.com/Starburst.ttf\" }"; - QTest::ignoreMessage(QtWarningMsg, "Cannot load font: QUrl( \"http://wrong.address.com/Starburst.ttf\" ) "); + QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://localhost:14445/nonexist.ttf\" }"; + QTest::ignoreMessage(QtWarningMsg, "Cannot load font: QUrl( \"http://localhost:14445/nonexist.ttf\" ) "); QDeclarativeComponent component(&engine); component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create()); diff --git a/tests/auto/declarative/qdeclarativegridview/data/gridview-initCurrent.qml b/tests/auto/declarative/qdeclarativegridview/data/gridview-initCurrent.qml index 32833d2..cc3e549 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/gridview-initCurrent.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/gridview-initCurrent.qml @@ -1,6 +1,7 @@ import Qt 4.6 Rectangle { + property int current: grid.currentIndex width: 240 height: 320 color: "#ffffff" diff --git a/tests/auto/declarative/qdeclarativegridview/data/gridview.qml b/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml index ba6b807..ba6b807 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/gridview.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml diff --git a/tests/auto/declarative/qdeclarativegridview/data/propertychanges.qml b/tests/auto/declarative/qdeclarativegridview/data/propertychangestest.qml index da2e8d0..da2e8d0 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/propertychanges.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/propertychangestest.qml diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index a1edc53..dd594774 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -165,7 +165,7 @@ void tst_QDeclarativeGridView::items() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid"); @@ -213,7 +213,7 @@ void tst_QDeclarativeGridView::changed() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeFlickable *gridview = findItem<QDeclarativeFlickable>(canvas->rootObject(), "grid"); @@ -246,7 +246,7 @@ void tst_QDeclarativeGridView::inserted() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid"); @@ -331,7 +331,7 @@ void tst_QDeclarativeGridView::removed() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid"); @@ -495,7 +495,7 @@ void tst_QDeclarativeGridView::moved() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid"); @@ -703,6 +703,11 @@ void tst_QDeclarativeGridView::currentIndex() QCOMPARE(gridview->highlightItem()->x(), hlPosX); QCOMPARE(gridview->highlightItem()->y(), hlPosY); + // insert item before currentIndex + gridview->setCurrentIndex(28); + model.insertItem(0, "Foo", "1111"); + QCOMPARE(canvas->rootObject()->property("current").toInt(), 29); + delete canvas; } @@ -718,7 +723,7 @@ void tst_QDeclarativeGridView::changeFlow() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid"); @@ -815,7 +820,7 @@ void tst_QDeclarativeGridView::propertyChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView"); QVERIFY(gridView); @@ -855,7 +860,7 @@ void tst_QDeclarativeGridView::componentChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView"); QVERIFY(gridView); @@ -890,7 +895,7 @@ void tst_QDeclarativeGridView::modelChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeGridView *gridView = canvas->rootObject()->findChild<QDeclarativeGridView*>("gridView"); QVERIFY(gridView); @@ -924,7 +929,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid"); @@ -944,7 +949,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() } // Position on a currently visible item - gridview->positionViewAtIndex(4); + gridview->positionViewAtIndex(4, QDeclarativeGridView::Beginning); QCOMPARE(gridview->contentY(), 60.); // Confirm items positioned correctly @@ -958,7 +963,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() } // Position on an item beyond the visible items - gridview->positionViewAtIndex(21); + gridview->positionViewAtIndex(21, QDeclarativeGridView::Beginning); QCOMPARE(gridview->contentY(), 420.); // Confirm items positioned correctly @@ -972,7 +977,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() } // Position on an item that would leave empty space if positioned at the top - gridview->positionViewAtIndex(31); + gridview->positionViewAtIndex(31, QDeclarativeGridView::Beginning); QCOMPARE(gridview->contentY(), 520.); // Confirm items positioned correctly @@ -986,7 +991,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() } // Position at the beginning again - gridview->positionViewAtIndex(0); + gridview->positionViewAtIndex(0, QDeclarativeGridView::Beginning); QCOMPARE(gridview->contentY(), 0.); // Confirm items positioned correctly @@ -999,6 +1004,47 @@ void tst_QDeclarativeGridView::positionViewAtIndex() QCOMPARE(item->y(), (i/3)*60.); } + // Position at End + gridview->positionViewAtIndex(30, QDeclarativeGridView::End); + QCOMPARE(gridview->contentY(), 340.); + + // Position in Center + gridview->positionViewAtIndex(15, QDeclarativeGridView::Center); + QCOMPARE(gridview->contentY(), 170.); + + // Ensure at least partially visible + gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 170.); + + gridview->setContentY(302); + gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 302.); + + gridview->setContentY(360); + gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 300.); + + gridview->setContentY(60); + gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 60.); + + gridview->setContentY(20); + gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 100.); + + // Ensure completely visible + gridview->setContentY(120); + gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain); + QCOMPARE(gridview->contentY(), 120.); + + gridview->setContentY(302); + gridview->positionViewAtIndex(15, QDeclarativeGridView::Contain); + QCOMPARE(gridview->contentY(), 300.); + + gridview->setContentY(60); + gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain); + QCOMPARE(gridview->contentY(), 100.); + delete canvas; } diff --git a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp index 636c5e3..5f6d9a4 100644 --- a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp +++ b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp @@ -93,7 +93,7 @@ void tst_qdeclarativeinstruction::dump() QDeclarativeInstruction i; i.line = 2; i.type = QDeclarativeInstruction::SetId; - i.setId.value = 0; + i.setId.value = data->primitives.count() - 1; i.setId.index = 0; data->bytecode << i; } @@ -171,17 +171,17 @@ void tst_qdeclarativeinstruction::dump() i.line = 10; i.type = QDeclarativeInstruction::StoreString; i.storeString.propertyIndex = 7; - i.storeString.value = 1; + i.storeString.value = data->primitives.count() - 1; data->bytecode << i; } { - data->primitives << "http://www.nokia.com"; + data->urls << QUrl("http://www.nokia.com"); QDeclarativeInstruction i; i.line = 11; i.type = QDeclarativeInstruction::StoreUrl; i.storeUrl.propertyIndex = 8; - i.storeUrl.value = 2; + i.storeUrl.value = data->urls.count() - 1; data->bytecode << i; } @@ -290,7 +290,7 @@ void tst_qdeclarativeinstruction::dump() i.line = 23; i.type = QDeclarativeInstruction::StoreVariant; i.storeString.propertyIndex = 20; - i.storeString.value = 3; + i.storeString.value = data->primitives.count() - 1; data->bytecode << i; } @@ -326,7 +326,7 @@ void tst_qdeclarativeinstruction::dump() i.line = 27; i.type = QDeclarativeInstruction::StoreSignal; i.storeSignal.signalIndex = 2; - i.storeSignal.value = 4; + i.storeSignal.value = data->primitives.count() - 1; data->bytecode << i; } @@ -527,7 +527,7 @@ void tst_qdeclarativeinstruction::dump() << "8\t\t8\tSTORE_INTEGER\t\t5\t9" << "9\t\t9\tSTORE_BOOL\t\t6\ttrue" << "10\t\t10\tSTORE_STRING\t\t7\t1\t\t\"Test String\"" - << "11\t\t11\tSTORE_URL\t\t8\t2\t\t\"http://www.nokia.com\"" + << "11\t\t11\tSTORE_URL\t\t8\t0\t\tQUrl(\"http://www.nokia.com\") " << "12\t\t12\tSTORE_COLOR\t\t9\t\t\t\"ff00ff00\"" << "13\t\t13\tSTORE_DATE\t\t10\t9" << "14\t\t14\tSTORE_TIME\t\t11\t33" @@ -539,11 +539,11 @@ void tst_qdeclarativeinstruction::dump() << "20\t\t20\tSTORE_RECT\t\t17\t2" << "21\t\t21\tSTORE_RECTF\t\t18\t19" << "22\t\t22\tSTORE_VECTOR3D\t\t19\t9" - << "23\t\t23\tSTORE_VARIANT\t\t20\t3\t\t\"color(1, 1, 1, 1)\"" + << "23\t\t23\tSTORE_VARIANT\t\t20\t2\t\t\"color(1, 1, 1, 1)\"" << "24\t\t24\tSTORE_OBJECT\t\t21" << "25\t\t25\tSTORE_VARIANT_OBJECT\t22" << "26\t\t26\tSTORE_INTERFACE\t\t23" - << "27\t\t27\tSTORE_SIGNAL\t\t2\t4\t\t\"console.log(1921)\"" + << "27\t\t27\tSTORE_SIGNAL\t\t2\t3\t\t\"console.log(1921)\"" << "28\t\t28\tSTORE_SCRIPT\t\t2" << "29\t\t29\tSTORE_SCRIPT_STRING\t24\t3\t1" << "30\t\t30\tASSIGN_SIGNAL_OBJECT\t0\t\t\t\"mySignal\"" diff --git a/tests/auto/declarative/qdeclarativeitem/data/keynavigation.qml b/tests/auto/declarative/qdeclarativeitem/data/keynavigationtest.qml index 08da901..08da901 100644 --- a/tests/auto/declarative/qdeclarativeitem/data/keynavigation.qml +++ b/tests/auto/declarative/qdeclarativeitem/data/keynavigationtest.qml diff --git a/tests/auto/declarative/qdeclarativeitem/data/keys.qml b/tests/auto/declarative/qdeclarativeitem/data/keystest.qml index 7d34fc8..7d34fc8 100644 --- a/tests/auto/declarative/qdeclarativeitem/data/keys.qml +++ b/tests/auto/declarative/qdeclarativeitem/data/keystest.qml diff --git a/tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml b/tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml new file mode 100644 index 0000000..bf4dd85 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml @@ -0,0 +1,10 @@ +import Qt 4.6 + +Item { + Item { + objectName: "item" + } + Item { + objectName: "parentItem" + } +}
\ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp index bbcc86e..ba69cd8 100644 --- a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp +++ b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp @@ -60,6 +60,7 @@ private slots: void clip(); void mapCoordinates(); void mapCoordinates_data(); + void propertyChanges(); private: template<typename T> @@ -119,7 +120,7 @@ void tst_QDeclarativeItem::keys() canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keys.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keystest.qml")); canvas->show(); qApp->processEvents(); @@ -214,7 +215,7 @@ void tst_QDeclarativeItem::keyNavigation() QDeclarativeView *canvas = new QDeclarativeView(0); canvas->setFixedSize(240,320); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigation.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml")); canvas->show(); qApp->processEvents(); @@ -289,7 +290,7 @@ void tst_QDeclarativeItem::smooth() QDeclarativeComponent component(&engine); component.setData("import Qt 4.6; Item { smooth: false; }", QUrl::fromLocalFile("")); QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); - QSignalSpy spy(item, SIGNAL(smoothChanged())); + QSignalSpy spy(item, SIGNAL(smoothChanged(bool))); QVERIFY(item); QVERIFY(!item->smooth()); @@ -297,6 +298,10 @@ void tst_QDeclarativeItem::smooth() item->setSmooth(true); QVERIFY(item->smooth()); QCOMPARE(spy.count(),1); + QList<QVariant> arguments = spy.first(); + QVERIFY(arguments.count() == 1); + QVERIFY(arguments.at(0).toBool() == true); + item->setSmooth(true); QCOMPARE(spy.count(),1); @@ -314,13 +319,18 @@ void tst_QDeclarativeItem::clip() QDeclarativeComponent component(&engine); component.setData("import Qt 4.6\nItem { clip: false\n }", QUrl::fromLocalFile("")); QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); - QSignalSpy spy(item, SIGNAL(clipChanged())); + QSignalSpy spy(item, SIGNAL(clipChanged(bool))); QVERIFY(item); QVERIFY(!item->clip()); item->setClip(true); QVERIFY(item->clip()); + + QList<QVariant> arguments = spy.first(); + QVERIFY(arguments.count() == 1); + QVERIFY(arguments.at(0).toBool() == true); + QCOMPARE(spy.count(),1); item->setClip(true); QCOMPARE(spy.count(),1); @@ -392,6 +402,84 @@ void tst_QDeclarativeItem::mapCoordinates_data() QTest::newRow(QTest::toString(i)) << i << i; } +void tst_QDeclarativeItem::propertyChanges() +{ + QDeclarativeView *canvas = new QDeclarativeView(0); + canvas->setFixedSize(240,320); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->show(); + + QEvent wa(QEvent::WindowActivate); + QApplication::sendEvent(canvas, &wa); + QFocusEvent fe(QEvent::FocusIn); + QApplication::sendEvent(canvas, &fe); + + QDeclarativeItem *item = findItem<QDeclarativeItem>(canvas->rootObject(), "item"); + QDeclarativeItem *parentItem = findItem<QDeclarativeItem>(canvas->rootObject(), "parentItem"); + + QVERIFY(item); + QVERIFY(parentItem); + + QSignalSpy parentSpy(item, SIGNAL(parentChanged(QDeclarativeItem *))); + QSignalSpy widthSpy(item, SIGNAL(widthChanged(qreal))); + QSignalSpy heightSpy(item, SIGNAL(heightChanged(qreal))); + QSignalSpy baselineOffsetSpy(item, SIGNAL(baselineOffsetChanged(qreal))); + QSignalSpy childrenRectSpy(parentItem, SIGNAL(childrenRectChanged(QRectF))); + QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool))); + QSignalSpy wantsFocusSpy(parentItem, SIGNAL(wantsFocusChanged(bool))); + + item->setParentItem(parentItem); + item->setWidth(100.0); + item->setHeight(200.0); + item->setFocus(true); + item->setBaselineOffset(10.0); + + QCOMPARE(item->parentItem(), parentItem); + QCOMPARE(parentSpy.count(),1); + QList<QVariant> parentArguments = parentSpy.first(); + QVERIFY(parentArguments.count() == 1); + QCOMPARE(item->parentItem(), qvariant_cast<QDeclarativeItem *>(parentArguments.at(0))); + + QCOMPARE(item->width(), 100.0); + QCOMPARE(widthSpy.count(),1); + QList<QVariant> widthArguments = widthSpy.first(); + QVERIFY(widthArguments.count() == 1); + QCOMPARE(item->width(), widthArguments.at(0).toReal()); + + QCOMPARE(item->height(), 200.0); + QCOMPARE(heightSpy.count(),1); + QList<QVariant> heightArguments = heightSpy.first(); + QVERIFY(heightArguments.count() == 1); + QCOMPARE(item->height(), heightArguments.at(0).toReal()); + + QCOMPARE(item->baselineOffset(), 10.0); + QCOMPARE(baselineOffsetSpy.count(),1); + QList<QVariant> baselineOffsetArguments = baselineOffsetSpy.first(); + QVERIFY(baselineOffsetArguments.count() == 1); + QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal()); + + QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0)); + QCOMPARE(childrenRectSpy.count(),2); + QList<QVariant> childrenRectArguments = childrenRectSpy.at(1); + QVERIFY(childrenRectArguments.count() == 1); + QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF()); + + QCOMPARE(item->hasFocus(), true); + QCOMPARE(focusSpy.count(),1); + QList<QVariant> focusArguments = focusSpy.first(); + QVERIFY(focusArguments.count() == 1); + QCOMPARE(focusArguments.at(0).toBool(), true); + + QCOMPARE(parentItem->hasFocus(), false); + QCOMPARE(parentItem->wantsFocus(), true); + QCOMPARE(wantsFocusSpy.count(),1); + QList<QVariant> wantsFocusArguments = wantsFocusSpy.first(); + QVERIFY(wantsFocusArguments.count() == 1); + QCOMPARE(wantsFocusArguments.at(0).toBool(), true); + + delete canvas; +} + template<typename T> T *tst_QDeclarativeItem::findItem(QGraphicsObject *parent, const QString &objectName) { diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir index b32f82b..303c5c8 100644 --- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir @@ -1,3 +1,3 @@ -Test 0.0 Test.qml -TestSubDir 0.0 TestSubDir.qml -TestLocal 0.0 TestLocal.qml +Test Test.qml +TestSubDir TestSubDir.qml +TestLocal TestLocal.qml diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir index f7016c7..a54f7df 100644 --- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir @@ -1 +1 @@ -SubTest 0.0 SubTest.qml +SubTest SubTest.qml diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp index 9ffe28a..6efe755 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp @@ -42,15 +42,15 @@ void registerTypes() { - QML_REGISTER_INTERFACE(MyInterface); - QML_REGISTER_TYPE(Test,1,0,MyQmlObject,MyQmlObject); - QML_REGISTER_TYPE(Test,1,0,MyTypeObject,MyTypeObject); - QML_REGISTER_TYPE(Test,1,0,MyContainer,MyContainer); - QML_REGISTER_TYPE(Test,1,0,MyPropertyValueSource,MyPropertyValueSource); - QML_REGISTER_TYPE(Test,1,0,MyDotPropertyObject,MyDotPropertyObject); - QML_REGISTER_TYPE(Test,1,0,MyNamespacedType,MyNamespace::MyNamespacedType); - QML_REGISTER_TYPE(Test,1,0,MySecondNamespacedType,MyNamespace::MySecondNamespacedType); - QML_REGISTER_NOCREATE_TYPE(MyGroupedObject); + qmlRegisterInterface<MyInterface>("MyInterface"); + qmlRegisterType<MyQmlObject>("Test",1,0,"MyQmlObject"); + qmlRegisterType<MyTypeObject>("Test",1,0,"MyTypeObject"); + qmlRegisterType<MyContainer>("Test",1,0,"MyContainer"); + qmlRegisterType<MyPropertyValueSource>("Test",1,0,"MyPropertyValueSource"); + qmlRegisterType<MyDotPropertyObject>("Test",1,0,"MyDotPropertyObject"); + qmlRegisterType<MyNamespace::MyNamespacedType>("Test",1,0,"MyNamespacedType"); + qmlRegisterType<MyNamespace::MySecondNamespacedType>("Test",1,0,"MySecondNamespacedType"); + qmlRegisterType<MyGroupedObject>(); } QVariant myCustomVariantTypeConverter(const QString &data) diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.h b/tests/auto/declarative/qdeclarativelanguage/testtypes.h index df93dc8..4963e2e 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.h +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.h @@ -106,8 +106,8 @@ class MyQmlObject : public QObject, public MyInterface, public QDeclarativeParse Q_PROPERTY(QRect rect READ rect WRITE setRect) Q_PROPERTY(QMatrix matrix READ matrix WRITE setMatrix) //assumed to be unsupported by QML Q_PROPERTY(MyInterface *interfaceProperty READ interface WRITE setInterface) - Q_PROPERTY(int onLiteralSignal READ onLiteralSignal WRITE setOnLiteralSignal); - Q_PROPERTY(MyCustomVariantType customType READ customType WRITE setCustomType); + Q_PROPERTY(int onLiteralSignal READ onLiteralSignal WRITE setOnLiteralSignal) + Q_PROPERTY(MyCustomVariantType customType READ customType WRITE setCustomType) Q_PROPERTY(MyQmlObject *qmlobjectProperty READ qmlobject WRITE setQmlobject) Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal) @@ -135,7 +135,7 @@ public: static MyAttachedObject *qmlAttachedProperties(QObject *other) { return new MyAttachedObject(other); } - Q_CLASSINFO("DefaultMethod", "basicSlot()"); + Q_CLASSINFO("DefaultMethod", "basicSlot()") int onLiteralSignal() const { return m_value; } void setOnLiteralSignal(int v) { m_value = v; } @@ -171,8 +171,8 @@ QML_DECLARE_TYPE(MyQmlObject); class MyGroupedObject : public QObject { Q_OBJECT - Q_PROPERTY(QDeclarativeScriptString script READ script WRITE setScript); - Q_PROPERTY(int value READ value WRITE setValue); + Q_PROPERTY(QDeclarativeScriptString script READ script WRITE setScript) + Q_PROPERTY(int value READ value WRITE setValue) public: QDeclarativeScriptString script() const { return m_script; } void setScript(const QDeclarativeScriptString &s) { m_script = s; } @@ -194,36 +194,36 @@ class MyTypeObject : public QObject Q_ENUMS(MyEnum) Q_FLAGS(MyFlags) - Q_PROPERTY(QString id READ id WRITE setId); - Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty); - Q_PROPERTY(QDeclarativeComponent *componentProperty READ componentProperty WRITE setComponentProperty); - Q_PROPERTY(MyFlags flagProperty READ flagProperty WRITE setFlagProperty); - Q_PROPERTY(MyEnum enumProperty READ enumProperty WRITE setEnumProperty); - Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty); - Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty); - Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty); - Q_PROPERTY(qreal realProperty READ realProperty WRITE setRealProperty); - Q_PROPERTY(double doubleProperty READ doubleProperty WRITE setDoubleProperty); - Q_PROPERTY(float floatProperty READ floatProperty WRITE setFloatProperty); - Q_PROPERTY(QColor colorProperty READ colorProperty WRITE setColorProperty); - Q_PROPERTY(QDate dateProperty READ dateProperty WRITE setDateProperty); - Q_PROPERTY(QTime timeProperty READ timeProperty WRITE setTimeProperty); - Q_PROPERTY(QDateTime dateTimeProperty READ dateTimeProperty WRITE setDateTimeProperty); - Q_PROPERTY(QPoint pointProperty READ pointProperty WRITE setPointProperty); - Q_PROPERTY(QPointF pointFProperty READ pointFProperty WRITE setPointFProperty); - Q_PROPERTY(QSize sizeProperty READ sizeProperty WRITE setSizeProperty); - Q_PROPERTY(QSizeF sizeFProperty READ sizeFProperty WRITE setSizeFProperty); - Q_PROPERTY(QRect rectProperty READ rectProperty WRITE setRectProperty NOTIFY rectPropertyChanged); - Q_PROPERTY(QRect rectProperty2 READ rectProperty2 WRITE setRectProperty2); - Q_PROPERTY(QRectF rectFProperty READ rectFProperty WRITE setRectFProperty); - Q_PROPERTY(bool boolProperty READ boolProperty WRITE setBoolProperty); - Q_PROPERTY(QVariant variantProperty READ variantProperty WRITE setVariantProperty); - Q_PROPERTY(QVector3D vectorProperty READ vectorProperty WRITE setVectorProperty); - Q_PROPERTY(QUrl urlProperty READ urlProperty WRITE setUrlProperty); - - Q_PROPERTY(QDeclarativeScriptString scriptProperty READ scriptProperty WRITE setScriptProperty); - Q_PROPERTY(MyGroupedObject *grouped READ grouped CONSTANT); - Q_PROPERTY(MyGroupedObject *nullGrouped READ nullGrouped CONSTANT); + Q_PROPERTY(QString id READ id WRITE setId) + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty) + Q_PROPERTY(QDeclarativeComponent *componentProperty READ componentProperty WRITE setComponentProperty) + Q_PROPERTY(MyFlags flagProperty READ flagProperty WRITE setFlagProperty) + Q_PROPERTY(MyEnum enumProperty READ enumProperty WRITE setEnumProperty) + Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty) + Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty) + Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty) + Q_PROPERTY(qreal realProperty READ realProperty WRITE setRealProperty) + Q_PROPERTY(double doubleProperty READ doubleProperty WRITE setDoubleProperty) + Q_PROPERTY(float floatProperty READ floatProperty WRITE setFloatProperty) + Q_PROPERTY(QColor colorProperty READ colorProperty WRITE setColorProperty) + Q_PROPERTY(QDate dateProperty READ dateProperty WRITE setDateProperty) + Q_PROPERTY(QTime timeProperty READ timeProperty WRITE setTimeProperty) + Q_PROPERTY(QDateTime dateTimeProperty READ dateTimeProperty WRITE setDateTimeProperty) + Q_PROPERTY(QPoint pointProperty READ pointProperty WRITE setPointProperty) + Q_PROPERTY(QPointF pointFProperty READ pointFProperty WRITE setPointFProperty) + Q_PROPERTY(QSize sizeProperty READ sizeProperty WRITE setSizeProperty) + Q_PROPERTY(QSizeF sizeFProperty READ sizeFProperty WRITE setSizeFProperty) + Q_PROPERTY(QRect rectProperty READ rectProperty WRITE setRectProperty NOTIFY rectPropertyChanged) + Q_PROPERTY(QRect rectProperty2 READ rectProperty2 WRITE setRectProperty2) + Q_PROPERTY(QRectF rectFProperty READ rectFProperty WRITE setRectFProperty) + Q_PROPERTY(bool boolProperty READ boolProperty WRITE setBoolProperty) + Q_PROPERTY(QVariant variantProperty READ variantProperty WRITE setVariantProperty) + Q_PROPERTY(QVector3D vectorProperty READ vectorProperty WRITE setVectorProperty) + Q_PROPERTY(QUrl urlProperty READ urlProperty WRITE setUrlProperty) + + Q_PROPERTY(QDeclarativeScriptString scriptProperty READ scriptProperty WRITE setScriptProperty) + Q_PROPERTY(MyGroupedObject *grouped READ grouped CONSTANT) + Q_PROPERTY(MyGroupedObject *nullGrouped READ nullGrouped CONSTANT) public: MyTypeObject() @@ -467,7 +467,7 @@ class MyContainer : public QObject Q_OBJECT Q_PROPERTY(QDeclarativeListProperty<QObject> children READ children) Q_PROPERTY(QDeclarativeListProperty<MyInterface> qlistInterfaces READ qlistInterfaces) - Q_CLASSINFO("DefaultProperty", "children"); + Q_CLASSINFO("DefaultProperty", "children") public: MyContainer() {} @@ -549,7 +549,7 @@ namespace MyNamespace { class MySecondNamespacedType : public QObject { Q_OBJECT - Q_PROPERTY(QDeclarativeListProperty<MyNamespace::MyNamespacedType> list READ list); + Q_PROPERTY(QDeclarativeListProperty<MyNamespace::MyNamespacedType> list READ list) public: QDeclarativeListProperty<MyNamespacedType> list() { return QDeclarativeListProperty<MyNamespacedType>(this, m_list); } diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 083c551..6b564d4 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -1418,12 +1418,12 @@ void tst_qdeclarativelanguage::initTestCase() { registerTypes(); - QML_REGISTER_TYPE(com.nokia.Test, 0, 0, TestTP, TestType); - QML_REGISTER_TYPE(com.nokia.Test, 1, 0, Test, TestType); - QML_REGISTER_TYPE(com.nokia.Test, 1, 5, Test, TestType); - QML_REGISTER_TYPE(com.nokia.Test, 1, 8, Test, TestType2); - QML_REGISTER_TYPE(com.nokia.Test, 1, 9, OldTest, TestType); - QML_REGISTER_TYPE(com.nokia.Test, 1, 12, Test, TestType2); + qmlRegisterType<TestType>("com.nokia.Test", 0, 0, "TestTP"); + qmlRegisterType<TestType>("com.nokia.Test", 1, 0, "Test"); + qmlRegisterType<TestType>("com.nokia.Test", 1, 5, "Test"); + qmlRegisterType<TestType2>("com.nokia.Test", 1, 8, "Test"); + qmlRegisterType<TestType>("com.nokia.Test", 1, 9, "OldTest"); + qmlRegisterType<TestType2>("com.nokia.Test", 1, 12, "Test"); // Create locale-specific file // For POSIX, this will just be data/I18nType.qml, since POSIX is 7-bit diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/model.qml b/tests/auto/declarative/qdeclarativelistmodel/data/model.qml new file mode 100644 index 0000000..ebd4ebf --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistmodel/data/model.qml @@ -0,0 +1,22 @@ +import Qt 4.6 + +Item { + id: item + property var model + property bool done: false + property var result + + function evalExpressionViaWorker(commands) { + done = false + worker.sendMessage({'commands': commands, 'model': model}) + } + + WorkerScript { + id: worker + source: "script.js" + onMessage: { + item.result = messageObject.result + item.done = true + } + } +} diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/script.js b/tests/auto/declarative/qdeclarativelistmodel/data/script.js new file mode 100644 index 0000000..66a4acb --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistmodel/data/script.js @@ -0,0 +1,13 @@ +WorkerScript.onMessage = function(msg) { + var result = null + try { + for (var i=0; i<msg.commands.length; i++) { + var c = 'msg.model.' + msg.commands[i] + result = eval(c) + } + msg.model.sync() + } catch(e) { } + WorkerScript.sendMessage({'done': true, 'result': result}) +} + + diff --git a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro index d728d08..8813242 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro +++ b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro @@ -4,3 +4,6 @@ QT += script macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativelistmodel.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index a1e6d6b..7a10ad0 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -39,10 +39,16 @@ ** ****************************************************************************/ #include <qtest.h> +#include <QtDeclarative/private/qdeclarativeitem_p.h> +#include <QtDeclarative/private/qdeclarativetext_p.h> #include <QtDeclarative/private/qdeclarativelistmodel_p.h> #include <QtDeclarative/private/qdeclarativeexpression_p.h> #include <QDeclarativeComponent> -#include <QDebug> + +#include <QtCore/qtimer.h> +#include <QtCore/qdebug.h> + +#include "../../../shared/util.h" class tst_QDeclarativeListModel : public QObject { @@ -50,6 +56,11 @@ class tst_QDeclarativeListModel : public QObject public: tst_QDeclarativeListModel() {} +private: + QScriptValue nestedListValue(QScriptEngine *eng) const; + QDeclarativeItem *createWorkerTest(QDeclarativeEngine *eng, QDeclarativeComponent *component, QDeclarativeListModel *model); + void waitForWorker(QDeclarativeItem *item); + private slots: void static_types(); void static_types_data(); @@ -58,10 +69,50 @@ private slots: void static_nestedElements_data(); void dynamic_data(); void dynamic(); + void dynamic_worker_data(); + void dynamic_worker(); + void convertNestedToFlat_fail(); + void convertNestedToFlat_fail_data(); + void convertNestedToFlat_ok(); + void convertNestedToFlat_ok_data(); void error_data(); void error(); }; +QScriptValue tst_QDeclarativeListModel::nestedListValue(QScriptEngine *eng) const +{ + QScriptValue list = eng->newArray(); + list.setProperty(0, eng->newObject()); + list.setProperty(1, eng->newObject()); + QScriptValue sv = eng->newObject(); + sv.setProperty("foo", list); + return sv; +} + +QDeclarativeItem *tst_QDeclarativeListModel::createWorkerTest(QDeclarativeEngine *eng, QDeclarativeComponent *component, QDeclarativeListModel *model) +{ + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component->create()); + QDeclarativeEngine::setContextForObject(model, eng->rootContext()); + if (item) + item->setProperty("model", qVariantFromValue(model)); + return item; +} + +void tst_QDeclarativeListModel::waitForWorker(QDeclarativeItem *item) +{ + QEventLoop loop; + QTimer timer; + timer.setSingleShot(true); + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + + QDeclarativeProperty prop(item, "done"); + QVERIFY(prop.isValid()); + QVERIFY(prop.connectNotifySignal(&loop, SLOT(quit()))); + timer.start(10000); + loop.exec(); + QVERIFY(timer.isActive()); +} + void tst_QDeclarativeListModel::static_i18n() { QString expect = QString::fromUtf8("na\303\257ve"); @@ -149,10 +200,10 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("remove2b") << "{append({'foo':123});append({'foo':456});remove(0);get(0).foo}" << 456 << ""; QTest::newRow("remove2c") << "{append({'foo':123});append({'foo':456});remove(1);get(0).foo}" << 123 << ""; QTest::newRow("remove3") << "{append({'foo':123});remove(0);get(0).foo}" << 0 << "QML ListModel (unknown location) get: index 0 out of range"; - QTest::newRow("remove3a") << "{append({'foo':123});remove(-1)}" << 0 << "QML ListModel (unknown location) remove: index -1 out of range"; + QTest::newRow("remove3a") << "{append({'foo':123});remove(-1);count}" << 1 << "QML ListModel (unknown location) remove: index -1 out of range"; QTest::newRow("remove4a") << "{remove(0)}" << 0 << "QML ListModel (unknown location) remove: index 0 out of range"; - QTest::newRow("remove4b") << "{append({'foo':123});remove(0);remove(0)}" << 0 << "QML ListModel (unknown location) remove: index 0 out of range"; - QTest::newRow("remove4c") << "{append({'foo':123});remove(1)}" << 0 << "QML ListModel (unknown location) remove: index 1 out of range"; + QTest::newRow("remove4b") << "{append({'foo':123});remove(0);remove(0);count}" << 0 << "QML ListModel (unknown location) remove: index 0 out of range"; + QTest::newRow("remove4c") << "{append({'foo':123});remove(1);count}" << 1 << "QML ListModel (unknown location) remove: index 1 out of range"; QTest::newRow("insert1") << "{insert(0,{'foo':123});count}" << 1 << ""; QTest::newRow("insert2") << "{insert(1,{'foo':123});count}" << 0 << "QML ListModel (unknown location) insert: index 1 out of range"; @@ -161,7 +212,7 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("insert3c") << "{append({'foo':123});insert(1,{'foo':456});get(1).foo}" << 456 << ""; QTest::newRow("insert3d") << "{append({'foo':123});insert(0,{'foo':456});get(0).foo}" << 456 << ""; QTest::newRow("insert3e") << "{append({'foo':123});insert(0,{'foo':456});get(1).foo}" << 123 << ""; - QTest::newRow("insert4") << "{append({'foo':123});insert(-1,{'foo':456})}" << 0 << "QML ListModel (unknown location) insert: index -1 out of range"; + QTest::newRow("insert4") << "{append({'foo':123});insert(-1,{'foo':456});count}" << 1 << "QML ListModel (unknown location) insert: index -1 out of range"; QTest::newRow("insert5a") << "{insert(0,123)}" << 0 << "QML ListModel (unknown location) insert: value is not an object"; QTest::newRow("insert5b") << "{insert(0,[1,2,3])}" << 0 << "QML ListModel (unknown location) insert: value is not an object"; @@ -171,8 +222,8 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("set3b") << "{append({'foo':123,'bar':456});set(0,{'foo':999});get(0).bar}" << 456 << ""; QTest::newRow("set4a") << "{set(0,{'foo':456})}" << 0 << "QML ListModel (unknown location) set: index 0 out of range"; QTest::newRow("set4c") << "{set(-1,{'foo':456})}" << 0 << "QML ListModel (unknown location) set: index -1 out of range"; - QTest::newRow("set5a") << "{append({'foo':123,'bar':456});set(0,123)}" << 0 << "QML ListModel (unknown location) set: value is not an object"; - QTest::newRow("set5b") << "{append({'foo':123,'bar':456});set(0,[1,2,3])}" << 0 << "QML ListModel (unknown location) set: value is not an object"; + QTest::newRow("set5a") << "{append({'foo':123,'bar':456});set(0,123);count}" << 1 << "QML ListModel (unknown location) set: value is not an object"; + QTest::newRow("set5b") << "{append({'foo':123,'bar':456});set(0,[1,2,3]);count}" << 1 << "QML ListModel (unknown location) set: value is not an object"; QTest::newRow("set6") << "{append({'foo':123});set(1,{'foo':456});count}" << 2 << ""; QTest::newRow("setprop1") << "{append({'foo':123});setProperty(0,'foo',456);count}" << 1 << ""; @@ -181,7 +232,7 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("setprop3b") << "{append({'foo':123,'bar':456});setProperty(0,'foo',999);get(0).bar}" << 456 << ""; QTest::newRow("setprop4a") << "{setProperty(0,'foo',456)}" << 0 << "QML ListModel (unknown location) set: index 0 out of range"; QTest::newRow("setprop4b") << "{setProperty(-1,'foo',456)}" << 0 << "QML ListModel (unknown location) set: index -1 out of range"; - QTest::newRow("setprop4c") << "{append({'foo':123,'bar':456});setProperty(1,'foo',456)}" << 0 << "QML ListModel (unknown location) set: index 1 out of range"; + QTest::newRow("setprop4c") << "{append({'foo':123,'bar':456});setProperty(1,'foo',456);count}" << 1 << "QML ListModel (unknown location) set: index 1 out of range"; QTest::newRow("setprop5") << "{append({'foo':123,'bar':456});append({'foo':111});setProperty(1,'bar',222);get(1).bar}" << 222 << ""; QTest::newRow("move1a") << "{append({'foo':123});append({'foo':456});move(0,1,1);count}" << 2 << ""; @@ -193,16 +244,22 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("move2b") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,1,2);get(0).foo}" << 789 << ""; QTest::newRow("move2c") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,1,2);get(1).foo}" << 123 << ""; QTest::newRow("move2d") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,1,2);get(2).foo}" << 456 << ""; - QTest::newRow("move3a") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,0,3)}" << 0 << "QML ListModel (unknown location) move: out of range"; - QTest::newRow("move3b") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,-1,1)}" << 0 << "QML ListModel (unknown location) move: out of range"; - QTest::newRow("move3c") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,0,-1)}" << 0 << "QML ListModel (unknown location) move: out of range"; - QTest::newRow("move3d") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,3,1)}" << 0 << "QML ListModel (unknown location) move: out of range"; + QTest::newRow("move3a") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,0,3);count}" << 3 << "QML ListModel (unknown location) move: out of range"; + QTest::newRow("move3b") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,-1,1);count}" << 3 << "QML ListModel (unknown location) move: out of range"; + QTest::newRow("move3c") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,0,-1);count}" << 3 << "QML ListModel (unknown location) move: out of range"; + QTest::newRow("move3d") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,3,1);count}" << 3 << "QML ListModel (unknown location) move: out of range"; + + // Nested models - // Structured model + QTest::newRow("nested-append1") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});count}" << 1 << ""; + QTest::newRow("nested-append2") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.get(1).a}" << 2 << ""; + QTest::newRow("nested-append3") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.append({'a':4});get(0).bars.get(3).a}" << 4 << ""; - QTest::newRow("listprop1a") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});count}" << 1 << ""; - QTest::newRow("listprop1b") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.get(1).a}" << 2 << ""; - QTest::newRow("listprop2a") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.append({'a':4});get(0).bars.get(3).a}" << 4 << ""; + QTest::newRow("nested-insert") << "{append({'foo':123});insert(0,{'bars':[{'a':1},{'b':2},{'c':3}]});get(0).bars.get(0).a}" << 1 << ""; + QTest::newRow("nested-set") << "{append({'foo':123});set(0,{'foo':[{'x':123}]});get(0).foo.get(0).x}" << 123 << ""; + + // XXX + //QTest::newRow("nested-setprop") << "{append({'foo':123});setProperty(0,'foo',[{'x':123}]);get(0).foo.get(0).x}" << 123 << ""; } void tst_QDeclarativeListModel::dynamic() @@ -214,10 +271,11 @@ void tst_QDeclarativeListModel::dynamic() QDeclarativeEngine engine; QDeclarativeListModel model; QDeclarativeEngine::setContextForObject(&model,engine.rootContext()); - engine.rootContext()->addDefaultObject(&model); + engine.rootContext()->setContextObject(&model); QDeclarativeExpression e(engine.rootContext(), script, &model); if (!warning.isEmpty()) QTest::ignoreMessage(QtWarningMsg, warning.toLatin1()); + int actual = e.value().toInt(); if (e.hasError()) qDebug() << e.error(); // errors not expected @@ -225,6 +283,161 @@ void tst_QDeclarativeListModel::dynamic() QCOMPARE(actual,result); } +void tst_QDeclarativeListModel::dynamic_worker_data() +{ + dynamic_data(); +} + +void tst_QDeclarativeListModel::dynamic_worker() +{ + QSKIP("Skip, awaiting imminent fixes", SkipAll); + + QFETCH(QString, script); + QFETCH(int, result); + QFETCH(QString, warning); + + QDeclarativeListModel model; + QDeclarativeEngine eng; + QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml")); + QDeclarativeItem *item = createWorkerTest(&eng, &component, &model); + QVERIFY(item != 0); + + if (script[0] == QLatin1Char('{') && script[script.length()-1] == QLatin1Char('}')) + script = script.mid(1, script.length() - 2); + QVariantList operations; + foreach (const QString &s, script.split(';')) { + if (!s.isEmpty()) + operations << s; + } + + if (!warning.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, warning.toLatin1()); + + if (operations.count() == 1) { + // test count(), get() return the correct default values in the worker list model + QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", + Q_ARG(QVariant, operations))); + waitForWorker(item); + QCOMPARE(QDeclarativeProperty(item, "result").read().toInt(), result); + } else { + // execute a set of commands on the worker list model, then check the + // changes are reflected in the list model in the main thread + if (QByteArray(QTest::currentDataTag()).startsWith("nested")) + QTest::ignoreMessage(QtWarningMsg, "QML ListModel (unknown location) Cannot add nested list values when modifying or after modification from a worker script"); + QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", + Q_ARG(QVariant, operations.mid(0, operations.length()-1)))); + waitForWorker(item); + + QDeclarativeExpression e(eng.rootContext(), operations.last().toString(), &model); + if (QByteArray(QTest::currentDataTag()).startsWith("nested")) + QVERIFY(e.value().toInt() != result); + else + QCOMPARE(e.value().toInt(), result); + } + + delete item; + QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running"); + qApp->processEvents(); +} + +void tst_QDeclarativeListModel::convertNestedToFlat_fail() +{ + QSKIP("Skip, awaiting imminent fixes", SkipAll); + // If a model has nested data, it cannot be used at all from a worker script + + QFETCH(QString, script); + + QDeclarativeListModel model; + QDeclarativeEngine eng; + QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml")); + QDeclarativeItem *item = createWorkerTest(&eng, &component, &model); + QVERIFY(item != 0); + + QScriptEngine s_eng; + QScriptValue plainData = s_eng.newObject(); + plainData.setProperty("foo", QScriptValue(123)); + model.append(plainData); + model.append(nestedListValue(&s_eng)); + QCOMPARE(model.count(), 2); + + QTest::ignoreMessage(QtWarningMsg, "QML ListModel (unknown location) List contains nested list values and cannot be used from a worker script"); + QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", Q_ARG(QVariant, script))); + waitForWorker(item); + + QCOMPARE(model.count(), 2); + + delete item; + QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running"); + qApp->processEvents(); +} + +void tst_QDeclarativeListModel::convertNestedToFlat_fail_data() +{ + QTest::addColumn<QString>("script"); + + QTest::newRow("clear") << "clear()"; + QTest::newRow("remove") << "remove(0)"; + QTest::newRow("append") << "append({'x':1})"; + QTest::newRow("insert") << "insert(0, {'x':1})"; + QTest::newRow("set") << "set(0, {'foo':1})"; + QTest::newRow("setProperty") << "setProperty(0, 'foo', 1})"; + QTest::newRow("move") << "move(0, 1, 1})"; + QTest::newRow("get") << "get(0)"; +} + +void tst_QDeclarativeListModel::convertNestedToFlat_ok() +{ + // If a model only has plain data, it can be modified from a worker script. However, + // once the model is used from a worker script, it no longer accepts nested data + + QSKIP("Skip, awaiting imminent fixes", SkipAll); + + QFETCH(QString, script); + + QDeclarativeListModel model; + QDeclarativeEngine eng; + QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml")); + QDeclarativeItem *item = createWorkerTest(&eng, &component, &model); + QVERIFY(item != 0); + + QScriptEngine s_eng; + QScriptValue plainData = s_eng.newObject(); + plainData.setProperty("foo", QScriptValue(123)); + model.append(plainData); + QCOMPARE(model.count(), 1); + + QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", Q_ARG(QVariant, script))); + waitForWorker(item); + + // can still add plain data + int count = model.count(); + model.append(plainData); + QCOMPARE(model.count(), count+1); + + QScriptValue nested = nestedListValue(&s_eng); + const char *warning = "QML ListModel (unknown location) Cannot add nested list values when modifying or after modification from a worker script"; + + QTest::ignoreMessage(QtWarningMsg, warning); + model.append(nested); + + QTest::ignoreMessage(QtWarningMsg, warning); + model.insert(0, nested); + + QTest::ignoreMessage(QtWarningMsg, warning); + model.set(0, nested); + + QCOMPARE(model.count(), count+1); + + delete item; + QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running"); + qApp->processEvents(); +} + +void tst_QDeclarativeListModel::convertNestedToFlat_ok_data() +{ + convertNestedToFlat_fail_data(); +} + void tst_QDeclarativeListModel::static_types_data() { QTest::addColumn<QString>("qml"); @@ -252,7 +465,7 @@ void tst_QDeclarativeListModel::static_types_data() QTest::newRow("enum") << "ListElement { foo: Text.AlignHCenter }" - << QVariant("QTBUG-5974:ListElement: constant script support for property value"); + << QVariant(double(QDeclarativeText::AlignHCenter)); } void tst_QDeclarativeListModel::static_types() @@ -309,7 +522,7 @@ void tst_QDeclarativeListModel::error_data() QTest::newRow("bindings not allowed in ListElement") << "import Qt 4.6\nRectangle { id: rect; ListModel { ListElement { foo: rect.color } } }" - << "ListElement: cannot use script for property value"; // but note QTBUG-5974 + << "ListElement: cannot use script for property value"; QTest::newRow("random object list properties allowed in ListElement") << "import Qt 4.6\nListModel { ListElement { foo: [ ListElement { bar: 123 } ] } }" diff --git a/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp b/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp index 1b7af19..908f336 100644 --- a/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp +++ b/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp @@ -91,8 +91,8 @@ private slots: class TestType : public QObject { Q_OBJECT - Q_PROPERTY(QDeclarativeListProperty<TestType> data READ dataProperty); - Q_PROPERTY(int intProperty READ intProperty); + Q_PROPERTY(QDeclarativeListProperty<TestType> data READ dataProperty) + Q_PROPERTY(int intProperty READ intProperty) public: TestType() : property(this, data) {} @@ -106,7 +106,7 @@ QML_DECLARE_TYPE(TestType); void tst_qdeclarativelistreference::initTestCase() { - QML_REGISTER_NOCREATE_TYPE(TestType); + qmlRegisterType<TestType>(); } void tst_qdeclarativelistreference::qmllistreference() diff --git a/tests/auto/declarative/qdeclarativelistview/data/listview-initCurrent.qml b/tests/auto/declarative/qdeclarativelistview/data/listview-initCurrent.qml index 74f5ef4..a6d7610 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/listview-initCurrent.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/listview-initCurrent.qml @@ -1,6 +1,7 @@ import Qt 4.6 Rectangle { + property int current: list.currentIndex width: 240 height: 320 color: "#ffffff" diff --git a/tests/auto/declarative/qdeclarativelistview/data/listview.qml b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml index 1c1b3f8..1c1b3f8 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/listview.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml diff --git a/tests/auto/declarative/qdeclarativelistview/data/propertychanges.qml b/tests/auto/declarative/qdeclarativelistview/data/propertychangestest.qml index a41f003..a41f003 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/propertychanges.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/propertychangestest.qml diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 75fbbf8..8d94804 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -321,7 +321,7 @@ void tst_QDeclarativeListView::items() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list"); @@ -402,7 +402,7 @@ void tst_QDeclarativeListView::changed() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeFlickable *listview = findItem<QDeclarativeFlickable>(canvas->rootObject(), "list"); @@ -438,7 +438,7 @@ void tst_QDeclarativeListView::inserted() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list"); @@ -531,7 +531,7 @@ void tst_QDeclarativeListView::removed(bool animated) testObject->setAnimate(animated); ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list"); @@ -673,7 +673,7 @@ void tst_QDeclarativeListView::clear() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list"); @@ -710,7 +710,7 @@ void tst_QDeclarativeListView::moved() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list"); @@ -851,7 +851,7 @@ void tst_QDeclarativeListView::spacing() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list"); @@ -925,6 +925,7 @@ void tst_QDeclarativeListView::sections() // Remove section boundary model.removeItem(5); + QTest::qWait(100); // New section header created QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", 5); @@ -932,6 +933,7 @@ void tst_QDeclarativeListView::sections() QCOMPARE(item->height(), 40.0); model.insertItem(3, "New Item", "0"); + QTest::qWait(100); // Section header moved item = findItem<QDeclarativeItem>(viewport, "wrapper", 5); @@ -944,6 +946,7 @@ void tst_QDeclarativeListView::sections() // insert item which will become a section header model.insertItem(6, "Replace header", "1"); + QTest::qWait(100); item = findItem<QDeclarativeItem>(viewport, "wrapper", 6); QVERIFY(item); @@ -1056,6 +1059,11 @@ void tst_QDeclarativeListView::currentIndex() QTest::qWait(500); QCOMPARE(listview->highlightItem()->y(), hlPos); + // insert item before currentIndex + listview->setCurrentIndex(28); + model.insertItem(0, "Foo", "1111"); + QCOMPARE(canvas->rootObject()->property("current").toInt(), 29); + delete canvas; } @@ -1114,7 +1122,7 @@ void tst_QDeclarativeListView::cacheBuffer() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list"); @@ -1166,7 +1174,7 @@ void tst_QDeclarativeListView::positionViewAtIndex() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list"); @@ -1185,7 +1193,7 @@ void tst_QDeclarativeListView::positionViewAtIndex() } // Position on a currently visible item - listview->positionViewAtIndex(3); + listview->positionViewAtIndex(3, QDeclarativeListView::Beginning); QCOMPARE(listview->contentY(), 60.); // Confirm items positioned correctly @@ -1198,7 +1206,7 @@ void tst_QDeclarativeListView::positionViewAtIndex() } // Position on an item beyond the visible items - listview->positionViewAtIndex(22); + listview->positionViewAtIndex(22, QDeclarativeListView::Beginning); QCOMPARE(listview->contentY(), 440.); // Confirm items positioned correctly @@ -1211,7 +1219,7 @@ void tst_QDeclarativeListView::positionViewAtIndex() } // Position on an item that would leave empty space if positioned at the top - listview->positionViewAtIndex(28); + listview->positionViewAtIndex(28, QDeclarativeListView::Beginning); QCOMPARE(listview->contentY(), 480.); // Confirm items positioned correctly @@ -1224,7 +1232,7 @@ void tst_QDeclarativeListView::positionViewAtIndex() } // Position at the beginning again - listview->positionViewAtIndex(0); + listview->positionViewAtIndex(0, QDeclarativeListView::Beginning); QCOMPARE(listview->contentY(), 0.); // Confirm items positioned correctly @@ -1236,6 +1244,47 @@ void tst_QDeclarativeListView::positionViewAtIndex() QCOMPARE(item->y(), i*20.); } + // Position at End + listview->positionViewAtIndex(20, QDeclarativeListView::End); + QCOMPARE(listview->contentY(), 100.); + + // Position in Center + listview->positionViewAtIndex(15, QDeclarativeListView::Center); + QCOMPARE(listview->contentY(), 150.); + + // Ensure at least partially visible + listview->positionViewAtIndex(15, QDeclarativeListView::Visible); + QCOMPARE(listview->contentY(), 150.); + + listview->setContentY(302); + listview->positionViewAtIndex(15, QDeclarativeListView::Visible); + QCOMPARE(listview->contentY(), 302.); + + listview->setContentY(320); + listview->positionViewAtIndex(15, QDeclarativeListView::Visible); + QCOMPARE(listview->contentY(), 300.); + + listview->setContentY(85); + listview->positionViewAtIndex(20, QDeclarativeListView::Visible); + QCOMPARE(listview->contentY(), 85.); + + listview->setContentY(75); + listview->positionViewAtIndex(20, QDeclarativeListView::Visible); + QCOMPARE(listview->contentY(), 100.); + + // Ensure completely visible + listview->setContentY(120); + listview->positionViewAtIndex(20, QDeclarativeListView::Contain); + QCOMPARE(listview->contentY(), 120.); + + listview->setContentY(302); + listview->positionViewAtIndex(15, QDeclarativeListView::Contain); + QCOMPARE(listview->contentY(), 300.); + + listview->setContentY(85); + listview->positionViewAtIndex(20, QDeclarativeListView::Contain); + QCOMPARE(listview->contentY(), 100.); + delete canvas; } @@ -1284,7 +1333,7 @@ void tst_QDeclarativeListView::propertyChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeListView *listView = canvas->rootObject()->findChild<QDeclarativeListView*>("listView"); QVERIFY(listView); @@ -1352,7 +1401,7 @@ void tst_QDeclarativeListView::componentChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeListView *listView = canvas->rootObject()->findChild<QDeclarativeListView*>("listView"); QVERIFY(listView); @@ -1400,7 +1449,7 @@ void tst_QDeclarativeListView::modelChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeListView *listView = canvas->rootObject()->findChild<QDeclarativeListView*>("listView"); QVERIFY(listView); diff --git a/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp b/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp index 818f108..36efe13 100644 --- a/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp +++ b/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp @@ -77,9 +77,9 @@ private slots: class TestType : public QObject { Q_OBJECT - Q_PROPERTY(int foo READ foo); + Q_PROPERTY(int foo READ foo) - Q_CLASSINFO("DefaultProperty", "foo"); + Q_CLASSINFO("DefaultProperty", "foo") public: int foo() { return 0; } }; @@ -88,7 +88,7 @@ QML_DECLARE_TYPE(TestType); class ParserStatusTestType : public QObject, public QDeclarativeParserStatus { Q_OBJECT - Q_CLASSINFO("DefaultProperty", "foo"); // Missing default property + Q_CLASSINFO("DefaultProperty", "foo") // Missing default property }; QML_DECLARE_TYPE(ParserStatusTestType); @@ -132,10 +132,10 @@ QML_DECLARE_TYPE(ValueInterceptorTestType); void tst_qdeclarativemetatype::initTestCase() { - QML_REGISTER_TYPE(Test, 1, 0, TestType, TestType); - QML_REGISTER_TYPE(Test, 1, 0, ParserStatusTestType, ParserStatusTestType); - QML_REGISTER_TYPE(Test, 1, 0, ValueSourceTestType, ValueSourceTestType); - QML_REGISTER_TYPE(Test, 1, 0, ValueInterceptorTestType, ValueInterceptorTestType); + qmlRegisterType<TestType>("Test", 1, 0, "TestType"); + qmlRegisterType<ParserStatusTestType>("Test", 1, 0, "ParserStatusTestType"); + qmlRegisterType<ValueSourceTestType>("Test", 1, 0, "ValueSourceTestType"); + qmlRegisterType<ValueInterceptorTestType>("Test", 1, 0, "ValueInterceptorTestType"); } void tst_qdeclarativemetatype::copy() diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp index 92f7aef..1335c7c 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp +++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp @@ -101,10 +101,13 @@ inline QUrl TEST_FILE(const QString &filename) void tst_qdeclarativemoduleplugin::importsPlugin() { +QSKIP("Fix me", SkipAll); QDeclarativeEngine engine; QTest::ignoreMessage(QtWarningMsg, "plugin created"); QTest::ignoreMessage(QtWarningMsg, "import worked"); QDeclarativeComponent component(&engine, TEST_FILE("plugin.qml")); + foreach (QDeclarativeError err, component.errors()) + qWarning() << err; VERIFY_ERRORS(0); QObject *object = component.create(); QVERIFY(object != 0); diff --git a/tests/auto/declarative/qdeclarativeparticles/data/particlemotion.qml b/tests/auto/declarative/qdeclarativeparticles/data/particlemotiontest.qml index ace61fe..f1e4909 100644 --- a/tests/auto/declarative/qdeclarativeparticles/data/particlemotion.qml +++ b/tests/auto/declarative/qdeclarativeparticles/data/particlemotiontest.qml @@ -1,10 +1,12 @@ import Qt 4.6 +import Qt.labs.particles 1.0 + Rectangle { width: 240 height: 320 color: "black" Particles { - objectName: "particles" + objectName: "particles" anchors.fill: parent width: 1 height: 1 @@ -30,4 +32,4 @@ Rectangle { pace: 100 } ] -}
\ No newline at end of file +} diff --git a/tests/auto/declarative/qdeclarativeparticles/data/particles.qml b/tests/auto/declarative/qdeclarativeparticles/data/particlestest.qml index 0d42645..4f168a9 100644 --- a/tests/auto/declarative/qdeclarativeparticles/data/particles.qml +++ b/tests/auto/declarative/qdeclarativeparticles/data/particlestest.qml @@ -1,4 +1,6 @@ import Qt 4.6 +import Qt.labs.particles 1.0 + Rectangle{ width: 100 height: 100 @@ -7,7 +9,7 @@ Rectangle{ Particles { id: particles objectName: "particles" width:1; height:1; anchors.centerIn: parent; opacity: 1 - lifeSpan: 100; lifeSpanDeviation: 20; count:1000; + lifeSpan: 100; lifeSpanDeviation: 20; count:1000; fadeInDuration: 20; fadeOutDuration: 20; emissionRate: 1000 angle: 0; angleDeviation: 360; velocity: 500; velocityDeviation:30 source: "particle.png" diff --git a/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp b/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp index 6090a07..093190c 100644 --- a/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp +++ b/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp @@ -41,7 +41,7 @@ #include <QtTest/QtTest> #include <QtTest/QSignalSpy> #include <qdeclarativeview.h> -#include <private/qdeclarativeparticles_p.h> +#include <QGraphicsObject> class tst_QDeclarativeParticles : public QObject { @@ -65,75 +65,77 @@ tst_QDeclarativeParticles::tst_QDeclarativeParticles() void tst_QDeclarativeParticles::properties() { - QDeclarativeView *canvas = createView(SRCDIR "/data/particles.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/particlestest.qml"); QVERIFY(canvas->rootObject()); - QDeclarativeParticles* particles = canvas->rootObject()->findChild<QDeclarativeParticles*>("particles"); + + QObject* particles = canvas->rootObject()->findChild<QObject*>("particles"); QVERIFY(particles); - particles->setSource(QUrl::fromLocalFile(SRCDIR "/data/particle.png")); - QCOMPARE(particles->source(), QUrl::fromLocalFile(SRCDIR "/data/particle.png")); + particles->setProperty("source", QUrl::fromLocalFile(SRCDIR "/data/particle.png")); + QCOMPARE(particles->property("source").toUrl(), QUrl::fromLocalFile(SRCDIR "/data/particle.png")); - particles->setLifeSpanDeviation(1000); - QCOMPARE(particles->lifeSpanDeviation(), 1000); + particles->setProperty("lifeSpanDeviation", (1000)); + QCOMPARE(particles->property("lifeSpanDeviation").toInt(), 1000); - particles->setFadeInDuration(1000); - QCOMPARE(particles->fadeInDuration(), 1000); + particles->setProperty("fadeInDuration", 1000); + QCOMPARE(particles->property("fadeInDuration").toInt(), 1000); - particles->setFadeOutDuration(1000); - QCOMPARE(particles->fadeOutDuration(), 1000); + particles->setProperty("fadeOutDuration", 1000); + QCOMPARE(particles->property("fadeOutDuration").toInt(), 1000); - particles->setAngle(100.0); - QCOMPARE(particles->angle(), 100.0); + particles->setProperty("angle", 100.0); + QCOMPARE(particles->property("angle").toDouble(), 100.0); - particles->setAngleDeviation(100.0); - QCOMPARE(particles->angleDeviation(), 100.0); + particles->setProperty("angleDeviation", 100.0); + QCOMPARE(particles->property("angleDeviation").toDouble(), 100.0); - particles->setVelocity(100.0); - QCOMPARE(particles->velocity(), 100.0); + particles->setProperty("velocity", 100.0); + QCOMPARE(particles->property("velocity").toDouble(), 100.0); - particles->setVelocityDeviation(100.0); - QCOMPARE(particles->velocityDeviation(), 100.0); + particles->setProperty("velocityDeviation", 100.0); + QCOMPARE(particles->property("velocityDeviation").toDouble(), 100.0); - particles->setEmissionVariance(0.5); - QCOMPARE(particles->emissionVariance(),0.5); + particles->setProperty("emissionVariance", 0.5); + QCOMPARE(particles->property("emissionVariance").toDouble(),0.5); - particles->setEmissionRate(12); - QCOMPARE(particles->emissionRate(), 12); + particles->setProperty("emissionRate", 12); + QCOMPARE(particles->property("emissionRate").toInt(), 12); } void tst_QDeclarativeParticles::motionGravity() { - QDeclarativeView *canvas = createView(SRCDIR "/data/particlemotion.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/particlemotiontest.qml"); QVERIFY(canvas->rootObject()); - QDeclarativeParticles* particles = canvas->rootObject()->findChild<QDeclarativeParticles*>("particles"); + + QObject* particles = canvas->rootObject()->findChild<QObject*>("particles"); QVERIFY(particles); - QDeclarativeParticleMotionGravity* motionGravity = canvas->rootObject()->findChild<QDeclarativeParticleMotionGravity*>("motionGravity"); - QCOMPARE(particles->motion(), motionGravity); + QObject* motionGravity = canvas->rootObject()->findChild<QObject*>("motionGravity"); + //QCOMPARE(qvariant_cast<QObject*>(particles->property("motion")), motionGravity); QSignalSpy xattractorSpy(motionGravity, SIGNAL(xattractorChanged())); QSignalSpy yattractorSpy(motionGravity, SIGNAL(yattractorChanged())); QSignalSpy accelerationSpy(motionGravity, SIGNAL(accelerationChanged())); - QCOMPARE(motionGravity->xAttractor(), 0.0); - QCOMPARE(motionGravity->yAttractor(), 1000.0); - QCOMPARE(motionGravity->acceleration(), 25.0); + QCOMPARE(motionGravity->property("xattractor").toDouble(), 0.0); + QCOMPARE(motionGravity->property("yattractor").toDouble(), 1000.0); + QCOMPARE(motionGravity->property("acceleration").toDouble(), 25.0); - motionGravity->setXAttractor(20.0); - motionGravity->setYAttractor(10.0); - motionGravity->setAcceleration(10.0); + motionGravity->setProperty("xattractor", 20.0); + motionGravity->setProperty("yattractor", 10.0); + motionGravity->setProperty("acceleration", 10.0); - QCOMPARE(motionGravity->xAttractor(), 20.0); - QCOMPARE(motionGravity->yAttractor(), 10.0); - QCOMPARE(motionGravity->acceleration(), 10.0); + QCOMPARE(motionGravity->property("xattractor").toDouble(), 20.0); + QCOMPARE(motionGravity->property("yattractor").toDouble(), 10.0); + QCOMPARE(motionGravity->property("acceleration").toDouble(), 10.0); QCOMPARE(xattractorSpy.count(), 1); QCOMPARE(yattractorSpy.count(), 1); QCOMPARE(accelerationSpy.count(), 1); - motionGravity->setXAttractor(20.0); - motionGravity->setYAttractor(10.0); - motionGravity->setAcceleration(10.0); + motionGravity->setProperty("xattractor", 20.0); + motionGravity->setProperty("yattractor", 10.0); + motionGravity->setProperty("acceleration", 10.0); QCOMPARE(xattractorSpy.count(), 1); QCOMPARE(yattractorSpy.count(), 1); @@ -142,44 +144,46 @@ void tst_QDeclarativeParticles::motionGravity() void tst_QDeclarativeParticles::motionWander() { - QDeclarativeView *canvas = createView(SRCDIR "/data/particlemotion.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/particlemotiontest.qml"); QVERIFY(canvas->rootObject()); - QDeclarativeParticles* particles = canvas->rootObject()->findChild<QDeclarativeParticles*>("particles"); + + QObject* particles = canvas->rootObject()->findChild<QObject*>("particles"); QVERIFY(particles); - + QSignalSpy motionSpy(particles, SIGNAL(motionChanged())); - QDeclarativeParticleMotionWander* motionWander = canvas->rootObject()->findChild<QDeclarativeParticleMotionWander*>("motionWander"); - - particles->setMotion(motionWander); - QCOMPARE(particles->motion(),motionWander); - QCOMPARE(motionSpy.count(), 1); - - particles->setMotion(motionWander); - QCOMPARE(motionSpy.count(), 1); + QObject* motionWander = canvas->rootObject()->findChild<QObject*>("motionWander"); + + QCOMPARE(motionSpy.count(), 0); + particles->setProperty("motion", QVariant::fromValue(motionWander)); + //QCOMPARE(particles->property("motion"), QVariant::fromValue(motionWander)); + //QCOMPARE(motionSpy.count(), 1); + + particles->setProperty("motion", QVariant::fromValue(motionWander)); + //QCOMPARE(motionSpy.count(), 1); QSignalSpy xvarianceSpy(motionWander, SIGNAL(xvarianceChanged())); QSignalSpy yvarianceSpy(motionWander, SIGNAL(yvarianceChanged())); QSignalSpy paceSpy(motionWander, SIGNAL(paceChanged())); - QCOMPARE(motionWander->xVariance(), 30.0); - QCOMPARE(motionWander->yVariance(), 30.0); - QCOMPARE(motionWander->pace(), 100.0); + QCOMPARE(motionWander->property("xvariance").toDouble(), 30.0); + QCOMPARE(motionWander->property("yvariance").toDouble(), 30.0); + QCOMPARE(motionWander->property("pace").toDouble(), 100.0); - motionWander->setXVariance(20.0); - motionWander->setYVariance(10.0); - motionWander->setPace(10.0); + motionWander->setProperty("xvariance", 20.0); + motionWander->setProperty("yvariance", 10.0); + motionWander->setProperty("pace", 10.0); - QCOMPARE(motionWander->xVariance(), 20.0); - QCOMPARE(motionWander->yVariance(), 10.0); - QCOMPARE(motionWander->pace(), 10.0); + QCOMPARE(motionWander->property("xvariance").toDouble(), 20.0); + QCOMPARE(motionWander->property("yvariance").toDouble(), 10.0); + QCOMPARE(motionWander->property("pace").toDouble(), 10.0); QCOMPARE(xvarianceSpy.count(), 1); QCOMPARE(yvarianceSpy.count(), 1); QCOMPARE(paceSpy.count(), 1); - motionWander->setXVariance(20.0); - motionWander->setYVariance(10.0); - motionWander->setPace(10.0); + QCOMPARE(motionWander->property("xvariance").toDouble(), 20.0); + QCOMPARE(motionWander->property("yvariance").toDouble(), 10.0); + QCOMPARE(motionWander->property("pace").toDouble(), 10.0); QCOMPARE(xvarianceSpy.count(), 1); QCOMPARE(yvarianceSpy.count(), 1); @@ -188,9 +192,10 @@ void tst_QDeclarativeParticles::motionWander() void tst_QDeclarativeParticles::runs() { - QDeclarativeView *canvas = createView(SRCDIR "/data/particles.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/particlestest.qml"); QVERIFY(canvas->rootObject()); - QDeclarativeParticles* particles = canvas->rootObject()->findChild<QDeclarativeParticles*>("particles"); + + QObject* particles = canvas->rootObject()->findChild<QObject*>("particles"); QVERIFY(particles); QTest::qWait(1000);//Run for one second. Test passes if it doesn't crash. } diff --git a/tests/auto/declarative/qdeclarativepathview/data/path.qml b/tests/auto/declarative/qdeclarativepathview/data/pathtest.qml index 7e82a48..7e82a48 100644 --- a/tests/auto/declarative/qdeclarativepathview/data/path.qml +++ b/tests/auto/declarative/qdeclarativepathview/data/pathtest.qml diff --git a/tests/auto/declarative/qdeclarativepathview/data/pathview.qml b/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml index ae0c86a..ae0c86a 100644 --- a/tests/auto/declarative/qdeclarativepathview/data/pathview.qml +++ b/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml diff --git a/tests/auto/declarative/qdeclarativepathview/data/pathview3.qml b/tests/auto/declarative/qdeclarativepathview/data/pathview3.qml index f8ed29f..70cfbcd 100644 --- a/tests/auto/declarative/qdeclarativepathview/data/pathview3.qml +++ b/tests/auto/declarative/qdeclarativepathview/data/pathview3.qml @@ -2,7 +2,7 @@ import Qt 4.6 PathView { id: photoPathView - y: 100; width: 800; height: 330; pathItemCount: 4; offset: 10 + y: 100; width: 800; height: 330; pathItemCount: 4; offset: 0.1 dragMargin: 24; snapPosition: 0.50 path: Path { diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp index 62eb8c3..c16c46f 100644 --- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp +++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp @@ -213,7 +213,7 @@ void tst_QDeclarativePathView::items() QDeclarativeContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml")); qApp->processEvents(); QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view"); @@ -262,7 +262,7 @@ void tst_QDeclarativePathView::pathview3() QVERIFY(obj->delegate() != 0); QVERIFY(obj->model() != QVariant()); QCOMPARE(obj->currentIndex(), 0); - QCOMPARE(obj->offset(), 50.); // ??? + QCOMPARE(obj->offset(), 0.5); // ??? QCOMPARE(obj->snapPosition(), 0.5); // ??? QCOMPARE(obj->dragMargin(), 24.); QCOMPARE(obj->count(), 8); @@ -272,7 +272,7 @@ void tst_QDeclarativePathView::pathview3() void tst_QDeclarativePathView::path() { QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/path.qml")); + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathtest.qml")); QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create()); QVERIFY(obj != 0); @@ -407,7 +407,7 @@ void tst_QDeclarativePathView::pathMoved() QDeclarativeContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml")); qApp->processEvents(); QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view"); @@ -422,14 +422,14 @@ void tst_QDeclarativePathView::pathMoved() offset.setX(firstItem->width()/2); offset.setY(firstItem->height()/2); QCOMPARE(firstItem->pos() + offset, start); - pathview->setOffset(10); + pathview->setOffset(0.1); for(int i=0; i<model.count(); i++){ QDeclarativeRectangle *curItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", i); QCOMPARE(curItem->pos() + offset, path->pointAt(0.1 + i*0.25)); } - pathview->setOffset(100); + pathview->setOffset(1.0); QCOMPARE(firstItem->pos() + offset, start); delete canvas; @@ -448,7 +448,7 @@ void tst_QDeclarativePathView::setCurrentIndex() QDeclarativeContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml")); qApp->processEvents(); QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view"); diff --git a/tests/auto/declarative/qdeclarativepositioners/data/grid.qml b/tests/auto/declarative/qdeclarativepositioners/data/gridtest.qml index 830df6a..830df6a 100644 --- a/tests/auto/declarative/qdeclarativepositioners/data/grid.qml +++ b/tests/auto/declarative/qdeclarativepositioners/data/gridtest.qml diff --git a/tests/auto/declarative/qdeclarativepositioners/data/propertychanges.qml b/tests/auto/declarative/qdeclarativepositioners/data/propertychangestest.qml index 4370a18..4370a18 100644 --- a/tests/auto/declarative/qdeclarativepositioners/data/propertychanges.qml +++ b/tests/auto/declarative/qdeclarativepositioners/data/propertychangestest.qml diff --git a/tests/auto/declarative/qdeclarativepositioners/data/repeater.qml b/tests/auto/declarative/qdeclarativepositioners/data/repeatertest.qml index 2bc5e94..2bc5e94 100644 --- a/tests/auto/declarative/qdeclarativepositioners/data/repeater.qml +++ b/tests/auto/declarative/qdeclarativepositioners/data/repeatertest.qml diff --git a/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp b/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp index d23d74c..0e1fee2 100644 --- a/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp +++ b/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp @@ -239,7 +239,7 @@ void tst_QDeclarativePositioners::test_vertical_animated() void tst_QDeclarativePositioners::test_grid() { - QDeclarativeView *canvas = createView(SRCDIR "/data/grid.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/gridtest.qml"); QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); QVERIFY(one != 0); @@ -365,9 +365,10 @@ void tst_QDeclarativePositioners::test_grid_animated() } void tst_QDeclarativePositioners::test_propertychanges() { - QDeclarativeView *canvas = createView(SRCDIR "/data/propertychanges.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/propertychangestest.qml"); QDeclarativeGrid *grid = qobject_cast<QDeclarativeGrid*>(canvas->rootObject()); + QVERIFY(grid != 0); QDeclarativeTransition *rowTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("rowTransition"); QDeclarativeTransition *columnTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("columnTransition"); @@ -421,7 +422,7 @@ void tst_QDeclarativePositioners::test_propertychanges() void tst_QDeclarativePositioners::test_repeater() { - QDeclarativeView *canvas = createView(SRCDIR "/data/repeater.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/repeatertest.qml"); QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); QVERIFY(one != 0); diff --git a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp index 9b8a643..eed12ea 100644 --- a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp +++ b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp @@ -183,15 +183,15 @@ void tst_qdeclarativeproperty::qmlmetaproperty() class PropertyObject : public QObject { Q_OBJECT - Q_PROPERTY(int defaultProperty READ defaultProperty); - Q_PROPERTY(QRect rectProperty READ rectProperty); - Q_PROPERTY(QRect wrectProperty READ wrectProperty WRITE setWRectProperty); - Q_PROPERTY(QUrl url READ url WRITE setUrl); - Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty); + Q_PROPERTY(int defaultProperty READ defaultProperty) + Q_PROPERTY(QRect rectProperty READ rectProperty) + Q_PROPERTY(QRect wrectProperty READ wrectProperty WRITE setWRectProperty) + Q_PROPERTY(QUrl url READ url WRITE setUrl) + Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty) Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal) - Q_PROPERTY(MyQmlObject *qmlObject READ qmlObject); + Q_PROPERTY(MyQmlObject *qmlObject READ qmlObject) - Q_CLASSINFO("DefaultProperty", "defaultProperty"); + Q_CLASSINFO("DefaultProperty", "defaultProperty") public: PropertyObject() : m_resetProperty(9) {} @@ -1348,9 +1348,9 @@ void tst_qdeclarativeproperty::copy() void tst_qdeclarativeproperty::initTestCase() { - QML_REGISTER_TYPE(Test,1,0,MyQmlObject,MyQmlObject); - QML_REGISTER_TYPE(Test,1,0,PropertyObject,PropertyObject); - QML_REGISTER_TYPE(Test,1,0,MyContainer,MyContainer); + qmlRegisterType<MyQmlObject>("Test",1,0,"MyQmlObject"); + qmlRegisterType<PropertyObject>("Test",1,0,"PropertyObject"); + qmlRegisterType<MyContainer>("Test",1,0,"MyContainer"); } diff --git a/tests/auto/declarative/qdeclarativeqt/data/closestangle.qml b/tests/auto/declarative/qdeclarativeqt/data/closestangle.qml deleted file mode 100644 index b5f7fc6..0000000 --- a/tests/auto/declarative/qdeclarativeqt/data/closestangle.qml +++ /dev/null @@ -1,12 +0,0 @@ -import Qt 4.6 - -QtObject { - property var testSame: Qt.closestAngle(0,1) - property var testLess: Qt.closestAngle(0,-359) - property var testMore: Qt.closestAngle(0,361) - property var testFail: Qt.closestAngle(0) - property var test5: Qt.closestAngle(0,1,2) - property var test6: Qt.closestAngle(123.45465768,1.11) - property var test7: Qt.closestAngle(-3.1415,1.11) -} - diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp index b70011b..debec02 100644 --- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp +++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp @@ -66,7 +66,6 @@ private slots: void lighter(); void darker(); void tint(); - void closestAngle(); void openUrlExternally(); void md5(); void createComponent(); @@ -262,23 +261,6 @@ void tst_qdeclarativeqt::tint() delete object; } -void tst_qdeclarativeqt::closestAngle() -{ - QDeclarativeComponent component(&engine, TEST_FILE("closestangle.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - - QCOMPARE(qvariant_cast<qreal>(object->property("testSame")), 1.0); - QCOMPARE(qvariant_cast<qreal>(object->property("testLess")), 1.0); - QCOMPARE(qvariant_cast<qreal>(object->property("testMore")), 1.0); - QCOMPARE(qvariant_cast<qreal>(object->property("testFail")), 0.0); - QCOMPARE(qvariant_cast<qreal>(object->property("test5")), 1.0); - QCOMPARE(qvariant_cast<qreal>(object->property("test6")), 1.11); - QCOMPARE(qvariant_cast<qreal>(object->property("test7")), 1.11); - - delete object; -} - void tst_qdeclarativeqt::openUrlExternally() { QEXPECT_FAIL("", "How do we test this?", Abort); diff --git a/tests/auto/declarative/qdeclarativerepeater/data/repeater.qml b/tests/auto/declarative/qdeclarativerepeater/data/repeater1.qml index 7d83230..7d83230 100644 --- a/tests/auto/declarative/qdeclarativerepeater/data/repeater.qml +++ b/tests/auto/declarative/qdeclarativerepeater/data/repeater1.qml diff --git a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp index 7a97e60..09c4879 100644 --- a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp +++ b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp @@ -109,7 +109,7 @@ public: setRoleNames(roles); } - int rowCount(const QModelIndex &parent=QModelIndex()) const { return list.count(); } + int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); } QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { QVariant rv; if (role == Name) @@ -224,7 +224,7 @@ void tst_QDeclarativeRepeater::stringList() QDeclarativeContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testData", data); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater1.qml")); qApp->processEvents(); QDeclarativeRepeater *repeater = findItem<QDeclarativeRepeater>(canvas->rootObject(), "repeater"); diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorChanges.qml b/tests/auto/declarative/qdeclarativestates/data/anchorChanges1.qml index 7dce889..7dce889 100644 --- a/tests/auto/declarative/qdeclarativestates/data/anchorChanges.qml +++ b/tests/auto/declarative/qdeclarativestates/data/anchorChanges1.qml diff --git a/tests/auto/declarative/qdeclarativestates/data/parentChange.qml b/tests/auto/declarative/qdeclarativestates/data/parentChange1.qml index b8c7818..b8c7818 100644 --- a/tests/auto/declarative/qdeclarativestates/data/parentChange.qml +++ b/tests/auto/declarative/qdeclarativestates/data/parentChange1.qml diff --git a/tests/auto/declarative/qdeclarativestates/data/reset.qml b/tests/auto/declarative/qdeclarativestates/data/reset.qml index a0a2b8c..8e9b13a 100644 --- a/tests/auto/declarative/qdeclarativestates/data/reset.qml +++ b/tests/auto/declarative/qdeclarativestates/data/reset.qml @@ -5,9 +5,9 @@ Rectangle { height: 480 Text { id: theText - width: 50 + width: 40 wrap: true - text: "a text string that is longer than 50 pixels" + text: "a text string that is longer than 40 pixels" } states: State { diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index 8d3ca7a..fe7ec15 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -110,7 +110,7 @@ private slots: void tst_qdeclarativestates::initTestCase() { - QML_REGISTER_TYPE(Qt.test, 1, 0, MyRectangle,MyRect); + qmlRegisterType<MyRect>("Qt.test", 1, 0, "MyRectangle"); } QByteArray tst_qdeclarativestates::fullDataPath(const QString &path) @@ -441,7 +441,7 @@ void tst_qdeclarativestates::parentChange() QDeclarativeEngine engine; { - QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange.qml"); + QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange1.qml"); QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create()); QVERIFY(rect != 0); @@ -546,7 +546,7 @@ void tst_qdeclarativestates::anchorChanges() { QDeclarativeEngine engine; - QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges.qml"); + QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges1.qml"); QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create()); QVERIFY(rect != 0); @@ -955,12 +955,12 @@ void tst_qdeclarativestates::reset() QDeclarativeText *text = rect->findChild<QDeclarativeText*>(); QVERIFY(text != 0); - QCOMPARE(text->width(), qreal(50.)); + QCOMPARE(text->width(), qreal(40.)); QVERIFY(text->width() < text->height()); rect->setState("state1"); - QVERIFY(text->width() > 51); + QVERIFY(text->width() > 41); QVERIFY(text->width() > text->height()); } diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.1.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.1.qml new file mode 100644 index 0000000..2697bb5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.1.qml @@ -0,0 +1,42 @@ +import Qt 4.6 + +Rectangle { + id: root + + width: 800 + height: 600 + + property alias font: myText.font + + property int myPixelSize: 12 + property int myPixelSize2: 24 + + Text { + id: other + font.pixelSize: 6 + } + + Text { + id: myText + + text: "Hello world!" + font.pixelSize: myPixelSize + } + + states: State { + name: "Swapped" + PropertyChanges { + target: myText + font: other.font + } + } + + function toggle() { + if (root.state == "") root.state = "Swapped"; else root.state = ""; + } + + MouseArea { + anchors.fill: parent + onClicked: { if (root.state == "") root.state = "Swapped"; else root.state = "";} + } +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.2.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.2.qml new file mode 100644 index 0000000..478104e1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.2.qml @@ -0,0 +1,42 @@ +import Qt 4.6 + +Rectangle { + id: root + + width: 800 + height: 600 + + property alias font: myText.font + + property int myPixelSize: 12 + property int myPixelSize2: 24 + + Text { + id: other + font.pixelSize: 6 + } + + Text { + id: myText + + text: "Hello world!" + font: other.font + } + + states: State { + name: "Swapped" + PropertyChanges { + target: myText + font.pixelSize: myPixelSize + } + } + + function toggle() { + if (root.state == "") root.state = "Swapped"; else root.state = ""; + } + + MouseArea { + anchors.fill: parent + onClicked: { if (root.state == "") root.state = "Swapped"; else root.state = "";} + } +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.3.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.3.qml new file mode 100644 index 0000000..d35c72e --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.3.qml @@ -0,0 +1,42 @@ +import Qt 4.6 + +Rectangle { + id: root + + width: 800 + height: 600 + + property alias font: myText.font + + property int myPixelSize: 12 + property int myPixelSize2: 24 + + Text { + id: other + font.pixelSize: 6 + } + + Text { + id: myText + + text: "Hello world!" + font.pixelSize: myPixelSize + } + + states: State { + name: "Swapped" + PropertyChanges { + target: myText + font.pixelSize: myPixelSize2 + } + } + + function toggle() { + if (root.state == "") root.state = "Swapped"; else root.state = ""; + } + + MouseArea { + anchors.fill: parent + onClicked: { if (root.state == "") root.state = "Swapped"; else root.state = "";} + } +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/testtypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/testtypes.cpp index aa8bd6e..e30a319 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativevaluetypes/testtypes.cpp @@ -42,7 +42,7 @@ void registerTypes() { - QML_REGISTER_TYPE(Test, 1, 0, MyTypeObject, MyTypeObject); - QML_REGISTER_TYPE(Test, 1, 0, MyConstantValueSource, MyConstantValueSource); - QML_REGISTER_TYPE(Test, 1, 0, MyOffsetValueInterceptor, MyOffsetValueInterceptor); + qmlRegisterType<MyTypeObject>("Test", 1, 0, "MyTypeObject"); + qmlRegisterType<MyConstantValueSource>("Test", 1, 0, "MyConstantValueSource"); + qmlRegisterType<MyOffsetValueInterceptor>("Test", 1, 0, "MyOffsetValueInterceptor"); } diff --git a/tests/auto/declarative/qdeclarativevaluetypes/testtypes.h b/tests/auto/declarative/qdeclarativevaluetypes/testtypes.h index dfc2829..0ad8449 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/testtypes.h +++ b/tests/auto/declarative/qdeclarativevaluetypes/testtypes.h @@ -59,14 +59,14 @@ class MyTypeObject : public QObject { Q_OBJECT - Q_PROPERTY(QPoint point READ point WRITE setPoint NOTIFY changed); - Q_PROPERTY(QPointF pointf READ pointf WRITE setPointf NOTIFY changed); - Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY changed); - Q_PROPERTY(QSizeF sizef READ sizef WRITE setSizef NOTIFY changed); - Q_PROPERTY(QRect rect READ rect WRITE setRect NOTIFY changed); - Q_PROPERTY(QRectF rectf READ rectf WRITE setRectf NOTIFY changed); - Q_PROPERTY(QVector3D vector READ vector WRITE setVector NOTIFY changed); - Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY changed); + Q_PROPERTY(QPoint point READ point WRITE setPoint NOTIFY changed) + Q_PROPERTY(QPointF pointf READ pointf WRITE setPointf NOTIFY changed) + Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY changed) + Q_PROPERTY(QSizeF sizef READ sizef WRITE setSizef NOTIFY changed) + Q_PROPERTY(QRect rect READ rect WRITE setRect NOTIFY changed) + Q_PROPERTY(QRectF rectf READ rectf WRITE setRectf NOTIFY changed) + Q_PROPERTY(QVector3D vector READ vector WRITE setVector NOTIFY changed) + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY changed) public: MyTypeObject() : diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp index 51f9a07..a5cb16f 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp +++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp @@ -77,6 +77,7 @@ private slots: void scriptVariantCopy(); void cppClasses(); void enums(); + void conflictingBindings(); private: QDeclarativeEngine engine; @@ -314,8 +315,17 @@ void tst_qdeclarativevaluetypes::font() font.setLetterSpacing(QFont::AbsoluteSpacing, 9.7); font.setWordSpacing(11.2); - QEXPECT_FAIL("", "QT-2920", Continue); - QCOMPARE(object->font(), font); + QFont f = object->font(); + QCOMPARE(f.family(), font.family()); + QCOMPARE(f.bold(), font.bold()); + QCOMPARE(f.weight(), font.weight()); + QCOMPARE(f.italic(), font.italic()); + QCOMPARE(f.underline(), font.underline()); + QCOMPARE(f.strikeOut(), font.strikeOut()); + QCOMPARE(f.pointSize(), font.pointSize()); + QCOMPARE(f.capitalization(), font.capitalization()); + QCOMPARE(f.letterSpacing(), font.letterSpacing()); + QCOMPARE(f.wordSpacing(), font.wordSpacing()); delete object; } @@ -422,12 +432,13 @@ void tst_qdeclarativevaluetypes::autoBindingRemoval() object->setProperty("value", QVariant(92)); - QEXPECT_FAIL("", "QT-2920", Continue); + //QEXPECT_FAIL("", "QT-2920", Continue); QCOMPARE(object->rect().x(), 42); delete object; } + /* { QDeclarativeComponent component(&engine, TEST_FILE("autoBindingRemoval.2.qml")); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); @@ -465,12 +476,11 @@ void tst_qdeclarativevaluetypes::autoBindingRemoval() object->setProperty("value", QVariant(QRect(19, 3, 4, 8))); - QEXPECT_FAIL("", "QT-2920", Continue); QCOMPARE(object->rect(), QRect(44, 22, 33, 44)); delete object; } - +*/ } // Test that property value sources assign to value types @@ -626,6 +636,65 @@ void tst_qdeclarativevaluetypes::enums() } } +// Tests switching between "conflicting" bindings (eg. a binding on the core +// property, to a binding on the value-type sub-property) +void tst_qdeclarativevaluetypes::conflictingBindings() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("conflicting.1.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 12); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 6); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 12); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("conflicting.2.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 6); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 12); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 6); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("conflicting.3.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 12); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 24); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast<QFont>(object->property("font")).pixelSize(), 12); + + delete object; + } +} + QTEST_MAIN(tst_qdeclarativevaluetypes) #include "tst_qdeclarativevaluetypes.moc" diff --git a/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml b/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml index 4d9df43..5f9f757 100644 --- a/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml +++ b/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml @@ -23,8 +23,8 @@ Grid { newWindowParent: pages url: "newwindows.html" Timer { - interval: 10; running: webView.status==WebView.Ready && total<4; repeat: false; - onTriggered: {total++; webView.evaluateJavaScript("clickTheLink()")} + interval: 10; running: total<4; repeat: false; + onTriggered: { if (webView.status==WebView.Ready) { total++; webView.evaluateJavaScript("clickTheLink()") } } } } } diff --git a/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp b/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp index b63e14b..ce389f3 100644 --- a/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp +++ b/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp @@ -122,8 +122,7 @@ void tst_qdeclarativewebview::cleanupTestCase() void tst_qdeclarativewebview::checkNoErrors(const QDeclarativeComponent& component) { // Wait until the component is ready - QTRY_VERIFY(component.isReady()); - + QTRY_VERIFY(component.isReady() || component.isError()); if (component.isError()) { QList<QDeclarativeError> errors = component.errors(); @@ -313,8 +312,8 @@ void tst_qdeclarativewebview::multipleWindows() QDeclarativeGrid *grid = qobject_cast<QDeclarativeGrid*>(component.create()); QVERIFY(grid != 0); - QTRY_COMPARE(grid->children().count(), 2+5); // Component, Loader, 5 WebViews - QDeclarativeItem* popup = qobject_cast<QDeclarativeItem*>(grid->children().at(3)); // first popup after Component, Loaded, original. + QTRY_COMPARE(grid->children().count(), 2+4); // Component, Loader (with 1 WebView), 4 new-window WebViews + QDeclarativeItem* popup = qobject_cast<QDeclarativeItem*>(grid->children().at(2)); // first popup after Component and Loader. QVERIFY(popup != 0); QTRY_COMPARE(popup->x(), 150.0); } diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/data/model.qml b/tests/auto/declarative/qdeclarativeworkerlistmodel/data/model.qml deleted file mode 100644 index be94e00..0000000 --- a/tests/auto/declarative/qdeclarativeworkerlistmodel/data/model.qml +++ /dev/null @@ -1,14 +0,0 @@ -import Qt 4.6 - -Item { - property alias model: model - - WorkerListModel { id: model } - - function workerModifyModel(cmd) { worker.sendMessage({'command': cmd, 'model': model}) } - - WorkerScript { - id: worker - source: "script.js" - } -} diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/data/script.js b/tests/auto/declarative/qdeclarativeworkerlistmodel/data/script.js deleted file mode 100644 index 8ee62b4..0000000 --- a/tests/auto/declarative/qdeclarativeworkerlistmodel/data/script.js +++ /dev/null @@ -1,6 +0,0 @@ -WorkerScript.onMessage = function(msg) { - eval("msg.model." + msg.command) - msg.model.sync() -} - - diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/qdeclarativeworkerlistmodel.pro b/tests/auto/declarative/qdeclarativeworkerlistmodel/qdeclarativeworkerlistmodel.pro deleted file mode 100644 index 960dbe1..0000000 --- a/tests/auto/declarative/qdeclarativeworkerlistmodel/qdeclarativeworkerlistmodel.pro +++ /dev/null @@ -1,9 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,declarative): QT += declarative -QT += script -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativeworkerlistmodel.cpp - -# Define SRCDIR equal to test's source directory -DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/tst_qdeclarativeworkerlistmodel.cpp b/tests/auto/declarative/qdeclarativeworkerlistmodel/tst_qdeclarativeworkerlistmodel.cpp deleted file mode 100644 index 11a7447..0000000 --- a/tests/auto/declarative/qdeclarativeworkerlistmodel/tst_qdeclarativeworkerlistmodel.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the 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 Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <qtest.h> -#include <QtCore/qdebug.h> - -#include <QtDeclarative/qdeclarativecomponent.h> -#include <QtDeclarative/qdeclarativeengine.h> -#include <QtDeclarative/qdeclarativeitem.h> - -#include <private/qdeclarativeworkerscript_p.h> -#include <private/qdeclarativelistmodel_p.h> -#include "../../../shared/util.h" - - - -class tst_QDeclarativeWorkerListModel : public QObject -{ - Q_OBJECT -public: - tst_QDeclarativeWorkerListModel() {} -private slots: - void clear(); - void remove(); - void append(); - void insert(); - void get(); - void set(); - -private: - QByteArray modificationWarning() const { - QString file = QUrl::fromLocalFile(SRCDIR "/data/model.qml").toString(); - return QString("QML WorkerListModel (" + file + ":6:5) List can only be modified from a WorkerScript").toUtf8(); - } - - QDeclarativeEngine m_engine; -}; - -void tst_QDeclarativeWorkerListModel::clear() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); - QVERIFY(model != 0); - - QCOMPARE(model->count(), 0); - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - - QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); - model->clear(); - QCOMPARE(model->count(), 1); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "clear()"))); - QTRY_COMPARE(model->count(), 0); - - qApp->processEvents(); -} - -void tst_QDeclarativeWorkerListModel::remove() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - - QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); - model->remove(0); - QCOMPARE(model->count(), 1); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "remove(0)"))); - QTRY_COMPARE(model->count(), 0); - - qApp->processEvents(); -} - -void tst_QDeclarativeWorkerListModel::append() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - - QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); - model->append(QScriptValue(1)); - QCOMPARE(model->count(), 1); - - qApp->processEvents(); -} - -void tst_QDeclarativeWorkerListModel::insert() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "insert(0, {'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - - QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); - model->insert(0, QScriptValue(1)); - QCOMPARE(model->count(), 1); - - qApp->processEvents(); -} - -void tst_QDeclarativeWorkerListModel::get() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - QCOMPARE(model->get(0).property("name").toString(), QString("A")); - - qApp->processEvents(); -} - -void tst_QDeclarativeWorkerListModel::set() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - - QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); - model->set(0, QScriptValue(1)); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "set(0, {'name': 'Z'})"))); - QTRY_COMPARE(model->get(0).property("name").toString(), QString("Z")); - - qApp->processEvents(); -} - -QTEST_MAIN(tst_QDeclarativeWorkerListModel) - -#include "tst_qdeclarativeworkerlistmodel.moc" - diff --git a/tests/auto/declarative/visual/animation/parentAnimation/parentAnimation.qml b/tests/auto/declarative/visual/animation/parentAnimation/parentAnimation.qml index 1833cf0..5db2cc6 100644 --- a/tests/auto/declarative/visual/animation/parentAnimation/parentAnimation.qml +++ b/tests/auto/declarative/visual/animation/parentAnimation/parentAnimation.qml @@ -10,7 +10,7 @@ Rectangle { width: 100; height: 100 } - MouseRegion { + MouseArea { id: mouser anchors.fill: parent } diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png Binary files differindex c7bbf38..454f6c1 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png Binary files differindex 612500b..9dde537 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png Binary files differindex c7bbf38..454f6c1 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png Binary files differindex c7bbf38..454f6c1 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png Binary files differindex 1910eb4..043b487 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png Binary files differindex 3b8eebd..79c791d 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png Binary files differindex c7bbf38..454f6c1 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png Binary files differindex c7bbf38..454f6c1 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png Binary files differindex 960be31..a7d6674 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml index 0f58de5..a130b75 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml @@ -386,115 +386,115 @@ VisualTest { } Frame { msec: 1472 - hash: "c2d6dd91f3e9cdcacbadcb449c8a9896" + hash: "eb3eeb37ab7b26692cbf100adfaf3772" } Frame { msec: 1488 - hash: "1098ea19aecebd71208e101d522c1981" + hash: "e1a8cdcb1f3ec097a968b3b20964c6e8" } Frame { msec: 1504 - hash: "8cc59c20d796c073038518d2855fb6f0" + hash: "44fc52479251327d0612de17ddb056eb" } Frame { msec: 1520 - hash: "914a89d0cfdc68145024ce2305a5e76e" + hash: "fa7e4a910aa60500575a34852c0c7cb8" } Frame { msec: 1536 - hash: "7a2e3ca2660df24d9a6ec49a7422ebe1" + hash: "66d205a02e35221e7684ab995acc1312" } Frame { msec: 1552 - hash: "b71496d986d5f0aa76b4f1663627f1f7" + hash: "4ebe8dba6d9f3179b610b2298a7484a2" } Frame { msec: 1568 - hash: "41b29a523db919bc0a4e0a9a88bfc873" + hash: "9b2582fccffa34fe389ba427ce47619a" } Frame { msec: 1584 - hash: "97632a0de766b9ffbf71f21eeb0ff9a2" + hash: "e6f15478bda9995f82976b9e16659c8e" } Frame { msec: 1600 - hash: "94cc196e62c150008461ff9996b4cae8" + hash: "f08df0885fff04819ada6c10b25dd489" } Frame { msec: 1616 - hash: "32e96ad2d15fa2386d365ab249ddf4f4" + hash: "0f57c152306747cfa27171f1947ca65d" } Frame { msec: 1632 - hash: "209394314f971b12fbc61ca45010cc62" + hash: "89d9c988abd55063e210b81193c6a8f0" } Frame { msec: 1648 - hash: "b917c2684dda8af00278b34ababdcf5c" + hash: "91e0d0a5d57210c790c2d2399d1f7022" } Frame { msec: 1664 - hash: "92b506860c1c5dc52f87c24c89921b05" + hash: "267874fdc09459b3e854c06d9ae99a54" } Frame { msec: 1680 - hash: "7b7e96113fa9359954be9b3ac87943c3" + hash: "2f58a508f439c40c6f2bd7da1f30deff" } Frame { msec: 1696 - hash: "42bc69db42c5df902038cec414246ec5" + hash: "1451548d9f0002a6c4765cb616ab7f59" } Frame { msec: 1712 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1728 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1744 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1760 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1776 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1792 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1808 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1824 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1840 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1856 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1872 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1888 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1904 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1920 @@ -502,47 +502,47 @@ VisualTest { } Frame { msec: 1936 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1952 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1968 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1984 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2000 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2016 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2032 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2048 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2064 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2080 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2096 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 2 @@ -554,31 +554,31 @@ VisualTest { } Frame { msec: 2112 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2128 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2144 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2160 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2176 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2192 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2208 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 3 @@ -590,67 +590,67 @@ VisualTest { } Frame { msec: 2224 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2240 - hash: "2d1aa011f2008a6147ba593e3cf272d7" + hash: "8ceca291e28f52368346f171c2f31664" } Frame { msec: 2256 - hash: "206699ea84ce9fd60c1603b7a48a5134" + hash: "903877286f3ef112e6a661abde5c17bd" } Frame { msec: 2272 - hash: "68eb6df93a2b6db7023f7c3cc71d5b5f" + hash: "cc2d15c96571f9328b929f96849c8f9e" } Frame { msec: 2288 - hash: "5a4cd0620959dde92eeeaaa4dcd13091" + hash: "26e6c03b1b91b725d6e0fe9216a7413e" } Frame { msec: 2304 - hash: "17b763187a777253b25b22f5dd7253ae" + hash: "213e8e9905bea32ddb97d38b75cd19cc" } Frame { msec: 2320 - hash: "1de9dcf4d385266f4482e2d0967d9119" + hash: "17d5726a282d42fcde7796be84606fcd" } Frame { msec: 2336 - hash: "833496add6dbc3103a28a47e453a738b" + hash: "f4629bf9f5837f687ae49008c9d28d02" } Frame { msec: 2352 - hash: "b3bab2e9c56db60cd54e68369e6b790d" + hash: "fbc927cb136d8d29b2578e78c4793e41" } Frame { msec: 2368 - hash: "ee91c6cd909bec401a1a7eebd10b8b02" + hash: "c7099e732490dd2f3205986a7c43a165" } Frame { msec: 2384 - hash: "0ed679ad0ab7bd3544947bccda88647b" + hash: "b3b464a8e67fab05109b49604f1ce705" } Frame { msec: 2400 - hash: "d7dfcdc8a4233821919f1732d8c39712" + hash: "7629b2a77f9f87aa0ef2535aa9b8d390" } Frame { msec: 2416 - hash: "c52829ee689e4c312a9dff8dbd4a79f9" + hash: "6a329c289236782e095cfa6f15409726" } Frame { msec: 2432 - hash: "7962badda0e80a61b67943d3b31f892d" + hash: "1cfbf6f4c292e1520b44d84dd59b93a8" } Frame { msec: 2448 - hash: "fc5f2c24e3d8743ab5b20aaa122bacc2" + hash: "a8d3d838bffb39053eb705aefcb39c46" } Frame { msec: 2464 - hash: "201b9ee6c9ac6208ef812fe2e95020ef" + hash: "a56ad66a949e07e3174a58c80145c85e" } Frame { msec: 2480 @@ -774,123 +774,123 @@ VisualTest { } Frame { msec: 2896 - hash: "c2d6dd91f3e9cdcacbadcb449c8a9896" + hash: "eb3eeb37ab7b26692cbf100adfaf3772" } Frame { msec: 2912 - hash: "1098ea19aecebd71208e101d522c1981" + hash: "e1a8cdcb1f3ec097a968b3b20964c6e8" } Frame { msec: 2928 - hash: "8cc59c20d796c073038518d2855fb6f0" + hash: "44fc52479251327d0612de17ddb056eb" } Frame { msec: 2944 - hash: "914a89d0cfdc68145024ce2305a5e76e" + hash: "fa7e4a910aa60500575a34852c0c7cb8" } Frame { msec: 2960 - hash: "7a2e3ca2660df24d9a6ec49a7422ebe1" + hash: "66d205a02e35221e7684ab995acc1312" } Frame { msec: 2976 - hash: "b71496d986d5f0aa76b4f1663627f1f7" + hash: "4ebe8dba6d9f3179b610b2298a7484a2" } Frame { msec: 2992 - hash: "41b29a523db919bc0a4e0a9a88bfc873" + hash: "9b2582fccffa34fe389ba427ce47619a" } Frame { msec: 3008 - hash: "97632a0de766b9ffbf71f21eeb0ff9a2" + hash: "e6f15478bda9995f82976b9e16659c8e" } Frame { msec: 3024 - hash: "94cc196e62c150008461ff9996b4cae8" + hash: "f08df0885fff04819ada6c10b25dd489" } Frame { msec: 3040 - hash: "32e96ad2d15fa2386d365ab249ddf4f4" + hash: "0f57c152306747cfa27171f1947ca65d" } Frame { msec: 3056 - hash: "209394314f971b12fbc61ca45010cc62" + hash: "89d9c988abd55063e210b81193c6a8f0" } Frame { msec: 3072 - hash: "b917c2684dda8af00278b34ababdcf5c" + hash: "91e0d0a5d57210c790c2d2399d1f7022" } Frame { msec: 3088 - hash: "92b506860c1c5dc52f87c24c89921b05" + hash: "267874fdc09459b3e854c06d9ae99a54" } Frame { msec: 3104 - hash: "7b7e96113fa9359954be9b3ac87943c3" + hash: "2f58a508f439c40c6f2bd7da1f30deff" } Frame { msec: 3120 - hash: "42bc69db42c5df902038cec414246ec5" + hash: "1451548d9f0002a6c4765cb616ab7f59" } Frame { msec: 3136 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3152 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3168 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3184 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3200 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3216 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3232 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3248 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3264 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3280 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3296 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3312 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3328 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3344 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3360 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 2 @@ -902,31 +902,31 @@ VisualTest { } Frame { msec: 3376 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3392 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3408 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3424 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3440 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3456 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3472 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 3 @@ -938,67 +938,67 @@ VisualTest { } Frame { msec: 3488 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3504 - hash: "2d1aa011f2008a6147ba593e3cf272d7" + hash: "8ceca291e28f52368346f171c2f31664" } Frame { msec: 3520 - hash: "206699ea84ce9fd60c1603b7a48a5134" + hash: "903877286f3ef112e6a661abde5c17bd" } Frame { msec: 3536 - hash: "68eb6df93a2b6db7023f7c3cc71d5b5f" + hash: "cc2d15c96571f9328b929f96849c8f9e" } Frame { msec: 3552 - hash: "5a4cd0620959dde92eeeaaa4dcd13091" + hash: "26e6c03b1b91b725d6e0fe9216a7413e" } Frame { msec: 3568 - hash: "17b763187a777253b25b22f5dd7253ae" + hash: "213e8e9905bea32ddb97d38b75cd19cc" } Frame { msec: 3584 - hash: "1de9dcf4d385266f4482e2d0967d9119" + hash: "17d5726a282d42fcde7796be84606fcd" } Frame { msec: 3600 - hash: "833496add6dbc3103a28a47e453a738b" + hash: "f4629bf9f5837f687ae49008c9d28d02" } Frame { msec: 3616 - hash: "b3bab2e9c56db60cd54e68369e6b790d" + hash: "fbc927cb136d8d29b2578e78c4793e41" } Frame { msec: 3632 - hash: "ee91c6cd909bec401a1a7eebd10b8b02" + hash: "c7099e732490dd2f3205986a7c43a165" } Frame { msec: 3648 - hash: "0ed679ad0ab7bd3544947bccda88647b" + hash: "b3b464a8e67fab05109b49604f1ce705" } Frame { msec: 3664 - hash: "d7dfcdc8a4233821919f1732d8c39712" + hash: "7629b2a77f9f87aa0ef2535aa9b8d390" } Frame { msec: 3680 - hash: "c52829ee689e4c312a9dff8dbd4a79f9" + hash: "6a329c289236782e095cfa6f15409726" } Frame { msec: 3696 - hash: "7962badda0e80a61b67943d3b31f892d" + hash: "1cfbf6f4c292e1520b44d84dd59b93a8" } Frame { msec: 3712 - hash: "fc5f2c24e3d8743ab5b20aaa122bacc2" + hash: "a8d3d838bffb39053eb705aefcb39c46" } Frame { msec: 3728 - hash: "201b9ee6c9ac6208ef812fe2e95020ef" + hash: "a56ad66a949e07e3174a58c80145c85e" } Frame { msec: 3744 @@ -2038,183 +2038,183 @@ VisualTest { } Frame { msec: 7696 - hash: "c2d6dd91f3e9cdcacbadcb449c8a9896" + hash: "eb3eeb37ab7b26692cbf100adfaf3772" } Frame { msec: 7712 - hash: "1098ea19aecebd71208e101d522c1981" + hash: "e1a8cdcb1f3ec097a968b3b20964c6e8" } Frame { msec: 7728 - hash: "8cc59c20d796c073038518d2855fb6f0" + hash: "44fc52479251327d0612de17ddb056eb" } Frame { msec: 7744 - hash: "914a89d0cfdc68145024ce2305a5e76e" + hash: "fa7e4a910aa60500575a34852c0c7cb8" } Frame { msec: 7760 - hash: "7a2e3ca2660df24d9a6ec49a7422ebe1" + hash: "66d205a02e35221e7684ab995acc1312" } Frame { msec: 7776 - hash: "b71496d986d5f0aa76b4f1663627f1f7" + hash: "4ebe8dba6d9f3179b610b2298a7484a2" } Frame { msec: 7792 - hash: "41b29a523db919bc0a4e0a9a88bfc873" + hash: "9b2582fccffa34fe389ba427ce47619a" } Frame { msec: 7808 - hash: "97632a0de766b9ffbf71f21eeb0ff9a2" + hash: "e6f15478bda9995f82976b9e16659c8e" } Frame { msec: 7824 - hash: "94cc196e62c150008461ff9996b4cae8" + hash: "f08df0885fff04819ada6c10b25dd489" } Frame { msec: 7840 - hash: "32e96ad2d15fa2386d365ab249ddf4f4" + hash: "0f57c152306747cfa27171f1947ca65d" } Frame { msec: 7856 - hash: "209394314f971b12fbc61ca45010cc62" + hash: "89d9c988abd55063e210b81193c6a8f0" } Frame { msec: 7872 - hash: "b917c2684dda8af00278b34ababdcf5c" + hash: "91e0d0a5d57210c790c2d2399d1f7022" } Frame { msec: 7888 - hash: "92b506860c1c5dc52f87c24c89921b05" + hash: "267874fdc09459b3e854c06d9ae99a54" } Frame { msec: 7904 - hash: "7b7e96113fa9359954be9b3ac87943c3" + hash: "2f58a508f439c40c6f2bd7da1f30deff" } Frame { msec: 7920 - hash: "42bc69db42c5df902038cec414246ec5" + hash: "1451548d9f0002a6c4765cb616ab7f59" } Frame { msec: 7936 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 7952 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 7968 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 7984 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8000 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8016 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8032 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8048 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8064 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8080 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8096 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8112 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8128 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8144 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8160 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8176 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8192 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8208 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8224 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8240 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8256 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8272 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8288 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8304 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8320 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8336 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8352 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8368 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8384 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8400 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 2 @@ -2226,31 +2226,31 @@ VisualTest { } Frame { msec: 8416 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8432 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8448 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8464 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8480 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8496 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8512 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 3 @@ -2262,31 +2262,31 @@ VisualTest { } Frame { msec: 8528 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8544 - hash: "b4f30663a9b21e42375645e970f57d0b" + hash: "49a6ed64f80094b41348eda19fa5a55e" } Frame { msec: 8560 - hash: "6c12dbf4af8801573515b61123d4b1d7" + hash: "3ee42fb431d7824c1cd6ddf95af91d10" } Frame { msec: 8576 - hash: "facc61397c734bb4409d5664dc059a14" + hash: "d807890cc0670eda9fac267769366771" } Frame { msec: 8592 - hash: "897e15e37276454d11fac6a528e967a6" + hash: "50cb68de9ca0c3a8db1df58d7cbb0d21" } Frame { msec: 8608 - hash: "cf8173519f1e042c227ff61c62308640" + hash: "0af06233156b3a469ce9e7d80a5767c0" } Frame { msec: 8624 - hash: "d0fcda14ea4bcfebf04ccf99e292ac6a" + hash: "9b2c77f004e480fd485e092c08feaf81" } Frame { msec: 8640 @@ -2294,35 +2294,35 @@ VisualTest { } Frame { msec: 8656 - hash: "74b4ababa97def538f5340e88a4419a4" + hash: "6ed9b6118a0dc81c22af9fee108b7432" } Frame { msec: 8672 - hash: "b96b5b64505b1814ddd42a52569d7fd9" + hash: "4d3aa8219edffe6fda316482821d4a64" } Frame { msec: 8688 - hash: "0e3e07aad030b2075c4bc61b02ebe49e" + hash: "ea8a7104840254ac2706ca2635b8a95f" } Frame { msec: 8704 - hash: "c5eebc652c58e3a44d5ed481100ef242" + hash: "a8569ef3287da9699809a2ad107b87b1" } Frame { msec: 8720 - hash: "d4a74185304c126739af728ddda40e0c" + hash: "91d09653dbced4ecb3d711737cb89ca1" } Frame { msec: 8736 - hash: "448572d3c1060b8311952429a7f9430d" + hash: "d5391f3b40f2dfada0336d889d438d69" } Frame { msec: 8752 - hash: "00f64c09657a8afd6caa186efb6ad860" + hash: "27cd9690607f97cc84c2a0a4455feccb" } Frame { msec: 8768 - hash: "2a360e6feaaf303e9ee63145085796e6" + hash: "f885588779a5de5d7d47f48bf9a2a6ee" } Frame { msec: 8784 @@ -2419,7 +2419,7 @@ VisualTest { Key { type: 6 key: 16777249 - modifiers: 67108864 + modifiers: 0 text: "" autorep: false count: 1 diff --git a/tests/auto/declarative/visual/animation/reanchor/reanchor.qml b/tests/auto/declarative/visual/animation/reanchor/reanchor.qml index d80631f..e41a254 100644 --- a/tests/auto/declarative/visual/animation/reanchor/reanchor.qml +++ b/tests/auto/declarative/visual/animation/reanchor/reanchor.qml @@ -52,7 +52,7 @@ Rectangle { }] transitions: Transition { - NumberAnimation { properties: "x,y,width,height" } + AnchorAnimation { } } MouseArea { diff --git a/tests/auto/qdbuscontext/tst_qdbuscontext.cpp b/tests/auto/qdbuscontext/tst_qdbuscontext.cpp index be62d5b..2b7ac06 100644 --- a/tests/auto/qdbuscontext/tst_qdbuscontext.cpp +++ b/tests/auto/qdbuscontext/tst_qdbuscontext.cpp @@ -47,7 +47,7 @@ const char errorMsg[] = "A generic error"; class TestObject: public QObject, protected QDBusContext { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.tst_QDBusContext.TestObject"); + Q_CLASSINFO("D-Bus Interface", "com.trolltech.tst_QDBusContext.TestObject") public: inline TestObject(QObject *parent) : QObject(parent) { } public Q_SLOTS: diff --git a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index 901099d..7138905 100644 --- a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -405,7 +405,7 @@ void tst_QFileSystemWatcher::removePaths() #if 0 class SignalTest : public QObject { - Q_OBJECT; + Q_OBJECT public slots: void fileSlot(const QString &file) { qDebug() << "file " << file;} void dirSlot(const QString &dir) { qDebug() << "dir" << dir;} diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 16a621a..fa3e0f9 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -48,7 +48,7 @@ #include <QtGui/qwindowsstyle.h> class tst_QGraphicsAnchorLayout : public QObject { - Q_OBJECT; + Q_OBJECT public: tst_QGraphicsAnchorLayout() : QObject() { diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 69d2ad2..23b3458 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -3426,85 +3426,106 @@ void tst_QGraphicsProxyWidget::clickFocus() scene.setItemIndexMethod(QGraphicsScene::NoIndex); QGraphicsProxyWidget *proxy = scene.addWidget(new QLineEdit); - EventSpy proxySpy(proxy); - EventSpy widgetSpy(proxy->widget()); - QGraphicsView view(&scene); - view.setFrameStyle(0); - view.resize(300, 300); - view.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&view); -#endif - QApplication::setActiveWindow(&view); - QTest::qWait(25); - QTRY_COMPARE(QApplication::activeWindow(), &view); - QVERIFY(!proxy->hasFocus()); - QVERIFY(!proxy->widget()->hasFocus()); + { + EventSpy proxySpy(proxy); + EventSpy widgetSpy(proxy->widget()); - QCOMPARE(proxySpy.counts[QEvent::FocusIn], 0); - QCOMPARE(proxySpy.counts[QEvent::FocusOut], 0); - QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 0); - QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 0); + view.setFrameStyle(0); + view.resize(300, 300); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QApplication::setActiveWindow(&view); + QTest::qWait(25); + QTRY_COMPARE(QApplication::activeWindow(), &view); - QPointF lineEditCenter = proxy->mapToScene(proxy->boundingRect().center()); - // Spontaneous mouse click sets focus on a clickable widget. - for (int retry = 0; retry < 50 && !proxy->hasFocus(); retry++) - QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter)); - QVERIFY(proxy->hasFocus()); - QVERIFY(proxy->widget()->hasFocus()); - QCOMPARE(proxySpy.counts[QEvent::FocusIn], 1); - QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 1); + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); - scene.setFocusItem(0); - QVERIFY(!proxy->hasFocus()); - QVERIFY(!proxy->widget()->hasFocus()); - QCOMPARE(proxySpy.counts[QEvent::FocusOut], 1); - QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 1); + QCOMPARE(proxySpy.counts[QEvent::FocusIn], 0); + QCOMPARE(proxySpy.counts[QEvent::FocusOut], 0); + QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 0); + QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 0); - // Non-spontaneous mouse click sets focus if the widget has been clicked before - { - QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); - event.setScenePos(lineEditCenter); - event.setButton(Qt::LeftButton); - qApp->sendEvent(&scene, &event); + QPointF lineEditCenter = proxy->mapToScene(proxy->boundingRect().center()); + // Spontaneous mouse click sets focus on a clickable widget. + for (int retry = 0; retry < 50 && !proxy->hasFocus(); retry++) + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter)); QVERIFY(proxy->hasFocus()); QVERIFY(proxy->widget()->hasFocus()); - QCOMPARE(proxySpy.counts[QEvent::FocusIn], 2); - QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 2); + QCOMPARE(proxySpy.counts[QEvent::FocusIn], 1); + QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 1); + + scene.setFocusItem(0); + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); + QCOMPARE(proxySpy.counts[QEvent::FocusOut], 1); + QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 1); + + // Non-spontaneous mouse click sets focus if the widget has been clicked before + { + QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); + event.setScenePos(lineEditCenter); + event.setButton(Qt::LeftButton); + qApp->sendEvent(&scene, &event); + QVERIFY(proxy->hasFocus()); + QVERIFY(proxy->widget()->hasFocus()); + QCOMPARE(proxySpy.counts[QEvent::FocusIn], 2); + QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 2); + } } scene.setFocusItem(0); proxy->setWidget(new QLineEdit); // resets focusWidget - QVERIFY(!proxy->hasFocus()); - QVERIFY(!proxy->widget()->hasFocus()); - QCOMPARE(proxySpy.counts[QEvent::FocusOut], 2); - QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 2); - // Non-spontaneous mouse click does not set focus on the embedded widget. { - QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); - event.setScenePos(lineEditCenter); - event.setButton(Qt::LeftButton); - qApp->sendEvent(&scene, &event); + QPointF lineEditCenter = proxy->mapToScene(proxy->boundingRect().center()); + EventSpy proxySpy(proxy); + EventSpy widgetSpy(proxy->widget()); QVERIFY(!proxy->hasFocus()); QVERIFY(!proxy->widget()->hasFocus()); - QCOMPARE(proxySpy.counts[QEvent::FocusIn], 2); - QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 2); - } + QCOMPARE(proxySpy.counts[QEvent::FocusOut], 0); + QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 0); - scene.setFocusItem(0); - QVERIFY(!proxy->hasFocus()); - QVERIFY(!proxy->widget()->hasFocus()); - QCOMPARE(proxySpy.counts[QEvent::FocusOut], 2); - QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 2); - - // Spontaneous click on non-clickable widget does not give focus. - proxy->widget()->setFocusPolicy(Qt::NoFocus); - QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter)); - QVERIFY(!proxy->hasFocus()); - QVERIFY(!proxy->widget()->hasFocus()); + // Non-spontaneous mouse click does not set focus on the embedded widget. + { + QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); + event.setScenePos(lineEditCenter); + event.setButton(Qt::LeftButton); + qApp->sendEvent(&scene, &event); + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); + QCOMPARE(proxySpy.counts[QEvent::FocusIn], 0); + QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 0); + } + + scene.setFocusItem(0); + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); + QCOMPARE(proxySpy.counts[QEvent::FocusOut], 0); + QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 0); + + // Spontaneous click on non-clickable widget does not give focus. + proxy->widget()->setFocusPolicy(Qt::NoFocus); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter)); + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); + + // Multiple clicks should only result in one FocusIn. + proxy->widget()->setFocusPolicy(Qt::StrongFocus); + scene.setFocusItem(0); + QVERIFY(!proxy->hasFocus()); + QVERIFY(!proxy->widget()->hasFocus()); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter)); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter)); + QVERIFY(proxy->hasFocus()); + QVERIFY(proxy->widget()->hasFocus()); + QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 1); + QCOMPARE(proxySpy.counts[QEvent::FocusIn], 1); + } } void tst_QGraphicsProxyWidget::windowFrameMargins() diff --git a/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp b/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp index a813110..99d775d 100644 --- a/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp +++ b/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp @@ -62,7 +62,7 @@ private slots: class DownloadCheckWidget : public QWidget { - Q_OBJECT; + Q_OBJECT public: DownloadCheckWidget(QWidget *parent = 0) : QWidget(parent) , progressDlg(this), netmanager(this) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 76e69c5..e11900e 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -3952,7 +3952,7 @@ void tst_QNetworkReply::httpReUsingConnectionSequential() } class HttpReUsingConnectionFromFinishedSlot : public QObject { - Q_OBJECT; + Q_OBJECT public: QNetworkReply* reply1; QNetworkReply* reply2; diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 56eaf25..2339b21 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -139,6 +139,8 @@ private slots: void taskQTBUG_7537_appearsAndSort(); void taskQTBUG_7716_unnecessaryDynamicSorting(); + void testMultipleProxiesWithSelection(); + protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); void checkHierarchy(const QStringList &data, const QAbstractItemModel *model); @@ -2951,5 +2953,90 @@ void tst_QSortFilterProxyModel::taskQTBUG_7716_unnecessaryDynamicSorting() } } +class SelectionProxyModel : QAbstractProxyModel +{ + Q_OBJECT +public: + SelectionProxyModel() + : QAbstractProxyModel(), selectionModel(0) + { + } + + QModelIndex mapFromSource(QModelIndex const&) const + { return QModelIndex(); } + + QModelIndex mapToSource(QModelIndex const&) const + { return QModelIndex(); } + + QModelIndex index(int, int, const QModelIndex&) const + { return QModelIndex(); } + + QModelIndex parent(const QModelIndex&) const + { return QModelIndex(); } + + int rowCount(const QModelIndex&) const + { return 0; } + + int columnCount(const QModelIndex&) const + { return 0; } + + void setSourceModel( QAbstractItemModel *sourceModel ) + { + beginResetModel(); + disconnect( sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) ); + QAbstractProxyModel::setSourceModel( sourceModel ); + connect( sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) ); + endResetModel(); + } + + void setSelectionModel( QItemSelectionModel *_selectionModel ) + { + selectionModel = _selectionModel; + } + +private slots: + void sourceModelAboutToBeReset() + { + QVERIFY( selectionModel->selectedIndexes().size() == 1 ); + beginResetModel(); + } + + void sourceModelReset() + { + endResetModel(); + } + +private: + QItemSelectionModel *selectionModel; + +}; + +void tst_QSortFilterProxyModel::testMultipleProxiesWithSelection() +{ + QStringListModel model; + const QStringList initial = QString("bravo charlie delta echo").split(" "); + model.setStringList(initial); + + QSortFilterProxyModel proxy; + proxy.setSourceModel( &model ); + + SelectionProxyModel proxy1; + QSortFilterProxyModel proxy2; + + // Note that the order here matters. The order of the sourceAboutToBeReset + // exposes the bug in QSortFilterProxyModel. + proxy2.setSourceModel( &proxy ); + proxy1.setSourceModel( &proxy ); + + QItemSelectionModel selectionModel(&proxy2); + proxy1.setSelectionModel( &selectionModel ); + + selectionModel.select( proxy2.index( 0, 0 ), QItemSelectionModel::Select ); + + // trick the proxy into emitting begin/end reset signals. + proxy.setSourceModel(0); + +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" diff --git a/tests/auto/xmlpatterns.pro b/tests/auto/xmlpatterns.pro index f670266..923f2c4 100644 --- a/tests/auto/xmlpatterns.pro +++ b/tests/auto/xmlpatterns.pro @@ -37,6 +37,7 @@ xmlpatternsdiagnosticsts.depends = xmlpatternssdk xmlpatternsview.depends = xmlpatternssdk xmlpatternsxslts.depends = xmlpatternssdk xmlpatternsschemats.depends = xmlpatternssdk +xmlpatternsxqts.depends = xmlpatternssdk !contains(QT_CONFIG, private_tests): SUBDIRS -= \ xmlpatternsdiagnosticsts \ diff --git a/tests/benchmarks/corelib/io/qurl/main.cpp b/tests/benchmarks/corelib/io/qurl/main.cpp new file mode 100644 index 0000000..49ace64 --- /dev/null +++ b/tests/benchmarks/corelib/io/qurl/main.cpp @@ -0,0 +1,244 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qurl.h> +#include <qtest.h> + +class tst_qurl: public QObject +{ + Q_OBJECT + +private slots: + void emptyUrl(); + void relativeUrl(); + void absoluteUrl(); + void isRelative_data(); + void isRelative(); + void toLocalFile_data(); + void toLocalFile(); + void toString_data(); + void toString(); + void toEncoded_data(); + void toEncoded(); + void resolved_data(); + void resolved(); + void equality_data(); + void equality(); + void qmlPropertyWriteUseCase(); + +private: + void generateFirstRunData(); +}; + +void tst_qurl::emptyUrl() +{ + QBENCHMARK { + QUrl url; + } +} + +void tst_qurl::relativeUrl() +{ + QBENCHMARK { + QUrl url("pics/avatar.png"); + } +} + +void tst_qurl::absoluteUrl() +{ + QBENCHMARK { + QUrl url("/tmp/avatar.png"); + } +} + +void tst_qurl::generateFirstRunData() +{ + QTest::addColumn<bool>("firstRun"); + + QTest::newRow("construction + first run") << true; + QTest::newRow("subsequent runs") << false; +} + +void tst_qurl::isRelative_data() +{ + generateFirstRunData(); +} + +void tst_qurl::isRelative() +{ + QFETCH(bool, firstRun); + if (firstRun) { + QBENCHMARK { + QUrl url("pics/avatar.png"); + url.isRelative(); + } + } else { + QUrl url("pics/avatar.png"); + QBENCHMARK { + url.isRelative(); + } + } +} + +void tst_qurl::toLocalFile_data() +{ + generateFirstRunData(); +} + +void tst_qurl::toLocalFile() +{ + QFETCH(bool, firstRun); + if (firstRun) { + QBENCHMARK { + QUrl url("/tmp/avatar.png"); + url.toLocalFile(); + } + } else { + QUrl url("/tmp/avatar.png"); + QBENCHMARK { + url.toLocalFile(); + } + } +} + +void tst_qurl::toString_data() +{ + generateFirstRunData(); +} + +void tst_qurl::toString() +{ + QFETCH(bool, firstRun); + if(firstRun) { + QBENCHMARK { + QUrl url("pics/avatar.png"); + url.toString(); + } + } else { + QUrl url("pics/avatar.png"); + QBENCHMARK { + url.toString(); + } + } +} + +void tst_qurl::toEncoded_data() +{ + generateFirstRunData(); +} + +void tst_qurl::toEncoded() +{ + QFETCH(bool, firstRun); + if(firstRun) { + QBENCHMARK { + QUrl url("pics/avatar.png"); + url.toEncoded(QUrl::FormattingOption(0x100)); + } + } else { + QUrl url("pics/avatar.png"); + QBENCHMARK { + url.toEncoded(QUrl::FormattingOption(0x100)); + } + } +} + +void tst_qurl::resolved_data() +{ + generateFirstRunData(); +} + +void tst_qurl::resolved() +{ + QFETCH(bool, firstRun); + if(firstRun) { + QBENCHMARK { + QUrl baseUrl("/home/user/"); + QUrl url("pics/avatar.png"); + baseUrl.resolved(url); + } + } else { + QUrl baseUrl("/home/user/"); + QUrl url("pics/avatar.png"); + QBENCHMARK { + baseUrl.resolved(url); + } + } +} + +void tst_qurl::equality_data() +{ + generateFirstRunData(); +} + +void tst_qurl::equality() +{ + QFETCH(bool, firstRun); + if(firstRun) { + QBENCHMARK { + QUrl url("pics/avatar.png"); + QUrl url2("pics/avatar2.png"); + //url == url2; + } + } else { + QUrl url("pics/avatar.png"); + QUrl url2("pics/avatar2.png"); + QBENCHMARK { + url == url2; + } + } +} + +void tst_qurl::qmlPropertyWriteUseCase() +{ + QUrl base("file:///home/user/qt/demos/declarative/samegame/SamegameCore/"); + QString str("pics/redStar.png"); + + QBENCHMARK { + QUrl u = QUrl(str); + if (!u.isEmpty() && u.isRelative()) + u = base.resolved(u); + } +} + +QTEST_MAIN(tst_qurl) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/io/qurl/qurl.pro b/tests/benchmarks/corelib/io/qurl/qurl.pro new file mode 100644 index 0000000..1d2d35e --- /dev/null +++ b/tests/benchmarks/corelib/io/qurl/qurl.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qurl +QT -= gui +win32: DEFINES+= _CRT_SECURE_NO_WARNINGS + +SOURCES += main.cpp diff --git a/tests/benchmarks/declarative/binding/testtypes.cpp b/tests/benchmarks/declarative/binding/testtypes.cpp index 043c8ab..1fc9ccd 100644 --- a/tests/benchmarks/declarative/binding/testtypes.cpp +++ b/tests/benchmarks/declarative/binding/testtypes.cpp @@ -42,5 +42,5 @@ void registerTypes() { - QML_REGISTER_TYPE(Test, 1, 0, MyQmlObject, MyQmlObject); + qmlRegisterType<MyQmlObject>("Test", 1, 0, "MyQmlObject"); } diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp index 5b0004f..7aec32a 100644 --- a/tests/benchmarks/declarative/creation/tst_creation.cpp +++ b/tests/benchmarks/declarative/creation/tst_creation.cpp @@ -47,6 +47,7 @@ #include <QGraphicsScene> #include <QGraphicsItem> #include <QDeclarativeItem> +#include <QDeclarativeContext> #include <private/qobject_p.h> #ifdef Q_OS_SYMBIAN @@ -59,7 +60,7 @@ class tst_creation : public QObject { Q_OBJECT public: - tst_creation() {} + tst_creation(); private slots: void qobject_cpp(); @@ -67,13 +68,11 @@ private slots: void qobject_qmltype(); void qobject_alloc(); - void objects_qmltype_data(); - void objects_qmltype(); + void qobject_10flat_qml(); + void qobject_10flat_cpp(); - void qgraphicsitem(); - void qgraphicsobject(); - void qgraphicsitem14(); - void qgraphicsitem_tree14(); + void qobject_10tree_qml(); + void qobject_10tree_cpp(); void itemtree_notree_cpp(); void itemtree_objtree_cpp(); @@ -82,10 +81,36 @@ private slots: void itemtree_qml(); void itemtree_scene_cpp(); + void elements_data(); + void elements(); + private: QDeclarativeEngine engine; }; +class TestType : public QObject +{ +Q_OBJECT +Q_PROPERTY(QDeclarativeListProperty<QObject> resources READ resources); +Q_CLASSINFO("DefaultProperty", "resources"); +public: + TestType(QObject *parent = 0) + : QObject(parent) {} + + QDeclarativeListProperty<QObject> resources() { + return QDeclarativeListProperty<QObject>(this, 0, resources_append); + } + + static void resources_append(QDeclarativeListProperty<QObject> *p, QObject *o) { + o->setParent(p->object); + } +}; + +tst_creation::tst_creation() +{ + qmlRegisterType<TestType>("Qt.test", 1, 0, "TestType"); +} + inline QUrl TEST_FILE(const QString &filename) { return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename); @@ -101,7 +126,8 @@ void tst_creation::qobject_cpp() void tst_creation::qobject_qml() { - QDeclarativeComponent component(&engine, TEST_FILE("qobject.qml")); + QDeclarativeComponent component(&engine); + component.setData("import Qt 4.6\nQtObject {}", QUrl()); QObject *obj = component.create(); delete obj; @@ -111,60 +137,73 @@ void tst_creation::qobject_qml() } } -void tst_creation::qobject_qmltype() +void tst_creation::qobject_10flat_qml() { - QDeclarativeType *t = QDeclarativeMetaType::qmlType("Qt/QtObject", 4, 6); + QDeclarativeComponent component(&engine); + component.setData("import Qt.test 1.0\nTestType { resources: [ TestType{},TestType{},TestType{},TestType{},TestType{},TestType{},TestType{},TestType{},TestType{},TestType{} ] }", QUrl()); + QObject *obj = component.create(); + delete obj; QBENCHMARK { - QObject *obj = t->create(); + QObject *obj = component.create(); delete obj; } } -struct QObjectFakeData { - char data[sizeof(QObjectPrivate)]; -}; - -struct QObjectFake { - QObjectFake(); - virtual ~QObjectFake(); -private: - QObjectFakeData *d; -}; - -QObjectFake::QObjectFake() +void tst_creation::qobject_10flat_cpp() { - d = new QObjectFakeData; + QBENCHMARK { + QObject *item = new TestType; + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + delete item; + } } -QObjectFake::~QObjectFake() +void tst_creation::qobject_10tree_qml() { - delete d; -} + QDeclarativeComponent component(&engine); + component.setData("import Qt.test 1.0\nTestType { TestType{ TestType { TestType{ TestType{ TestType{ TestType{ TestType{ TestType{ TestType{ TestType{ } } } } } } } } } } }", QUrl()); + + QObject *obj = component.create(); + delete obj; -void tst_creation::qobject_alloc() -{ QBENCHMARK { - QObjectFake *obj = new QObjectFake; + QObject *obj = component.create(); delete obj; } } -void tst_creation::objects_qmltype_data() +void tst_creation::qobject_10tree_cpp() { - QTest::addColumn<QByteArray>("type"); - - QList<QByteArray> types = QDeclarativeMetaType::qmlTypeNames(); - foreach (QByteArray type, types) - QTest::newRow(type.constData()) << type; + QBENCHMARK { + QObject *item = new TestType; + QObject *root = item; + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + delete root; + } } -void tst_creation::objects_qmltype() +void tst_creation::qobject_qmltype() { - QFETCH(QByteArray, type); - QDeclarativeType *t = QDeclarativeMetaType::qmlType(type, 4, 6); - if (!t || !t->isCreatable()) - QSKIP("Non-creatable type", SkipSingle); + QDeclarativeType *t = QDeclarativeMetaType::qmlType("Qt/QtObject", 4, 6); QBENCHMARK { QObject *obj = t->create(); @@ -172,114 +211,32 @@ void tst_creation::objects_qmltype() } } -class QGraphicsItemDummy : public QGraphicsItem -{ -public: - virtual QRectF boundingRect() const { return QRectF(); } - virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {} +struct QObjectFakeData { + char data[sizeof(QObjectPrivate)]; }; -class QGraphicsObjectDummy : public QGraphicsObject -{ -public: - virtual QRectF boundingRect() const { return QRectF(); } - virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {} +struct QObjectFake { + QObjectFake(); + virtual ~QObjectFake(); +private: + QObjectFakeData *d; }; -void tst_creation::qgraphicsitem() -{ - QBENCHMARK { - QGraphicsItemDummy *i = new QGraphicsItemDummy(); - delete i; - } -} - -void tst_creation::qgraphicsobject() +QObjectFake::QObjectFake() { - QBENCHMARK { - QGraphicsObjectDummy *i = new QGraphicsObjectDummy(); - delete i; - } + d = new QObjectFakeData; } -void tst_creation::qgraphicsitem14() +QObjectFake::~QObjectFake() { - QBENCHMARK { - QGraphicsItemDummy *i1 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i2 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i3 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i4 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i5 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i6 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i7 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i8 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i9 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i10 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i11 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i12 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i13 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i14 = new QGraphicsItemDummy(); - - delete i1; - delete i2; - delete i3; - delete i4; - delete i5; - delete i6; - delete i7; - delete i8; - delete i9; - delete i10; - delete i11; - delete i12; - delete i13; - delete i14; - } + delete d; } -void tst_creation::qgraphicsitem_tree14() +void tst_creation::qobject_alloc() { QBENCHMARK { - // i1 - // +-------------------------+ - // i2 i3 - // +-----------+ +-----+-----+ - // i4 i5 i6 i7 - // +----+ +--+ +--+--+ +----+ - // i8 i9 i10 i11 i12 i13 i14 - - QGraphicsItemDummy *i1 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i2 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i3 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i4 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i5 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i6 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i7 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i8 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i9 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i10 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i11 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i12 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i13 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i14 = new QGraphicsItemDummy(); - - i14->setParentItem(i7); - i13->setParentItem(i7); - i12->setParentItem(i6); - i11->setParentItem(i6); - i10->setParentItem(i5); - i9->setParentItem(i4); - i8->setParentItem(i4); - - i7->setParentItem(i3); - i6->setParentItem(i3); - i5->setParentItem(i2); - i4->setParentItem(i2); - - i3->setParentItem(i1); - i2->setParentItem(i1); - - delete i1; + QObjectFake *obj = new QObjectFake; + delete obj; } } @@ -378,6 +335,27 @@ void tst_creation::itemtree_scene_cpp() delete root; } +void tst_creation::elements_data() +{ + QTest::addColumn<QByteArray>("type"); + + QList<QByteArray> types = QDeclarativeMetaType::qmlTypeNames(); + foreach (QByteArray type, types) + QTest::newRow(type.constData()) << type; +} + +void tst_creation::elements() +{ + QFETCH(QByteArray, type); + QDeclarativeType *t = QDeclarativeMetaType::qmlType(type, 4, 6); + if (!t || !t->isCreatable()) + QSKIP("Non-creatable type", SkipSingle); + + QBENCHMARK { + QObject *obj = t->create(); + delete obj; + } +} QTEST_MAIN(tst_creation) diff --git a/tests/benchmarks/declarative/declarative.pro b/tests/benchmarks/declarative/declarative.pro index 8c0ed42..38ea6c4 100644 --- a/tests/benchmarks/declarative/declarative.pro +++ b/tests/benchmarks/declarative/declarative.pro @@ -2,9 +2,10 @@ TEMPLATE = subdirs SUBDIRS += \ binding \ creation \ + painting \ pointers \ qdeclarativecomponent \ qdeclarativeimage \ qdeclarativemetaproperty \ script \ -# qdeclarativetime + qdeclarativetime diff --git a/tests/benchmarks/declarative/painting/paintbenchmark.pro b/tests/benchmarks/declarative/painting/painting.pro index 2f98e8b..2f98e8b 100644 --- a/tests/benchmarks/declarative/painting/paintbenchmark.pro +++ b/tests/benchmarks/declarative/painting/painting.pro diff --git a/tests/benchmarks/declarative/qdeclarativecomponent/data/samegame/BoomBlock.qml b/tests/benchmarks/declarative/qdeclarativecomponent/data/samegame/BoomBlock.qml index e48194a..b14531d 100644 --- a/tests/benchmarks/declarative/qdeclarativecomponent/data/samegame/BoomBlock.qml +++ b/tests/benchmarks/declarative/qdeclarativecomponent/data/samegame/BoomBlock.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id:block property bool dying: false diff --git a/tests/benchmarks/declarative/qdeclarativecomponent/testtypes.cpp b/tests/benchmarks/declarative/qdeclarativecomponent/testtypes.cpp index acdc395..7bc6ca2 100644 --- a/tests/benchmarks/declarative/qdeclarativecomponent/testtypes.cpp +++ b/tests/benchmarks/declarative/qdeclarativecomponent/testtypes.cpp @@ -42,5 +42,5 @@ void registerTypes() { - QML_REGISTER_TYPE(Qt.test, 4, 6, MyQmlObject, MyQmlObject); + qmlRegisterType<MyQmlObject>("Qt.test", 4, 6, "MyQmlObject"); } diff --git a/tests/benchmarks/declarative/qdeclarativetime/qdeclarativetime.cpp b/tests/benchmarks/declarative/qdeclarativetime/qdeclarativetime.cpp index a924337..20f0d93d 100644 --- a/tests/benchmarks/declarative/qdeclarativetime/qdeclarativetime.cpp +++ b/tests/benchmarks/declarative/qdeclarativetime/qdeclarativetime.cpp @@ -156,7 +156,7 @@ int main(int argc, char ** argv) { QApplication app(argc, argv); - QML_REGISTER_TYPE(QDeclarativeTime, 1, 0, Timer, Timer); + qmlRegisterType<Timer>("QDeclarativeTime", 1, 0, "Timer"); uint iterations = 1024; QString filename; diff --git a/tests/benchmarks/declarative/script/tst_script.cpp b/tests/benchmarks/declarative/script/tst_script.cpp index 9dd4076..8ea6dcd 100644 --- a/tests/benchmarks/declarative/script/tst_script.cpp +++ b/tests/benchmarks/declarative/script/tst_script.cpp @@ -144,7 +144,7 @@ int TestObject::x() void tst_script::initTestCase() { - QML_REGISTER_TYPE(Qt.test, 1, 0, TestObject, TestObject); + qmlRegisterType<TestObject>("Qt.test", 1, 0, "TestObject"); } diff --git a/tests/benchmarks/gui/painting/qregion/main.cpp b/tests/benchmarks/gui/painting/qregion/main.cpp index 3d16e41..1d19854 100644 --- a/tests/benchmarks/gui/painting/qregion/main.cpp +++ b/tests/benchmarks/gui/painting/qregion/main.cpp @@ -49,6 +49,9 @@ class tst_qregion : public QObject private slots: void map_data(); void map(); + + void intersects_data(); + void intersects(); }; @@ -84,6 +87,53 @@ void tst_qregion::map() } } +void tst_qregion::intersects_data() +{ + QTest::addColumn<QRegion>("region"); + QTest::addColumn<QRect>("rect"); + + QRegion region(0, 0, 100, 100); + QRegion complexRegion; + complexRegion = complexRegion.united(QRect(0, 0, 100, 100)); + complexRegion = complexRegion.united(QRect(120, 20, 100, 100)); + + { + QRect rect(0, 0, 100, 100); + QTest::newRow("same -- simple") << region << rect; + } + { + QRect rect(10, 10, 10, 10); + QTest::newRow("inside -- simple") << region << rect; + } + { + QRect rect(110, 110, 10, 10); + QTest::newRow("outside -- simple") << region << rect; + } + + { + QRect rect(0, 0, 100, 100); + QTest::newRow("same -- complex") << complexRegion << rect; + } + { + QRect rect(10, 10, 10, 10); + QTest::newRow("inside -- complex") << complexRegion << rect; + } + { + QRect rect(110, 110, 10, 10); + QTest::newRow("outside -- complex") << complexRegion << rect; + } +} + +void tst_qregion::intersects() +{ + QFETCH(QRegion, region); + QFETCH(QRect, rect); + + QBENCHMARK { + region.intersects(rect); + } +} + QTEST_MAIN(tst_qregion) #include "main.moc" diff --git a/tools/assistant/tools/assistant/assistant.pro b/tools/assistant/tools/assistant/assistant.pro index bc4d495..eb8cc51 100644 --- a/tools/assistant/tools/assistant/assistant.pro +++ b/tools/assistant/tools/assistant/assistant.pro @@ -15,7 +15,7 @@ DEPENDPATH += ../shared # ## Work around a qmake issue when statically linking to # ## not-yet-installed plugins -LIBS += -L$$QT_BUILD_TREE/plugins/sqldrivers +QMAKE_LIBDIR += $$QT_BUILD_TREE/plugins/sqldrivers HEADERS += aboutdialog.h \ bookmarkdialog.h \ bookmarkfiltermodel.h \ diff --git a/tools/designer/src/designer/designer.pro b/tools/designer/src/designer/designer.pro index 2050c72..8590c7b 100644 --- a/tools/designer/src/designer/designer.pro +++ b/tools/designer/src/designer/designer.pro @@ -14,10 +14,8 @@ INCLUDEPATH += \ ../lib/uilib \ extra -LIBS += -L../../lib \ - -L../../../../lib \ - -lQtDesignerComponents \ - -lQtDesigner +QMAKE_LIBDIR += ../../lib ../../../../lib +LIBS += -lQtDesignerComponents -lQtDesigner RESOURCES += designer.qrc diff --git a/tools/qml/qdeclarativefolderlistmodel.cpp b/tools/qml/qdeclarativefolderlistmodel.cpp index 58bf59b..d36033d 100644 --- a/tools/qml/qdeclarativefolderlistmodel.cpp +++ b/tools/qml/qdeclarativefolderlistmodel.cpp @@ -413,7 +413,7 @@ void QDeclarativeFolderListModel::setShowOnlyReadable(bool on) void QDeclarativeFolderListModel::registerTypes() { - QML_REGISTER_TYPE(Qt,4,6,FolderListModel,QDeclarativeFolderListModel); + qmlRegisterType<QDeclarativeFolderListModel>("Qt",4,6,"FolderListModel"); } QT_END_NAMESPACE diff --git a/tools/qml/qfxtester.cpp b/tools/qml/qfxtester.cpp index 638a3c9..28bbf5e 100644 --- a/tools/qml/qfxtester.cpp +++ b/tools/qml/qfxtester.cpp @@ -372,10 +372,10 @@ void QDeclarativeTester::updateCurrentTime(int msec) void QDeclarativeTester::registerTypes() { - QML_REGISTER_TYPE(Qt.VisualTest, 4,6, VisualTest, QDeclarativeVisualTest); - QML_REGISTER_TYPE(Qt.VisualTest, 4,6, Frame, QDeclarativeVisualTestFrame); - QML_REGISTER_TYPE(Qt.VisualTest, 4,6, Mouse, QDeclarativeVisualTestMouse); - QML_REGISTER_TYPE(Qt.VisualTest, 4,6, Key, QDeclarativeVisualTestKey); + qmlRegisterType<QDeclarativeVisualTest>("Qt.VisualTest", 4,6, "VisualTest"); + qmlRegisterType<QDeclarativeVisualTestFrame>("Qt.VisualTest", 4,6, "Frame"); + qmlRegisterType<QDeclarativeVisualTestMouse>("Qt.VisualTest", 4,6, "Mouse"); + qmlRegisterType<QDeclarativeVisualTestKey>("Qt.VisualTest", 4,6, "Key"); } QT_END_NAMESPACE diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 7da3f5a..6660947 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -351,30 +351,10 @@ private: class NetworkAccessManagerFactory : public QDeclarativeNetworkAccessManagerFactory { public: - NetworkAccessManagerFactory() : cookieJar(0), cacheSize(0) {} - ~NetworkAccessManagerFactory() { - delete cookieJar; - } + NetworkAccessManagerFactory() : cacheSize(0) {} + ~NetworkAccessManagerFactory() {} - QNetworkAccessManager *create(QObject *parent) { - QMutexLocker lock(&mutex); - QNetworkAccessManager *manager = new QNetworkAccessManager(parent); - if (!cookieJar) - cookieJar = new PersistentCookieJar(0); - manager->setCookieJar(cookieJar); - cookieJar->setParent(0); - setupProxy(manager); - if (cacheSize > 0) { - QNetworkDiskCache *cache = new QNetworkDiskCache; - cache->setCacheDirectory(QDir::tempPath()+QLatin1String("/qml-duiviewer-network-cache")); - cache->setMaximumCacheSize(cacheSize); - manager->setCache(cache); - } else { - manager->setCache(0); - } - qDebug() << "created new network access manager for" << parent; - return manager; - } + QNetworkAccessManager *create(QObject *parent); void setupProxy(QNetworkAccessManager *nam) { @@ -419,11 +399,41 @@ public: } } - PersistentCookieJar *cookieJar; + static PersistentCookieJar *cookieJar; QMutex mutex; int cacheSize; }; +PersistentCookieJar *NetworkAccessManagerFactory::cookieJar = 0; + +static void cleanup_cookieJar() +{ + delete NetworkAccessManagerFactory::cookieJar; + NetworkAccessManagerFactory::cookieJar = 0; +} + +QNetworkAccessManager *NetworkAccessManagerFactory::create(QObject *parent) +{ + QMutexLocker lock(&mutex); + QNetworkAccessManager *manager = new QNetworkAccessManager(parent); + if (!cookieJar) { + qAddPostRoutine(cleanup_cookieJar); + cookieJar = new PersistentCookieJar(0); + } + manager->setCookieJar(cookieJar); + cookieJar->setParent(0); + setupProxy(manager); + if (cacheSize > 0) { + QNetworkDiskCache *cache = new QNetworkDiskCache; + cache->setCacheDirectory(QDir::tempPath()+QLatin1String("/qml-duiviewer-network-cache")); + cache->setMaximumCacheSize(cacheSize); + manager->setCache(cache); + } else { + manager->setCache(0); + } + qDebug() << "created new network access manager for" << parent; + return manager; +} QString QDeclarativeViewer::getVideoFileName() { @@ -1444,10 +1454,15 @@ void QDeclarativeViewer::setUseGL(bool useGL) #ifdef GL_SUPPORTED if (useGL) { QGLFormat format = QGLFormat::defaultFormat(); +#ifdef Q_WS_MAC + format.setSampleBuffers(true); +#else format.setSampleBuffers(false); +#endif QGLWidget *glWidget = new QGLWidget(format); glWidget->setAutoFillBackground(false); + canvas->setViewport(glWidget); } #endif @@ -1460,7 +1475,7 @@ void QDeclarativeViewer::setUseNativeFileBrowser(bool use) void QDeclarativeViewer::registerTypes() { - QML_REGISTER_TYPE(QDeclarativeViewer, 1, 0, Screen, Screen); + qmlRegisterType<Screen>("QDeclarativeViewer", 1, 0, "Screen"); } QT_END_NAMESPACE diff --git a/translations/translations.pro b/translations/translations.pro index 8f37451..ca83d07 100644 --- a/translations/translations.pro +++ b/translations/translations.pro @@ -10,7 +10,8 @@ contains(TEMPLATE_PREFIX, vc):vcproj = 1 TEMPLATE = app TARGET = qm_phony_target -CONFIG -= qt separate_debug_info +CONFIG -= qt separate_debug_info sis_targets +CONFIG += no_icon QT = LIBS = @@ -45,3 +46,8 @@ translations.files ~= s,\\.ts$,.qm,g translations.files ~= s,^,$$OUT_PWD/,g translations.CONFIG += no_check_exist INSTALLS += translations + +# Make dummy "sis" target to keep recursive "make sis" working. +sis_target.target = sis +sis_target.commands = +QMAKE_EXTRA_TARGETS += sis_target diff --git a/util/s60pixelmetrics/pixel_metrics.cpp b/util/s60pixelmetrics/pixel_metrics.cpp index 93873fb..beb785e 100644 --- a/util/s60pixelmetrics/pixel_metrics.cpp +++ b/util/s60pixelmetrics/pixel_metrics.cpp @@ -1012,12 +1012,15 @@ TInt PixelMetrics::PixelMetricValue(QStyle::PixelMetric metric) value = PixelMetricTabValue(QStyle::PM_TabBarScrollButtonWidth, appWindow.Rect(), landscape); break; + case QStyle::PM_MenuScrollerHeight: + value = 0; + break; + // todo: re-check if these really are not available in s60 case QStyle::PM_MenuDesktopFrameWidth: // not needed in S60 - dislocates Menu both horizontally and vertically case QStyle::PM_HeaderMarkSize: // The size of the sort indicator in a header. Not in S60 case QStyle::PM_SpinBoxSliderHeight: // The height of the optional spin box slider. Not in S60 case QStyle::PM_HeaderMargin: // not in S60 - case QStyle::PM_MenuScrollerHeight: // not in S60 case QStyle::PM_MenuTearoffHeight: // not in S60 case QStyle::PM_DockWidgetFrameWidth: // not in S60 case QStyle::PM_DockWidgetSeparatorExtent: // not in S60 |