summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.profiles/symbian/headerexport411
-rw-r--r--config.profiles/symbian/qtconfig.flm2
-rwxr-xr-xconfigure6
-rw-r--r--doc/src/declarative/dynamicobjects.qdoc8
-rw-r--r--doc/src/declarative/elements.qdoc2
-rw-r--r--doc/src/declarative/extending.qdoc6
-rw-r--r--doc/src/declarative/qmlinuse.qdoc2
-rw-r--r--doc/src/declarative/whatsnew.qdoc61
-rw-r--r--doc/src/development/qmake-manual.qdoc3
-rw-r--r--doc/src/snippets/declarative/componentCreation.js7
-rw-r--r--examples/declarative/touchinteraction/pincharea/flickresize.qml11
-rw-r--r--mkspecs/common/symbian/symbian-makefile.conf2
-rw-r--r--mkspecs/symbian-gcce/qmake.conf2
-rw-r--r--qmake/generators/win32/winmakefile.cpp4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp13
-rw-r--r--src/corelib/global/qglobal.h124
-rw-r--r--src/corelib/global/qnamespace.h3
-rw-r--r--src/corelib/global/qnamespace.qdoc4
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice.cpp14
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice_p.h10
-rw-r--r--src/corelib/tools/qchar.cpp4
-rw-r--r--src/declarative/debugger/qdeclarativedebugservice_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage.cpp23
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp88
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable_p_p.h7
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp20
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp25
-rw-r--r--src/declarative/graphicsitems/qdeclarativepositioners.cpp6
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp47
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp107
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p.h10
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextlayout.cpp11
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp26
-rw-r--r--src/declarative/util/qdeclarativeopenmetaobject.cpp14
-rw-r--r--src/declarative/util/qdeclarativepropertymap.cpp15
-rw-r--r--src/gui/dialogs/qfilesystemmodel.cpp1
-rw-r--r--src/gui/image/image.pri14
-rw-r--r--src/gui/image/qpixmap.cpp20
-rw-r--r--src/gui/image/qpixmap_raster.cpp3
-rw-r--r--src/gui/image/qpixmapdata_p.h3
-rw-r--r--src/gui/image/qvolatileimage.cpp318
-rw-r--r--src/gui/image/qvolatileimage_p.h101
-rw-r--r--src/gui/image/qvolatileimagedata.cpp113
-rw-r--r--src/gui/image/qvolatileimagedata_p.h97
-rw-r--r--src/gui/image/qvolatileimagedata_symbian.cpp471
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp15
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.h1
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm2
-rw-r--r--src/gui/kernel/qwidget_x11.cpp2
-rw-r--r--src/gui/painting/qgraphicssystem.cpp5
-rw-r--r--src/gui/painting/qgraphicssystem_p.h2
-rw-r--r--src/gui/painting/qpaintengine_s60.cpp21
-rw-r--r--src/gui/styles/qs60style_s60.cpp26
-rw-r--r--src/gui/text/qfont.cpp3
-rw-r--r--src/gui/text/qfontdatabase.cpp6
-rw-r--r--src/gui/text/qfontdatabase.h1
-rw-r--r--src/gui/text/qfontdatabase_x11.cpp22
-rw-r--r--src/gui/text/qtextcontrol.cpp8
-rw-r--r--src/gui/text/qtextengine_mac.cpp5
-rw-r--r--src/gui/widgets/qlinecontrol.cpp2
-rw-r--r--src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp2
-rw-r--r--src/imports/gestures/qdeclarativegesturearea.cpp4
-rw-r--r--src/network/access/access.pri6
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp6
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp37
-rw-r--r--src/network/access/qhttpnetworkreply.cpp6
-rw-r--r--src/network/access/qhttpnetworkreply_p.h1
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp518
-rw-r--r--src/network/access/qhttpthreaddelegate_p.h285
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp22
-rw-r--r--src/network/access/qnetworkaccessbackend_p.h15
-rw-r--r--src/network/access/qnetworkaccessfilebackend.cpp2
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp795
-rw-r--r--src/network/access/qnetworkaccesshttpbackend_p.h43
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp13
-rw-r--r--src/network/access/qnetworkaccessmanager.h2
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h5
-rw-r--r--src/network/access/qnetworkcookie.cpp21
-rw-r--r--src/network/access/qnetworkreplyfileimpl.cpp48
-rw-r--r--src/network/access/qnetworkreplyfileimpl_p.h6
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp59
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h3
-rw-r--r--src/network/access/qnetworkrequest.cpp2
-rw-r--r--src/network/access/qnetworkrequest.h4
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp3
-rw-r--r--src/network/bearer/qsharednetworksession.cpp2
-rw-r--r--src/network/socket/qabstractsocket.cpp11
-rw-r--r--src/network/socket/qhttpsocketengine.cpp5
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp25
-rw-r--r--src/network/ssl/qsslsocket.cpp42
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp34
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp3
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h1
-rw-r--r--src/network/ssl/qsslsocket_p.h5
-rw-r--r--src/opengl/qpixmapdata_gl.cpp2
-rw-r--r--src/opengl/qwindowsurface_gl.cpp4
-rw-r--r--src/openvg/qpaintengine_vg.cpp16
-rw-r--r--src/openvg/qpixmapdata_vg.cpp104
-rw-r--r--src/openvg/qpixmapdata_vg_p.h6
-rw-r--r--src/openvg/qvg_symbian.cpp123
-rw-r--r--src/openvg/qvgfontglyphcache_p.h2
-rw-r--r--src/openvg/qvgimagepool.cpp15
-rw-r--r--src/plugins/bearer/symbian/symbianengine.cpp12
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.cpp7
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.h1
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp21
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h7
-rw-r--r--src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp6
-rw-r--r--src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h2
-rw-r--r--src/s60installs/bwins/QtCoreu.def6
-rw-r--r--src/s60installs/bwins/QtDeclarativeu.def48
-rw-r--r--src/s60installs/bwins/QtGuiu.def55
-rw-r--r--src/s60installs/bwins/QtOpenGLu.def131
-rw-r--r--src/s60installs/bwins/QtOpenVGu.def3
-rw-r--r--src/s60installs/bwins/QtTestu.def89
-rw-r--r--src/s60installs/eabi/QtCoreu.def5
-rw-r--r--src/s60installs/eabi/QtDeclarativeu.def44
-rw-r--r--src/s60installs/eabi/QtGuiu.def55
-rw-r--r--src/s60installs/eabi/QtOpenGLu.def32
-rw-r--r--src/s60installs/eabi/QtOpenVGu.def3
-rw-r--r--src/s60installs/eabi/QtTestu.def94
-rw-r--r--src/script/api/qscriptcontext.cpp10
-rw-r--r--src/script/api/qscriptcontextinfo.cpp10
-rw-r--r--src/script/api/qscriptengine.cpp31
-rw-r--r--src/script/api/qscriptvalue.cpp13
-rw-r--r--src/script/script.pro2
-rw-r--r--src/tools/moc/moc.cpp5
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.cpp36
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.h2
-rw-r--r--tests/arthur/baselineserver/src/report.cpp25
-rw-r--r--tests/arthur/baselineserver/src/report.h3
-rw-r--r--tests/arthur/common/baselineprotocol.cpp2
-rw-r--r--tests/auto/baselineexample/baselineexample.pro2
-rw-r--r--tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp4
-rw-r--r--tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp34
-rw-r--r--tests/auto/declarative/qdeclarativelistview/data/listview-sections_delegate.qml3
-rw-r--r--tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp48
-rw-r--r--tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp34
-rw-r--r--tests/auto/declarative/qdeclarativetext/data/qtbug_14734.qml10
-rw-r--r--tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp14
-rw-r--r--tests/auto/declarative/qdeclarativetextedit/data/navigation.qml1
-rw-r--r--tests/auto/declarative/qdeclarativetextedit/data/positionAt.qml9
-rw-r--r--tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp186
-rw-r--r--tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp255
-rw-r--r--tests/auto/gui.pro1
-rw-r--r--tests/auto/lancelot/lancelot.pro8
-rw-r--r--tests/auto/moc/tst_moc.cpp26
-rw-r--r--tests/auto/network.pro2
-rw-r--r--tests/auto/networkselftest/tst_networkselftest.cpp2
-rw-r--r--tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp2
-rw-r--r--tests/auto/qfont/tst_qfont.cpp7
-rw-r--r--tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp24
-rw-r--r--tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp4
-rw-r--r--tests/auto/qnetworkreply/tst_qnetworkreply.cpp103
-rw-r--r--tests/auto/qscriptcontext/tst_qscriptcontext.cpp12
-rw-r--r--tests/auto/qscriptengine/tst_qscriptengine.cpp62
-rw-r--r--tests/auto/qscriptjstestsuite/expect_fail.txt198
-rw-r--r--tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro2
-rw-r--r--tests/auto/qscriptjstestsuite/qscriptjstestsuite.qrc6
-rw-r--r--tests/auto/qscriptjstestsuite/skip.txt9
-rw-r--r--tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp819
-rw-r--r--tests/auto/qscriptv8testsuite/abstracttestsuite.cpp481
-rw-r--r--tests/auto/qscriptv8testsuite/abstracttestsuite.h125
-rw-r--r--tests/auto/qscriptv8testsuite/abstracttestsuite.pri4
-rw-r--r--tests/auto/qscriptv8testsuite/expect_fail.txt16
-rw-r--r--tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro1
-rw-r--r--tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc2
-rw-r--r--tests/auto/qscriptv8testsuite/skip.txt17
-rw-r--r--tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp366
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.cpp5
-rw-r--r--tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp57
-rw-r--r--tests/auto/qsslsocket/tst_qsslsocket.cpp8
-rw-r--r--tests/auto/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro36
-rw-r--r--tests/auto/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp225
-rw-r--r--tests/auto/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro36
-rw-r--r--tests/auto/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp226
-rw-r--r--tests/auto/qtextlayout/tst_qtextlayout.cpp13
-rw-r--r--tests/auto/qtimer/tst_qtimer.cpp8
-rw-r--r--tests/auto/qvolatileimage/qvolatileimage.pro7
-rw-r--r--tests/auto/qvolatileimage/tst_qvolatileimage.cpp403
-rw-r--r--tests/benchmarks/network/ssl/qsslsocket/tst_qsslsocket.cpp13
-rw-r--r--tests/benchmarks/script/script.pro4
-rw-r--r--tests/benchmarks/script/sunspider/tst_sunspider.cpp2
-rw-r--r--tests/benchmarks/script/v8/tst_v8.cpp4
-rw-r--r--tools/designer/src/components/formeditor/qdesigner_resource.cpp1
-rw-r--r--tools/designer/src/designer/qdesigner_formwindow.cpp1
-rw-r--r--tools/designer/src/designer/qdesigner_workbench.cpp4
-rw-r--r--tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp2
-rw-r--r--tools/qmeegographicssystemhelper/qmeegoruntime.cpp12
-rw-r--r--tools/qmeegographicssystemhelper/qmeegoruntime.h1
-rw-r--r--tools/qmeegographicssystemhelper/qmeegoswitchevent.cpp2
-rw-r--r--tools/qml/qml.pri2
194 files changed, 7096 insertions, 2313 deletions
diff --git a/config.profiles/symbian/headerexport b/config.profiles/symbian/headerexport
index d9f99e5..e59979c 100644
--- a/config.profiles/symbian/headerexport
+++ b/config.profiles/symbian/headerexport
@@ -48,7 +48,6 @@ my %modules = ( # path to module name map
"QtDesigner" => "$basedir/tools/designer/src/lib",
"QtUiTools" => "$basedir/tools/designer/src/uitools",
"QtDBus" => "$basedir/src/dbus",
-# "QtWebKit" => "$basedir/src/3rdparty/webkit/WebCore", // :TODO:disabled since QtWebKit built separately, better logic needed here.
"phonon" => "$basedir/src/phonon",
"QtMultimedia" => "$basedir/src/multimedia",
"QtMeeGoGraphicsSystemHelper" => "$basedir/tools/qmeegographicssystemhelper",
@@ -61,22 +60,12 @@ my %moduleheaders = ( # restrict the module headers to those found in relative p
#$modules{"QtCore"} .= ";$basedir/mkspecs/" . $ENV{"MKSPEC"} if defined $ENV{"MKSPEC"};
# global variables (modified by options)
-my $module = 0;
-my $showonly = 0;
-my $quiet = 0;
-my $remove_stale = 1;
my $force_win = 0;
-my $force_relative = 0;
my $check_includes = 0;
-my $copy_headers = 0;
my $create_uic_class_map = 1;
-my $create_private_headers = 1;
-my $oneway = 0;
my @modules_to_sync ;
-$force_relative = 1 if ( -d "/System/Library/Frameworks" );
my $out_basedir = $basedir;
$out_basedir =~ s=\\=/=g;
-my $out_subdir = 'include';
# functions ----------------------------------------------------------
@@ -90,17 +79,8 @@ my $out_subdir = 'include';
sub showUsage
{
print "$0 usage:\n";
- print " -copy Copy headers instead of include-fwd(default: " . ($copy_headers ? "yes" : "no") . ")\n";
- print " -remove-stale Removes stale headers (default: " . ($remove_stale ? "yes" : "no") . ")\n";
- print " -relative Force relative symlinks (default: " . ($force_relative ? "yes" : "no") . ")\n";
print " -windows Force platform to Windows (default: " . ($force_win ? "yes" : "no") . ")\n";
- print " -showonly Show action but not perform (default: " . ($showonly ? "yes" : "no") . ")\n";
print " -outdir <PATH> Specify output directory for sync (default: $out_basedir)\n";
- print " -outsubdir <DIR> Target subdir under outdir (default: $out_subdir)\n";
- print " -public Create only public headers (default: " . ($create_private_headers ? "no" : "yes") . ")\n";
- print " -oneway Don't sync back from outdir (default: " . ($oneway ? "yes" : "no") . ")\n";
- print " -quiet Only report problems, not activity (default: " . ($quiet ? "yes" : "no") . ")\n";
- print " -separate-module <NAME>:<PROFILEDIR>:<HEADERDIR> Create headers for <NAME> with original headers in <HEADERDIR> relative to <PROFILEDIR> \n";
print " -help This help\n";
exit 0;
}
@@ -331,7 +311,7 @@ sub syncHeader {
unless(-e $header) {
my $header_dir = dirname($header);
- mkpath $header_dir, !$quiet;
+ mkpath $header_dir;
#write it
my $iheader_out = fixPaths($iheader, $header_dir);
@@ -459,7 +439,7 @@ sub copyFile
close I;
my $ifile_dir = dirname($ifile);
- mkpath $ifile_dir, !$quiet unless(-e $ifile_dir);
+ mkpath $ifile_dir unless(-e $ifile_dir);
open(O, "> " . $ifile) || die "Could not open $ifile for writing (no write permission?)";
local $/;
binmode O;
@@ -469,36 +449,6 @@ sub copyFile
}
######################################################################
-# Syntax: symlinkFile(file, ifile)
-# Params: file, string, filename to create "symlink" for
-# ifile, string, destination name of symlink
-#
-# Purpose: File is symlinked to ifile (or copied if filesystem doesn't
-# support symlink).
-# Returns: 1 on success, else 0.
-######################################################################
-sub symlinkFile
-{
- my ($file,$ifile) = @_;
-
- if ($isunix) {
- print "symlink created for $file " unless $quiet;
- if ( $force_relative && ($ifile =~ /^$basedir/)) {
- my $t = getcwd();
- my $c = -1;
- my $p = "../";
- $t =~ s-^$basedir/--;
- $p .= "../" while( ($c = index( $t, "/", $c + 1)) != -1 );
- $file =~ s-^$basedir/-$p-;
- print " ($file)\n" unless $quiet;
- }
- print "\n" unless $quiet;
- return symlink($file, $ifile);
- }
- return copyFile($file, $ifile);
-}
-
-######################################################################
# Syntax: findFiles(dir, match, descend)
# Params: dir, string, directory to search for name
# match, string, regular expression to match in dir
@@ -550,9 +500,6 @@ while ( @ARGV ) {
if ($arg eq "-h" || $arg eq "-help" || $arg eq "?") {
$var = "show_help";
$val = "yes";
- } elsif($arg eq "-copy") {
- $var = "copy";
- $val = "yes";
} elsif($arg eq "-o" || $arg eq "-outdir") {
$var = "output";
$val = shift @ARGV;
@@ -567,96 +514,28 @@ while ( @ARGV ) {
} elsif($arg eq "-inc") {
$var = "output";
$val = shift @ARGV;
- } elsif($arg eq "-module") {
- $var = "module";
- $val = shift @ARGV;
- } elsif($arg eq "-separate-module") {
- $var = "separate-module";
- $val = shift @ARGV;
- } elsif($arg eq "-show") {
- $var = "showonly";
- $val = "yes";
- } elsif($arg eq "-quiet") {
- $var = "quiet";
- $val = "yes";
} elsif($arg eq "-base-dir") {
# skip, it's been dealt with at the top of the file
shift @ARGV;
next;
- } elsif("$arg" eq "-outsubdir") {
- $var = "outsubdir";
- $val = shift @ARGV;
- } elsif("$arg" eq "-public") {
- $var = "public";
- $val = "yes";
- } elsif("$arg" eq "-oneway") {
- $var = "oneway";
- $val = "yes";
}
#do something
if(!$var || $var eq "show_help") {
print "Unknown option: $arg\n\n" if(!$var);
showUsage();
- } elsif ($var eq "copy") {
- if($val eq "yes") {
- $copy_headers++;
- } elsif($showonly) {
- $copy_headers--;
- }
- } elsif ($var eq "showonly") {
- if($val eq "yes") {
- $showonly++;
- } elsif($showonly) {
- $showonly--;
- }
- } elsif ($var eq "quiet") {
- if($val eq "yes") {
- $quiet++;
- } elsif($quiet) {
- $quiet--;
- }
} elsif ($var eq "check-includes") {
if($val eq "yes") {
$check_includes++;
} elsif($check_includes) {
$check_includes--;
}
- } elsif ($var eq "remove-stale") {
- if($val eq "yes") {
- $remove_stale++;
- } elsif($remove_stale) {
- $remove_stale--;
- }
} elsif ($var eq "windows") {
if($val eq "yes") {
$force_win++;
} elsif($force_win) {
$force_win--;
}
- } elsif ($var eq "relative") {
- if($val eq "yes") {
- $force_relative++;
- } elsif($force_relative) {
- $force_relative--;
- }
- } elsif ("$var" eq "public") {
- $create_private_headers = ("$val" eq "yes" ? 0 : 1);
- } elsif ("$var" eq "oneway") {
- $oneway = ("$val" eq "yes" ? 1 : 0);
- } elsif ("$var" eq "outsubdir") {
- $out_subdir = $val;
- } elsif ($var eq "module") {
- print "module :$val:\n" unless $quiet;
- die "No such module: $val" unless(defined $modules{$val});
- push @modules_to_sync, $val;
- } elsif ($var eq "separate-module") {
- my ($module, $prodir, $headerdir) = split(/:/, $val);
- $modules{$module} = $prodir;
- push @modules_to_sync, $module;
- $moduleheaders{$module} = $headerdir;
- $create_uic_class_map = 0;
- $create_private_headers = 0;
} elsif ($var eq "output") {
my $outdir = $val;
if(checkRelative($outdir)) {
@@ -675,8 +554,8 @@ while ( @ARGV ) {
$isunix = checkUnix; #cache checkUnix
# create path
-mkpath "$out_basedir/include", !$quiet;
-mkpath "$out_basedir/$out_subdir/Qt", !$quiet;
+mkpath "$out_basedir/include";
+mkpath "$out_basedir/mw/Qt";
my @ignore_headers = ();
my $class_lib_map_contents = "";
@@ -734,41 +613,39 @@ foreach my $lib (@modules_to_sync) {
}
#remove the old files
- if($remove_stale) {
- my @subdirs = ("$out_basedir/$out_subdir/$lib");
- foreach my $subdir (@subdirs) {
- if (opendir DIR, $subdir) {
- while(my $t = readdir(DIR)) {
- my $file = "$subdir/$t";
- if(-d $file) {
- push @subdirs, $file unless($t eq "." || $t eq "..");
- } else {
- my @files = ($file);
- #push @files, "$out_basedir/$out_subdir/Qt/$t" if(-e "$out_basedir/$out_subdir/Qt/$t");
- foreach my $file (@files) {
- my $remove_file = 0;
- if(open(F, "<$file")) {
- while(my $line = <F>) {
- chomp $line;
- if($line =~ /^\#include \"([^\"]*)\"$/) {
- my $include = $1;
- $include = $subdir . "/" . $include unless(substr($include, 0, 1) eq "/");
- $remove_file = 1 unless(-e $include);
- } else {
- $remove_file = 0;
- last;
- }
+ my @subdirs = ("$out_basedir/mw/$lib");
+ foreach my $subdir (@subdirs) {
+ if (opendir DIR, $subdir) {
+ while(my $t = readdir(DIR)) {
+ my $file = "$subdir/$t";
+ if(-d $file) {
+ push @subdirs, $file unless($t eq "." || $t eq "..");
+ } else {
+ my @files = ($file);
+ #push @files, "$out_basedir/mw/Qt/$t" if(-e "$out_basedir/mw/Qt/$t");
+ foreach my $file (@files) {
+ my $remove_file = 0;
+ if(open(F, "<$file")) {
+ while(my $line = <F>) {
+ chomp $line;
+ if($line =~ /^\#include \"([^\"]*)\"$/) {
+ my $include = $1;
+ $include = $subdir . "/" . $include unless(substr($include, 0, 1) eq "/");
+ $remove_file = 1 unless(-e $include);
+ } else {
+ $remove_file = 0;
+ last;
}
- close(F);
- unlink $file if($remove_file);
}
+ close(F);
+ unlink $file if($remove_file);
}
}
}
- closedir DIR;
}
-
+ closedir DIR;
}
+
}
#create the new ones
@@ -813,91 +690,85 @@ foreach my $lib (@modules_to_sync) {
my $iheader = $subdir . "/" . $header;
$iheader =~ s/^\Q$basedir\E/$out_basedir/ if ($shadow);
my @classes = $public_header ? classNames($iheader) : ();
- if($showonly) {
- print "$header [$lib]\n";
- foreach(@classes) {
- print "SYMBOL: $_\n";
- }
- } else {
- #find out all the places it goes..
- my @headers;
- if ($public_header) {
- @headers = ( "$out_basedir/$out_subdir/$lib/$header" );
- # write forwarding headers to include/Qt
- if ($lib ne "phonon" && $subdir =~ /^$basedir\/src/) {
- my $file_name = "$out_basedir/$out_subdir/Qt/$header";
- my $file_op = '>';
- my $header_content = '';
- if (exists $colliding_headers{$file_name}) {
- $file_op = '>>';
- } else {
- $colliding_headers{$file_name} = 1;
- my $warning_msg = 'Inclusion of header files from include/Qt is deprecated.';
- $header_content = "#ifndef QT_NO_QT_INCLUDE_WARN\n" .
- " #if defined(__GNUC__)\n" .
- " #warning \"$warning_msg\"\n" .
- " #elif defined(_MSC_VER)\n" .
- " #pragma message(\"WARNING: $warning_msg\")\n" .
- " #endif\n".
- "#endif\n\n";
- }
- $header_content .= '#include "' . "../$lib/$header" . "\"\n";
- open HEADERFILE, $file_op, $file_name or die "unable to open '$file_name' : $!\n";
- print HEADERFILE $header_content;
- close HEADERFILE;
+ #find out all the places it goes..
+ my @headers;
+ if ($public_header) {
+ @headers = ( "$out_basedir/mw/$lib/$header" );
+
+ # write forwarding headers to include/Qt
+ if ($lib ne "phonon" && $subdir =~ /^$basedir\/src/) {
+ my $file_name = "$out_basedir/mw/Qt/$header";
+ my $file_op = '>';
+ my $header_content = '';
+ if (exists $colliding_headers{$file_name}) {
+ $file_op = '>>';
+ } else {
+ $colliding_headers{$file_name} = 1;
+ my $warning_msg = 'Inclusion of header files from include/Qt is deprecated.';
+ $header_content = "#ifndef QT_NO_QT_INCLUDE_WARN\n" .
+ " #if defined(__GNUC__)\n" .
+ " #warning \"$warning_msg\"\n" .
+ " #elif defined(_MSC_VER)\n" .
+ " #pragma message(\"WARNING: $warning_msg\")\n" .
+ " #endif\n".
+ "#endif\n\n";
}
+ $header_content .= '#include "' . "../$lib/$header" . "\"\n";
+ open HEADERFILE, $file_op, $file_name or die "unable to open '$file_name' : $!\n";
+ print HEADERFILE $header_content;
+ close HEADERFILE;
+ }
- foreach my $full_class (@classes) {
- my $header_base = basename($header);
- # Strip namespaces:
- my $class = $full_class;
- $class =~ s/^.*:://;
+ foreach my $full_class (@classes) {
+ my $header_base = basename($header);
+ # Strip namespaces:
+ my $class = $full_class;
+ $class =~ s/^.*:://;
# if ($class =~ m/::/) {
# class =~ s,::,/,g;
# }
- $class_lib_map_contents .= "QT_CLASS_LIB($full_class, $lib, $header_base)\n";
- $header_copies++ if(syncHeader("$out_basedir/$out_subdir/$lib/$class", "$out_basedir/$out_subdir/$lib/$header", 0));
+ $class_lib_map_contents .= "QT_CLASS_LIB($full_class, $lib, $header_base)\n";
+ $header_copies++ if(syncHeader("$out_basedir/mw/$lib/$class", "$out_basedir/mw/$lib/$header", 0));
- # KDE-Compat headers for Phonon
- if ($lib eq "phonon") {
- $header_copies++ if (syncHeader("$out_basedir/$out_subdir/phonon_compat/Phonon/$class", "$out_basedir/$out_subdir/$lib/$header", 0));
- }
+ # KDE-Compat headers for Phonon
+ if ($lib eq "phonon") {
+ $header_copies++ if (syncHeader("$out_basedir/mw/phonon_compat/Phonon/$class", "$out_basedir/mw/$lib/$header", 0));
}
- } elsif ($create_private_headers) {
- @headers = ( "$out_basedir/$out_subdir/$lib/private/$header" );
- }
- foreach(@headers) { #sync them
- $header_copies++ if(syncHeader($_, $iheader, $copy_headers));
}
+ } else {
+ @headers = ( "$out_basedir/mw/$lib/private/$header" );
+ }
+ foreach(@headers) { #sync them
+ $header_copies++ if(syncHeader($_, $iheader, 1));
+ }
- if($public_header) {
- #put it into the master file
- $master_contents .= "#include \"$public_header\"\n" if(shouldMasterInclude($iheader));
+ if($public_header) {
+ #put it into the master file
+ $master_contents .= "#include \"$public_header\"\n" if(shouldMasterInclude($iheader));
- #deal with the install directives
- if($public_header) {
- my $pri_install_iheader = fixPaths($iheader, $current_dir);
- foreach my $class (@classes) {
- # Strip namespaces:
- $class =~ s/^.*:://;
+ #deal with the install directives
+ if($public_header) {
+ my $pri_install_iheader = fixPaths($iheader, $current_dir);
+ foreach my $class (@classes) {
+ # Strip namespaces:
+ $class =~ s/^.*:://;
# if ($class =~ m/::/) {
# $class =~ s,::,/,g;
# }
- my $class_header = fixPaths("$out_basedir/$out_subdir/$lib/$class",
- $current_dir) . " ";
- $pri_install_classes .= $class_header
- unless($pri_install_classes =~ $class_header);
- }
- $pri_install_files.= "$pri_install_iheader ";;
+ my $class_header = fixPaths("$out_basedir/mw/$lib/$class",
+ $current_dir) . " ";
+ $pri_install_classes .= $class_header
+ unless($pri_install_classes =~ $class_header);
}
+ $pri_install_files.= "$pri_install_iheader ";;
}
- else {
- my $pri_install_iheader = fixPaths($iheader, $current_dir);
- $pri_install_pfiles.= "$pri_install_iheader ";;
- }
}
- print "header created for $iheader ($header_copies)\n" if($header_copies > 0 && !$quiet);
+ else {
+ my $pri_install_iheader = fixPaths($iheader, $current_dir);
+ $pri_install_pfiles.= "$pri_install_iheader ";;
+ }
+ print "header created for $iheader ($header_copies)\n" if($header_copies > 0);
}
}
}
@@ -906,59 +777,57 @@ foreach my $lib (@modules_to_sync) {
# close the master include:
$master_contents .= "#endif\n";
- unless($showonly) {
- my @master_includes;
- push @master_includes, "$out_basedir/$out_subdir/$lib/$lib";
- push @master_includes, "$out_basedir/$out_subdir/phonon_compat/Phonon/Phonon" if ($lib eq "phonon");
- foreach my $master_include (@master_includes) {
- #generate the "master" include file
- my @tmp = split(/;/,$modules{$lib});
- $pri_install_files .= fixPaths($master_include, $tmp[0]) . " "; #get the master file installed too
- if($master_include && -e $master_include) {
- open MASTERINCLUDE, "<$master_include";
- local $/;
- binmode MASTERINCLUDE;
- my $oldmaster = <MASTERINCLUDE>;
- close MASTERINCLUDE;
- $oldmaster =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
- $master_include = 0 if($oldmaster eq $master_contents);
- }
- if($master_include && $master_contents) {
- my $master_dir = dirname($master_include);
- mkpath $master_dir, !$quiet;
- print "header (master) created for $lib\n" unless $quiet;
- open MASTERINCLUDE, ">$master_include";
- print MASTERINCLUDE $master_contents;
- close MASTERINCLUDE;
- }
- }
-
- #handle the headers.pri for each module
- my $headers_pri_contents = "";
- $headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n";
- $headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n";
- $headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n";
- my $headers_pri_file = "$out_basedir/$out_subdir/$lib/headers.pri";
- if(-e $headers_pri_file) {
- open HEADERS_PRI_FILE, "<$headers_pri_file";
+ my @master_includes;
+ push @master_includes, "$out_basedir/mw/$lib/$lib";
+ push @master_includes, "$out_basedir/mw/phonon_compat/Phonon/Phonon" if ($lib eq "phonon");
+ foreach my $master_include (@master_includes) {
+ #generate the "master" include file
+ my @tmp = split(/;/,$modules{$lib});
+ $pri_install_files .= fixPaths($master_include, $tmp[0]) . " "; #get the master file installed too
+ if($master_include && -e $master_include) {
+ open MASTERINCLUDE, "<$master_include";
local $/;
- binmode HEADERS_PRI_FILE;
- my $old_headers_pri_contents = <HEADERS_PRI_FILE>;
- close HEADERS_PRI_FILE;
- $old_headers_pri_contents =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
- $headers_pri_file = 0 if($old_headers_pri_contents eq $headers_pri_contents);
+ binmode MASTERINCLUDE;
+ my $oldmaster = <MASTERINCLUDE>;
+ close MASTERINCLUDE;
+ $oldmaster =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
+ $master_include = 0 if($oldmaster eq $master_contents);
}
- if($headers_pri_file && $master_contents) {
- my $headers_pri_dir = dirname($headers_pri_file);
- mkpath $headers_pri_dir, !$quiet;
- print "headers.pri file created for $lib\n" unless $quiet;
- open HEADERS_PRI_FILE, ">$headers_pri_file";
- print HEADERS_PRI_FILE $headers_pri_contents;
- close HEADERS_PRI_FILE;
+ if($master_include && $master_contents) {
+ my $master_dir = dirname($master_include);
+ mkpath $master_dir;
+ print "header (master) created for $lib\n";
+ open MASTERINCLUDE, ">$master_include";
+ print MASTERINCLUDE $master_contents;
+ close MASTERINCLUDE;
}
}
+
+ #handle the headers.pri for each module
+ my $headers_pri_contents = "";
+ $headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n";
+ $headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n";
+ $headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n";
+ my $headers_pri_file = "$out_basedir/mw/$lib/headers.pri";
+ if(-e $headers_pri_file) {
+ open HEADERS_PRI_FILE, "<$headers_pri_file";
+ local $/;
+ binmode HEADERS_PRI_FILE;
+ my $old_headers_pri_contents = <HEADERS_PRI_FILE>;
+ close HEADERS_PRI_FILE;
+ $old_headers_pri_contents =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
+ $headers_pri_file = 0 if($old_headers_pri_contents eq $headers_pri_contents);
+ }
+ if($headers_pri_file && $master_contents) {
+ my $headers_pri_dir = dirname($headers_pri_file);
+ mkpath $headers_pri_dir;
+ print "headers.pri file created for $lib\n";
+ open HEADERS_PRI_FILE, ">$headers_pri_file";
+ print HEADERS_PRI_FILE $headers_pri_contents;
+ close HEADERS_PRI_FILE;
+ }
}
-unless($showonly || !$create_uic_class_map) {
+unless(!$create_uic_class_map) {
my $class_lib_map = "$out_basedir/src/tools/uic/qclass_lib_map.h";
if(-e $class_lib_map) {
open CLASS_LIB_MAP, "<$class_lib_map";
@@ -971,7 +840,7 @@ unless($showonly || !$create_uic_class_map) {
}
if($class_lib_map) {
my $class_lib_map_dir = dirname($class_lib_map);
- mkpath $class_lib_map_dir, !$quiet;
+ mkpath $class_lib_map_dir;
open CLASS_LIB_MAP, ">$class_lib_map";
print CLASS_LIB_MAP $class_lib_map_contents;
close CLASS_LIB_MAP;
@@ -1054,7 +923,7 @@ if($check_includes) {
}
if($include) {
for my $trylib (keys(%modules)) {
- if(-e "$out_basedir/$out_subdir/$trylib/$include") {
+ if(-e "$out_basedir/mw/$trylib/$include") {
print "WARNING: $iheader includes $include when it should include $trylib/$include\n";
}
}
diff --git a/config.profiles/symbian/qtconfig.flm b/config.profiles/symbian/qtconfig.flm
index 03f860f..93410f0 100644
--- a/config.profiles/symbian/qtconfig.flm
+++ b/config.profiles/symbian/qtconfig.flm
@@ -60,7 +60,7 @@ $(SOURCEDIR)/qmake$(DOTEXE): $(EXTENSION_ROOT)/$(QT_ROOT)/$(CONFIGURE_APP)
$(call endrule,qtconf)
$(call startrule,headerexport) \
cd $(EXTENSION_ROOT)/$(QT_ROOT)/config.profiles/symbian && \
- perl headerexport -base-dir $(EXTENSION_ROOT)/$(QT_ROOT) -copy -oneway -outdir $(EPOCROOT)/epoc32/include/ -outsubdir mw
+ perl headerexport -base-dir $(EXTENSION_ROOT)/$(QT_ROOT) -outdir $(EPOCROOT)/epoc32/include/
$(call endrule,headerexport)
$(call startrule,mkspecexport) \
$(GNUCP) -R $(EXTENSION_ROOT)/$(QT_ROOT)/mkspecs $(MKSPECDIR)
diff --git a/configure b/configure
index a542314..09ab545 100755
--- a/configure
+++ b/configure
@@ -6707,6 +6707,8 @@ if [ "$CFG_JAVASCRIPTCORE_JIT" = "yes" ] || [ "$CFG_JAVASCRIPTCORE_JIT" = "auto"
if [ $? != "0" ]; then
CFG_JAVASCRIPTCORE_JIT=no
fi
+ elif [ "$XPLATFORM" = "symbian-gcce" ]; then
+ CFG_JAVASCRIPTCORE_JIT=no
fi
fi
@@ -7412,11 +7414,11 @@ EOF
canBuildWebKit="no"
canBuildQtConcurrent="no"
;;
- symbian/*-gcce)
+ symbian-gcce)
canBuildWebKit="no"
canBuildQtConcurrent="no"
;;
- symbian/*-armcc)
+ symbian-armcc)
canBuildQtConcurrent="no"
;;
esac
diff --git a/doc/src/declarative/dynamicobjects.qdoc b/doc/src/declarative/dynamicobjects.qdoc
index 316fe6b..f2ca0fd 100644
--- a/doc/src/declarative/dynamicobjects.qdoc
+++ b/doc/src/declarative/dynamicobjects.qdoc
@@ -68,9 +68,11 @@ the component. This function can take one or two arguments:
\o The first is the parent for the new item. Since graphical items will not appear on the scene without a parent, it is
recommended that you set the parent this way. However, if you wish to set the parent later you can safely pass \c null to
this function.
-\o The second is optional and is a script which assigns values to the item's properties during creation. This avoids warnings
- when certain properties have been bound to before they have been set by the code. Additionally, there are small performance
- benefits when instantiating objects in this way.
+\o The second is optional and is a map of property-value items that define initial any property values for the item.
+ Property values specified by this argument are applied to the object before its creation is finalized, avoiding
+ binding errors that may occur if particular properties must be initialized to enable other property bindings.
+ when certain properties have been bound to before they have been set by the code. Additionally, there are small
+ performance benefits when compared to defining property values and bindings after the object is created.
\endlist
Here is an example. First there is \c Sprite.qml, which defines a simple QML component:
diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc
index 466b940..e2d9350 100644
--- a/doc/src/declarative/elements.qdoc
+++ b/doc/src/declarative/elements.qdoc
@@ -76,7 +76,7 @@ To see the QML elements listed by functional area, see the
\o \l {FocusScope} - Element that mediate keyboard focus changes
\o \l {Flickable} - Provides a surface that can be "flicked"
\o \l {Flipable} - Provides a surface that produces "flipping" effects
-\o \l {GestureArea} - Enables simple gesture handling
+\o \l {PinchArea} - Enables simple pinch gesture handling
\endlist
\section1 Positioners and Repeater
diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc
index a287533..80b6e72 100644
--- a/doc/src/declarative/extending.qdoc
+++ b/doc/src/declarative/extending.qdoc
@@ -51,7 +51,7 @@ to either instantiating an object instance, or assigning a property a value.
QML relies heavily on Qt's meta object system and can only instantiate classes
that derive from QObject. For visual element types, this will usually mean a subclass
of QDeclarativeItem; for models used with the view elements, a subclass of QAbstractItemModel;
-and for abitrary objects with properties, a direct subclass of QObject.
+and for arbitrary objects with properties, a direct subclass of QObject.
The QML engine has no intrinsic knowledge of any class types. Instead the
programmer must register the C++ types with their corresponding QML names.
@@ -522,7 +522,7 @@ The \c {invite()} method is similarly available if it is declared as a slot.
\snippet examples/declarative/cppextensions/referenceexamples/valuesource/example.qml 0
\snippet examples/declarative/cppextensions/referenceexamples/valuesource/example.qml 1
-The QML snippet shown above applies a property value source to the \c announcment property.
+The QML snippet shown above applies a property value source to the \c announcement property.
A property value source generates a value for a property that changes over time.
Property value sources are most commonly used to do animation. Rather than
@@ -562,7 +562,7 @@ assignment fails does the engine call the \l {QDeclarativePropertyValueSource::}
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
-implement the \c HappyBirthdaySong property value source.
+to implement the \c HappyBirthdaySong property value source.
\section1 Property Binding
diff --git a/doc/src/declarative/qmlinuse.qdoc b/doc/src/declarative/qmlinuse.qdoc
index 7380ef5..131be1b 100644
--- a/doc/src/declarative/qmlinuse.qdoc
+++ b/doc/src/declarative/qmlinuse.qdoc
@@ -207,7 +207,7 @@
<li><a href="qml-flipable.html">Flipable Element</a> - The Flipable item provides a surface that can be flipped or reflected.</li>
<li><a href="qml-focuspanel.html">FocusPanel Element</a> - The FocusPanel item explicitly creates a focus panel.</li>
<li><a href="qml-focusscope.html">FocusScope Element</a> - The FocusScope object explicitly creates a focus scope for focus management.</li>
- <li><a href="qml-gesturearea.html">GestureArea Element</a> - The GestureArea item enables simple gesture handling.</li>
+ <li><a href="qml-pincharea.html">PinchArea Element</a> - The PinchArea item enables simple pinch gesture handling.</li>
<li><a href="qml-keynavigation.html">KeyNavigation Element</a> - The KeyNavigation attached property supports key navigation by arrow keys.</li>
<li><a href="qml-keys.html">Keys Element</a> - The Keys attached property provides key handling to Items.</li>
<li><a href="qml-mousearea.html">MouseArea Element</a> - The MouseArea item enables simple mouse handling.</li>
diff --git a/doc/src/declarative/whatsnew.qdoc b/doc/src/declarative/whatsnew.qdoc
index f4359f9..e8c2124 100644
--- a/doc/src/declarative/whatsnew.qdoc
+++ b/doc/src/declarative/whatsnew.qdoc
@@ -41,10 +41,10 @@ PinchArea provides support for the common two finger pinch gesture.
Added the following properties:
\list
-\o lineSpacing
-\o lineCount
-\o maximumLineCount
-\o truncated
+\o \l {Text::}{lineHeight}
+\o \l {Text::}{lineCount}
+\o \l {Text::}{maximumLineCount}
+\o \l {Text::}{truncated}
\endlist
horizontalAlignment now accepts Text.AlignJustify alignment mode.
@@ -53,85 +53,88 @@ horizontalAlignment now accepts Text.AlignJustify alignment mode.
Added the following properties, methods and signal handlers:
\list
-\o canPaste
-\o lineCount
-\o deselect()
-\o moveCursorSelection(int pos, SelectionMode mode) to enable selection by word
-\o onLinkActivated(string link)
+\o \l {TextEdit::}{canPaste}
+\o \l {TextEdit::}{lineCount}
+\o \l {TextEdit::}{deselect()}
+\o \l {TextEdit::}{moveCursorSelection()} to enable selection by word
+\o \l {TextEdit::}{onLinkActivated}
\endlist
\section2 TextInput
Added the following properties and methods:
\list
-\o canPaste
-\o deselect()
-\o moveCursorSelection(int pos, SelectionMode mode) to enable selection by word
+\o \l{TextInput::}{canPaste}
+\o \l{TextInput::}{deselect()}
+\o \l{TextInput::}{moveCursorSelection()} to enable selection by word
\endlist
\section2 Image, BorderImage and AnimatedImage
Added the following properties:
\list
-\o cache
-\o mirror
+\o \l{Image::}{cache}
+\o \l{Image::}{mirror}
\endlist
\section2 Item
Added the following properties:
\list
-\o implicitWidth and implicitHeight
+\o \l{Item::}{implicitWidth} and \l{Item::}{implicitHeight}
\endlist
\section2 Flickable
Added the following methods:
\list
-\o resizeContent(qreal w, qreal h, QPointF center)
-\o returnToBounds()
+\o \l{Flickable::}{resizeContent()}
+\o \l{Flickable::}{returnToBounds()}
\endlist
\section2 ListView and GridView
Added the following methods:
\list
-\o positionViewAtBeginning()
-\o positionViewAtEnd()
+\o \l{ListView::}{positionViewAtBeginning()}
+\o \l{ListView::}{positionViewAtEnd()}
\endlist
-\section2 Flow, Grid, Row
+\section2 Flow, Grid and Row
Added the following properties:
\list
-\o layoutDirection
+\o \l{Flow::}{layoutDirection}
\endlist
\section2 Repeater
Added the following methods and signal handlers:
\list
-\o onItemAdded()
-\o onItemRemoved()
-\o itemAt(int index)
+\o \l{Repeater::}{onItemAdded}
+\o \l{Repeater::}{onItemRemoved}
+\o \l{Repeater::}{itemAt()}
\endlist
\section2 Component
-The createObject() method now accepts a map of initial property values for the created object.
+\list
+\o The \l{Component::}{createObject()} method now accepts a map of initial property values for
+the created object.
+\endlist
\section2 Qt
-Added the following properties and methods:
\list
-\o application.layoutDirection
-\o application.active
+\o Added the \l {QML:Qt::application}{Qt.application} object to hold generic global application
+properties.
\endlist
\section2 Other changes
\list
-\o Functions can be assigned to properties from JavaScript to create property bindings
+\o Functions can be \l{Binding Properties from JavaScript}{assigned to properties from JavaScript}
+to create property bindings.
\endlist
diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc
index f2ca21e..1c5d903 100644
--- a/doc/src/development/qmake-manual.qdoc
+++ b/doc/src/development/qmake-manual.qdoc
@@ -1647,8 +1647,7 @@
\section1 INCLUDEPATH
This variable specifies the #include directories which should be
- searched when compiling the project. Use ';' or a space as the
- directory separator.
+ searched when compiling the project.
For example:
diff --git a/doc/src/snippets/declarative/componentCreation.js b/doc/src/snippets/declarative/componentCreation.js
index cf59777..7364139 100644
--- a/doc/src/snippets/declarative/componentCreation.js
+++ b/doc/src/snippets/declarative/componentCreation.js
@@ -32,13 +32,10 @@ function createSpriteObjects() {
//![finishCreation]
function finishCreation() {
if (component.status == Component.Ready) {
- sprite = component.createObject(appWindow);
+ sprite = component.createObject(appWindow, {"x": 100, "y": 100});
if (sprite == null) {
// Error Handling
- } else {
- sprite.x = 100;
- sprite.y = 100;
- // ...
+ console.log("Error creating object");
}
} else if (component.status == Component.Error) {
// Error Handling
diff --git a/examples/declarative/touchinteraction/pincharea/flickresize.qml b/examples/declarative/touchinteraction/pincharea/flickresize.qml
index a2f81ff..9439ace 100644
--- a/examples/declarative/touchinteraction/pincharea/flickresize.qml
+++ b/examples/declarative/touchinteraction/pincharea/flickresize.qml
@@ -54,14 +54,21 @@ Rectangle {
PinchArea {
width: Math.max(flick.contentWidth, flick.width)
height: Math.max(flick.contentHeight, flick.height)
+
+ property real initialWidth
+ property real initialHeight
+ onPinchStarted: {
+ initialWidth = flick.contentWidth
+ initialHeight = flick.contentHeight
+ }
+
onPinchUpdated: {
// adjust content pos due to drag
flick.contentX += pinch.previousCenter.x - pinch.center.x
flick.contentY += pinch.previousCenter.y - pinch.center.y
// resize content
- var scale = 1.0 + pinch.scale - pinch.previousScale
- flick.resizeContent(flick.contentWidth * scale, flick.contentHeight * scale, pinch.center)
+ flick.resizeContent(initialWidth * pinch.scale, initialHeight * pinch.scale, pinch.center)
}
onPinchFinished: {
diff --git a/mkspecs/common/symbian/symbian-makefile.conf b/mkspecs/common/symbian/symbian-makefile.conf
index cffc859..b248117 100644
--- a/mkspecs/common/symbian/symbian-makefile.conf
+++ b/mkspecs/common/symbian/symbian-makefile.conf
@@ -33,7 +33,7 @@ QMAKE_LINK_OBJECT_SCRIPT = objects
is_using_gnupoc {
DEFINES *= __QT_PRODUCT_INCLUDE_IS_LOWERCASE__
}
-QMAKE_SYMBIAN_INCLUDES = $$[QT_INSTALL_DATA]/mkspecs/common/symbian/symbianincludes.h
+QMAKE_SYMBIAN_INCLUDES = $$IN_PWD/symbianincludes.h
symbian-armcc {
QMAKE_CFLAGS += --preinclude $$QMAKE_SYMBIAN_INCLUDES
QMAKE_CXXFLAGS += --preinclude $$QMAKE_SYMBIAN_INCLUDES
diff --git a/mkspecs/symbian-gcce/qmake.conf b/mkspecs/symbian-gcce/qmake.conf
index 1d1053c..f550751a 100644
--- a/mkspecs/symbian-gcce/qmake.conf
+++ b/mkspecs/symbian-gcce/qmake.conf
@@ -54,7 +54,7 @@ DEFINES += __GCCE__ \
UNICODE
QMAKE_LFLAGS_APP += --entry=_E32Startup -u _E32Startup
-QMAKE_LFLAGS_SHLIB += -shared --default-symver --entry _E32Dll -u _E32Dll
+QMAKE_LFLAGS_SHLIB += -shared --default-symver --entry=_E32Dll -u _E32Dll
QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB
gcceExtraFlags = --include=$${EPOCROOT}epoc32/include/gcce/gcce.h -march=armv5t -mapcs -mthumb-interwork -nostdinc -c -msoft-float -T script
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index 603ffb5..c85533b 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -701,10 +701,10 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t)
if(project->isActiveConfig("shared") && !project->values("DLLDESTDIR").isEmpty()) {
QStringList dlldirs = project->values("DLLDESTDIR");
for (QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir) {
- t << "\n\t" << "-$(COPY_FILE) \"$(DESTDIR_TARGET)\" " << Option::fixPathToTargetOS(*dlldir, false);
+ t << "\t" << "-$(COPY_FILE) \"$(DESTDIR_TARGET)\" " << Option::fixPathToTargetOS(*dlldir, false) << endl;
}
}
- t << endl << endl;
+ t << endl;
writeRcFilePart(t);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp
index b3c229e..d8027ff 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp
@@ -1168,8 +1168,17 @@ DEFINE_STUB_FUNCTION(int, timeout_check)
globalData->exception = createInterruptedExecutionException(globalData);
VM_THROW_EXCEPTION_AT_END();
}
-
- CHECK_FOR_EXCEPTION_AT_END();
+#ifdef QT_BUILD_SCRIPT_LIB
+ else {
+ // It's possible that the call to QtScript's implementation of
+ // TimeoutChecker::didTimeOut() caused an error to be thrown.
+ // In that case, didTimeOut() should still return false, since
+ // we don't want the interrupted-exception to override the
+ // user-thrown error. But we need to check for exception here,
+ // otherwise JSC would continue normal execution.
+ CHECK_FOR_EXCEPTION_AT_END();
+ }
+#endif
return timeoutChecker->ticksUntilNextCheck();
}
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 7a69bca..d5106cc 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1833,32 +1833,32 @@ public:
inline ~QGlobalStatic() { pointer = 0; }
};
-#define Q_GLOBAL_STATIC(TYPE, NAME) \
- static TYPE *NAME() \
- { \
- static TYPE this_##NAME; \
- static QGlobalStatic<TYPE > global_##NAME(&this_##NAME); \
- return global_##NAME.pointer; \
+#define Q_GLOBAL_STATIC(TYPE, NAME) \
+ static TYPE *NAME() \
+ { \
+ static TYPE thisVariable; \
+ static QGlobalStatic<TYPE > thisGlobalStatic(&thisVariable); \
+ return thisGlobalStatic.pointer; \
}
-#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
- static TYPE *NAME() \
- { \
- static TYPE this_##NAME ARGS; \
- static QGlobalStatic<TYPE > global_##NAME(&this_##NAME); \
- return global_##NAME.pointer; \
+#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
+ static TYPE *NAME() \
+ { \
+ static TYPE thisVariable ARGS; \
+ static QGlobalStatic<TYPE > thisGlobalStatic(&thisVariable); \
+ return thisGlobalStatic.pointer; \
}
-#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \
- static TYPE *NAME() \
- { \
- static TYPE this_##NAME; \
- static QGlobalStatic<TYPE > global_##NAME(0); \
- if (!global_##NAME.pointer) { \
- TYPE *x = global_##NAME.pointer = &this_##NAME; \
- INITIALIZER; \
- } \
- return global_##NAME.pointer; \
+#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \
+ static TYPE *NAME() \
+ { \
+ static TYPE thisVariable; \
+ static QGlobalStatic<TYPE > thisGlobalStatic(0); \
+ if (!thisGlobalStatic.pointer) { \
+ TYPE *x = thisGlobalStatic.pointer = &thisVariable; \
+ INITIALIZER; \
+ } \
+ return thisGlobalStatic.pointer; \
}
#else
@@ -1893,50 +1893,50 @@ public:
}
};
-#define Q_GLOBAL_STATIC_INIT(TYPE, NAME) \
- static QGlobalStatic<TYPE > this_##NAME = { Q_BASIC_ATOMIC_INITIALIZER(0), false }
-
-#define Q_GLOBAL_STATIC(TYPE, NAME) \
- Q_GLOBAL_STATIC_INIT(TYPE, NAME); \
- static TYPE *NAME() \
- { \
- if (!this_##NAME.pointer && !this_##NAME.destroyed) { \
- TYPE *x = new TYPE; \
- if (!this_##NAME.pointer.testAndSetOrdered(0, x)) \
- delete x; \
- else \
- static QGlobalStaticDeleter<TYPE > cleanup(this_##NAME); \
- } \
- return this_##NAME.pointer; \
+#define Q_GLOBAL_STATIC(TYPE, NAME) \
+ static TYPE *NAME() \
+ { \
+ static QGlobalStatic<TYPE > thisGlobalStatic \
+ = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \
+ if (!thisGlobalStatic.pointer && !thisGlobalStatic.destroyed) { \
+ TYPE *x = new TYPE; \
+ if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) \
+ delete x; \
+ else \
+ static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \
+ } \
+ return thisGlobalStatic.pointer; \
}
-#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
- Q_GLOBAL_STATIC_INIT(TYPE, NAME); \
- static TYPE *NAME() \
- { \
- if (!this_##NAME.pointer && !this_##NAME.destroyed) { \
- TYPE *x = new TYPE ARGS; \
- if (!this_##NAME.pointer.testAndSetOrdered(0, x)) \
- delete x; \
- else \
- static QGlobalStaticDeleter<TYPE > cleanup(this_##NAME); \
- } \
- return this_##NAME.pointer; \
+#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
+ static TYPE *NAME() \
+ { \
+ static QGlobalStatic<TYPE > thisGlobalStatic \
+ = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \
+ if (!thisGlobalStatic.pointer && !thisGlobalStatic.destroyed) { \
+ TYPE *x = new TYPE ARGS; \
+ if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) \
+ delete x; \
+ else \
+ static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \
+ } \
+ return thisGlobalStatic.pointer; \
}
-#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \
- Q_GLOBAL_STATIC_INIT(TYPE, NAME); \
- static TYPE *NAME() \
- { \
- if (!this_##NAME.pointer && !this_##NAME.destroyed) { \
- QScopedPointer<TYPE > x(new TYPE); \
- INITIALIZER; \
- if (this_##NAME.pointer.testAndSetOrdered(0, x.data())) { \
- static QGlobalStaticDeleter<TYPE > cleanup(this_##NAME); \
- x.take(); \
- } \
- } \
- return this_##NAME.pointer; \
+#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \
+ static TYPE *NAME() \
+ { \
+ static QGlobalStatic<TYPE > thisGlobalStatic \
+ = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \
+ if (!thisGlobalStatic.pointer && !thisGlobalStatic.destroyed) { \
+ QScopedPointer<TYPE > x(new TYPE); \
+ INITIALIZER; \
+ if (thisGlobalStatic.pointer.testAndSetOrdered(0, x.data())) { \
+ static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \
+ x.take(); \
+ } \
+ } \
+ return thisGlobalStatic.pointer; \
}
#endif
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index d84da0d..afbaa27 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -578,7 +578,8 @@ public:
PreferDither = 0x00000040,
AvoidDither = 0x00000080,
- NoOpaqueDetection = 0x00000100
+ NoOpaqueDetection = 0x00000100,
+ NoFormatConversion = 0x00000200
};
Q_DECLARE_FLAGS(ImageConversionFlags, ImageConversionFlag)
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index cbdf9d1..f98ea4a 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -743,6 +743,10 @@
until a non-opaque pixel is found, or if you want the pixmap to
retain an alpha channel for some other reason. If the image has no
alpha channel this flag has no effect.
+
+ \omitvalue NoFormatConversion Don't do any format conversions on the image.
+ Can be useful when converting a QImage to a QPixmap for a one-time
+ rendering operation for example.
*/
/*! \enum Qt::GUIStyle
diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp
index 235f671..71cf92d 100644
--- a/src/corelib/io/qnoncontiguousbytedevice.cpp
+++ b/src/corelib/io/qnoncontiguousbytedevice.cpp
@@ -153,6 +153,7 @@ void QNonContiguousByteDevice::disableReset()
resetDisabled = true;
}
+// FIXME we should scrap this whole implementation and instead change the ByteArrayImpl to be able to cope with sub-arrays?
QNonContiguousByteDeviceBufferImpl::QNonContiguousByteDeviceBufferImpl(QBuffer *b) : QNonContiguousByteDevice()
{
buffer = b;
@@ -244,7 +245,7 @@ qint64 QNonContiguousByteDeviceByteArrayImpl::size()
return byteArray->size();
}
-QNonContiguousByteDeviceRingBufferImpl::QNonContiguousByteDeviceRingBufferImpl(QRingBuffer *rb)
+QNonContiguousByteDeviceRingBufferImpl::QNonContiguousByteDeviceRingBufferImpl(QSharedPointer<QRingBuffer> rb)
: QNonContiguousByteDevice(), currentPosition(0)
{
ringBuffer = rb;
@@ -355,6 +356,11 @@ bool QNonContiguousByteDeviceIoDeviceImpl::advanceReadPointer(qint64 amount)
// normal advancement
currentReadBufferPosition += amount;
+ if (size() == -1)
+ emit readProgress(totalAdvancements, totalAdvancements);
+ else
+ emit readProgress(totalAdvancements, size());
+
// advancing over that what has actually been read before
if (currentReadBufferPosition > currentReadBufferAmount) {
qint64 i = currentReadBufferPosition - currentReadBufferAmount;
@@ -370,10 +376,6 @@ bool QNonContiguousByteDeviceIoDeviceImpl::advanceReadPointer(qint64 amount)
currentReadBufferAmount = 0;
}
- if (size() == -1)
- emit readProgress(totalAdvancements, totalAdvancements);
- else
- emit readProgress(totalAdvancements, size());
return true;
}
@@ -505,7 +507,7 @@ QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QIODevice *dev
\internal
*/
-QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QRingBuffer *ringBuffer)
+QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QSharedPointer<QRingBuffer> ringBuffer)
{
return new QNonContiguousByteDeviceRingBufferImpl(ringBuffer);
}
diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h
index ff946ed..5e0b1bb 100644
--- a/src/corelib/io/qnoncontiguousbytedevice_p.h
+++ b/src/corelib/io/qnoncontiguousbytedevice_p.h
@@ -57,6 +57,7 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qbuffer.h>
#include <QtCore/qiodevice.h>
+#include <QtCore/QSharedPointer>
#include "private/qringbuffer_p.h"
QT_BEGIN_NAMESPACE
@@ -70,6 +71,7 @@ public:
virtual bool atEnd() = 0;
virtual bool reset() = 0;
void disableReset();
+ bool isResetDisabled() { return resetDisabled; }
virtual qint64 size() = 0;
virtual ~QNonContiguousByteDevice();
@@ -89,7 +91,7 @@ class Q_CORE_EXPORT QNonContiguousByteDeviceFactory
public:
static QNonContiguousByteDevice* create(QIODevice *device);
static QNonContiguousByteDevice* create(QByteArray *byteArray);
- static QNonContiguousByteDevice* create(QRingBuffer *ringBuffer);
+ static QNonContiguousByteDevice* create(QSharedPointer<QRingBuffer> ringBuffer);
static QIODevice* wrap(QNonContiguousByteDevice* byteDevice);
};
@@ -114,7 +116,7 @@ protected:
class QNonContiguousByteDeviceRingBufferImpl : public QNonContiguousByteDevice
{
public:
- QNonContiguousByteDeviceRingBufferImpl(QRingBuffer *rb);
+ QNonContiguousByteDeviceRingBufferImpl(QSharedPointer<QRingBuffer> rb);
~QNonContiguousByteDeviceRingBufferImpl();
const char* readPointer(qint64 maximumLength, qint64 &len);
bool advanceReadPointer(qint64 amount);
@@ -122,13 +124,14 @@ public:
bool reset();
qint64 size();
protected:
- QRingBuffer* ringBuffer;
+ QSharedPointer<QRingBuffer> ringBuffer;
qint64 currentPosition;
};
class QNonContiguousByteDeviceIoDeviceImpl : public QNonContiguousByteDevice
{
+ Q_OBJECT
public:
QNonContiguousByteDeviceIoDeviceImpl(QIODevice *d);
~QNonContiguousByteDeviceIoDeviceImpl();
@@ -150,6 +153,7 @@ protected:
class QNonContiguousByteDeviceBufferImpl : public QNonContiguousByteDevice
{
+ Q_OBJECT
public:
QNonContiguousByteDeviceBufferImpl(QBuffer *b);
~QNonContiguousByteDeviceBufferImpl();
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index c003214..a903007 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -677,7 +677,7 @@ bool QChar::isSymbol() const
\since 4.7
Returns true if the UCS-4-encoded character specified by \a ucs4
- is the high part of a utf16 surrogate
+ is the low part of a utf16 surrogate
(ie. if its code point is between 0xdc00 and 0xdfff, inclusive).
*/
@@ -686,7 +686,7 @@ bool QChar::isSymbol() const
\since 4.7
Returns true if the UCS-4-encoded character specified by \a ucs4
- can be splited to the high and low parts of a utf16 surrogate
+ can be split into the high and low parts of a utf16 surrogate
(ie. if its code point is greater than or equals to 0x10000).
*/
diff --git a/src/declarative/debugger/qdeclarativedebugservice_p.h b/src/declarative/debugger/qdeclarativedebugservice_p.h
index 1730d11..5e30350 100644
--- a/src/declarative/debugger/qdeclarativedebugservice_p.h
+++ b/src/declarative/debugger/qdeclarativedebugservice_p.h
@@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QDeclarativeDebugServicePrivate;
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDebugService : public QObject
+class Q_DECLARATIVE_EXPORT QDeclarativeDebugService : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QDeclarativeDebugService)
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
index c03c624..8f37e90 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
@@ -149,6 +149,20 @@ QT_BEGIN_NAMESPACE
\sa Image, AnimatedImage
*/
+/*!
+ \qmlproperty bool BorderImage::asynchronous
+
+ Specifies that images on the local filesystem should be loaded
+ asynchronously in a separate thread. The default value is
+ false, causing the user interface thread to block while the
+ image is loaded. Setting \a asynchronous to true is useful where
+ maintaining a responsive user interface is more desirable
+ than having images immediately visible.
+
+ Note that this property is only valid for images read from the
+ local filesystem. Images loaded via a network resource (e.g. HTTP)
+ are always loaded asynchonously.
+*/
QDeclarativeBorderImage::QDeclarativeBorderImage(QDeclarativeItem *parent)
: QDeclarativeImageBase(*(new QDeclarativeBorderImagePrivate), parent)
{
@@ -200,6 +214,15 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage()
*/
/*!
+ \qmlproperty bool BorderImage::cache
+ \since Quick 1.1
+
+ Specifies whether the image should be cached. The default value is
+ true. Setting \a cache to false is useful when dealing with large images,
+ to make sure that they aren't cached at the expense of small 'ui element' images.
+*/
+
+/*!
\qmlproperty bool BorderImage::mirror
\since Quick 1.1
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index 1f1b39a..1e2b70c 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -143,7 +143,7 @@ QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate()
, stealMouse(false), pressed(false), interactive(true), calcVelocity(false)
, deceleration(500), maxVelocity(2000), reportedVelocitySmoothing(100)
, delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(600)
- , vTime(0), visibleArea(0)
+ , fixupMode(Normal), vTime(0), visibleArea(0)
, flickableDirection(QDeclarativeFlickable::AutoFlickDirection)
, boundsBehavior(QDeclarativeFlickable::DragAndOvershootBounds)
{
@@ -219,6 +219,7 @@ void QDeclarativeFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal
{
Q_Q(QDeclarativeFlickable);
qreal maxDistance = -1;
+ data.fixingUp = false;
bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds;
// -ve velocity means list is moving up
if (velocity > 0) {
@@ -288,24 +289,45 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal
if (data.move.value() > minExtent || maxExtent > minExtent) {
timeline.reset(data.move);
if (data.move.value() != minExtent) {
- if (fixupDuration) {
- qreal dist = minExtent - data.move;
- timeline.move(data.move, minExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
- timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
- } else {
+ switch (fixupMode) {
+ case Immediate:
timeline.set(data.move, minExtent);
+ break;
+ case ExtentChanged:
+ // The target has changed. Don't start from the beginning; just complete the
+ // second half of the animation using the new extent.
+ timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
+ data.fixingUp = true;
+ break;
+ default: {
+ qreal dist = minExtent - data.move;
+ timeline.move(data.move, minExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
+ timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
+ data.fixingUp = true;
+ }
}
}
} else if (data.move.value() < maxExtent) {
timeline.reset(data.move);
- if (fixupDuration) {
- qreal dist = maxExtent - data.move;
- timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
- timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
- } else {
+ switch (fixupMode) {
+ case Immediate:
timeline.set(data.move, maxExtent);
+ break;
+ case ExtentChanged:
+ // The target has changed. Don't start from the beginning; just complete the
+ // second half of the animation using the new extent.
+ timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
+ data.fixingUp = true;
+ break;
+ default: {
+ qreal dist = maxExtent - data.move;
+ timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
+ timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
+ data.fixingUp = true;
+ }
}
}
+ fixupMode = Normal;
vTime = timeline.time();
}
@@ -688,6 +710,12 @@ void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEven
vData.velocity = 0;
hData.dragStartOffset = 0;
vData.dragStartOffset = 0;
+ hData.dragMinBound = q->minXExtent();
+ vData.dragMinBound = q->minYExtent();
+ hData.dragMaxBound = q->maxXExtent();
+ vData.dragMaxBound = q->maxYExtent();
+ hData.fixingUp = false;
+ vData.fixingUp = false;
lastPos = QPoint();
QDeclarativeItemPrivate::start(lastPosTime);
pressPos = event->pos();
@@ -716,8 +744,8 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
if (!vMoved)
vData.dragStartOffset = dy;
qreal newY = dy + vData.pressPos - vData.dragStartOffset;
- const qreal minY = q->minYExtent();
- const qreal maxY = q->maxYExtent();
+ const qreal minY = vData.dragMinBound;
+ const qreal maxY = vData.dragMaxBound;
if (newY > minY)
newY = minY + (newY - minY) / 2;
if (newY < maxY && maxY - minY <= 0)
@@ -748,8 +776,8 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
if (!hMoved)
hData.dragStartOffset = dx;
qreal newX = dx + hData.pressPos - hData.dragStartOffset;
- const qreal minX = q->minXExtent();
- const qreal maxX = q->maxXExtent();
+ const qreal minX = hData.dragMinBound;
+ const qreal maxX = hData.dragMaxBound;
if (newX > minX)
newX = minX + (newX - minX) / 2;
if (newX < maxX && maxX - minX <= 0)
@@ -1065,10 +1093,8 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry,
}
// Make sure that we're entirely in view.
if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
- int oldDuration = d->fixupDuration;
- d->fixupDuration = 0;
+ d->fixupMode = QDeclarativeFlickablePrivate::Immediate;
d->fixupX();
- d->fixupDuration = oldDuration;
}
}
if (newGeometry.height() != oldGeometry.height()) {
@@ -1080,10 +1106,8 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry,
}
// Make sure that we're entirely in view.
if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
- int oldDuration = d->fixupDuration;
- d->fixupDuration = 0;
+ d->fixupMode = QDeclarativeFlickablePrivate::Immediate;
d->fixupY();
- d->fixupDuration = oldDuration;
}
}
@@ -1237,10 +1261,11 @@ void QDeclarativeFlickable::setContentWidth(qreal w)
d->contentItem->setWidth(w);
// Make sure that we're entirely in view.
if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
- int oldDuration = d->fixupDuration;
- d->fixupDuration = 0;
+ d->fixupMode = QDeclarativeFlickablePrivate::Immediate;
+ d->fixupX();
+ } else if (!d->pressed && d->hData.fixingUp) {
+ d->fixupMode = QDeclarativeFlickablePrivate::ExtentChanged;
d->fixupX();
- d->fixupDuration = oldDuration;
}
emit contentWidthChanged();
d->updateBeginningEnd();
@@ -1264,10 +1289,11 @@ void QDeclarativeFlickable::setContentHeight(qreal h)
d->contentItem->setHeight(h);
// Make sure that we're entirely in view.
if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
- int oldDuration = d->fixupDuration;
- d->fixupDuration = 0;
+ d->fixupMode = QDeclarativeFlickablePrivate::Immediate;
+ d->fixupY();
+ } else if (!d->pressed && d->vData.fixingUp) {
+ d->fixupMode = QDeclarativeFlickablePrivate::ExtentChanged;
d->fixupY();
- d->fixupDuration = oldDuration;
}
emit contentHeightChanged();
d->updateBeginningEnd();
@@ -1276,11 +1302,10 @@ void QDeclarativeFlickable::setContentHeight(qreal h)
/*!
\qmlmethod Flickable::resizeContent(real width, real height, QPointF center)
\preliminary
+ \since Quick 1.1
Resizes the content to \a width x \a height about \a center.
- \bold {This method was added in QtQuick 1.1.}
-
This does not scale the contents of the Flickable - it only resizes the \l contentWidth
and \l contentHeight.
@@ -1312,11 +1337,10 @@ void QDeclarativeFlickable::resizeContent(qreal w, qreal h, QPointF center)
/*!
\qmlmethod Flickable::returnToBounds()
\preliminary
+ \since Quick 1.1
Ensures the content is within legal bounds.
- \bold {This method was added in QtQuick 1.1.}
-
This may be called to ensure that the content is within legal bounds
after manually positioning the content.
*/
@@ -1641,6 +1665,7 @@ void QDeclarativeFlickable::movementXEnding()
emit movementEnded();
}
}
+ d->hData.fixingUp = false;
}
void QDeclarativeFlickable::movementYEnding()
@@ -1663,6 +1688,7 @@ void QDeclarativeFlickable::movementYEnding()
emit movementEnded();
}
}
+ d->vData.fixingUp = false;
}
void QDeclarativeFlickablePrivate::updateVelocity()
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
index 1b6081c..38a5eb3 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
@@ -94,17 +94,21 @@ public:
struct AxisData {
AxisData(QDeclarativeFlickablePrivate *fp, void (QDeclarativeFlickablePrivate::*func)(qreal))
: move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true)
+ , fixingUp(false)
{}
QDeclarativeTimeLineValueProxy<QDeclarativeFlickablePrivate> move;
qreal viewSize;
qreal pressPos;
qreal dragStartOffset;
+ qreal dragMinBound;
+ qreal dragMaxBound;
qreal velocity;
qreal flickTarget;
QDeclarativeFlickablePrivate::Velocity smoothVelocity;
bool atEnd : 1;
bool atBeginning : 1;
+ bool fixingUp : 1;
};
void flickX(qreal velocity);
@@ -161,6 +165,9 @@ public:
int pressDelay;
int fixupDuration;
+ enum FixupMode { Normal, Immediate, ExtentChanged };
+ FixupMode fixupMode;
+
static void fixupY_callback(void *);
static void fixupX_callback(void *);
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index 6d2285d..1d2ad1c 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -912,8 +912,7 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
|| (flow == QDeclarativeGridView::LeftToRight && &data == &hData))
return;
- int oldDuration = fixupDuration;
- fixupDuration = moveReason == Mouse ? fixupDuration : 0;
+ fixupMode = moveReason == Mouse ? fixupMode : Immediate;
if (snapMode != QDeclarativeGridView::NoSnap) {
FxGridItem *topItem = snapItemAt(position()+highlightRangeStart);
@@ -932,7 +931,6 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
pos = qMax(qMin(bottomItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent);
} else {
QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent);
- fixupDuration = oldDuration;
return;
}
if (currentItem && haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) {
@@ -947,10 +945,12 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
qreal dist = qAbs(data.move + pos);
if (dist > 0) {
timeline.reset(data.move);
- if (fixupDuration)
+ if (fixupMode != Immediate) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ data.fixingUp = true;
+ } else {
timeline.set(data.move, -pos);
+ }
vTime = timeline.time();
}
} else if (haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) {
@@ -965,23 +965,26 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
timeline.reset(data.move);
if (viewPos != position()) {
- if (fixupDuration)
+ if (fixupMode != Immediate) {
timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ data.fixingUp = true;
+ } else {
timeline.set(data.move, -viewPos);
+ }
}
vTime = timeline.time();
}
} else {
QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent);
}
- fixupDuration = oldDuration;
+ fixupMode = Normal;
}
void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
{
Q_Q(QDeclarativeGridView);
+ data.fixingUp = false;
moveReason = Mouse;
if ((!haveHighlightRange || highlightRange != QDeclarativeGridView::StrictlyEnforceRange)
&& snapMode == QDeclarativeGridView::NoSnap) {
@@ -2250,6 +2253,7 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode)
/*!
\qmlmethod GridView::positionViewAtBeginning()
\qmlmethod GridView::positionViewAtEnd()
+ \since Quick 1.1
Positions the view at the beginning or end, taking into account any header or footer.
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index 338cb58..e369ba6 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -942,7 +942,7 @@ void QDeclarativeListViewPrivate::createSection(FxListItem *listItem)
} else {
QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q));
context->setContextProperty(QLatin1String("section"), listItem->attached->m_section);
- QObject *nobj = sectionCriteria->delegate()->create(context);
+ QObject *nobj = sectionCriteria->delegate()->beginCreate(context);
if (nobj) {
QDeclarative_setParent_noEvent(context, nobj);
listItem->section = qobject_cast<QDeclarativeItem *>(nobj);
@@ -956,6 +956,7 @@ void QDeclarativeListViewPrivate::createSection(FxListItem *listItem)
} else {
delete context;
}
+ sectionCriteria->delegate()->completeCreate();
}
listItem->setPosition(pos);
} else {
@@ -1197,8 +1198,7 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
return;
correctFlick = false;
- int oldDuration = fixupDuration;
- fixupDuration = moveReason == Mouse ? fixupDuration : 0;
+ fixupMode = moveReason == Mouse ? fixupMode : Immediate;
if (currentItem && haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) {
updateHighlight();
@@ -1211,10 +1211,12 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
timeline.reset(data.move);
if (viewPos != position()) {
- if (fixupDuration)
+ if (fixupMode != Immediate) {
timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ data.fixingUp = true;
+ } else {
timeline.set(data.move, -viewPos);
+ }
}
vTime = timeline.time();
} else if (snapMode != QDeclarativeListView::NoSnap) {
@@ -1230,23 +1232,24 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
pos = qMax(qMin(bottomItem->position() - highlightRangeStart, -maxExtent), -minExtent);
} else {
QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent);
- fixupDuration = oldDuration;
return;
}
qreal dist = qAbs(data.move + pos);
if (dist > 0) {
timeline.reset(data.move);
- if (fixupDuration)
+ if (fixupMode != Immediate) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ data.fixingUp = true;
+ } else {
timeline.set(data.move, -pos);
+ }
vTime = timeline.time();
}
} else {
QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent);
}
- fixupDuration = oldDuration;
+ fixupMode = Normal;
}
void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
@@ -1254,6 +1257,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
{
Q_Q(QDeclarativeListView);
+ data.fixingUp = false;
moveReason = Mouse;
if ((!haveHighlightRange || highlightRange != QDeclarativeListView::StrictlyEnforceRange) && snapMode == QDeclarativeListView::NoSnap) {
correctFlick = true;
@@ -2708,6 +2712,7 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode)
/*!
\qmlmethod ListView::positionViewAtBeginning()
\qmlmethod ListView::positionViewAtEnd()
+ \since Quick 1.1
Positions the view at the beginning or end, taking into account any header or footer.
@@ -2797,6 +2802,8 @@ void QDeclarativeListView::updateSections()
roles << d->sectionCriteria->property().toUtf8();
d->model->setWatchedRoles(roles);
d->updateSections();
+ if (d->itemCount)
+ d->layout();
}
}
diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
index 27a1301..c0be2a2 100644
--- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
@@ -584,6 +584,8 @@ QDeclarativeRow::QDeclarativeRow(QDeclarativeItem *parent)
/*!
\qmlproperty enumeration Row::layoutDirection
+ \since Quick 1.1
+
This property holds the layoutDirection of the row.
Possible values:
@@ -859,6 +861,8 @@ void QDeclarativeGrid::setFlow(Flow flow)
/*!
\qmlproperty enumeration Grid::layoutDirection
+ \since Quick 1.1
+
This property holds the layout direction of the layout.
Possible values are:
@@ -1201,6 +1205,8 @@ void QDeclarativeFlow::setFlow(Flow flow)
/*!
\qmlproperty enumeration Flow::layoutDirection
+ \since Quick 1.1
+
This property holds the layout direction of the layout.
Possible values are:
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index 559d061..12e1c0f 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -1145,6 +1145,7 @@ void QDeclarativeText::setWrapMode(WrapMode mode)
/*!
\qmlproperty int Text::lineCount
+ \since Quick 1.1
Returns the number of lines visible in the text item.
@@ -1160,6 +1161,7 @@ int QDeclarativeText::lineCount() const
/*!
\qmlproperty bool Text::truncated
+ \since Quick 1.1
Returns true if the text has been truncated due to \l maximumLineCount
or \l elide.
@@ -1176,6 +1178,7 @@ bool QDeclarativeText::truncated() const
/*!
\qmlproperty int Text::maximumLineCount
+ \since Quick 1.1
Set this property to limit the number of lines that the text item will show.
If elide is set to Text.ElideRight, the text will be elided appropriately.
@@ -1428,6 +1431,7 @@ qreal QDeclarativeText::paintedHeight() const
/*!
\qmlproperty real Text::lineHeight
+ \since Quick 1.1
Sets the line height for the text.
The value can be in pixels or a multiplier depending on lineHeightMode.
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index 7f383a6..d3c5b82 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -544,6 +544,7 @@ void QDeclarativeTextEdit::setWrapMode(WrapMode mode)
/*!
\qmlproperty int TextEdit::lineCount
+ \since Quick 1.1
Returns the total number of lines in the textEdit item.
*/
@@ -605,6 +606,22 @@ int QDeclarativeTextEdit::positionAt(int x, int y) const
{
Q_D(const QDeclarativeTextEdit);
int r = d->document->documentLayout()->hitTest(QPoint(x,y-d->yoff), Qt::FuzzyHit);
+ QTextCursor cursor = d->control->textCursor();
+ if (r > cursor.position()) {
+ // The cursor position includes positions within the preedit text, but only positions in the
+ // same text block are offset so it is possible to get a position that is either part of the
+ // preedit or the next text block.
+ QTextLayout *layout = cursor.block().layout();
+ const int preeditLength = layout
+ ? layout->preeditAreaText().length()
+ : 0;
+ if (preeditLength > 0
+ && d->document->documentLayout()->blockBoundingRect(cursor.block()).contains(x,y-d->yoff)) {
+ r = r > cursor.position() + preeditLength
+ ? r - preeditLength
+ : cursor.position();
+ }
+ }
return r;
}
@@ -1134,6 +1151,7 @@ void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus)
/*!
\qmlmethod void TextEdit::deselect()
+ \since Quick 1.1
Removes active text selection.
*/
@@ -1316,7 +1334,10 @@ Handles the given input method \a event.
void QDeclarativeTextEdit::inputMethodEvent(QInputMethodEvent *event)
{
Q_D(QDeclarativeTextEdit);
+ const bool wasComposing = isInputMethodComposing();
d->control->processEvent(event, QPointF(0, -d->yoff));
+ if (wasComposing != isInputMethodComposing())
+ emit inputMethodComposingChanged();
}
/*!
@@ -1381,19 +1402,38 @@ void QDeclarativeTextEdit::updateImgCache(const QRectF &rf)
/*!
\qmlproperty bool TextEdit::canPaste
+ \since QtQuick 1.1
Returns true if the TextEdit is writable and the content of the clipboard is
suitable for pasting into the TextEdit.
-
- \since QtQuick 1.1
*/
-
bool QDeclarativeTextEdit::canPaste() const
{
Q_D(const QDeclarativeTextEdit);
return d->canPaste;
}
+/*!
+ \qmlproperty bool TextEdit::isInputMethodComposing()
+
+ \since QtQuick 1.1
+
+ This property holds whether the TextEdit has partial text input from an
+ input method.
+
+ While it is composing an input method may rely on mouse or key events from
+ the TextEdit to edit or commit the partial text. This property can be used
+ to determine when to disable events handlers that may interfere with the
+ correct operation of an input method.
+*/
+bool QDeclarativeTextEdit::isInputMethodComposing() const
+{
+ Q_D(const QDeclarativeTextEdit);
+ if (QTextLayout *layout = d->control->textCursor().block().layout())
+ return layout->preeditAreaText().length() > 0;
+ return false;
+}
+
void QDeclarativeTextEditPrivate::init()
{
Q_Q(QDeclarativeTextEdit);
@@ -1429,6 +1469,7 @@ void QDeclarativeTextEditPrivate::init()
#ifndef QT_NO_CLIPBOARD
QObject::connect(q, SIGNAL(readOnlyChanged(bool)), q, SLOT(q_canPasteChanged()));
QObject::connect(QApplication::clipboard(), SIGNAL(dataChanged()), q, SLOT(q_canPasteChanged()));
+ canPaste = control->canPaste();
#endif
document = control->document();
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
index 7785a7a..612f9a9 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
@@ -94,6 +94,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextEdit : public QDeclarativeImplicitSizePa
Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged REVISION 1)
Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged REVISION 1)
+ Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged REVISION 1)
public:
QDeclarativeTextEdit(QDeclarativeItem *parent=0);
@@ -215,6 +216,8 @@ public:
QRectF boundingRect() const;
+ bool isInputMethodComposing() const;
+
Q_SIGNALS:
void textChanged(const QString &);
void paintedSizeChanged();
@@ -242,6 +245,7 @@ Q_SIGNALS:
Q_REVISION(1) void mouseSelectionModeChanged(SelectionMode mode);
Q_REVISION(1) void linkActivated(const QString &link);
Q_REVISION(1) void canPasteChanged();
+ Q_REVISION(1) void inputMethodComposingChanged();
public Q_SLOTS:
void selectAll();
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index 78f34db..29b1f6b 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -482,6 +482,7 @@ QRect QDeclarativeTextInput::cursorRectangle() const
Q_D(const QDeclarativeTextInput);
QRect r = d->control->cursorRect();
r.setHeight(r.height()-1); // Make consistent with TextEdit (QLineControl inexplicably adds 1)
+ r.moveLeft(r.x() - d->hscroll);
return r;
}
@@ -921,14 +922,22 @@ void QDeclarativeTextInput::moveCursor()
QRectF QDeclarativeTextInput::positionToRectangle(int pos) const
{
Q_D(const QDeclarativeTextInput);
+ if (pos > d->control->cursorPosition())
+ pos += d->control->preeditAreaText().length();
return QRectF(d->control->cursorToX(pos)-d->hscroll,
0.0,
d->control->cursorWidth(),
cursorRectangle().height());
}
+int QDeclarativeTextInput::positionAt(int x) const
+{
+ return positionAt(x, CursorBetweenCharacters);
+}
+
/*!
- \qmlmethod int TextInput::positionAt(int x)
+ \qmlmethod int TextInput::positionAt(int x, CursorPosition position = CursorBetweenCharacters)
+ \since Quick 1.1
This function returns the character position at
x pixels from the left of the textInput. Position 0 is before the
@@ -937,11 +946,26 @@ QRectF QDeclarativeTextInput::positionToRectangle(int pos) const
This means that for all x values before the first character this function returns 0,
and for all x values after the last character this function returns text.length.
+
+ The cursor position type specifies how the cursor position should be resolved.
+
+ \list
+ \o TextInput.CursorBetweenCharacters - Returns the position between characters that is nearest x.
+ \o TextInput.CursorOnCharacter - Returns the position before the character that is nearest x.
+ \endlist
*/
-int QDeclarativeTextInput::positionAt(int x) const
+int QDeclarativeTextInput::positionAt(int x, CursorPosition position) const
{
Q_D(const QDeclarativeTextInput);
- return d->control->xToPos(x + d->hscroll);
+ int pos = d->control->xToPos(x + d->hscroll, QTextLine::CursorPosition(position));
+ const int cursor = d->control->cursor();
+ if (pos > cursor) {
+ const int preeditLength = d->control->preeditAreaText().length();
+ pos = pos > cursor + preeditLength
+ ? pos - preeditLength
+ : cursor;
+ }
+ return pos;
}
void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus)
@@ -982,18 +1006,22 @@ void QDeclarativeTextInput::inputMethodEvent(QInputMethodEvent *ev)
{
Q_D(QDeclarativeTextInput);
ev->ignore();
+ const bool wasComposing = d->control->preeditAreaText().length() > 0;
inputMethodPreHandler(ev);
- if (ev->isAccepted())
- return;
- if (d->control->isReadOnly()) {
- ev->ignore();
- } else {
- d->control->processInputMethodEvent(ev);
- updateSize();
- d->updateHorizontalScroll();
+ if (!ev->isAccepted()) {
+ if (d->control->isReadOnly()) {
+ ev->ignore();
+ } else {
+ d->control->processInputMethodEvent(ev);
+ updateSize();
+ d->updateHorizontalScroll();
+ }
}
if (!ev->isAccepted())
QDeclarativePaintedItem::inputMethodEvent(ev);
+
+ if (wasComposing != (d->control->preeditAreaText().length() > 0))
+ emit inputMethodComposingChanged();
}
/*!
@@ -1047,7 +1075,7 @@ void QDeclarativeTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QDeclarativeTextInput);
if (d->sendMouseEventToInputContext(event, QEvent::MouseMove))
- event->setAccepted(true);
+ return;
if (d->selectByMouse) {
if (qAbs(int(event->pos().x() - d->pressPos.x())) > QApplication::startDragDistance())
setKeepMouseGrab(true);
@@ -1260,7 +1288,7 @@ QVariant QDeclarativeTextInput::inputMethodQuery(Qt::InputMethodQuery property)
Q_D(const QDeclarativeTextInput);
switch(property) {
case Qt::ImMicroFocus:
- return d->control->cursorRect();
+ return cursorRectangle();
case Qt::ImFont:
return font();
case Qt::ImCursorPosition:
@@ -1285,6 +1313,7 @@ QVariant QDeclarativeTextInput::inputMethodQuery(Qt::InputMethodQuery property)
/*!
\qmlmethod void TextInput::deselect()
+ \since Quick 1.1
Removes active text selection.
*/
@@ -1466,6 +1495,13 @@ void QDeclarativeTextInput::setMouseSelectionMode(SelectionMode mode)
}
}
+/*!
+ \qmlproperty bool TextInput::canPaste
+ \since QtQuick 1.1
+
+ Returns true if the TextInput is writable and the content of the clipboard is
+ suitable for pasting into the TextEdit.
+*/
bool QDeclarativeTextInput::canPaste() const
{
Q_D(const QDeclarativeTextInput);
@@ -1534,38 +1570,41 @@ void QDeclarativeTextInput::moveCursorSelection(int pos, SelectionMode mode)
anchor = d->control->selectionStart();
if (anchor < pos || (anchor == pos && cursor < pos)) {
- QTextBoundaryFinder finder(QTextBoundaryFinder::Word, d->control->text());
+ const QString text = d->control->text();
+ QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text);
finder.setPosition(anchor);
const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons();
- if (!(reasons & QTextBoundaryFinder::StartWord)
+ if (anchor < text.length() && !(reasons & QTextBoundaryFinder::StartWord)
|| ((reasons & QTextBoundaryFinder::EndWord) && anchor > cursor)) {
finder.toPreviousBoundary();
}
- anchor = finder.position();
+ anchor = finder.position() != -1 ? finder.position() : 0;
finder.setPosition(pos);
- if (!finder.isAtBoundary())
+ if (pos > 0 && !finder.boundaryReasons())
finder.toNextBoundary();
+ const int cursor = finder.position() != -1 ? finder.position() : text.length();
- d->control->setSelection(anchor, finder.position() - anchor);
+ d->control->setSelection(anchor, cursor - anchor);
} else if (anchor > pos || (anchor == pos && cursor > pos)) {
- QTextBoundaryFinder finder(QTextBoundaryFinder::Word, d->control->text());
+ const QString text = d->control->text();
+ QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text);
finder.setPosition(anchor);
const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons();
- if (!(reasons & QTextBoundaryFinder::EndWord)
+ if (anchor > 0 && !(reasons & QTextBoundaryFinder::EndWord)
|| ((reasons & QTextBoundaryFinder::StartWord) && anchor < cursor)) {
finder.toNextBoundary();
}
-
- anchor = finder.position();
+ anchor = finder.position() != -1 ? finder.position() : text.length();
finder.setPosition(pos);
- if (!finder.isAtBoundary())
+ if (pos < text.length() && !finder.boundaryReasons())
finder.toPreviousBoundary();
+ const int cursor = finder.position() != -1 ? finder.position() : 0;
- d->control->setSelection(anchor, finder.position() - anchor);
+ d->control->setSelection(anchor, cursor - anchor);
}
}
}
@@ -1684,6 +1723,25 @@ void QDeclarativeTextInput::focusInEvent(QFocusEvent *event)
QDeclarativePaintedItem::focusInEvent(event);
}
+/*!
+ \qmlproperty bool TextInput::isInputMethodComposing()
+
+ \since QtQuick 1.1
+
+ This property holds whether the TextInput has partial text input from an
+ input method.
+
+ While it is composing an input method may rely on mouse or key events from
+ the TextInput to edit or commit the partial text. This property can be
+ used to determine when to disable events handlers that may interfere with
+ the correct operation of an input method.
+*/
+bool QDeclarativeTextInput::isInputMethodComposing() const
+{
+ Q_D(const QDeclarativeTextInput);
+ return d->control->preeditAreaText().length() > 0;
+}
+
void QDeclarativeTextInputPrivate::init()
{
Q_Q(QDeclarativeTextInput);
@@ -1708,6 +1766,7 @@ void QDeclarativeTextInputPrivate::init()
q, SLOT(q_canPasteChanged()));
q->connect(QApplication::clipboard(), SIGNAL(dataChanged()),
q, SLOT(q_canPasteChanged()));
+ canPaste = !control->isReadOnly() && QApplication::clipboard()->text().length() != 0;
#endif // QT_NO_CLIPBOARD
q->connect(control, SIGNAL(updateMicroFocus()),
q, SLOT(updateMicroFocus()));
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
index e1e66a9..822d5e2 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
@@ -97,6 +97,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextInput : public QDeclarativeImplicitSizeP
Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged REVISION 1)
Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged REVISION 1)
+ Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged REVISION 1)
public:
QDeclarativeTextInput(QDeclarativeItem* parent=0);
@@ -120,8 +121,14 @@ public:
SelectWords
};
+ enum CursorPosition {
+ CursorBetweenCharacters,
+ CursorOnCharacter
+ };
+
//Auxilliary functions needed to control the TextInput from QML
Q_INVOKABLE int positionAt(int x) const;
+ Q_INVOKABLE Q_REVISION(1) int positionAt(int x, CursorPosition position) const;
Q_INVOKABLE QRectF positionToRectangle(int pos) const;
Q_INVOKABLE void moveCursorSelection(int pos);
Q_INVOKABLE Q_REVISION(1) void moveCursorSelection(int pos, SelectionMode mode);
@@ -204,6 +211,8 @@ public:
QRectF boundingRect() const;
bool canPaste() const;
+ bool isInputMethodComposing() const;
+
Q_SIGNALS:
void textChanged();
void cursorPositionChanged();
@@ -231,6 +240,7 @@ Q_SIGNALS:
void selectByMouseChanged(bool selectByMouse);
Q_REVISION(1) void mouseSelectionModeChanged(SelectionMode mode);
Q_REVISION(1) void canPasteChanged();
+ Q_REVISION(1) void inputMethodComposingChanged();
protected:
virtual void geometryChanged(const QRectF &newGeometry,
diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
index b24dd2c..31819f5 100644
--- a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
@@ -99,7 +99,6 @@ class DrawTextItemRecorder: public QPaintEngine
needFreshCurrentItem = false;
last.numChars += ti.num_chars;
- last.numGlyphs += ti.glyphs.numGlyphs;
}
}
@@ -111,7 +110,7 @@ class DrawTextItemRecorder: public QPaintEngine
currentItem.font = ti.font();
currentItem.charOffset = charOffset;
currentItem.numChars = ti.num_chars;
- currentItem.numGlyphs = ti.glyphs.numGlyphs;
+ currentItem.numGlyphs = 0;
currentItem.glyphOffset = glyphOffset;
currentItem.positionOffset = positionOffset;
currentItem.useBackendOptimizations = m_useBackendOptimizations;
@@ -121,6 +120,8 @@ class DrawTextItemRecorder: public QPaintEngine
m_inertText->items.append(currentItem);
}
+ QStaticTextItem &currentItem = m_inertText->items.last();
+
QTransform matrix = m_untransformedCoordinates ? QTransform() : state->transform();
matrix.translate(position.x(), position.y());
@@ -129,18 +130,18 @@ class DrawTextItemRecorder: public QPaintEngine
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
int size = glyphs.size();
- Q_ASSERT(size == ti.glyphs.numGlyphs);
Q_ASSERT(size == positions.size());
+ currentItem.numGlyphs += size;
m_inertText->glyphs.resize(m_inertText->glyphs.size() + size);
m_inertText->positions.resize(m_inertText->glyphs.size());
m_inertText->chars.resize(m_inertText->chars.size() + ti.num_chars);
glyph_t *glyphsDestination = m_inertText->glyphs.data() + glyphOffset;
- qMemCopy(glyphsDestination, glyphs.constData(), sizeof(glyph_t) * ti.glyphs.numGlyphs);
+ qMemCopy(glyphsDestination, glyphs.constData(), sizeof(glyph_t) * size);
QFixedPoint *positionsDestination = m_inertText->positions.data() + positionOffset;
- qMemCopy(positionsDestination, positions.constData(), sizeof(QFixedPoint) * ti.glyphs.numGlyphs);
+ qMemCopy(positionsDestination, positions.constData(), sizeof(QFixedPoint) * size);
QChar *charsDestination = m_inertText->chars.data() + charOffset;
qMemCopy(charsDestination, ti.chars, sizeof(QChar) * ti.num_chars);
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index cf40182..fc393d1 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -615,10 +615,11 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q
}
/*!
- \qmlmethod object Component::createObject(Item parent, Script valuemap = null)
+ \qmlmethod object Component::createObject(Item parent, object properties)
- Creates and returns an object instance of this component that will have the given
- \a parent. Returns null if object creation fails.
+ Creates and returns an object instance of this component that will have
+ the given \a parent and \a properties. The \a properties argument is optional.
+ Returns null if object creation fails.
The object will be created in the same context as the one in which the component
was created. This function will always return null when called on components
@@ -630,14 +631,23 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q
property, or else the object will not be visible.
If a \a parent is not provided to createObject(), a reference to the returned object must be held so that
- it is not destroyed by the garbage collector. This is regardless of Item.parent being set afterwards,
+ it is not destroyed by the garbage collector. This is true regardless of whether \l{Item::parent} is set afterwards,
since setting the Item parent does not change object ownership; only the graphical parent is changed.
- Since QtQuick 1.1, a map of property values can be optionally passed to the method that applies values to the object's properties
- before its creation is finalised. This will avoid binding issues that can occur when the object is
- instantiated before property bindings have been set. For example:
+ As of QtQuick 1.1, this method accepts an optional \a properties argument that specifies a
+ map of initial property values for the created object. These values are applied before object
+ creation is finalized. (This is more efficient than setting property values after object creation,
+ particularly where large sets of property values are defined, and also allows property bindings
+ to be set up before the object is created.)
- \code component.createObject(parent, {"x": 100, "y": 100, "specialProperty": someObject}); \endcode
+ The \a properties argument is specified as a map of property-value items. For example, the code
+ below creates an object with initial \c x and \c y values of 100 and 200, respectively:
+
+ \qml
+ var component = Qt.createComponent("Button.qml");
+ if (component.status == Component.Ready)
+ component.createObject(parent, {"x": 100, "y": 100});
+ \endqml
Dynamically created instances can be deleted with the \c destroy() method.
See \l {Dynamic Object Management in QML} for more information.
diff --git a/src/declarative/util/qdeclarativeopenmetaobject.cpp b/src/declarative/util/qdeclarativeopenmetaobject.cpp
index 0ceda35..8a8d05e 100644
--- a/src/declarative/util/qdeclarativeopenmetaobject.cpp
+++ b/src/declarative/util/qdeclarativeopenmetaobject.cpp
@@ -289,17 +289,19 @@ void QDeclarativeOpenMetaObject::setValue(const QByteArray &name, const QVariant
int id = -1;
if (iter == d->type->d->names.end()) {
- id = d->type->createProperty(name.constData()) - d->type->d->propertyOffset;
+ id = createProperty(name.constData(), "") - d->type->d->propertyOffset;
} else {
id = *iter;
}
- QVariant &dataVal = d->getData(id);
- if (dataVal == val)
- return;
+ if (id >= 0) {
+ QVariant &dataVal = d->getData(id);
+ if (dataVal == val)
+ return;
- dataVal = val;
- activate(d->object, id + d->type->d->signalOffset, 0);
+ dataVal = val;
+ activate(d->object, id + d->type->d->signalOffset, 0);
+ }
}
// returns true if this value has been initialized by a call to either value() or setValue()
diff --git a/src/declarative/util/qdeclarativepropertymap.cpp b/src/declarative/util/qdeclarativepropertymap.cpp
index 1a3e0be..915f027 100644
--- a/src/declarative/util/qdeclarativepropertymap.cpp
+++ b/src/declarative/util/qdeclarativepropertymap.cpp
@@ -182,7 +182,18 @@ QVariant QDeclarativePropertyMap::value(const QString &key) const
void QDeclarativePropertyMap::insert(const QString &key, const QVariant &value)
{
Q_D(QDeclarativePropertyMap);
- d->mo->setValue(key.toUtf8(), value);
+ //The following strings shouldn't be used as property names
+ if (key != QLatin1String("keys")
+ && key != QLatin1String("valueChanged")
+ && key != QLatin1String("QObject")
+ && key != QLatin1String("destroyed")
+ && key != QLatin1String("deleteLater")) {
+ d->mo->setValue(key.toUtf8(), value);
+ } else {
+ qWarning() << "Creating property with name"
+ << key
+ << "is not permitted, conflicts with internal symbols.";
+ }
}
/*!
@@ -258,7 +269,7 @@ QVariant &QDeclarativePropertyMap::operator[](const QString &key)
Q_D(QDeclarativePropertyMap);
QByteArray utf8key = key.toUtf8();
if (!d->keys.contains(key))
- d->mo->setValue(utf8key, QVariant()); //force creation -- needed below
+ insert(key, QVariant());//force creation -- needed below
return (*(d->mo))[utf8key];
}
diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp
index dd27aff..cb8eb6a 100644
--- a/src/gui/dialogs/qfilesystemmodel.cpp
+++ b/src/gui/dialogs/qfilesystemmodel.cpp
@@ -1458,7 +1458,6 @@ void QFileSystemModel::setIconProvider(QFileIconProvider *provider)
{
Q_D(QFileSystemModel);
d->fileInfoGatherer.setIconProvider(provider);
- QApplication::processEvents();
d->root.updateIcon(provider, QString());
}
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index 92ea397..a5e37f3 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -29,7 +29,9 @@ HEADERS += \
image/qpixmapdata_p.h \
image/qpixmapdatafactory_p.h \
image/qpixmapfilter_p.h \
- image/qimagepixmapcleanuphooks_p.h
+ image/qimagepixmapcleanuphooks_p.h \
+ image/qvolatileimage_p.h \
+ image/qvolatileimagedata_p.h
SOURCES += \
image/qbitmap.cpp \
@@ -53,7 +55,8 @@ SOURCES += \
image/qpixmap_raster.cpp \
image/qpixmap_blitter.cpp \
image/qnativeimage.cpp \
- image/qimagepixmapcleanuphooks.cpp
+ image/qimagepixmapcleanuphooks.cpp \
+ image/qvolatileimage.cpp
win32 {
SOURCES += image/qpixmap_win.cpp
@@ -77,6 +80,13 @@ else:symbian {
SOURCES += image/qpixmap_s60.cpp
}
+!symbian|contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2) {
+ SOURCES += image/qvolatileimagedata.cpp
+}
+else {
+ SOURCES += image/qvolatileimagedata_symbian.cpp
+}
+
# Built-in image format support
HEADERS += \
image/qbmphandler_p.h \
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index f896572..6e13324 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -112,8 +112,16 @@ void QPixmap::init(int w, int h, Type type)
init(w, h, int(type));
}
+extern QApplication::Type qt_appType;
+
void QPixmap::init(int w, int h, int type)
{
+ if (qt_appType == QApplication::Tty) {
+ qWarning("QPixmap: Cannot create a QPixmap when no GUI is being used");
+ data = 0;
+ return;
+ }
+
if ((w > 0 && h > 0) || type == QPixmapData::BitmapType)
data = QPixmapData::create(w, h, (QPixmapData::PixelType) type);
else
@@ -1636,16 +1644,6 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
{Implicit Data Sharing} documentation. QPixmap objects can also be
streamed.
- Depending on the system, QPixmap is stored using a RGB32 or a
- premultiplied alpha format. If the image has an alpha channel, and
- if the system allows, the preferred format is premultiplied alpha.
- Note also that QPixmap, unlike QImage, may be hardware dependent.
- On X11, Mac and Symbian, a QPixmap is stored on the server side while
- a QImage is stored on the client side (on Windows, these two classes
- have an equivalent internal representation, i.e. both QImage and
- QPixmap are stored on the client side and don't use any GDI
- resources).
-
Note that the pixel data in a pixmap is internal and is managed by
the underlying window system. Because QPixmap is a QPaintDevice
subclass, QPainter can be used to draw directly onto pixmaps.
@@ -2012,7 +2010,7 @@ void QPixmap::detach()
}
if (data->is_cached && data->ref == 1)
- QImagePixmapCleanupHooks::executePixmapDataModificationHooks(pd);
+ QImagePixmapCleanupHooks::executePixmapDataModificationHooks(data.data());
#if defined(Q_WS_MAC)
QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(pd) : 0;
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 1e7ff04..a5f42c1 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -386,6 +386,9 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace)
{
QImage::Format format;
+ if (flags & Qt::NoFormatConversion)
+ format = sourceImage.format();
+ else
#ifdef Q_WS_QWS
if (pixelType() == BitmapType) {
format = QImage::Format_Mono;
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index 5c05c28..db5ff4a 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -71,7 +71,8 @@ public:
#if defined(Q_OS_SYMBIAN)
enum NativeType {
FbsBitmap,
- SgImage
+ SgImage,
+ VolatileImage
};
#endif
enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass,
diff --git a/src/gui/image/qvolatileimage.cpp b/src/gui/image/qvolatileimage.cpp
new file mode 100644
index 0000000..098e9a1
--- /dev/null
+++ b/src/gui/image/qvolatileimage.cpp
@@ -0,0 +1,318 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 "qvolatileimage_p.h"
+#include "qvolatileimagedata_p.h"
+#include <QtGui/private/qpaintengine_raster_p.h>
+#include <QtGui/private/qpixmapdata_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVolatileImagePaintEnginePrivate : public QRasterPaintEnginePrivate
+{
+public:
+ QVolatileImagePaintEnginePrivate() { }
+ QVolatileImage *img;
+};
+
+class QVolatileImagePaintEngine : public QRasterPaintEngine
+{
+ Q_DECLARE_PRIVATE(QVolatileImagePaintEngine)
+
+public:
+ QVolatileImagePaintEngine(QPaintDevice *device, QVolatileImage *img);
+ bool begin(QPaintDevice *device);
+ bool end();
+ void drawPixmap(const QPointF &p, const QPixmap &pm);
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+};
+
+QVolatileImage::QVolatileImage()
+ : d(new QVolatileImageData)
+{
+}
+
+QVolatileImage::QVolatileImage(int w, int h, QImage::Format format)
+ : d(new QVolatileImageData(w, h, format))
+{
+}
+
+QVolatileImage::QVolatileImage(const QImage &sourceImage)
+ : d(new QVolatileImageData(sourceImage))
+{
+}
+
+QVolatileImage::QVolatileImage(void *nativeImage, void *nativeMask)
+ : d(new QVolatileImageData(nativeImage, nativeMask))
+{
+}
+
+// Need non-inline, non-autogenerated copy ctor, dtor, op= to keep the
+// fwd declared QSharedData working.
+
+QVolatileImage::QVolatileImage(const QVolatileImage &other)
+ : d(other.d)
+{
+}
+
+QVolatileImage::~QVolatileImage()
+{
+}
+
+QVolatileImage &QVolatileImage::operator=(const QVolatileImage &rhs)
+{
+ d = rhs.d;
+ return *this;
+}
+
+bool QVolatileImage::isNull() const
+{
+ return d->image.isNull();
+}
+
+QImage::Format QVolatileImage::format() const
+{
+ return d->image.format();
+}
+
+int QVolatileImage::width() const
+{
+ return d->image.width();
+}
+
+int QVolatileImage::height() const
+{
+ return d->image.height();
+}
+
+int QVolatileImage::bytesPerLine() const
+{
+ return d->image.bytesPerLine();
+}
+
+int QVolatileImage::byteCount() const
+{
+ return d->image.byteCount();
+}
+
+int QVolatileImage::depth() const
+{
+ return d->image.depth();
+}
+
+bool QVolatileImage::hasAlphaChannel() const
+{
+ return d->image.hasAlphaChannel();
+}
+
+void QVolatileImage::beginDataAccess() const
+{
+ d->beginDataAccess();
+}
+
+void QVolatileImage::endDataAccess(bool readOnly) const
+{
+ d->endDataAccess(readOnly);
+}
+
+/*!
+ Access to pixel data via bits() or constBits() should be guarded by
+ begin/endDataAccess().
+ */
+uchar *QVolatileImage::bits()
+{
+ return d->image.bits();
+}
+
+const uchar *QVolatileImage::constBits() const
+{
+ return d->image.constBits();
+}
+
+bool QVolatileImage::ensureFormat(QImage::Format format)
+{
+ return d->ensureFormat(format);
+}
+
+/*!
+ This will always perform a copy of the pixel data.
+ */
+QImage QVolatileImage::toImage() const
+{
+ d->beginDataAccess();
+ QImage newImage = d->image.copy(); // no sharing allowed
+ d->endDataAccess(true);
+ return newImage;
+}
+
+/*!
+ Returns a reference to the image that is potentially using some native
+ buffer internally. Access to the image's pixel data should be guarded by
+ begin/endDataAccess(). Use it when there is a need for QImage APIs not provided
+ by this class. The returned QImage must never be shared or assigned to.
+ */
+QImage &QVolatileImage::imageRef() // non-const, in order to cause a detach
+{
+ d->ensureImage();
+ return d->image;
+}
+
+void *QVolatileImage::duplicateNativeImage() const
+{
+ return d->duplicateNativeImage();
+}
+
+void QVolatileImage::setAlphaChannel(const QPixmap &alphaChannel)
+{
+ ensureFormat(QImage::Format_ARGB32_Premultiplied);
+ beginDataAccess();
+ imageRef().setAlphaChannel(alphaChannel.toImage());
+ endDataAccess();
+ d->ensureImage();
+}
+
+void QVolatileImage::fill(uint pixelValue)
+{
+ beginDataAccess();
+ imageRef().fill(pixelValue);
+ endDataAccess();
+ d->ensureImage();
+}
+
+void QVolatileImage::copyFrom(QVolatileImage *source, const QRect &rect)
+{
+ if (source->isNull()) {
+ return;
+ }
+ QRect r = rect;
+ if (rect.isNull()) {
+ r = QRect(0, 0, source->width(), source->height());
+ }
+ source->beginDataAccess();
+ QImage &srcImgRef(source->imageRef());
+ int srcbpl = srcImgRef.bytesPerLine();
+ int srcbpp = srcImgRef.depth() / 8;
+ const uchar *sptr = srcImgRef.constBits() + r.y() * srcbpl;
+ beginDataAccess();
+ QImage &dstImgRef(imageRef());
+ int dstbpl = dstImgRef.bytesPerLine();
+ uchar *dptr = dstImgRef.bits();
+ for (int y = 0; y < r.height(); ++y) {
+ qMemCopy(dptr, sptr + r.x() * srcbpp, r.width() * srcbpp);
+ sptr += srcbpl;
+ dptr += dstbpl;
+ }
+ endDataAccess();
+ source->endDataAccess(true);
+}
+
+/*!
+ To be called from the PixmapData's paintEngine().
+ */
+QPaintEngine *QVolatileImage::paintEngine()
+{
+ if (!d->pengine) {
+ d->pengine = new QVolatileImagePaintEngine(&imageRef(), this);
+ }
+ return d->pengine;
+}
+
+QVolatileImagePaintEngine::QVolatileImagePaintEngine(QPaintDevice *device,
+ QVolatileImage *img)
+ : QRasterPaintEngine(*(new QVolatileImagePaintEnginePrivate), device)
+{
+ Q_D(QVolatileImagePaintEngine);
+ d->img = img;
+}
+
+bool QVolatileImagePaintEngine::begin(QPaintDevice *device)
+{
+ Q_D(QVolatileImagePaintEngine);
+ d->img->beginDataAccess();
+ return QRasterPaintEngine::begin(device);
+}
+
+bool QVolatileImagePaintEngine::end()
+{
+ Q_D(QVolatileImagePaintEngine);
+ bool ret = QRasterPaintEngine::end();
+ d->img->endDataAccess();
+ return ret;
+}
+
+// For non-RasterClass pixmaps drawPixmap() would call toImage() which is slow in
+// our case. Therefore drawPixmap() is rerouted to drawImage().
+
+void QVolatileImagePaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
+{
+#ifdef Q_OS_SYMBIAN
+ void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
+ if (nativeData) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
+ img->beginDataAccess();
+ QRasterPaintEngine::drawImage(p, img->imageRef());
+ img->endDataAccess(true);
+ } else {
+ QRasterPaintEngine::drawPixmap(p, pm);
+ }
+#else
+ QRasterPaintEngine::drawPixmap(p, pm);
+#endif
+}
+
+void QVolatileImagePaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
+{
+#ifdef Q_OS_SYMBIAN
+ void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
+ if (nativeData) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
+ img->beginDataAccess();
+ QRasterPaintEngine::drawImage(r, img->imageRef(), sr);
+ img->endDataAccess(true);
+ } else {
+ QRasterPaintEngine::drawPixmap(r, pm, sr);
+ }
+#else
+ QRasterPaintEngine::drawPixmap(r, pm, sr);
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qvolatileimage_p.h b/src/gui/image/qvolatileimage_p.h
new file mode 100644
index 0000000..fc5d6b1
--- /dev/null
+++ b/src/gui/image/qvolatileimage_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 QVOLATILEIMAGE_P_H
+#define QVOLATILEIMAGE_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 <QtGui/qimage.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVolatileImageData;
+
+class Q_GUI_EXPORT QVolatileImage
+{
+public:
+ QVolatileImage();
+ QVolatileImage(int w, int h, QImage::Format format);
+ explicit QVolatileImage(const QImage &sourceImage);
+ explicit QVolatileImage(void *nativeImage, void *nativeMask = 0);
+ QVolatileImage(const QVolatileImage &other);
+ ~QVolatileImage();
+ QVolatileImage &operator=(const QVolatileImage &rhs);
+
+ bool isNull() const;
+ QImage::Format format() const;
+ int width() const;
+ int height() const;
+ int bytesPerLine() const;
+ int byteCount() const;
+ int depth() const;
+ bool hasAlphaChannel() const;
+ void beginDataAccess() const;
+ void endDataAccess(bool readOnly = false) const;
+ uchar *bits();
+ const uchar *constBits() const;
+ bool ensureFormat(QImage::Format format);
+ QImage toImage() const;
+ QImage &imageRef();
+ QPaintEngine *paintEngine();
+ void setAlphaChannel(const QPixmap &alphaChannel);
+ void fill(uint pixelValue);
+ void *duplicateNativeImage() const;
+ void copyFrom(QVolatileImage *source, const QRect &rect);
+
+private:
+ QSharedDataPointer<QVolatileImageData> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QVOLATILEIMAGE_P_H
diff --git a/src/gui/image/qvolatileimagedata.cpp b/src/gui/image/qvolatileimagedata.cpp
new file mode 100644
index 0000000..51b5995
--- /dev/null
+++ b/src/gui/image/qvolatileimagedata.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 "qvolatileimagedata_p.h"
+#include <QtGui/qpaintengine.h>
+
+QT_BEGIN_NAMESPACE
+
+QVolatileImageData::QVolatileImageData()
+ : pengine(0)
+{
+}
+
+QVolatileImageData::QVolatileImageData(int w, int h, QImage::Format format)
+ : pengine(0)
+{
+ image = QImage(w, h, format);
+}
+
+QVolatileImageData::QVolatileImageData(const QImage &sourceImage)
+ : pengine(0)
+{
+ image = sourceImage;
+}
+
+QVolatileImageData::QVolatileImageData(void *, void *)
+ : pengine(0)
+{
+ // Not supported.
+}
+
+QVolatileImageData::QVolatileImageData(const QVolatileImageData &other)
+{
+ image = other.image;
+ // The detach is not mandatory here but we do it nonetheless in order to
+ // keep the behavior consistent with other platforms.
+ image.detach();
+ pengine = 0;
+}
+
+QVolatileImageData::~QVolatileImageData()
+{
+ delete pengine;
+}
+
+void QVolatileImageData::beginDataAccess() const
+{
+ // nothing to do here
+}
+
+void QVolatileImageData::endDataAccess(bool readOnly) const
+{
+ Q_UNUSED(readOnly);
+ // nothing to do here
+}
+
+bool QVolatileImageData::ensureFormat(QImage::Format format)
+{
+ if (image.format() != format) {
+ image = image.convertToFormat(format);
+ }
+ return true;
+}
+
+void *QVolatileImageData::duplicateNativeImage() const
+{
+ return 0;
+}
+
+void QVolatileImageData::ensureImage()
+{
+ // nothing to do here
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qvolatileimagedata_p.h b/src/gui/image/qvolatileimagedata_p.h
new file mode 100644
index 0000000..dab1685
--- /dev/null
+++ b/src/gui/image/qvolatileimagedata_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 QVOLATILEIMAGEDATA_P_H
+#define QVOLATILEIMAGEDATA_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 <QtGui/qimage.h>
+#include <QtCore/qshareddata.h>
+
+#ifdef Q_OS_SYMBIAN
+class CFbsBitmap;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QVolatileImageData : public QSharedData
+{
+public:
+ QVolatileImageData();
+ QVolatileImageData(int w, int h, QImage::Format format);
+ QVolatileImageData(const QImage &sourceImage);
+ QVolatileImageData(void *nativeImage, void *nativeMask);
+ QVolatileImageData(const QVolatileImageData &other);
+ ~QVolatileImageData();
+
+ void beginDataAccess() const;
+ void endDataAccess(bool readOnly = false) const;
+ bool ensureFormat(QImage::Format format);
+ void *duplicateNativeImage() const;
+ void ensureImage();
+
+#ifdef Q_OS_SYMBIAN
+ void updateImage();
+ void initWithBitmap(CFbsBitmap *source);
+ void applyMask(CFbsBitmap *mask);
+ void ensureBitmap();
+ void release();
+ QVolatileImageData *next;
+ QVolatileImageData *prev;
+ CFbsBitmap *bitmap;
+#endif
+ QImage image;
+ QPaintEngine *pengine;
+};
+
+QT_END_NAMESPACE
+
+#endif // QVOLATILEIMAGEDATA_P_H
diff --git a/src/gui/image/qvolatileimagedata_symbian.cpp b/src/gui/image/qvolatileimagedata_symbian.cpp
new file mode 100644
index 0000000..474d0ef
--- /dev/null
+++ b/src/gui/image/qvolatileimagedata_symbian.cpp
@@ -0,0 +1,471 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 "qvolatileimagedata_p.h"
+#include <fbs.h>
+#include <QtGui/private/qt_s60_p.h>
+#include <QtGui/qpaintengine.h>
+#include <QtGui/private/qimage_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static CFbsBitmap *rasterizeBitmap(CFbsBitmap *bitmap, TDisplayMode newMode)
+{
+ if (!bitmap) {
+ return 0;
+ }
+ QScopedPointer<CFbsBitmap> newBitmap(new CFbsBitmap);
+ if (newBitmap->Create(bitmap->SizeInPixels(), newMode) != KErrNone) {
+ qWarning("QVolatileImage: Failed to create new bitmap");
+ return 0;
+ }
+ CFbsBitmapDevice *bitmapDevice = 0;
+ CFbsBitGc *bitmapGc = 0;
+ QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(newBitmap.data()));
+ QScopedPointer<CFbsBitmapDevice> bitmapDevicePtr(bitmapDevice);
+ QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
+ bitmapGc->Activate(bitmapDevice);
+ bitmapGc->BitBlt(TPoint(), bitmap);
+ delete bitmapGc;
+ return newBitmap.take();
+}
+
+static inline TDisplayMode format2TDisplayMode(QImage::Format format)
+{
+ TDisplayMode mode;
+ switch (format) {
+ case QImage::Format_MonoLSB:
+ mode = EGray2;
+ break;
+ case QImage::Format_Indexed8:
+ mode = EColor256;
+ break;
+ case QImage::Format_RGB444:
+ mode = EColor4K;
+ break;
+ case QImage::Format_RGB16:
+ mode = EColor64K;
+ break;
+ case QImage::Format_RGB888:
+ mode = EColor16M;
+ break;
+ case QImage::Format_RGB32:
+ mode = EColor16MU;
+ break;
+ case QImage::Format_ARGB32:
+ mode = EColor16MA;
+ break;
+ case QImage::Format_ARGB32_Premultiplied:
+ mode = Q_SYMBIAN_ECOLOR16MAP;
+ break;
+ default:
+ mode = ENone;
+ break;
+ }
+ return mode;
+}
+
+static CFbsBitmap *imageToBitmap(const QImage &image)
+{
+ if (image.isNull()) {
+ return 0;
+ }
+ CFbsBitmap *bitmap = new CFbsBitmap;
+ if (bitmap->Create(TSize(image.width(), image.height()),
+ format2TDisplayMode(image.format())) == KErrNone) {
+ bitmap->BeginDataAccess();
+ uchar *dptr = reinterpret_cast<uchar *>(bitmap->DataAddress());
+ int bmpLineLen = bitmap->DataStride();
+ int imgLineLen = image.bytesPerLine();
+ if (bmpLineLen == imgLineLen) {
+ qMemCopy(dptr, image.constBits(), image.byteCount());
+ } else {
+ int len = qMin(bmpLineLen, imgLineLen);
+ const uchar *sptr = image.constBits();
+ for (int y = 0; y < image.height(); ++y) {
+ qMemCopy(dptr, sptr, len);
+ dptr += bmpLineLen;
+ sptr += imgLineLen;
+ }
+ }
+ bitmap->EndDataAccess();
+ } else {
+ qWarning("QVolatileImage: Failed to create source bitmap");
+ delete bitmap;
+ bitmap = 0;
+ }
+ return bitmap;
+}
+
+static CFbsBitmap *copyData(const QVolatileImageData &source)
+{
+ source.beginDataAccess();
+ CFbsBitmap *bmp = imageToBitmap(source.image);
+ source.endDataAccess();
+ return bmp;
+}
+
+static CFbsBitmap *convertData(const QVolatileImageData &source, QImage::Format newFormat)
+{
+ source.beginDataAccess();
+ QImage img = source.image.convertToFormat(newFormat);
+ CFbsBitmap *bmp = imageToBitmap(img);
+ source.endDataAccess();
+ return bmp;
+}
+
+static CFbsBitmap *duplicateBitmap(const CFbsBitmap &sourceBitmap)
+{
+ CFbsBitmap *bitmap = new CFbsBitmap;
+ if (bitmap->Duplicate(sourceBitmap.Handle()) != KErrNone) {
+ qWarning("QVolatileImage: Failed to duplicate source bitmap");
+ delete bitmap;
+ bitmap = 0;
+ }
+ return bitmap;
+}
+
+static CFbsBitmap *createBitmap(int w, int h, QImage::Format format)
+{
+ CFbsBitmap *bitmap = new CFbsBitmap;
+ if (bitmap->Create(TSize(w, h), format2TDisplayMode(format)) != KErrNone) {
+ qWarning("QVolatileImage: Failed to create source bitmap %d,%d (%d)", w, h, format);
+ delete bitmap;
+ bitmap = 0;
+ }
+ return bitmap;
+}
+
+static inline bool bitmapNeedsCopy(CFbsBitmap *bitmap)
+{
+ bool needsCopy = bitmap->IsCompressedInRAM();
+#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
+ needsCopy |= (bitmap->ExtendedBitmapType() != KNullUid);
+#endif
+ return needsCopy;
+}
+
+static bool cleanup_function_registered = false;
+static QVolatileImageData *firstImageData = 0;
+
+static void cleanup()
+{
+ if (RFbsSession::GetSession()) {
+ QVolatileImageData *imageData = firstImageData;
+ while (imageData) {
+ imageData->release();
+ imageData = imageData->next;
+ }
+ }
+}
+
+static void ensureCleanup()
+{
+ // Destroy all underlying bitmaps in a post routine to prevent panics.
+ // This is a must because CFbsBitmap destructor needs the fbs session,
+ // that was used to create the bitmap, to be open still.
+ if (!cleanup_function_registered) {
+ qAddPostRoutine(cleanup);
+ cleanup_function_registered = true;
+ }
+}
+
+static void registerImageData(QVolatileImageData *imageData)
+{
+ ensureCleanup();
+ imageData->next = firstImageData;
+ if (firstImageData) {
+ firstImageData->prev = imageData;
+ }
+ firstImageData = imageData;
+}
+
+static void unregisterImageData(QVolatileImageData *imageData)
+{
+ if (imageData->prev) {
+ imageData->prev->next = imageData->next;
+ } else {
+ firstImageData = imageData->next;
+ }
+ if (imageData->next) {
+ imageData->next->prev = imageData->prev;
+ }
+}
+
+QVolatileImageData::QVolatileImageData()
+ : next(0), prev(0), bitmap(0), pengine(0)
+{
+ registerImageData(this);
+}
+
+QVolatileImageData::QVolatileImageData(int w, int h, QImage::Format format)
+ : next(0), prev(0), bitmap(0), pengine(0)
+{
+ registerImageData(this);
+ bitmap = createBitmap(w, h, format);
+ updateImage();
+}
+
+QVolatileImageData::QVolatileImageData(const QImage &sourceImage)
+ : next(0), prev(0), bitmap(0), pengine(0)
+{
+ registerImageData(this);
+ image = sourceImage;
+ // The following is not mandatory, but we do it here to have a bitmap
+ // created always in order to reduce local heap usage.
+ ensureBitmap();
+}
+
+QVolatileImageData::QVolatileImageData(void *nativeImage, void *nativeMask)
+ : next(0), prev(0), bitmap(0), pengine(0)
+{
+ registerImageData(this);
+ if (nativeImage) {
+ CFbsBitmap *source = static_cast<CFbsBitmap *>(nativeImage);
+ CFbsBitmap *mask = static_cast<CFbsBitmap *>(nativeMask);
+ initWithBitmap(source);
+ if (mask) {
+ applyMask(mask);
+ }
+ }
+}
+
+QVolatileImageData::QVolatileImageData(const QVolatileImageData &other)
+{
+ bitmap = 0;
+ pengine = 0;
+ next = prev = 0;
+ registerImageData(this);
+ if (!other.image.isNull()) {
+ bitmap = copyData(other);
+ updateImage();
+ }
+}
+
+QVolatileImageData::~QVolatileImageData()
+{
+ release();
+ unregisterImageData(this);
+}
+
+void QVolatileImageData::release()
+{
+ delete bitmap;
+ bitmap = 0;
+ delete pengine;
+ pengine = 0;
+}
+
+void QVolatileImageData::beginDataAccess() const
+{
+ if (bitmap) {
+ bitmap->BeginDataAccess();
+ }
+}
+
+void QVolatileImageData::endDataAccess(bool readOnly) const
+{
+ if (bitmap) {
+ bitmap->EndDataAccess(readOnly);
+ }
+}
+
+bool QVolatileImageData::ensureFormat(QImage::Format format)
+{
+ if (image.isNull()) {
+ return false;
+ }
+ if (image.format() != format) {
+ CFbsBitmap *newBitmap = convertData(*this, format);
+ if (newBitmap && newBitmap != bitmap) {
+ delete bitmap;
+ bitmap = newBitmap;
+ updateImage();
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+void *QVolatileImageData::duplicateNativeImage() const
+{
+ const_cast<QVolatileImageData *>(this)->ensureBitmap();
+ if (bitmap) {
+ if (bitmap->DisplayMode() == EColor16M) {
+ // slow path: needs rgb swapping
+ beginDataAccess();
+ QImage tmp = image.rgbSwapped();
+ endDataAccess(true);
+ return imageToBitmap(tmp);
+ } else if (bitmap->DisplayMode() == EGray2) {
+ // slow path: needs inverting pixels
+ beginDataAccess();
+ QImage tmp = image.copy();
+ endDataAccess(true);
+ tmp.invertPixels();
+ return imageToBitmap(tmp);
+ } else {
+ // fast path: just duplicate the bitmap
+ return duplicateBitmap(*bitmap);
+ }
+ }
+ return 0;
+}
+
+void QVolatileImageData::updateImage()
+{
+ if (bitmap) {
+ TSize size = bitmap->SizeInPixels();
+ beginDataAccess();
+ // Use existing buffer, no copy. The data address never changes so it
+ // is enough to do this whenever we have a new CFbsBitmap. N.B. never
+ // use const uchar* here, that would create a read-only image data which
+ // would make a copy in detach() even when refcount is 1.
+ image = QImage(reinterpret_cast<uchar *>(bitmap->DataAddress()),
+ size.iWidth, size.iHeight, bitmap->DataStride(),
+ qt_TDisplayMode2Format(bitmap->DisplayMode()));
+ endDataAccess(true);
+ } else {
+ image = QImage();
+ }
+}
+
+void QVolatileImageData::initWithBitmap(CFbsBitmap *source)
+{
+ bool needsCopy = bitmapNeedsCopy(source);
+ if (source->DisplayMode() == EColor16M) {
+ // EColor16M is BGR
+ CFbsBitmap *unswappedBmp = source;
+ if (needsCopy) {
+ unswappedBmp = rasterizeBitmap(source, source->DisplayMode());
+ }
+ unswappedBmp->BeginDataAccess();
+ TSize sourceSize = unswappedBmp->SizeInPixels();
+ QImage img((uchar *) unswappedBmp->DataAddress(),
+ sourceSize.iWidth, sourceSize.iHeight, unswappedBmp->DataStride(),
+ qt_TDisplayMode2Format(unswappedBmp->DisplayMode()));
+ img = img.rgbSwapped();
+ unswappedBmp->EndDataAccess(true);
+ bitmap = imageToBitmap(img);
+ if (needsCopy) {
+ delete unswappedBmp;
+ }
+ } else if (needsCopy) {
+ // Rasterize extended and compressed bitmaps.
+ bitmap = rasterizeBitmap(source, EColor16MAP);
+ } else {
+ // Efficient path: no pixel data copying. Just duplicate. This of course
+ // means the original bitmap's data may get modified, but that's fine
+ // and is in accordance with the QPixmap::fromSymbianCFbsBitmap() docs.
+ bitmap = duplicateBitmap(*source);
+ }
+ updateImage();
+ if (bitmap && bitmap->DisplayMode() == EGray2) {
+ // Symbian thinks set pixels are white/transparent, Qt thinks they are
+ // foreground/solid. Invert mono bitmaps so that masks work correctly.
+ beginDataAccess();
+ image.invertPixels();
+ endDataAccess();
+ }
+}
+
+void QVolatileImageData::applyMask(CFbsBitmap *mask)
+{
+ ensureFormat(QImage::Format_ARGB32_Premultiplied);
+ bool destroyMask = false;
+ if (bitmapNeedsCopy(mask)) {
+ mask = rasterizeBitmap(mask, EColor16MU);
+ if (!mask) {
+ return;
+ }
+ destroyMask = true;
+ }
+ mask->BeginDataAccess();
+ TSize maskSize = mask->SizeInPixels();
+ QImage maskImg((const uchar *) mask->DataAddress(), maskSize.iWidth, maskSize.iHeight,
+ mask->DataStride(), qt_TDisplayMode2Format(mask->DisplayMode()));
+ if (mask->DisplayMode() == EGray2) {
+ maskImg = maskImg.copy();
+ maskImg.invertPixels();
+ }
+ beginDataAccess();
+ image.setAlphaChannel(maskImg);
+ endDataAccess();
+ mask->EndDataAccess(true);
+ ensureImage();
+ if (destroyMask) {
+ delete mask;
+ }
+}
+
+void QVolatileImageData::ensureImage()
+{
+ if (bitmap && !image.isNull()) {
+ QImageData *imaged = image.data_ptr();
+ if (imaged->ref != 1 || imaged->ro_data) {
+ // This is bad, the imagedata got shared somehow. Detach, in order to
+ // have the next check fail and thus have 'image' recreated.
+ beginDataAccess();
+ image.detach();
+ endDataAccess(true);
+ }
+ }
+ if (bitmap && image.constBits() != reinterpret_cast<const uchar *>(bitmap->DataAddress())) {
+ // Should not ever get here. If we do it means that either 'image' has
+ // been replaced with a copy (e.g. because some QImage API assigned a
+ // new, regular QImage to *this) or the bitmap's data address changed
+ // unexpectedly.
+ qWarning("QVolatileImageData: Ptr mismatch");
+ // Recover by recreating the image so that it uses the bitmap as its buffer.
+ updateImage();
+ }
+}
+
+void QVolatileImageData::ensureBitmap()
+{
+ if (!bitmap && !image.isNull()) {
+ bitmap = imageToBitmap(image);
+ updateImage();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index 3196ba5..eb56f56 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -227,7 +227,7 @@ public:
void _q_sourceColumnsRemoved(const QModelIndex &source_parent,
int start, int end);
- void clear_mapping();
+ void _q_clearMapping();
void sort();
bool update_source_sort_column();
@@ -281,7 +281,7 @@ typedef QHash<QModelIndex, QSortFilterProxyModelPrivate::Mapping *> IndexMap;
void QSortFilterProxyModelPrivate::_q_sourceModelDestroyed()
{
QAbstractProxyModelPrivate::_q_sourceModelDestroyed();
- clear_mapping();
+ _q_clearMapping();
}
void QSortFilterProxyModelPrivate::remove_from_mapping(const QModelIndex &source_parent)
@@ -293,7 +293,7 @@ void QSortFilterProxyModelPrivate::remove_from_mapping(const QModelIndex &source
}
}
-void QSortFilterProxyModelPrivate::clear_mapping()
+void QSortFilterProxyModelPrivate::_q_clearMapping()
{
// store the persistent indexes
QModelIndexPairList source_indexes = store_persistent_indexes();
@@ -1225,7 +1225,7 @@ void QSortFilterProxyModelPrivate::_q_sourceReset()
{
Q_Q(QSortFilterProxyModel);
invalidatePersistentIndexes();
- clear_mapping();
+ _q_clearMapping();
// All internal structures are deleted in clear()
q->endResetModel();
update_source_sort_column();
@@ -1521,6 +1521,7 @@ QSortFilterProxyModel::QSortFilterProxyModel(QObject *parent)
d->filter_column = 0;
d->filter_role = Qt::DisplayRole;
d->dynamic_sortfilter = false;
+ connect(this, SIGNAL(modelReset()), this, SLOT(_q_clearMapping()));
}
/*!
@@ -1622,7 +1623,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
connect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset()));
connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset()));
- d->clear_mapping();
+ d->_q_clearMapping();
endResetModel();
if (d->update_source_sort_column() && d->dynamic_sortfilter)
d->sort();
@@ -2313,7 +2314,7 @@ void QSortFilterProxyModel::clear()
{
Q_D(QSortFilterProxyModel);
emit layoutAboutToBeChanged();
- d->clear_mapping();
+ d->_q_clearMapping();
emit layoutChanged();
}
@@ -2328,7 +2329,7 @@ void QSortFilterProxyModel::invalidate()
{
Q_D(QSortFilterProxyModel);
emit layoutAboutToBeChanged();
- d->clear_mapping();
+ d->_q_clearMapping();
emit layoutChanged();
}
diff --git a/src/gui/itemviews/qsortfilterproxymodel.h b/src/gui/itemviews/qsortfilterproxymodel.h
index 09fd20f..afeaa69 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.h
+++ b/src/gui/itemviews/qsortfilterproxymodel.h
@@ -189,6 +189,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(const QModelIndex &source_parent, int start, int end))
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end))
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_clearMapping())
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index ff2dfe7..5e8b37e 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -983,7 +983,7 @@ static int qCocoaViewCount = 0;
QString qtText;
// Cursor position is retrived from the range.
QList<QInputMethodEvent::Attribute> attrs;
- attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, selRange.location, 1, QVariant());
+ attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, selRange.location + selRange.length, 1, QVariant());
if ([aString isKindOfClass:[NSAttributedString class]]) {
qtText = QCFString::toQString(reinterpret_cast<CFStringRef>([aString string]));
composingLength = qtText.length();
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index b378b78..4bff5ac 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -1496,7 +1496,7 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
|| !QX11Info::appDefaultColormap(xinfo.screen())) {
// unknown DE or non-default visual/colormap, use 1bpp bitmap
if (!forceReset || !topData->iconPixmap)
- topData->iconPixmap = new QBitmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
+ topData->iconPixmap = new QPixmap(qt_toX11Pixmap(QBitmap(icon.pixmap(QSize(64,64)))));
pixmap_handle = topData->iconPixmap->handle();
} else {
// default depth, use a normal pixmap (even though this
diff --git a/src/gui/painting/qgraphicssystem.cpp b/src/gui/painting/qgraphicssystem.cpp
index 8d39b59..171ef46 100644
--- a/src/gui/painting/qgraphicssystem.cpp
+++ b/src/gui/painting/qgraphicssystem.cpp
@@ -89,4 +89,9 @@ QPixmapData *QGraphicsSystem::createPixmapData(QPixmapData *origin)
return createPixmapData(origin->pixelType());
}
+void QGraphicsSystem::releaseCachedResources()
+{
+ // Do nothing here
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qgraphicssystem_p.h b/src/gui/painting/qgraphicssystem_p.h
index 1aa3aa0..0f99a31 100644
--- a/src/gui/painting/qgraphicssystem_p.h
+++ b/src/gui/painting/qgraphicssystem_p.h
@@ -76,6 +76,8 @@ public:
//### Remove this & change qpixmap.cpp & qbitmap.cpp once every platform is gaurenteed
// to have a graphics system.
static QPixmapData *createDefaultPixmapData(QPixmapData::PixelType type);
+
+ virtual void releaseCachedResources();
};
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintengine_s60.cpp b/src/gui/painting/qpaintengine_s60.cpp
index 1bc7799..ca303be 100644
--- a/src/gui/painting/qpaintengine_s60.cpp
+++ b/src/gui/painting/qpaintengine_s60.cpp
@@ -41,6 +41,7 @@
#include <private/qpaintengine_s60_p.h>
#include <private/qpixmap_s60_p.h>
#include <private/qt_s60_p.h>
+#include <private/qvolatileimage_p.h>
QT_BEGIN_NAMESPACE
@@ -90,7 +91,15 @@ void QS60PaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
QRasterPaintEngine::drawPixmap(p, pm);
srcData->endDataAccess();
} else {
- QRasterPaintEngine::drawPixmap(p, pm);
+ void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
+ if (nativeData) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
+ img->beginDataAccess();
+ QRasterPaintEngine::drawImage(p, img->imageRef());
+ img->endDataAccess(true);
+ } else {
+ QRasterPaintEngine::drawPixmap(p, pm);
+ }
}
}
@@ -102,7 +111,15 @@ void QS60PaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRect
QRasterPaintEngine::drawPixmap(r, pm, sr);
srcData->endDataAccess();
} else {
- QRasterPaintEngine::drawPixmap(r, pm, sr);
+ void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
+ if (nativeData) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
+ img->beginDataAccess();
+ QRasterPaintEngine::drawImage(r, img->imageRef(), sr);
+ img->endDataAccess(true);
+ } else {
+ QRasterPaintEngine::drawPixmap(r, pm, sr);
+ }
}
}
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index 605872e..600c631 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -47,6 +47,7 @@
#include "private/qt_s60_p.h"
#include "private/qpixmap_s60_p.h"
#include "private/qcore_symbian_p.h"
+#include "private/qvolatileimage_p.h"
#include "qapplication.h"
#include "qsettings.h"
@@ -637,9 +638,22 @@ QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask
if (error)
return QPixmap();
- QPixmap pixmap = QPixmap::fromSymbianCFbsBitmap(icon);
- if (mask)
- pixmap.setAlphaChannel(QPixmap::fromSymbianCFbsBitmap(mask));
+ QPixmap pixmap;
+ QScopedPointer<QPixmapData> pd(QPixmapData::create(0, 0, QPixmapData::PixmapType));
+ bool nativeMaskSupported = (pd->toNativeType(QPixmapData::VolatileImage) != 0);
+ if (mask && nativeMaskSupported) {
+ // Efficient path, less copying and conversion.
+ QVolatileImage img(icon, mask);
+ pd->fromNativeType(&img, QPixmapData::VolatileImage);
+ pixmap = QPixmap(pd.take());
+ } else {
+ // Potentially more expensive path.
+ pd->fromNativeType(icon, QPixmapData::FbsBitmap);
+ pixmap = QPixmap(pd.take());
+ if (mask) {
+ pixmap.setAlphaChannel(QPixmap::fromSymbianCFbsBitmap(mask));
+ }
+ }
if ((flags & QS60StylePrivate::SF_PointEast) ||
(flags & QS60StylePrivate::SF_PointSouth) ||
@@ -795,6 +809,8 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size);
MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+ static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
+ static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamRGBOnly;
QPixmap result;
@@ -833,7 +849,7 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
// QS60WindowSurface::unlockBitmapHeap();
CFbsBitmap *background = new (ELeave) CFbsBitmap(); //offscreen
CleanupStack::PushL(background);
- User::LeaveIfError(background->Create(targetSize, EColor16MA));
+ User::LeaveIfError(background->Create(targetSize, displayMode));
CFbsBitmapDevice *dev = CFbsBitmapDevice::NewL(background);
CleanupStack::PushL(dev);
@@ -854,7 +870,7 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
*gc,
TPoint(),
targetSize,
- KAknsDrawParamDefault | KAknsDrawParamRGBOnly);
+ drawParam);
if (drawn)
result = fromFbsBitmap(background, NULL, flags, targetSize);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 084b7ac..64eb27a 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -139,6 +139,9 @@ bool QFontDef::exactMatch(const QFontDef &other) const
QFontDatabase::parseFontName(family, this_foundry, this_family);
QFontDatabase::parseFontName(other.family, other_foundry, other_family);
+ this_family = QFontDatabase::resolveFontFamilyAlias(this_family);
+ other_family = QFontDatabase::resolveFontFamilyAlias(other_family);
+
return (styleHint == other.styleHint
&& styleStrategy == other.styleStrategy
&& weight == other.weight
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 8e92b1a..1e94bf5 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -1087,6 +1087,12 @@ QT_BEGIN_INCLUDE_NAMESPACE
#elif defined(Q_OS_SYMBIAN)
# include "qfontdatabase_s60.cpp"
#endif
+#if !defined(Q_WS_X11)
+QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
+{
+ return family;
+}
+#endif
QT_END_INCLUDE_NAMESPACE
static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey)
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 3e9483b..ae1130e 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -152,6 +152,7 @@ public:
private:
static void createDatabase();
static void parseFontName(const QString &name, QString &foundry, QString &family);
+ static QString resolveFontFamilyAlias(const QString &family);
#if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request);
#endif
diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp
index f923d87..02b0148 100644
--- a/src/gui/text/qfontdatabase_x11.cpp
+++ b/src/gui/text/qfontdatabase_x11.cpp
@@ -2120,4 +2120,26 @@ bool QFontDatabase::supportsThreadedFontRendering()
#endif
}
+QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
+{
+#if defined(QT_NO_FONTCONFIG)
+ return family;
+#else
+ FcPattern *pattern = FcPatternCreate();
+ if (!pattern)
+ return family;
+
+ FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) family.toUtf8().data());
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+
+ FcChar8 *familyAfterSubstitution;
+ FcPatternGetString(pattern, FC_FAMILY, 0, &familyAfterSubstitution);
+ QString resolved = QString::fromUtf8((const char *) familyAfterSubstitution);
+ FcPatternDestroy(pattern);
+
+ return resolved;
+#endif
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index 46f1d62..c847bb5 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -285,7 +285,7 @@ bool QTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
if (cursor.position() != oldCursorPos)
emit q->cursorPositionChanged();
emit q->microFocusChanged();
- } else if (ignoreNavigationEvents && isNavigationEvent) {
+ } else if (ignoreNavigationEvents && isNavigationEvent && oldSelection.anchor() == cursor.anchor()) {
return false;
}
@@ -1650,8 +1650,10 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
emit q->cursorPositionChanged();
_q_updateCurrentCharFormatAndSelection();
#ifndef QT_NO_IM
- if (QInputContext *ic = inputContext()) {
- ic->update();
+ if (contextWidget) {
+ if (QInputContext *ic = inputContext()) {
+ ic->update();
+ }
}
#endif //QT_NO_IM
} else {
diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp
index c0a1e64..97e8c5b 100644
--- a/src/gui/text/qtextengine_mac.cpp
+++ b/src/gui/text/qtextengine_mac.cpp
@@ -607,8 +607,9 @@ void QTextEngine::shapeTextMac(int item) const
bool stringToCMapFailed = false;
if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
ensureSpace(num_glyphs);
- stringToCMapFailed = fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
- attributes());
+ g = availableGlyphs(&si);
+ stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
+ attributes());
}
if (!stringToCMapFailed) {
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index 023b9ee..f20e018 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -420,7 +420,7 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
int c = m_cursor; // cursor position after insertion of commit string
if (event->replacementStart() <= 0)
- c += event->commitString().length() + qMin(-event->replacementStart(), event->replacementLength());
+ c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength());
m_cursor += event->replacementStart();
diff --git a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp
index d5726c1..9fe01bf 100644
--- a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp
+++ b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp
@@ -365,7 +365,7 @@ void QDeclarativeFolderListModel::refresh()
{
d->folderIndex = QModelIndex();
if (d->count) {
- emit beginRemoveRows(QModelIndex(), 0, d->count);
+ emit beginRemoveRows(QModelIndex(), 0, d->count-1);
d->count = 0;
emit endRemoveRows();
}
diff --git a/src/imports/gestures/qdeclarativegesturearea.cpp b/src/imports/gestures/qdeclarativegesturearea.cpp
index 1b6e723..c2a2e98 100644
--- a/src/imports/gestures/qdeclarativegesturearea.cpp
+++ b/src/imports/gestures/qdeclarativegesturearea.cpp
@@ -89,6 +89,10 @@ public:
\warning Elements in the Qt.labs module are not guaranteed to remain compatible
in future versions.
+ \warning GestureArea is an experimental element whose development has
+ been discontinued. PinchArea is available in QtQuick 1.1 and handles
+ two finger gesture input.
+
\note This element is only functional on devices with touch input.
\qml
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index 7497c1a..57a79b3 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -33,7 +33,8 @@ HEADERS += \
access/qabstractnetworkcache_p.h \
access/qabstractnetworkcache.h \
access/qnetworkdiskcache_p.h \
- access/qnetworkdiskcache.h
+ access/qnetworkdiskcache.h \
+ access/qhttpthreaddelegate_p.h
SOURCES += \
access/qftp.cpp \
@@ -60,6 +61,7 @@ SOURCES += \
access/qnetworkreplydataimpl.cpp \
access/qnetworkreplyfileimpl.cpp \
access/qabstractnetworkcache.cpp \
- access/qnetworkdiskcache.cpp
+ access/qnetworkdiskcache.cpp \
+ access/qhttpthreaddelegate.cpp
include($$PWD/../../3rdparty/zlib_dependency.pri)
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index e94b099..3502113 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -286,7 +286,13 @@ void QHttpNetworkConnectionPrivate::emitReplyError(QAbstractSocket *socket,
int i = indexOf(socket);
// remove the corrupt data if any
reply->d_func()->eraseData();
+
+ // Clean the channel
channels[i].close();
+ channels[i].reply = 0;
+ channels[i].request = QHttpNetworkRequest();
+ channels[i].requeueCurrentlyPipelinedRequests();
+
// send the next request
QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
}
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 079f608..41bc64a 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -253,7 +253,7 @@ bool QHttpNetworkConnectionChannel::sendRequest()
#endif
{
// get pointer to upload data
- qint64 currentReadSize;
+ qint64 currentReadSize = 0;
qint64 desiredReadSize = qMin(socketWriteMaxSize, bytesTotal - written);
const char *readPointer = uploadByteDevice->readPointer(desiredReadSize, currentReadSize);
@@ -476,7 +476,8 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
}
#ifndef QT_NO_COMPRESS
else if (!expand(false)) { // expand a chunk if possible
- return; // ### expand failed
+ // If expand() failed we can just return, it had already called connection->emitReplyError()
+ return;
}
#endif
}
@@ -645,28 +646,38 @@ void QHttpNetworkConnectionChannel::allDone()
{
#ifndef QT_NO_COMPRESS
// expand the whole data.
- if (reply->d_func()->expectContent() && reply->d_func()->autoDecompress && !reply->d_func()->streamEnd)
- expand(true); // ### if expand returns false, its an error
+ if (reply->d_func()->expectContent() && reply->d_func()->autoDecompress && !reply->d_func()->streamEnd) {
+ bool expandResult = expand(true);
+ // If expand() failed we can just return, it had already called connection->emitReplyError()
+ if (!expandResult)
+ return;
+ }
#endif
+
+ if (!reply) {
+ qWarning() << "QHttpNetworkConnectionChannel::allDone() called without reply. Please report at http://bugreports.qt.nokia.com/";
+ return;
+ }
+
// while handling 401 & 407, we might reset the status code, so save this.
bool emitFinished = reply->d_func()->shouldEmitSignals();
- handleStatus();
- // ### at this point there should be no more data on the socket
- // close if server requested
bool connectionCloseEnabled = reply->d_func()->isConnectionCloseEnabled();
- if (connectionCloseEnabled)
- close();
+ detectPipeliningSupport();
+
+ handleStatus();
+ // handleStatus() might have removed the reply because it already called connection->emitReplyError()
+
// queue the finished signal, this is required since we might send new requests from
// slot connected to it. The socket will not fire readyRead signal, if we are already
// in the slot connected to readyRead
- if (emitFinished)
+ if (reply && emitFinished)
QMetaObject::invokeMethod(reply, "finished", Qt::QueuedConnection);
+
+
// reset the reconnection attempts after we receive a complete reply.
// in case of failures, each channel will attempt two reconnects before emitting error.
reconnectAttempts = 2;
- detectPipeliningSupport();
-
// now the channel can be seen as free/idle again, all signal emissions for the reply have been done
this->state = QHttpNetworkConnectionChannel::IdleState;
@@ -717,6 +728,8 @@ void QHttpNetworkConnectionChannel::allDone()
// leading whitespace.
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
} else if (alreadyPipelinedRequests.isEmpty()) {
+ if (connectionCloseEnabled)
+ close();
if (qobject_cast<QHttpNetworkConnection*>(connection))
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 7f6b71f..704cf3a 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -177,6 +177,12 @@ qint64 QHttpNetworkReply::bytesAvailableNextBlock() const
return -1;
}
+bool QHttpNetworkReply::readAnyAvailable() const
+{
+ Q_D(const QHttpNetworkReply);
+ return (d->responseData.bufferCount() > 0);
+}
+
QByteArray QHttpNetworkReply::readAny()
{
Q_D(QHttpNetworkReply);
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index 1856d7a..cc0f671 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -125,6 +125,7 @@ public:
qint64 bytesAvailable() const;
qint64 bytesAvailableNextBlock() const;
+ bool readAnyAvailable() const;
QByteArray readAny();
QByteArray readAll();
void setDownstreamLimited(bool t);
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
new file mode 100644
index 0000000..b5cf00a
--- /dev/null
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -0,0 +1,518 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 "qhttpthreaddelegate_p.h"
+
+#include <QThread>
+#include <QTimer>
+#include <QAuthenticator>
+#include <QEventLoop>
+
+#include "private/qhttpnetworkreply_p.h"
+#include "private/qnetworkaccesscache_p.h"
+#include "private/qnoncontiguousbytedevice_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const QUrl &url)
+{
+ QNetworkReply::NetworkError code;
+ // we've got an error
+ switch (httpStatusCode) {
+ case 401: // Authorization required
+ code = QNetworkReply::AuthenticationRequiredError;
+ break;
+
+ case 403: // Access denied
+ code = QNetworkReply::ContentOperationNotPermittedError;
+ break;
+
+ case 404: // Not Found
+ code = QNetworkReply::ContentNotFoundError;
+ break;
+
+ case 405: // Method Not Allowed
+ code = QNetworkReply::ContentOperationNotPermittedError;
+ break;
+
+ case 407:
+ code = QNetworkReply::ProxyAuthenticationRequiredError;
+ break;
+
+ default:
+ if (httpStatusCode > 500) {
+ // some kind of server error
+ code = QNetworkReply::ProtocolUnknownError;
+ } else if (httpStatusCode >= 400) {
+ // content error we did not handle above
+ code = QNetworkReply::UnknownContentError;
+ } else {
+ qWarning("QNetworkAccess: got HTTP status code %d which is not expected from url: \"%s\"",
+ httpStatusCode, qPrintable(url.toString()));
+ code = QNetworkReply::ProtocolFailure;
+ }
+ }
+
+ return code;
+}
+
+
+static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
+{
+ QByteArray result;
+ QUrl copy = url;
+ bool isEncrypted = copy.scheme().toLower() == QLatin1String("https");
+ copy.setPort(copy.port(isEncrypted ? 443 : 80));
+ result = copy.toEncoded(QUrl::RemoveUserInfo | QUrl::RemovePath |
+ QUrl::RemoveQuery | QUrl::RemoveFragment);
+
+#ifndef QT_NO_NETWORKPROXY
+ if (proxy && proxy->type() != QNetworkProxy::NoProxy) {
+ QUrl key;
+
+ switch (proxy->type()) {
+ case QNetworkProxy::Socks5Proxy:
+ key.setScheme(QLatin1String("proxy-socks5"));
+ break;
+
+ case QNetworkProxy::HttpProxy:
+ case QNetworkProxy::HttpCachingProxy:
+ key.setScheme(QLatin1String("proxy-http"));
+ break;
+
+ default:
+ break;
+ }
+
+ if (!key.scheme().isEmpty()) {
+ key.setUserName(proxy->user());
+ key.setHost(proxy->hostName());
+ key.setPort(proxy->port());
+ key.setEncodedQuery(result);
+ result = key.toEncoded();
+ }
+ }
+#endif
+
+ return "http-connection:" + result;
+}
+
+class QNetworkAccessCachedHttpConnection: public QHttpNetworkConnection,
+ public QNetworkAccessCache::CacheableObject
+{
+ // Q_OBJECT
+public:
+ QNetworkAccessCachedHttpConnection(const QString &hostName, quint16 port, bool encrypt)
+ : QHttpNetworkConnection(hostName, port, encrypt)
+ {
+ setExpires(true);
+ setShareable(true);
+ }
+
+ virtual void dispose()
+ {
+#if 0 // sample code; do this right with the API
+ Q_ASSERT(!isWorking());
+#endif
+ delete this;
+ }
+};
+
+
+QThreadStorage<QNetworkAccessCache *> QHttpThreadDelegate::connections;
+
+
+QHttpThreadDelegate::~QHttpThreadDelegate()
+{
+ // It could be that the main thread has asked us to shut down, so we need to delete the HTTP reply
+ if (httpReply) {
+ delete httpReply;
+ }
+
+ // Get the object cache that stores our QHttpNetworkConnection objects
+ // and release the entry for this QHttpNetworkConnection
+ if (connections.hasLocalData() && !cacheKey.isEmpty()) {
+ connections.localData()->releaseEntry(cacheKey);
+ }
+}
+
+
+QHttpThreadDelegate::QHttpThreadDelegate(QObject *parent) :
+ QObject(parent)
+ , ssl(false)
+ , downloadBufferMaximumSize(0)
+ , pendingDownloadData(0)
+ , pendingDownloadProgress(0)
+ , synchronous(false)
+ , incomingStatusCode(0)
+ , isPipeliningUsed(false)
+ , incomingContentLength(-1)
+ , incomingErrorCode(QNetworkReply::NoError)
+ , downloadBuffer(0)
+ , httpConnection(0)
+ , httpReply(0)
+{
+}
+
+// This is invoked as BlockingQueuedConnection from QNetworkAccessHttpBackend in the user thread
+void QHttpThreadDelegate::startRequestSynchronously()
+{
+ synchronous = true;
+
+ QEventLoop synchronousRequestLoop;
+ this->synchronousRequestLoop = &synchronousRequestLoop;
+
+ // Worst case timeout
+ QTimer::singleShot(30*1000, this, SLOT(abortRequest()));
+
+ QMetaObject::invokeMethod(this, "startRequest", Qt::QueuedConnection);
+ synchronousRequestLoop.exec();
+
+ connections.localData()->releaseEntry(cacheKey);
+ connections.setLocalData(0);
+
+}
+
+
+// This is invoked as QueuedConnection from QNetworkAccessHttpBackend in the user thread
+void QHttpThreadDelegate::startRequest()
+{
+ // Check QThreadStorage for the QNetworkAccessCache
+ // If not there, create this connection cache
+ if (!connections.hasLocalData()) {
+ connections.setLocalData(new QNetworkAccessCache());
+ }
+
+ // check if we have an open connection to this host
+ QUrl urlCopy = httpRequest.url();
+ urlCopy.setPort(urlCopy.port(ssl ? 443 : 80));
+
+ if (transparentProxy.type() != QNetworkProxy::NoProxy)
+ cacheKey = makeCacheKey(urlCopy, &transparentProxy);
+ else if (cacheProxy.type() != QNetworkProxy::NoProxy)
+ cacheKey = makeCacheKey(urlCopy, &cacheProxy);
+ else
+ cacheKey = makeCacheKey(urlCopy, 0);
+
+
+ // the http object is actually a QHttpNetworkConnection
+ httpConnection = static_cast<QNetworkAccessCachedHttpConnection *>(connections.localData()->requestEntryNow(cacheKey));
+ if (httpConnection == 0) {
+ // no entry in cache; create an object
+ // the http object is actually a QHttpNetworkConnection
+ httpConnection = new QNetworkAccessCachedHttpConnection(urlCopy.host(), urlCopy.port(), ssl);
+#ifndef QT_NO_OPENSSL
+ // Set the QSslConfiguration from this QNetworkRequest.
+ if (ssl) {
+ httpConnection->setSslConfiguration(incomingSslConfiguration);
+ }
+#endif
+
+#ifndef QT_NO_NETWORKPROXY
+ httpConnection->setTransparentProxy(transparentProxy);
+ httpConnection->setCacheProxy(cacheProxy);
+#endif
+
+ // cache the QHttpNetworkConnection corresponding to this cache key
+ connections.localData()->addEntry(cacheKey, httpConnection);
+ }
+
+
+ // Send the request to the connection
+ httpReply = httpConnection->sendRequest(httpRequest);
+ httpReply->setParent(this);
+
+ // Connect the reply signals that we need to handle and then forward
+ if (synchronous) {
+ connect(httpReply,SIGNAL(headerChanged()), this, SLOT(synchronousHeaderChangedSlot()));
+ connect(httpReply,SIGNAL(finished()), this, SLOT(synchronousFinishedSlot()));
+ connect(httpReply,SIGNAL(finishedWithError(QNetworkReply::NetworkError, const QString)),
+ this, SLOT(synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError,QString)));
+
+ connect(httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
+ this, SLOT(synchronousAuthenticationRequiredSlot(QHttpNetworkRequest,QAuthenticator*)));
+ connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
+ this, SLOT(synchronousProxyAuthenticationRequiredSlot(QNetworkProxy,QAuthenticator*)));
+
+ // Don't care about ignored SSL errors for now in the synchronous HTTP case.
+ } else if (!synchronous) {
+ connect(httpReply,SIGNAL(headerChanged()), this, SLOT(headerChangedSlot()));
+ connect(httpReply,SIGNAL(finished()), this, SLOT(finishedSlot()));
+ connect(httpReply,SIGNAL(finishedWithError(QNetworkReply::NetworkError, const QString)),
+ this, SLOT(finishedWithErrorSlot(QNetworkReply::NetworkError,QString)));
+ // some signals are only interesting when normal asynchronous style is used
+ connect(httpReply,SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
+ connect(httpReply,SIGNAL(dataReadProgress(int, int)), this, SLOT(dataReadProgressSlot(int,int)));
+ connect(httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)),
+ this, SLOT(cacheCredentialsSlot(QHttpNetworkRequest,QAuthenticator*)));
+#ifndef QT_NO_OPENSSL
+ connect(httpReply,SIGNAL(sslErrors(const QList<QSslError>)), this, SLOT(sslErrorsSlot(QList<QSslError>)));
+#endif
+
+ // In the asynchronous HTTP case we can just forward those signals
+ // Connect the reply signals that we can directly forward
+ connect(httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
+ this, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)));
+ connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
+ this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
+ }
+}
+
+// This gets called from the user thread or by the synchronous HTTP timeout timer
+void QHttpThreadDelegate::abortRequest()
+{
+ if (httpReply) {
+ delete httpReply;
+ httpReply = 0;
+ this->deleteLater();
+ }
+
+ // Got aborted by the timeout timer
+ if (synchronous)
+ incomingErrorCode = QNetworkReply::TimeoutError;
+}
+
+void QHttpThreadDelegate::readyReadSlot()
+{
+ // Don't do in zerocopy case
+ if (!downloadBuffer.isNull())
+ return;
+
+ while (httpReply->readAnyAvailable()) {
+ pendingDownloadData->fetchAndAddRelease(1);
+ emit downloadData(httpReply->readAny());
+ }
+}
+
+void QHttpThreadDelegate::finishedSlot()
+{
+ if (!httpReply) {
+ qWarning() << "QHttpThreadDelegate::finishedSlot: HTTP reply had already been deleted, internal problem. Please report.";
+ return;
+ }
+
+ // If there is still some data left emit that now
+ while (httpReply->readAnyAvailable()) {
+ pendingDownloadData->fetchAndAddRelease(1);
+ emit downloadData(httpReply->readAny());
+ }
+
+#ifndef QT_NO_OPENSSL
+ if (ssl)
+ emit sslConfigurationChanged(httpReply->sslConfiguration());
+#endif
+
+ if (httpReply->statusCode() >= 400) {
+ // it's an error reply
+ QString msg = QLatin1String(QT_TRANSLATE_NOOP("QNetworkReply",
+ "Error downloading %1 - server replied: %2"));
+ msg = msg.arg(QString::fromAscii(httpRequest.url().toEncoded()), httpReply->reasonPhrase());
+ emit error(statusCodeFromHttp(httpReply->statusCode(), httpRequest.url()), msg);
+ }
+
+ emit downloadFinished();
+
+ QMetaObject::invokeMethod(httpReply, "deleteLater", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection);
+ httpReply = 0;
+}
+
+void QHttpThreadDelegate::synchronousFinishedSlot()
+{
+ if (httpReply->statusCode() >= 400) {
+ // it's an error reply
+ QString msg = QLatin1String(QT_TRANSLATE_NOOP("QNetworkReply",
+ "Error downloading %1 - server replied: %2"));
+ incomingErrorDetail = msg.arg(QString::fromAscii(httpRequest.url().toEncoded()), httpReply->reasonPhrase());
+ incomingErrorCode = statusCodeFromHttp(httpReply->statusCode(), httpRequest.url());
+ }
+
+ synchronousDownloadData = httpReply->readAll();
+
+ QMetaObject::invokeMethod(httpReply, "deleteLater", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(synchronousRequestLoop, "quit", Qt::QueuedConnection);
+ httpReply = 0;
+}
+
+void QHttpThreadDelegate::finishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail)
+{
+ if (!httpReply) {
+ qWarning() << "QHttpThreadDelegate::finishedWithErrorSlot: HTTP reply had already been deleted, internal problem. Please report.";
+ return;
+ }
+
+#ifndef QT_NO_OPENSSL
+ if (ssl)
+ emit sslConfigurationChanged(httpReply->sslConfiguration());
+#endif
+ emit error(errorCode,detail);
+ emit downloadFinished();
+
+
+ QMetaObject::invokeMethod(httpReply, "deleteLater", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection);
+ httpReply = 0;
+}
+
+
+void QHttpThreadDelegate::synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail)
+{
+ incomingErrorCode = errorCode;
+ incomingErrorDetail = detail;
+
+ QMetaObject::invokeMethod(httpReply, "deleteLater", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(synchronousRequestLoop, "quit", Qt::QueuedConnection);
+ httpReply = 0;
+}
+
+static void downloadBufferDeleter(char *ptr)
+{
+ delete[] ptr;
+}
+
+void QHttpThreadDelegate::headerChangedSlot()
+{
+#ifndef QT_NO_OPENSSL
+ if (ssl)
+ emit sslConfigurationChanged(httpReply->sslConfiguration());
+#endif
+
+ // Is using a zerocopy buffer allowed by user and possible with this reply?
+ if (httpReply->supportsUserProvidedDownloadBuffer()
+ && downloadBufferMaximumSize > 0) {
+ char *buf = new char[httpReply->contentLength()]; // throws if allocation fails
+ if (buf) {
+ downloadBuffer = QSharedPointer<char>(buf, downloadBufferDeleter);
+ httpReply->setUserProvidedDownloadBuffer(buf);
+ }
+ }
+
+ // We fetch this into our own
+ incomingHeaders = httpReply->header();
+ incomingStatusCode = httpReply->statusCode();
+ incomingReasonPhrase = httpReply->reasonPhrase();
+ isPipeliningUsed = httpReply->isPipeliningUsed();
+ incomingContentLength = httpReply->contentLength();
+
+ emit downloadMetaData(incomingHeaders,
+ incomingStatusCode,
+ incomingReasonPhrase,
+ isPipeliningUsed,
+ downloadBuffer,
+ incomingContentLength);
+}
+
+void QHttpThreadDelegate::synchronousHeaderChangedSlot()
+{
+ // Store the information we need in this object, the QNetworkAccessHttpBackend will later read it
+ incomingHeaders = httpReply->header();
+ incomingStatusCode = httpReply->statusCode();
+ incomingReasonPhrase = httpReply->reasonPhrase();
+ isPipeliningUsed = httpReply->isPipeliningUsed();
+ incomingContentLength = httpReply->contentLength();
+}
+
+
+void QHttpThreadDelegate::dataReadProgressSlot(int done, int total)
+{
+ // If we don't have a download buffer don't attempt to go this codepath
+ // It is not used by QNetworkAccessHttpBackend
+ if (downloadBuffer.isNull())
+ return;
+
+ pendingDownloadProgress->fetchAndAddRelease(1);
+ emit downloadProgress(done, total);
+}
+
+void QHttpThreadDelegate::cacheCredentialsSlot(const QHttpNetworkRequest &request, QAuthenticator *authenticator)
+{
+ authenticationManager->cacheCredentials(request.url(), authenticator);
+}
+
+
+#ifndef QT_NO_OPENSSL
+void QHttpThreadDelegate::sslErrorsSlot(const QList<QSslError> &errors)
+{
+ emit sslConfigurationChanged(httpReply->sslConfiguration());
+
+ bool ignoreAll = false;
+ QList<QSslError> specificErrors;
+ emit sslErrors(errors, &ignoreAll, &specificErrors);
+ if (ignoreAll)
+ httpReply->ignoreSslErrors();
+ if (!specificErrors.isEmpty())
+ httpReply->ignoreSslErrors(specificErrors);
+}
+#endif
+
+void QHttpThreadDelegate::synchronousAuthenticationRequiredSlot(const QHttpNetworkRequest &request, QAuthenticator *a)
+{
+ Q_UNUSED(request);
+
+ // Ask the credential cache
+ QNetworkAuthenticationCredential credential = authenticationManager->fetchCachedCredentials(httpRequest.url(), a);
+ if (!credential.isNull()) {
+ a->setUser(credential.user);
+ a->setPassword(credential.password);
+ }
+
+ // Disconnect this connection now since we only want to ask the authentication cache once.
+ QObject::disconnect(this, SLOT(synchronousAuthenticationRequiredSlot(QHttpNetworkRequest,QAuthenticator*)));
+}
+
+#ifndef QT_NO_NETWORKPROXY
+void QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot(const QNetworkProxy &p, QAuthenticator *a)
+{
+ // Ask the credential cache
+ QNetworkAuthenticationCredential credential = authenticationManager->fetchCachedProxyCredentials(p, a);
+ if (!credential.isNull()) {
+ a->setUser(credential.user);
+ a->setPassword(credential.password);
+ }
+
+ // Disconnect this connection now since we only want to ask the authentication cache once.
+ QObject::disconnect(this, SLOT(synchronousProxyAuthenticationRequiredSlot(QNetworkProxy,QAuthenticator*)));
+}
+
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h
new file mode 100644
index 0000000..086a35d
--- /dev/null
+++ b/src/network/access/qhttpthreaddelegate_p.h
@@ -0,0 +1,285 @@
+/****************************************************************************
+**
+** 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 QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 QHTTPTHREADDELEGATE_H
+#define QHTTPTHREADDELEGATE_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Network Access API. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QObject>
+#include <QThreadStorage>
+#include <QNetworkProxy>
+#include <QSslConfiguration>
+#include <QSslError>
+#include <QList>
+#include <QNetworkReply>
+#include "qhttpnetworkrequest_p.h"
+#include "qhttpnetworkconnection_p.h"
+#include <QSharedPointer>
+#include "qsslconfiguration.h"
+#include "private/qnoncontiguousbytedevice_p.h"
+#include "qnetworkaccessauthenticationmanager_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAuthenticator;
+class QHttpNetworkReply;
+class QEventLoop;
+class QNetworkAccessCache;
+class QNetworkAccessCachedHttpConnection;
+
+class QHttpThreadDelegate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QHttpThreadDelegate(QObject *parent = 0);
+
+ ~QHttpThreadDelegate();
+
+ // incoming
+ bool ssl;
+#ifndef QT_NO_OPENSSL
+ QSslConfiguration incomingSslConfiguration;
+#endif
+ QHttpNetworkRequest httpRequest;
+ qint64 downloadBufferMaximumSize;
+ // From backend, modified by us for signal compression
+ QSharedPointer<QAtomicInt> pendingDownloadData;
+ QSharedPointer<QAtomicInt> pendingDownloadProgress;
+#ifndef QT_NO_NETWORKPROXY
+ QNetworkProxy cacheProxy;
+ QNetworkProxy transparentProxy;
+#endif
+ QSharedPointer<QNetworkAccessAuthenticationManager> authenticationManager;
+ bool synchronous;
+
+ // outgoing, Retrieved in the synchronous HTTP case
+ QByteArray synchronousDownloadData;
+ QList<QPair<QByteArray,QByteArray> > incomingHeaders;
+ int incomingStatusCode;
+ QString incomingReasonPhrase;
+ bool isPipeliningUsed;
+ qint64 incomingContentLength;
+ QNetworkReply::NetworkError incomingErrorCode;
+ QString incomingErrorDetail;
+
+protected:
+ // The zerocopy download buffer, if used:
+ QSharedPointer<char> downloadBuffer;
+ // The QHttpNetworkConnection that is used
+ QNetworkAccessCachedHttpConnection *httpConnection;
+ QByteArray cacheKey;
+ QHttpNetworkReply *httpReply;
+
+ // Used for implementing the synchronous HTTP, see startRequestSynchronously()
+ QEventLoop *synchronousRequestLoop;
+
+signals:
+ void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *);
+#ifndef QT_NO_NETWORKPROXY
+ void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
+#endif
+#ifndef QT_NO_OPENSSL
+ void sslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
+ void sslConfigurationChanged(const QSslConfiguration);
+#endif
+ void downloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64);
+ void downloadProgress(qint64, qint64);
+ void downloadData(QByteArray);
+ void error(QNetworkReply::NetworkError, const QString);
+ void downloadFinished();
+public slots:
+ // This are called via QueuedConnection from user thread
+ void startRequest();
+ void abortRequest();
+ // This is called with a BlockingQueuedConnection from user thread
+ void startRequestSynchronously();
+protected slots:
+ // From QHttp*
+ void readyReadSlot();
+ void finishedSlot();
+ void finishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
+ void synchronousFinishedSlot();
+ void synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
+ void headerChangedSlot();
+ void synchronousHeaderChangedSlot();
+ void dataReadProgressSlot(int done, int total);
+ void cacheCredentialsSlot(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
+#ifndef QT_NO_OPENSSL
+ void sslErrorsSlot(const QList<QSslError> &errors);
+#endif
+
+ void synchronousAuthenticationRequiredSlot(const QHttpNetworkRequest &request, QAuthenticator *);
+#ifndef QT_NO_NETWORKPROXY
+ void synchronousProxyAuthenticationRequiredSlot(const QNetworkProxy &, QAuthenticator *);
+#endif
+
+protected:
+ // Cache for all the QHttpNetworkConnection objects.
+ // This is per thread.
+ static QThreadStorage<QNetworkAccessCache *> connections;
+
+};
+
+// This QNonContiguousByteDevice is connected to the QNetworkAccessHttpBackend
+// and represents the PUT/POST data.
+class QNonContiguousByteDeviceThreadForwardImpl : public QNonContiguousByteDevice
+{
+ Q_OBJECT
+protected:
+ bool wantDataPending;
+ qint64 m_amount;
+ char *m_data;
+ QByteArray m_dataArray;
+ bool m_atEnd;
+ qint64 m_size;
+public:
+ QNonContiguousByteDeviceThreadForwardImpl(bool aE, qint64 s)
+ : QNonContiguousByteDevice(),
+ wantDataPending(false),
+ m_amount(0),
+ m_data(0),
+ m_atEnd(aE),
+ m_size(s)
+ {
+ }
+
+ ~QNonContiguousByteDeviceThreadForwardImpl()
+ {
+ }
+
+ const char* readPointer(qint64 maximumLength, qint64 &len)
+ {
+ if (m_amount == 0 && wantDataPending == false) {
+ len = 0;
+ wantDataPending = true;
+ emit wantData(maximumLength);
+ } else if (m_amount == 0 && wantDataPending == true) {
+ // Do nothing, we already sent a wantData signal and wait for results
+ len = 0;
+ } else if (m_amount > 0) {
+ len = m_amount;
+ return m_data;
+ }
+ // cannot happen
+ return 0;
+ }
+
+ bool advanceReadPointer(qint64 a)
+ {
+ if (m_data == 0)
+ return false;
+
+ m_amount -= a;
+ m_data += a;
+
+ // To main thread to inform about our state
+ emit processedData(a);
+
+ // FIXME possible optimization, already ask user thread for some data
+
+ return true;
+ }
+
+ bool atEnd()
+ {
+ if (m_amount > 0)
+ return false;
+ else
+ return m_atEnd;
+ }
+
+ bool reset()
+ {
+ m_amount = 0;
+ m_data = 0;
+
+ // Communicate as BlockingQueuedConnection
+ bool b = false;
+ emit resetData(&b);
+ return b;
+ }
+
+ qint64 size()
+ {
+ return m_size;
+ }
+
+public slots:
+ // From user thread:
+ void haveDataSlot(QByteArray dataArray, bool dataAtEnd, qint64 dataSize)
+ {
+ wantDataPending = false;
+
+ m_dataArray = dataArray;
+ m_data = const_cast<char*>(m_dataArray.constData());
+ m_amount = dataArray.size();
+
+ m_atEnd = dataAtEnd;
+ m_size = dataSize;
+
+ // This will tell the HTTP code (QHttpNetworkConnectionChannel) that we have data available now
+ emit readyRead();
+ }
+
+signals:
+ // void readyRead(); in parent class
+ // void readProgress(qint64 current, qint64 total); happens in the main thread with the real bytedevice
+
+ // to main thread:
+ void wantData(qint64);
+ void processedData(qint64);
+ void resetData(bool *b);
+};
+
+QT_END_NAMESPACE
+
+#endif // QHTTPTHREADDELEGATE_H
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index 53ae29e..5aedac9 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -106,12 +106,10 @@ QNetworkAccessBackend *QNetworkAccessManagerPrivate::findBackend(QNetworkAccessM
QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
{
- QNonContiguousByteDevice* device = 0;
-
if (reply->outgoingDataBuffer)
- device = QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer);
+ uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer));
else if (reply->outgoingData) {
- device = QNonContiguousByteDeviceFactory::create(reply->outgoingData);
+ uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(reply->outgoingData));
} else {
return 0;
}
@@ -120,14 +118,13 @@ QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
reply->request.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute,
QVariant(false)) == QVariant(true);
if (bufferDisallowed)
- device->disableReset();
-
- // make sure we delete this later
- device->setParent(this);
+ uploadByteDevice->disableReset();
- connect(device, SIGNAL(readProgress(qint64,qint64)), this, SLOT(emitReplyUploadProgress(qint64,qint64)));
+ // We want signal emissions only for normal asynchronous uploads
+ if (!isSynchronous())
+ connect(uploadByteDevice.data(), SIGNAL(readProgress(qint64,qint64)), this, SLOT(emitReplyUploadProgress(qint64,qint64)));
- return device;
+ return uploadByteDevice.data();
}
// need to have this function since the reply is a private member variable
@@ -327,11 +324,6 @@ void QNetworkAccessBackend::authenticationRequired(QAuthenticator *authenticator
manager->authenticationRequired(this, authenticator);
}
-void QNetworkAccessBackend::cacheCredentials(QAuthenticator *authenticator)
-{
- manager->authenticationManager->cacheCredentials(this->reply->url, authenticator);
-}
-
void QNetworkAccessBackend::metaDataChanged()
{
reply->metaDataChanged();
diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h
index 26ee61a..644ae2d 100644
--- a/src/network/access/qnetworkaccessbackend_p.h
+++ b/src/network/access/qnetworkaccessbackend_p.h
@@ -70,7 +70,6 @@ class QNetworkAccessManagerPrivate;
class QNetworkReplyImplPrivate;
class QAbstractNetworkCache;
class QNetworkCacheMetaData;
-class QNetworkAccessBackendUploadIODevice;
class QNonContiguousByteDevice;
// Should support direct file upload from disk or download to disk.
@@ -175,7 +174,6 @@ protected:
// Create the device used for reading the upload data
QNonContiguousByteDevice* createUploadByteDevice();
-
// these functions control the downstream mechanism
// that is, data that has come via the connection and is going out the backend
qint64 nextDownstreamBlockSize() const;
@@ -185,6 +183,8 @@ protected:
void writeDownstreamDataDownloadBuffer(qint64, qint64);
char* getDownloadBuffer(qint64);
+ QSharedPointer<QNonContiguousByteDevice> uploadByteDevice;
+
public slots:
// for task 251801, needs to be a slot to be called asynchronously
void writeDownstreamData(QIODevice *data);
@@ -196,19 +196,22 @@ protected slots:
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth);
#endif
void authenticationRequired(QAuthenticator *auth);
- void cacheCredentials(QAuthenticator *auth);
void metaDataChanged();
void redirectionRequested(const QUrl &destination);
void sslErrors(const QList<QSslError> &errors);
void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal);
+protected:
+ // FIXME In the long run we should get rid of our QNAM architecture
+ // and scrap this ReplyImpl/Backend distinction.
+ QNetworkAccessManagerPrivate *manager;
+ QNetworkReplyImplPrivate *reply;
+
private:
friend class QNetworkAccessManager;
friend class QNetworkAccessManagerPrivate;
- friend class QNetworkAccessBackendUploadIODevice;
friend class QNetworkReplyImplPrivate;
- QNetworkAccessManagerPrivate *manager;
- QNetworkReplyImplPrivate *reply;
+
bool synchronous;
};
diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp
index 6da0722..7ebf626 100644
--- a/src/network/access/qnetworkaccessfilebackend.cpp
+++ b/src/network/access/qnetworkaccessfilebackend.cpp
@@ -75,6 +75,8 @@ QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op,
//
// this construct here must match the one below in open()
QFileInfo fi(url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery));
+ if ((url.scheme().length()==1) && fi.exists())
+ qWarning("QNetworkAccessFileBackendFactory: URL has no schema set, use file:// for files");
if (fi.exists() || (op == QNetworkAccessManager::PutOperation && fi.dir().exists()))
return new QNetworkAccessFileBackend;
}
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index 79c43fa..4908e0a 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -52,60 +52,19 @@
#include "QtCore/qdatetime.h"
#include "QtCore/qelapsedtimer.h"
#include "QtNetwork/qsslconfiguration.h"
+#include "qhttpthreaddelegate_p.h"
+#include "qthread.h"
#ifndef QT_NO_HTTP
#include <string.h> // for strchr
-QT_BEGIN_NAMESPACE
+Q_DECLARE_METATYPE(QSharedPointer<char>)
-enum {
- DefaultHttpPort = 80,
- DefaultHttpsPort = 443
-};
+QT_BEGIN_NAMESPACE
class QNetworkProxy;
-static QByteArray makeCacheKey(QNetworkAccessHttpBackend *backend, QNetworkProxy *proxy)
-{
- QByteArray result;
- QUrl copy = backend->url();
- bool isEncrypted = copy.scheme().toLower() == QLatin1String("https");
- copy.setPort(copy.port(isEncrypted ? DefaultHttpsPort : DefaultHttpPort));
- result = copy.toEncoded(QUrl::RemoveUserInfo | QUrl::RemovePath |
- QUrl::RemoveQuery | QUrl::RemoveFragment);
-
-#ifndef QT_NO_NETWORKPROXY
- if (proxy->type() != QNetworkProxy::NoProxy) {
- QUrl key;
-
- switch (proxy->type()) {
- case QNetworkProxy::Socks5Proxy:
- key.setScheme(QLatin1String("proxy-socks5"));
- break;
-
- case QNetworkProxy::HttpProxy:
- case QNetworkProxy::HttpCachingProxy:
- key.setScheme(QLatin1String("proxy-http"));
- break;
-
- default:
- break;
- }
-
- if (!key.scheme().isEmpty()) {
- key.setUserName(proxy->user());
- key.setHost(proxy->hostName());
- key.setPort(proxy->port());
- key.setEncodedQuery(result);
- result = key.toEncoded();
- }
- }
-#endif
-
- return "http-connection:" + result;
-}
-
static inline bool isSeparator(register char c)
{
static const char separators[] = "()<>@,;:\\\"/[]?={}";
@@ -230,71 +189,13 @@ QNetworkAccessHttpBackendFactory::create(QNetworkAccessManager::Operation op,
return 0;
}
-static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const QUrl &url)
-{
- QNetworkReply::NetworkError code;
- // we've got an error
- switch (httpStatusCode) {
- case 401: // Authorization required
- code = QNetworkReply::AuthenticationRequiredError;
- break;
-
- case 403: // Access denied
- code = QNetworkReply::ContentOperationNotPermittedError;
- break;
-
- case 404: // Not Found
- code = QNetworkReply::ContentNotFoundError;
- break;
-
- case 405: // Method Not Allowed
- code = QNetworkReply::ContentOperationNotPermittedError;
- break;
-
- case 407:
- code = QNetworkReply::ProxyAuthenticationRequiredError;
- break;
-
- default:
- if (httpStatusCode > 500) {
- // some kind of server error
- code = QNetworkReply::ProtocolUnknownError;
- } else if (httpStatusCode >= 400) {
- // content error we did not handle above
- code = QNetworkReply::UnknownContentError;
- } else {
- qWarning("QNetworkAccess: got HTTP status code %d which is not expected from url: \"%s\"",
- httpStatusCode, qPrintable(url.toString()));
- code = QNetworkReply::ProtocolFailure;
- }
- }
-
- return code;
-}
-
-class QNetworkAccessCachedHttpConnection: public QHttpNetworkConnection,
- public QNetworkAccessCache::CacheableObject
-{
- // Q_OBJECT
-public:
- QNetworkAccessCachedHttpConnection(const QString &hostName, quint16 port, bool encrypt)
- : QHttpNetworkConnection(hostName, port, encrypt)
- {
- setExpires(true);
- setShareable(true);
- }
-
- virtual void dispose()
- {
-#if 0 // sample code; do this right with the API
- Q_ASSERT(!isWorking());
-#endif
- delete this;
- }
-};
-
QNetworkAccessHttpBackend::QNetworkAccessHttpBackend()
- : QNetworkAccessBackend(), httpReply(0), http(0), uploadDevice(0)
+ : QNetworkAccessBackend()
+ , statusCode(0)
+ , pendingDownloadDataEmissions(new QAtomicInt())
+ , pendingDownloadProgressEmissions(new QAtomicInt())
+ , loadingFromCache(false)
+ , usingZerocopyDownloadBuffer(false)
#ifndef QT_NO_OPENSSL
, pendingSslConfiguration(0), pendingIgnoreAllSslErrors(false)
#endif
@@ -304,44 +205,14 @@ QNetworkAccessHttpBackend::QNetworkAccessHttpBackend()
QNetworkAccessHttpBackend::~QNetworkAccessHttpBackend()
{
- if (http)
- disconnectFromHttp();
+ // This will do nothing if the request was already finished or aborted
+ emit abortHttpRequest();
+
#ifndef QT_NO_OPENSSL
delete pendingSslConfiguration;
#endif
}
-void QNetworkAccessHttpBackend::disconnectFromHttp()
-{
- if (http) {
- // This is abut disconnecting signals, not about disconnecting TCP connections
- disconnect(http, 0, this, 0);
-
- // Get the object cache that stores our QHttpNetworkConnection objects
- QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this);
-
- // synchronous calls are not put into the cache, so for them the key is empty
- if (!cacheKey.isEmpty())
- cache->releaseEntry(cacheKey);
- }
-
- // This is abut disconnecting signals, not about disconnecting TCP connections
- if (httpReply)
- disconnect(httpReply, 0, this, 0);
-
- http = 0;
- httpReply = 0;
- cacheKey.clear();
-}
-
-void QNetworkAccessHttpBackend::finished()
-{
- if (http)
- disconnectFromHttp();
- // call parent
- QNetworkAccessBackend::finished();
-}
-
/*
For a given httpRequest
1) If AlwaysNetwork, return
@@ -487,9 +358,82 @@ static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& pr
void QNetworkAccessHttpBackend::postRequest()
{
+ QThread *thread = 0;
+ if (isSynchronous()) {
+ // A synchronous HTTP request uses its own thread
+ thread = new QThread();
+ QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
+ thread->start();
+ } else if (!manager->httpThread) {
+ // We use the manager-global thread.
+ // At some point we could switch to having multiple threads if it makes sense.
+ manager->httpThread = new QThread();
+ QObject::connect(manager->httpThread, SIGNAL(finished()), manager->httpThread, SLOT(deleteLater()));
+ manager->httpThread->start();
+#ifndef QT_NO_NETWORKPROXY
+ qRegisterMetaType<QNetworkProxy>("QNetworkProxy");
+#endif
+#ifndef QT_NO_OPENSSL
+ qRegisterMetaType<QList<QSslError> >("QList<QSslError>");
+ qRegisterMetaType<QSslConfiguration>("QSslConfiguration");
+#endif
+ qRegisterMetaType<QList<QPair<QByteArray,QByteArray> > >("QList<QPair<QByteArray,QByteArray> >");
+ qRegisterMetaType<QHttpNetworkRequest>("QHttpNetworkRequest");
+ qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError");
+ qRegisterMetaType<QSharedPointer<char> >("QSharedPointer<char>");
+
+ thread = manager->httpThread;
+ } else {
+ // Asynchronous request, thread already exists
+ thread = manager->httpThread;
+ }
+
+ QUrl url = request().url();
+ httpRequest.setUrl(url);
+
+ bool ssl = url.scheme().toLower() == QLatin1String("https");
+ setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, ssl);
+ httpRequest.setSsl(ssl);
+
+
+#ifndef QT_NO_NETWORKPROXY
+ QNetworkProxy transparentProxy, cacheProxy;
+
+ foreach (const QNetworkProxy &p, proxyList()) {
+ // use the first proxy that works
+ // for non-encrypted connections, any transparent or HTTP proxy
+ // for encrypted, only transparent proxies
+ if (!ssl
+ && (p.capabilities() & QNetworkProxy::CachingCapability)
+ && (p.type() == QNetworkProxy::HttpProxy ||
+ p.type() == QNetworkProxy::HttpCachingProxy)) {
+ cacheProxy = p;
+ transparentProxy = QNetworkProxy::NoProxy;
+ break;
+ }
+ if (p.isTransparentProxy()) {
+ transparentProxy = p;
+ cacheProxy = QNetworkProxy::NoProxy;
+ break;
+ }
+ }
+
+ // check if at least one of the proxies
+ if (transparentProxy.type() == QNetworkProxy::DefaultProxy &&
+ cacheProxy.type() == QNetworkProxy::DefaultProxy) {
+ // unsuitable proxies
+ QMetaObject::invokeMethod(this, "error", isSynchronous() ? Qt::DirectConnection : Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError),
+ Q_ARG(QString, tr("No suitable proxy found")));
+ QMetaObject::invokeMethod(this, "finished", isSynchronous() ? Qt::DirectConnection : Qt::QueuedConnection);
+ return;
+ }
+#endif
+
+
bool loadedFromCache = false;
- QHttpNetworkRequest httpRequest;
httpRequest.setPriority(convert(request().priority()));
+
switch (operation()) {
case QNetworkAccessManager::GetOperation:
httpRequest.setOperation(QHttpNetworkRequest::Get);
@@ -504,13 +448,13 @@ void QNetworkAccessHttpBackend::postRequest()
case QNetworkAccessManager::PostOperation:
invalidateCache();
httpRequest.setOperation(QHttpNetworkRequest::Post);
- httpRequest.setUploadByteDevice(createUploadByteDevice());
+ createUploadByteDevice();
break;
case QNetworkAccessManager::PutOperation:
invalidateCache();
httpRequest.setOperation(QHttpNetworkRequest::Put);
- httpRequest.setUploadByteDevice(createUploadByteDevice());
+ createUploadByteDevice();
break;
case QNetworkAccessManager::DeleteOperation:
@@ -521,7 +465,7 @@ void QNetworkAccessHttpBackend::postRequest()
case QNetworkAccessManager::CustomOperation:
invalidateCache(); // for safety reasons, we don't know what the operation does
httpRequest.setOperation(QHttpNetworkRequest::Custom);
- httpRequest.setUploadByteDevice(createUploadByteDevice());
+ createUploadByteDevice();
httpRequest.setCustomVerb(request().attribute(
QNetworkRequest::CustomVerbAttribute).toByteArray());
break;
@@ -530,11 +474,6 @@ void QNetworkAccessHttpBackend::postRequest()
break; // can't happen
}
- bool encrypt = (url().scheme().toLower() == QLatin1String("https"));
- httpRequest.setSsl(encrypt);
-
- httpRequest.setUrl(url());
-
QList<QByteArray> headers = request().rawHeaderList();
if (resumeOffset != 0) {
if (headers.contains("Range")) {
@@ -558,6 +497,7 @@ void QNetworkAccessHttpBackend::postRequest()
httpRequest.setHeaderField("Range", "bytes=" + QByteArray::number(resumeOffset) + '-');
}
}
+
foreach (const QByteArray &header, headers)
httpRequest.setHeaderField(header, request().rawHeader(header));
@@ -576,30 +516,155 @@ void QNetworkAccessHttpBackend::postRequest()
QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Manual)
httpRequest.setWithCredentials(false);
- httpReply = http->sendRequest(httpRequest);
- httpReply->setParent(this);
+
+ // Create the HTTP thread delegate
+ QHttpThreadDelegate *delegate = new QHttpThreadDelegate;
+
+ // For the synchronous HTTP, this is the normal way the delegate gets deleted
+ // For the asynchronous HTTP this is a safety measure, the delegate deletes itself when HTTP is finished
+ connect(thread, SIGNAL(finished()), delegate, SLOT(deleteLater()));
+
+ // Set the properties it needs
+ delegate->httpRequest = httpRequest;
+#ifndef QT_NO_NETWORKPROXY
+ delegate->cacheProxy = cacheProxy;
+ delegate->transparentProxy = transparentProxy;
+#endif
+ delegate->ssl = ssl;
#ifndef QT_NO_OPENSSL
- if (pendingSslConfiguration)
- httpReply->setSslConfiguration(*pendingSslConfiguration);
- if (pendingIgnoreAllSslErrors)
- httpReply->ignoreSslErrors();
- httpReply->ignoreSslErrors(pendingIgnoreSslErrorsList);
- connect(httpReply, SIGNAL(sslErrors(QList<QSslError>)),
- SLOT(sslErrors(QList<QSslError>)));
+ if (ssl)
+ delegate->incomingSslConfiguration = request().sslConfiguration();
#endif
- connect(httpReply, SIGNAL(finished()), SLOT(replyFinished()));
- connect(httpReply, SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)),
- SLOT(httpError(QNetworkReply::NetworkError,QString)));
- connect(httpReply, SIGNAL(headerChanged()), SLOT(replyHeaderChanged()));
- connect(httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)),
- SLOT(httpCacheCredentials(QHttpNetworkRequest,QAuthenticator*)));
+ // Do we use synchronous HTTP?
+ delegate->synchronous = isSynchronous();
+
+ // The authentication manager is used to avoid the BlockingQueuedConnection communication
+ // from HTTP thread to user thread in some cases.
+ delegate->authenticationManager = manager->authenticationManager;
+
+ if (!isSynchronous()) {
+ // Tell our zerocopy policy to the delegate
+ delegate->downloadBufferMaximumSize =
+ request().attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute).toLongLong();
+
+ // These atomic integers are used for signal compression
+ delegate->pendingDownloadData = pendingDownloadDataEmissions;
+ delegate->pendingDownloadProgress = pendingDownloadProgressEmissions;
+
+ // Connect the signals of the delegate to us
+ connect(delegate, SIGNAL(downloadData(QByteArray)),
+ this, SLOT(replyDownloadData(QByteArray)),
+ Qt::QueuedConnection);
+ connect(delegate, SIGNAL(downloadFinished()),
+ this, SLOT(replyFinished()),
+ Qt::QueuedConnection);
+ connect(delegate, SIGNAL(downloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64)),
+ this, SLOT(replyDownloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64)),
+ Qt::QueuedConnection);
+ connect(delegate, SIGNAL(downloadProgress(qint64,qint64)),
+ this, SLOT(replyDownloadProgressSlot(qint64,qint64)),
+ Qt::QueuedConnection);
+ connect(delegate, SIGNAL(error(QNetworkReply::NetworkError,QString)),
+ this, SLOT(httpError(QNetworkReply::NetworkError, const QString)),
+ Qt::QueuedConnection);
+#ifndef QT_NO_OPENSSL
+ connect(delegate, SIGNAL(sslConfigurationChanged(QSslConfiguration)),
+ this, SLOT(replySslConfigurationChanged(QSslConfiguration)),
+ Qt::QueuedConnection);
+#endif
+ // Those need to report back, therefire BlockingQueuedConnection
+ connect(delegate, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
+ this, SLOT(httpAuthenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
+ Qt::BlockingQueuedConnection);
#ifndef QT_NO_NETWORKPROXY
- connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
- SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
+ connect (delegate, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
+ this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
+ Qt::BlockingQueuedConnection);
#endif
- connect(httpReply, SIGNAL(authenticationRequired(const QHttpNetworkRequest,QAuthenticator*)),
- SLOT(httpAuthenticationRequired(const QHttpNetworkRequest,QAuthenticator*)));
+#ifndef QT_NO_OPENSSL
+ connect(delegate, SIGNAL(sslErrors(QList<QSslError>,bool*,QList<QSslError>*)),
+ this, SLOT(replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *)),
+ Qt::BlockingQueuedConnection);
+#endif
+ // This signal we will use to start the request.
+ connect(this, SIGNAL(startHttpRequest()), delegate, SLOT(startRequest()));
+ connect(this, SIGNAL(abortHttpRequest()), delegate, SLOT(abortRequest()));
+
+ if (uploadByteDevice) {
+ QNonContiguousByteDeviceThreadForwardImpl *forwardUploadDevice =
+ new QNonContiguousByteDeviceThreadForwardImpl(uploadByteDevice->atEnd(), uploadByteDevice->size());
+ if (uploadByteDevice->isResetDisabled())
+ forwardUploadDevice->disableReset();
+ forwardUploadDevice->setParent(delegate); // needed to make sure it is moved on moveToThread()
+ delegate->httpRequest.setUploadByteDevice(forwardUploadDevice);
+
+ // From main thread to user thread:
+ QObject::connect(this, SIGNAL(haveUploadData(QByteArray, bool, qint64)),
+ forwardUploadDevice, SLOT(haveDataSlot(QByteArray, bool, qint64)), Qt::QueuedConnection);
+ QObject::connect(uploadByteDevice.data(), SIGNAL(readyRead()),
+ forwardUploadDevice, SIGNAL(readyRead()),
+ Qt::QueuedConnection);
+
+ // From http thread to user thread:
+ QObject::connect(forwardUploadDevice, SIGNAL(wantData(qint64)),
+ this, SLOT(wantUploadDataSlot(qint64)));
+ QObject::connect(forwardUploadDevice, SIGNAL(processedData(qint64)),
+ this, SLOT(sentUploadDataSlot(qint64)));
+ connect(forwardUploadDevice, SIGNAL(resetData(bool*)),
+ this, SLOT(resetUploadDataSlot(bool*)),
+ Qt::BlockingQueuedConnection); // this is the only one with BlockingQueued!
+ }
+ } else if (isSynchronous()) {
+ connect(this, SIGNAL(startHttpRequestSynchronously()), delegate, SLOT(startRequestSynchronously()), Qt::BlockingQueuedConnection);
+
+ if (uploadByteDevice) {
+ // For the synchronous HTTP use case the use thread (this one here) is blocked
+ // so we cannot use the asynchronous upload architecture.
+ // We therefore won't use the QNonContiguousByteDeviceThreadForwardImpl but directly
+ // use the uploadByteDevice provided to us by the QNetworkReplyImpl.
+ // The code that is in QNetworkReplyImplPrivate::setup() makes sure it is safe to use from a thread
+ // since it only wraps a QRingBuffer
+ delegate->httpRequest.setUploadByteDevice(uploadByteDevice.data());
+ }
+ }
+
+
+ // Move the delegate to the http thread
+ delegate->moveToThread(thread);
+ // This call automatically moves the uploadDevice too for the asynchronous case.
+
+ // Send an signal to the delegate so it starts working in the other thread
+ if (isSynchronous()) {
+ emit startHttpRequestSynchronously(); // This one is BlockingQueuedConnection, so it will return when all work is done
+
+ if (delegate->incomingErrorCode != QNetworkReply::NoError) {
+ replyDownloadMetaData
+ (delegate->incomingHeaders,
+ delegate->incomingStatusCode,
+ delegate->incomingReasonPhrase,
+ delegate->isPipeliningUsed,
+ QSharedPointer<char>(),
+ delegate->incomingContentLength);
+ httpError(delegate->incomingErrorCode, delegate->incomingErrorDetail);
+ } else {
+ replyDownloadMetaData
+ (delegate->incomingHeaders,
+ delegate->incomingStatusCode,
+ delegate->incomingReasonPhrase,
+ delegate->isPipeliningUsed,
+ QSharedPointer<char>(),
+ delegate->incomingContentLength);
+ replyDownloadData(delegate->synchronousDownloadData);
+ }
+
+ // End the thread. It will delete itself from the finished() signal
+ thread->quit();
+
+ finished();
+ } else {
+ emit startHttpRequest(); // Signal to the HTTP thread and go back to user.
+ }
}
void QNetworkAccessHttpBackend::invalidateCache()
@@ -611,159 +676,52 @@ void QNetworkAccessHttpBackend::invalidateCache()
void QNetworkAccessHttpBackend::open()
{
- QUrl url = request().url();
- bool encrypt = url.scheme().toLower() == QLatin1String("https");
- setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, encrypt);
-
- // set the port number in the reply if it wasn't set
- url.setPort(url.port(encrypt ? DefaultHttpsPort : DefaultHttpPort));
-
- QNetworkProxy *theProxy = 0;
-#ifndef QT_NO_NETWORKPROXY
- QNetworkProxy transparentProxy, cacheProxy;
-
- foreach (const QNetworkProxy &p, proxyList()) {
- // use the first proxy that works
- // for non-encrypted connections, any transparent or HTTP proxy
- // for encrypted, only transparent proxies
- if (!encrypt
- && (p.capabilities() & QNetworkProxy::CachingCapability)
- && (p.type() == QNetworkProxy::HttpProxy ||
- p.type() == QNetworkProxy::HttpCachingProxy)) {
- cacheProxy = p;
- transparentProxy = QNetworkProxy::NoProxy;
- theProxy = &cacheProxy;
- break;
- }
- if (p.isTransparentProxy()) {
- transparentProxy = p;
- cacheProxy = QNetworkProxy::NoProxy;
- theProxy = &transparentProxy;
- break;
- }
- }
-
- // check if at least one of the proxies
- if (transparentProxy.type() == QNetworkProxy::DefaultProxy &&
- cacheProxy.type() == QNetworkProxy::DefaultProxy) {
- // unsuitable proxies
- if (isSynchronous()) {
- error(QNetworkReply::ProxyNotFoundError, tr("No suitable proxy found"));
- finished();
- } else {
- QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
- Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError),
- Q_ARG(QString, tr("No suitable proxy found")));
- QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
- }
- return;
- }
-#endif
-
- if (isSynchronous()) {
- // for synchronous requests, we just create a new connection
- http = new QHttpNetworkConnection(1, url.host(), url.port(), encrypt, this);
-#ifndef QT_NO_NETWORKPROXY
- http->setTransparentProxy(transparentProxy);
- http->setCacheProxy(cacheProxy);
-#endif
- postRequest();
- processRequestSynchronously();
- } else {
- // check if we have an open connection to this host
- cacheKey = makeCacheKey(this, theProxy);
- QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this);
- // the http object is actually a QHttpNetworkConnection
- http = static_cast<QNetworkAccessCachedHttpConnection *>(cache->requestEntryNow(cacheKey));
- if (http == 0) {
- // no entry in cache; create an object
- // the http object is actually a QHttpNetworkConnection
- http = new QNetworkAccessCachedHttpConnection(url.host(), url.port(), encrypt);
-
-#ifndef QT_NO_NETWORKPROXY
- http->setTransparentProxy(transparentProxy);
- http->setCacheProxy(cacheProxy);
-#endif
-
- // cache the QHttpNetworkConnection corresponding to this cache key
- cache->addEntry(cacheKey, static_cast<QNetworkAccessCachedHttpConnection *>(http.data()));
- }
- postRequest();
- }
+ postRequest();
}
void QNetworkAccessHttpBackend::closeDownstreamChannel()
{
- // this indicates that the user closed the stream while the reply isn't finished yet
+ // FIXME Maybe we can get rid of this whole architecture part
}
void QNetworkAccessHttpBackend::downstreamReadyWrite()
{
- readFromHttp();
- if (httpReply && httpReply->bytesAvailable() == 0 && httpReply->isFinished())
- replyFinished();
+ // FIXME Maybe we can get rid of this whole architecture part
}
void QNetworkAccessHttpBackend::setDownstreamLimited(bool b)
{
- if (httpReply)
- httpReply->setDownstreamLimited(b);
-}
-
-void QNetworkAccessHttpBackend::replyReadyRead()
-{
- readFromHttp();
+ Q_UNUSED(b);
+ // We know that readBuffer maximum size limiting is broken since quite a while.
+ // The task to fix this is QTBUG-15065
}
-void QNetworkAccessHttpBackend::readFromHttp()
+void QNetworkAccessHttpBackend::replyDownloadData(QByteArray d)
{
- if (!httpReply)
+ int pendingSignals = (int)pendingDownloadDataEmissions->fetchAndAddAcquire(-1) - 1;
+
+ if (pendingSignals > 0) {
+ // Some more signal emissions to this slot are pending.
+ // Instead of writing the downstream data, we wait
+ // and do it in the next call we get
+ // (signal comppression)
+ pendingDownloadData.append(d);
return;
-
- // We read possibly more than nextDownstreamBlockSize(), but
- // this is not a critical thing since it is already in the
- // memory anyway
-
- QByteDataBuffer list;
-
- while (httpReply->bytesAvailable() != 0 && nextDownstreamBlockSize() != 0 && nextDownstreamBlockSize() > list.byteAmount()) {
- list.append(httpReply->readAny());
}
- if (!list.isEmpty())
- writeDownstreamData(list);
+ pendingDownloadData.append(d);
+ d.clear();
+ writeDownstreamData(pendingDownloadData);
+ pendingDownloadData.clear();
}
void QNetworkAccessHttpBackend::replyFinished()
{
- if (httpReply->bytesAvailable())
- // we haven't read everything yet. Wait some more.
+ // We are already loading from cache, we still however
+ // got this signal because it was posted already
+ if (loadingFromCache)
return;
- int statusCode = httpReply->statusCode();
- if (statusCode >= 400) {
- // it's an error reply
- QString msg = QLatin1String(QT_TRANSLATE_NOOP("QNetworkReply",
- "Error downloading %1 - server replied: %2"));
- msg = msg.arg(url().toString(), httpReply->reasonPhrase());
- error(statusCodeFromHttp(httpReply->statusCode(), httpReply->url()), msg);
- }
-
-#ifndef QT_NO_OPENSSL
- // store the SSL configuration now
- // once we call finished(), we won't have access to httpReply anymore
- QSslConfiguration sslConfig = httpReply->sslConfiguration();
- if (pendingSslConfiguration) {
- *pendingSslConfiguration = sslConfig;
- } else if (!sslConfig.isNull()) {
- QT_TRY {
- pendingSslConfiguration = new QSslConfiguration(sslConfig);
- } QT_CATCH(...) {
- qWarning("QNetworkAccess: could not allocate a QSslConfiguration object for a SSL connection.");
- }
- }
-#endif
-
finished();
}
@@ -785,12 +743,27 @@ void QNetworkAccessHttpBackend::checkForRedirect(const int statusCode)
}
}
-void QNetworkAccessHttpBackend::replyHeaderChanged()
+void QNetworkAccessHttpBackend::replyDownloadMetaData
+ (QList<QPair<QByteArray,QByteArray> > hm,
+ int sc,QString rp,bool pu,
+ QSharedPointer<char> db,
+ qint64 contentLength)
{
- setAttribute(QNetworkRequest::HttpPipeliningWasUsedAttribute, httpReply->isPipeliningUsed());
+ statusCode = sc;
+ reasonPhrase = rp;
+
+ // Download buffer
+ if (!db.isNull()) {
+ reply->setDownloadBuffer(db, contentLength);
+ usingZerocopyDownloadBuffer = true;
+ } else {
+ usingZerocopyDownloadBuffer = false;
+ }
+
+ setAttribute(QNetworkRequest::HttpPipeliningWasUsedAttribute, pu);
// reconstruct the HTTP header
- QList<QPair<QByteArray, QByteArray> > headerMap = httpReply->header();
+ QList<QPair<QByteArray, QByteArray> > headerMap = hm;
QList<QPair<QByteArray, QByteArray> >::ConstIterator it = headerMap.constBegin(),
end = headerMap.constEnd();
QByteArray header;
@@ -807,11 +780,10 @@ void QNetworkAccessHttpBackend::replyHeaderChanged()
setRawHeader(it->first, value);
}
- setAttribute(QNetworkRequest::HttpStatusCodeAttribute, httpReply->statusCode());
- setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, httpReply->reasonPhrase());
+ setAttribute(QNetworkRequest::HttpStatusCodeAttribute, statusCode);
+ setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, reasonPhrase);
// is it a redirection?
- const int statusCode = httpReply->statusCode();
checkForRedirect(statusCode);
if (statusCode >= 500 && statusCode < 600) {
@@ -854,29 +826,21 @@ void QNetworkAccessHttpBackend::replyHeaderChanged()
setCachingEnabled(true);
}
- // Check if a download buffer is supported from the HTTP reply
- char *buf = 0;
- if (httpReply->supportsUserProvidedDownloadBuffer()) {
- // Check if a download buffer is supported by the user
- buf = getDownloadBuffer(httpReply->contentLength());
- if (buf) {
- httpReply->setUserProvidedDownloadBuffer(buf);
- // If there is a download buffer we react on the progress signal
- connect(httpReply, SIGNAL(dataReadProgress(int,int)), SLOT(replyDownloadProgressSlot(int,int)));
- }
- }
-
- // If there is no buffer, we react on the readyRead signal
- if (!buf) {
- connect(httpReply, SIGNAL(readyRead()), SLOT(replyReadyRead()));
- }
-
metaDataChanged();
}
-void QNetworkAccessHttpBackend::replyDownloadProgressSlot(int received, int total)
+void QNetworkAccessHttpBackend::replyDownloadProgressSlot(qint64 received, qint64 total)
{
// we can be sure here that there is a download buffer
+
+ int pendingSignals = (int)pendingDownloadProgressEmissions->fetchAndAddAcquire(-1) - 1;
+ if (pendingSignals > 0) {
+ // Let's ignore this signal and look at the next one coming in
+ // (signal comppression)
+ return;
+ }
+
+ // Now do the actual notification of new bytes
writeDownstreamDataDownloadBuffer(received, total);
}
@@ -886,20 +850,62 @@ void QNetworkAccessHttpBackend::httpAuthenticationRequired(const QHttpNetworkReq
authenticationRequired(auth);
}
-void QNetworkAccessHttpBackend::httpCacheCredentials(const QHttpNetworkRequest &,
- QAuthenticator *auth)
-{
- cacheCredentials(auth);
-}
-
void QNetworkAccessHttpBackend::httpError(QNetworkReply::NetworkError errorCode,
const QString &errorString)
{
#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
qDebug() << "http error!" << errorCode << errorString;
#endif
+
error(errorCode, errorString);
- finished();
+}
+
+#ifndef QT_NO_OPENSSL
+void QNetworkAccessHttpBackend::replySslErrors(
+ const QList<QSslError> &list, bool *ignoreAll, QList<QSslError> *toBeIgnored)
+{
+ // Go to generic backend
+ sslErrors(list);
+ // Check if the callback set any ignore and return this here to http thread
+ if (pendingIgnoreAllSslErrors)
+ *ignoreAll = true;
+ if (!pendingIgnoreSslErrorsList.isEmpty())
+ *toBeIgnored = pendingIgnoreSslErrorsList;
+}
+
+void QNetworkAccessHttpBackend::replySslConfigurationChanged(const QSslConfiguration &c)
+{
+ // Receiving the used SSL configuration from the HTTP thread
+ if (pendingSslConfiguration)
+ *pendingSslConfiguration = c;
+ else if (!c.isNull())
+ pendingSslConfiguration = new QSslConfiguration(c);
+}
+#endif
+
+// Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread
+void QNetworkAccessHttpBackend::resetUploadDataSlot(bool *r)
+{
+ *r = uploadByteDevice->reset();
+}
+
+// Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread
+void QNetworkAccessHttpBackend::sentUploadDataSlot(qint64 amount)
+{
+ uploadByteDevice->advanceReadPointer(amount);
+}
+
+// Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread
+void QNetworkAccessHttpBackend::wantUploadDataSlot(qint64 maxSize)
+{
+ // call readPointer
+ qint64 currentUploadDataLength = 0;
+ char *data = const_cast<char*>(uploadByteDevice->readPointer(maxSize, currentUploadDataLength));
+ // Let's make a copy of this data
+ QByteArray dataArray(data, currentUploadDataLength);
+
+ // Communicate back to HTTP thread
+ emit haveUploadData(dataArray, uploadByteDevice->atEnd(), uploadByteDevice->size());
}
/*
@@ -950,8 +956,10 @@ bool QNetworkAccessHttpBackend::sendCacheContents(const QNetworkCacheMetaData &m
#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
qDebug() << "Successfully sent cache:" << url() << contents->size() << "bytes";
#endif
- if (httpReply)
- disconnect(httpReply, SIGNAL(finished()), this, SLOT(replyFinished()));
+
+ // Set the following flag so we can ignore some signals from HTTP thread
+ // that would still come
+ loadingFromCache = true;
return true;
}
@@ -964,39 +972,29 @@ void QNetworkAccessHttpBackend::copyFinished(QIODevice *dev)
#ifndef QT_NO_OPENSSL
void QNetworkAccessHttpBackend::ignoreSslErrors()
{
- if (httpReply)
- httpReply->ignoreSslErrors();
- else
- pendingIgnoreAllSslErrors = true;
+ pendingIgnoreAllSslErrors = true;
}
void QNetworkAccessHttpBackend::ignoreSslErrors(const QList<QSslError> &errors)
{
- if (httpReply) {
- httpReply->ignoreSslErrors(errors);
- } else {
- // the pending list is set if QNetworkReply::ignoreSslErrors(const QList<QSslError> &errors)
- // is called before QNetworkAccessManager::get() (or post(), etc.)
- pendingIgnoreSslErrorsList = errors;
- }
+ // the pending list is set if QNetworkReply::ignoreSslErrors(const QList<QSslError> &errors)
+ // is called before QNetworkAccessManager::get() (or post(), etc.)
+ pendingIgnoreSslErrorsList = errors;
}
void QNetworkAccessHttpBackend::fetchSslConfiguration(QSslConfiguration &config) const
{
- if (httpReply)
- config = httpReply->sslConfiguration();
- else if (pendingSslConfiguration)
+ if (pendingSslConfiguration)
config = *pendingSslConfiguration;
+ else
+ config = request().sslConfiguration();
}
void QNetworkAccessHttpBackend::setSslConfiguration(const QSslConfiguration &newconfig)
{
- if (httpReply)
- httpReply->setSslConfiguration(newconfig);
- else if (pendingSslConfiguration)
- *pendingSslConfiguration = newconfig;
- else
- pendingSslConfiguration = new QSslConfiguration(newconfig);
+ // Setting a SSL configuration on a reply is not supported. The user needs to set
+ // her/his QSslConfiguration on the QNetworkRequest.
+ Q_UNUSED(newconfig);
}
#endif
@@ -1101,7 +1099,7 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo
bool canDiskCache;
// only cache GET replies by default, all other replies (POST, PUT, DELETE)
// are not cacheable by default (according to RFC 2616 section 9)
- if (httpReply->request().operation() == QHttpNetworkRequest::Get) {
+ if (httpRequest.operation() == QHttpNetworkRequest::Get) {
canDiskCache = true;
// 14.32
@@ -1119,7 +1117,7 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo
canDiskCache = false;
// responses to POST might be cacheable
- } else if (httpReply->request().operation() == QHttpNetworkRequest::Post) {
+ } else if (httpRequest.operation() == QHttpNetworkRequest::Post) {
canDiskCache = false;
// some pages contain "expires:" and "cache-control: no-cache" field,
@@ -1133,12 +1131,11 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo
}
metaData.setSaveToDisk(canDiskCache);
- int statusCode = httpReply->statusCode();
QNetworkCacheMetaData::AttributesMap attributes;
if (statusCode != 304) {
// update the status code
attributes.insert(QNetworkRequest::HttpStatusCodeAttribute, statusCode);
- attributes.insert(QNetworkRequest::HttpReasonPhraseAttribute, httpReply->reasonPhrase());
+ attributes.insert(QNetworkRequest::HttpReasonPhraseAttribute, reasonPhrase);
} else {
// this is a redirection, keep the attributes intact
attributes = oldMetaData.attributes();
@@ -1154,7 +1151,8 @@ bool QNetworkAccessHttpBackend::canResume() const
return false;
// Can only resume if server/resource supports Range header.
- if (httpReply->headerField("Accept-Ranges", "none") == "none")
+ QByteArray acceptRangesheaderName("Accept-Ranges");
+ if (!hasRawHeader(acceptRangesheaderName) || rawHeader(acceptRangesheaderName) == "none")
return false;
// We only support resuming for byte ranges.
@@ -1166,7 +1164,7 @@ bool QNetworkAccessHttpBackend::canResume() const
// If we're using a download buffer then we don't support resuming/migration
// right now. Too much trouble.
- if (httpReply->userProvidedDownloadBuffer())
+ if (usingZerocopyDownloadBuffer)
return false;
return true;
@@ -1177,87 +1175,6 @@ void QNetworkAccessHttpBackend::setResumeOffset(quint64 offset)
resumeOffset = offset;
}
-bool QNetworkAccessHttpBackend::processRequestSynchronously()
-{
- QHttpNetworkConnectionChannel *channel = &http->channels()[0];
-
- // Disconnect all socket signals. They will only confuse us when using waitFor*
- QObject::disconnect(channel->socket, 0, 0, 0);
-
- qint64 timeout = 20*1000; // 20 sec
- QElapsedTimer timeoutTimer;
-
- bool waitResult = channel->socket->waitForConnected(timeout);
- timeoutTimer.start();
-
- if (!waitResult || channel->socket->state() != QAbstractSocket::ConnectedState) {
- error(QNetworkReply::UnknownNetworkError, QLatin1String("could not connect"));
- return false;
- }
- channel->_q_connected(); // this will send the request (via sendRequest())
-
-#ifndef QT_NO_OPENSSL
- if (http->isSsl()) {
- qint64 remainingTimeEncrypted = timeout - timeoutTimer.elapsed();
- if (!static_cast<QSslSocket *>(channel->socket)->waitForEncrypted(remainingTimeEncrypted)) {
- error(QNetworkReply::SslHandshakeFailedError,
- QLatin1String("could not encrypt or timeout while encrypting"));
- return false;
- }
- channel->_q_encrypted();
- }
-#endif
-
- // if we get a 401 or 407, we might need to send the request twice, see below
- bool authenticating = false;
-
- do {
- channel->sendRequest();
-
- qint64 remainingTimeBytesWritten;
- while(channel->socket->bytesToWrite() > 0 ||
- channel->state == QHttpNetworkConnectionChannel::WritingState) {
- remainingTimeBytesWritten = timeout - timeoutTimer.elapsed();
- channel->sendRequest(); // triggers channel->socket->write()
- if (!channel->socket->waitForBytesWritten(remainingTimeBytesWritten)) {
- error(QNetworkReply::TimeoutError,
- QLatin1String("could not write bytes to socket or timeout while writing"));
- return false;
- }
- }
-
- qint64 remainingTimeBytesRead = timeout - timeoutTimer.elapsed();
- // Loop for at most remainingTime until either the socket disconnects
- // or the reply is finished
- do {
- waitResult = channel->socket->waitForReadyRead(remainingTimeBytesRead);
- remainingTimeBytesRead = timeout - timeoutTimer.elapsed();
- if (!waitResult || remainingTimeBytesRead <= 0
- || channel->socket->state() != QAbstractSocket::ConnectedState) {
- error(QNetworkReply::TimeoutError,
- QLatin1String("could not read from socket or timeout while reading"));
- return false;
- }
-
- if (channel->socket->bytesAvailable())
- channel->_q_readyRead();
-
- if (!httpReply)
- return false; // we got a 401 or 407 and cannot handle it (it might happen that
- // disconnectFromHttp() was called, in that case the reply is zero)
- // ### I am quite sure this does not work for NTLM
- // ### how about uploading to an auth / proxyAuth site?
-
- authenticating = (httpReply->statusCode() == 401 || httpReply->statusCode() == 407);
-
- if (httpReply->isFinished())
- break;
- } while (remainingTimeBytesRead > 0);
- } while (authenticating);
-
- return true;
-}
-
QT_END_NAMESPACE
#endif // QT_NO_HTTP
diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h
index 7064d4a..712dd2f 100644
--- a/src/network/access/qnetworkaccesshttpbackend_p.h
+++ b/src/network/access/qnetworkaccesshttpbackend_p.h
@@ -61,6 +61,8 @@
#include "QtCore/qpointer.h"
#include "QtCore/qdatetime.h"
+#include "QtCore/qsharedpointer.h"
+#include "qatomic.h"
#ifndef QT_NO_HTTP
@@ -99,24 +101,44 @@ public:
bool canResume() const;
void setResumeOffset(quint64 offset);
- virtual bool processRequestSynchronously();
+signals:
+ // To HTTP thread:
+ void startHttpRequest();
+ void abortHttpRequest();
+ void startHttpRequestSynchronously();
+
+ void haveUploadData(QByteArray dataArray, bool dataAtEnd, qint64 dataSize);
private slots:
- void replyReadyRead();
+ // From HTTP thread:
+ void replyDownloadData(QByteArray);
void replyFinished();
- void replyHeaderChanged();
- void replyDownloadProgressSlot(int,int);
+ void replyDownloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64);
+ void replyDownloadProgressSlot(qint64,qint64);
void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth);
- void httpCacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *auth);
void httpError(QNetworkReply::NetworkError error, const QString &errorString);
+#ifndef QT_NO_OPENSSL
+ void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
+ void replySslConfigurationChanged(const QSslConfiguration&);
+#endif
+
+ // From QNonContiguousByteDeviceThreadForwardImpl in HTTP thread:
+ void resetUploadDataSlot(bool *r);
+ void wantUploadDataSlot(qint64);
+ void sentUploadDataSlot(qint64);
+
bool sendCacheContents(const QNetworkCacheMetaData &metaData);
- void finished(); // override
private:
- QHttpNetworkReply *httpReply;
- QPointer<QHttpNetworkConnection> http;
- QByteArray cacheKey;
- QNetworkAccessBackendUploadIODevice *uploadDevice;
+ QHttpNetworkRequest httpRequest; // There is also a copy in the HTTP thread
+ int statusCode;
+ QString reasonPhrase;
+ // Will be increased by HTTP thread:
+ QSharedPointer<QAtomicInt> pendingDownloadDataEmissions;
+ QSharedPointer<QAtomicInt> pendingDownloadProgressEmissions;
+ bool loadingFromCache;
+ QByteDataBuffer pendingDownloadData;
+ bool usingZerocopyDownloadBuffer;
#ifndef QT_NO_OPENSSL
QSslConfiguration *pendingSslConfiguration;
@@ -126,7 +148,6 @@ private:
quint64 resumeOffset;
- void disconnectFromHttp();
void validateCache(QHttpNetworkRequest &httpRequest, bool &loadedFromCache);
void invalidateCache();
void postRequest();
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 22f62cb..7e75045 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -65,6 +65,8 @@
#include "QtNetwork/qsslconfiguration.h"
#include "QtNetwork/qnetworkconfigmanager.h"
+#include "qthread.h"
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_HTTP
@@ -1099,10 +1101,21 @@ void QNetworkAccessManagerPrivate::clearCache(QNetworkAccessManager *manager)
{
manager->d_func()->objectCache.clear();
manager->d_func()->authenticationManager->clearCache();
+
+ if (manager->d_func()->httpThread) {
+ // The thread will deleteLater() itself from its finished() signal
+ manager->d_func()->httpThread->quit();
+ manager->d_func()->httpThread = 0;
+ }
}
QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate()
{
+ if (httpThread) {
+ // The thread will deleteLater() itself from its finished() signal
+ httpThread->quit();
+ httpThread = 0;
+ }
}
#ifndef QT_NO_BEARERMANAGEMENT
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 7ef009f..d67b8ac 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -156,6 +156,8 @@ protected:
private:
friend class QNetworkReplyImplPrivate;
+ friend class QNetworkAccessHttpBackend;
+
Q_DECLARE_PRIVATE(QNetworkAccessManager)
Q_PRIVATE_SLOT(d_func(), void _q_replyFinished())
Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>))
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index dba1fd2..ee6ad70 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -73,6 +73,7 @@ class QNetworkAccessManagerPrivate: public QObjectPrivate
public:
QNetworkAccessManagerPrivate()
: networkCache(0), cookieJar(0),
+ httpThread(0),
#ifndef QT_NO_NETWORKPROXY
proxyFactory(0),
#endif
@@ -123,6 +124,8 @@ public:
QNetworkCookieJar *cookieJar;
+ QThread *httpThread;
+
#ifndef QT_NO_NETWORKPROXY
QNetworkProxy proxy;
@@ -140,7 +143,7 @@ public:
bool cookieJarCreated;
// The cache with authorization data:
- QNetworkAccessAuthenticationManager* authenticationManager;
+ QSharedPointer<QNetworkAccessAuthenticationManager> authenticationManager;
// this cache can be used by individual backends to cache e.g. their TCP connections to a server
// and use the connections for multiple requests.
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp
index 70ea5c2..c2a6925 100644
--- a/src/network/access/qnetworkcookie.cpp
+++ b/src/network/access/qnetworkcookie.cpp
@@ -359,7 +359,7 @@ void QNetworkCookie::setValue(const QByteArray &value)
}
// ### move this to qnetworkcookie_p.h and share with qnetworkaccesshttpbackend
-static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &position)
+static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &position, bool isNameValue)
{
// format is one of:
// (1) token
@@ -394,13 +394,22 @@ static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &posi
// quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
// qdtext = <any TEXT except <">>
// quoted-pair = "\" CHAR
+
+ // If its NAME=VALUE, retain the value as is
+ // refer to ttp://bugreports.qt.nokia.com/browse/QTBUG-17746
+ if (isNameValue)
+ second += '"';
++i;
while (i < length) {
register char c = text.at(i);
if (c == '"') {
// end of quoted text
+ if (isNameValue)
+ second += '"';
break;
} else if (c == '\\') {
+ if (isNameValue)
+ second += '\\';
++i;
if (i >= length)
// broken line
@@ -476,10 +485,12 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const
result = d->name;
result += '=';
- if (d->value.contains(';') ||
+ if ((d->value.contains(';') ||
d->value.contains(',') ||
d->value.contains(' ') ||
- d->value.contains('"')) {
+ d->value.contains('"')) &&
+ (!d->value.startsWith('"') &&
+ !d->value.endsWith('"'))) {
result += '"';
QByteArray value = d->value;
@@ -947,7 +958,7 @@ QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt
QNetworkCookie cookie;
// The first part is always the "NAME=VALUE" part
- QPair<QByteArray,QByteArray> field = nextField(cookieString, position);
+ QPair<QByteArray,QByteArray> field = nextField(cookieString, position, true);
if (field.first.isEmpty() || field.second.isNull())
// parsing error
break;
@@ -965,7 +976,7 @@ QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt
case ';':
// new field in the cookie
- field = nextField(cookieString, position);
+ field = nextField(cookieString, position, false);
field.first = field.first.toLower(); // everything but the NAME=VALUE is case-insensitive
if (field.first == "expires") {
diff --git a/src/network/access/qnetworkreplyfileimpl.cpp b/src/network/access/qnetworkreplyfileimpl.cpp
index 686eb5f..babee32 100644
--- a/src/network/access/qnetworkreplyfileimpl.cpp
+++ b/src/network/access/qnetworkreplyfileimpl.cpp
@@ -49,15 +49,10 @@
QT_BEGIN_NAMESPACE
QNetworkReplyFileImplPrivate::QNetworkReplyFileImplPrivate()
- : QNetworkReplyPrivate(), fileEngine(0), fileSize(0), filePos(0)
+ : QNetworkReplyPrivate(), realFileSize(0)
{
}
-QNetworkReplyFileImplPrivate::~QNetworkReplyFileImplPrivate()
-{
- delete fileEngine;
-}
-
QNetworkReplyFileImpl::~QNetworkReplyFileImpl()
{
}
@@ -112,15 +107,15 @@ QNetworkReplyFileImpl::QNetworkReplyFileImpl(QObject *parent, const QNetworkRequ
return;
}
- d->fileEngine = QAbstractFileEngine::create(fileName);
- bool opened = d->fileEngine->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+ d->realFile.setFileName(fileName);
+ bool opened = d->realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
// could we open the file?
if (!opened) {
QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2")
- .arg(fileName, d->fileEngine->errorString());
+ .arg(d->realFile.fileName(), d->realFile.errorString());
- if (fi.exists()) {
+ if (d->realFile.exists()) {
setError(QNetworkReply::ContentAccessDenied, msg);
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentAccessDenied));
@@ -133,13 +128,13 @@ QNetworkReplyFileImpl::QNetworkReplyFileImpl(QObject *parent, const QNetworkRequ
return;
}
- d->fileSize = fi.size();
setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified());
- setHeader(QNetworkRequest::ContentLengthHeader, d->fileSize);
+ d->realFileSize = fi.size();
+ setHeader(QNetworkRequest::ContentLengthHeader, d->realFileSize);
QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection,
- Q_ARG(qint64, d->fileSize), Q_ARG(qint64, d->fileSize));
+ Q_ARG(qint64, d->realFileSize), Q_ARG(qint64, d->realFileSize));
QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
}
@@ -147,25 +142,20 @@ void QNetworkReplyFileImpl::close()
{
Q_D(QNetworkReplyFileImpl);
QNetworkReply::close();
- if (d->fileEngine)
- d->fileEngine->close();
+ d->realFile.close();
}
void QNetworkReplyFileImpl::abort()
{
Q_D(QNetworkReplyFileImpl);
QNetworkReply::close();
- if (d->fileEngine)
- d->fileEngine->close();
+ d->realFile.close();
}
qint64 QNetworkReplyFileImpl::bytesAvailable() const
{
Q_D(const QNetworkReplyFileImpl);
- if (!d->fileEngine)
- return 0;
-
- return QNetworkReply::bytesAvailable() + d->fileSize - d->filePos;
+ return QNetworkReply::bytesAvailable() + d->realFile.bytesAvailable();
}
bool QNetworkReplyFileImpl::isSequential () const
@@ -176,7 +166,7 @@ bool QNetworkReplyFileImpl::isSequential () const
qint64 QNetworkReplyFileImpl::size() const
{
Q_D(const QNetworkReplyFileImpl);
- return d->fileSize;
+ return d->realFileSize;
}
/*!
@@ -185,17 +175,11 @@ qint64 QNetworkReplyFileImpl::size() const
qint64 QNetworkReplyFileImpl::readData(char *data, qint64 maxlen)
{
Q_D(QNetworkReplyFileImpl);
- if (!d->fileEngine)
+ qint64 ret = d->realFile.read(data, maxlen);
+ if (ret == 0 && bytesAvailable() == 0)
return -1;
-
- qint64 ret = d->fileEngine->read(data, maxlen);
- if (ret == 0 && bytesAvailable() == 0) {
- return -1; // everything had been read
- } else if (ret > 0) {
- d->filePos += ret;
- }
-
- return ret;
+ else
+ return ret;
}
diff --git a/src/network/access/qnetworkreplyfileimpl_p.h b/src/network/access/qnetworkreplyfileimpl_p.h
index 627363f..393e3cd 100644
--- a/src/network/access/qnetworkreplyfileimpl_p.h
+++ b/src/network/access/qnetworkreplyfileimpl_p.h
@@ -86,11 +86,9 @@ class QNetworkReplyFileImplPrivate: public QNetworkReplyPrivate
{
public:
QNetworkReplyFileImplPrivate();
- ~QNetworkReplyFileImplPrivate();
- QAbstractFileEngine *fileEngine;
- qint64 fileSize;
- qint64 filePos;
+ QFile realFile;
+ qint64 realFileSize;
Q_DECLARE_PUBLIC(QNetworkReplyFileImpl)
};
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 41a6c62..485f449 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -57,7 +57,7 @@ Q_DECLARE_METATYPE(QSharedPointer<char>)
QT_BEGIN_NAMESPACE
inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate()
- : backend(0), outgoingData(0), outgoingDataBuffer(0),
+ : backend(0), outgoingData(0),
copyDevice(0),
cacheEnabled(false), cacheSaveDevice(0),
notificationHandlingPaused(false),
@@ -212,7 +212,7 @@ void QNetworkReplyImplPrivate::_q_bufferOutgoingData()
if (!outgoingDataBuffer) {
// first call, create our buffer
- outgoingDataBuffer = new QRingBuffer();
+ outgoingDataBuffer = QSharedPointer<QRingBuffer>(new QRingBuffer());
QObject::connect(outgoingData, SIGNAL(readyRead()), q, SLOT(_q_bufferOutgoingData()));
QObject::connect(outgoingData, SIGNAL(readChannelFinished()), q, SLOT(_q_bufferOutgoingDataFinished()));
@@ -306,20 +306,22 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const
// Internal code that does a HTTP reply for the synchronous Ajax
// in QtWebKit.
QVariant synchronousHttpAttribute = req.attribute(
- static_cast<QNetworkRequest::Attribute>(QNetworkRequest::DownloadBufferAttribute + 1));
- if (backend && synchronousHttpAttribute.toBool()) {
- backend->setSynchronous(true);
- if (outgoingData && outgoingData->isSequential()) {
- outgoingDataBuffer = new QRingBuffer();
- QByteArray data;
- do {
- data = outgoingData->readAll();
- if (data.isEmpty())
- break;
- outgoingDataBuffer->append(data);
- } while (1);
- }
+ static_cast<QNetworkRequest::Attribute>(QNetworkRequest::SynchronousRequestAttribute));
+ // The synchronous HTTP is a corner case, we will put all upload data in one big QByteArray in the outgoingDataBuffer.
+ // Yes, this is not the most efficient thing to do, but on the other hand synchronous XHR needs to die anyway.
+ if (synchronousHttpAttribute.toBool() && outgoingData) {
+ outgoingDataBuffer = QSharedPointer<QRingBuffer>(new QRingBuffer());
+ qint64 previousDataSize = 0;
+ do {
+ previousDataSize = outgoingDataBuffer->size();
+ outgoingDataBuffer->append(outgoingData->readAll());
+ } while (outgoingDataBuffer->size() != previousDataSize);
}
+
+ if (backend)
+ backend->setSynchronous(synchronousHttpAttribute.toBool());
+
+
if (outgoingData && backend && !backend->isSynchronous()) {
// there is data to be uploaded, e.g. HTTP POST.
@@ -349,10 +351,6 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const
}
}
} else {
- // No outgoing data (e.g. HTTP GET request)
- // or no backend
- // if no backend, _q_startOperation will handle the error of this
-
// for HTTP, we want to send out the request as fast as possible to the network, without
// invoking methods in a QueuedConnection
#ifndef QT_NO_HTTP
@@ -634,8 +632,9 @@ char* QNetworkReplyImplPrivate::getDownloadBuffer(qint64 size)
{
Q_Q(QNetworkReplyImpl);
- // Check attribute() if allocating a buffer of that size can be allowed
if (!downloadBuffer) {
+ // We are requested to create it
+ // Check attribute() if allocating a buffer of that size can be allowed
QVariant bufferAllocationPolicy = request.attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute);
if (bufferAllocationPolicy.isValid() && bufferAllocationPolicy.toLongLong() >= size) {
downloadBufferCurrentSize = 0;
@@ -650,6 +649,18 @@ char* QNetworkReplyImplPrivate::getDownloadBuffer(qint64 size)
return downloadBuffer;
}
+void QNetworkReplyImplPrivate::setDownloadBuffer(QSharedPointer<char> sp, qint64 size)
+{
+ Q_Q(QNetworkReplyImpl);
+
+ downloadBufferPointer = sp;
+ downloadBuffer = downloadBufferPointer.data();
+ downloadBufferCurrentSize = 0;
+ downloadBufferMaximumSize = size;
+ q->setAttribute(QNetworkRequest::DownloadBufferAttribute, qVariantFromValue<QSharedPointer<char> > (downloadBufferPointer));
+}
+
+
void QNetworkReplyImplPrivate::appendDownstreamDataDownloadBuffer(qint64 bytesReceived, qint64 bytesTotal)
{
Q_Q(QNetworkReplyImpl);
@@ -746,6 +757,11 @@ void QNetworkReplyImplPrivate::finished()
void QNetworkReplyImplPrivate::error(QNetworkReplyImpl::NetworkError code, const QString &errorMessage)
{
Q_Q(QNetworkReplyImpl);
+ // Can't set and emit multiple errors.
+ if (errorCode != QNetworkReply::NoError) {
+ qWarning() << "QNetworkReplyImplPrivate::error: Internal problem, this method must only be called once.";
+ return;
+ }
errorCode = code;
q->setErrorString(errorMessage);
@@ -803,9 +819,6 @@ QNetworkReplyImpl::~QNetworkReplyImpl()
// save had been properly finished. So if it is still enabled it means we got deleted/aborted.
if (d->isCachingEnabled())
d->networkCache()->remove(url());
-
- if (d->outgoingDataBuffer)
- delete d->outgoingDataBuffer;
}
void QNetworkReplyImpl::abort()
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index 238bee5..1a9ab7e 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -164,6 +164,7 @@ public:
void appendDownstreamData(QIODevice *data);
void appendDownstreamData(const QByteArray &data);
+ void setDownloadBuffer(QSharedPointer<char> sp, qint64 size);
char* getDownloadBuffer(qint64 size);
void appendDownstreamDataDownloadBuffer(qint64, qint64);
@@ -175,7 +176,7 @@ public:
QNetworkAccessBackend *backend;
QIODevice *outgoingData;
- QRingBuffer *outgoingDataBuffer;
+ QSharedPointer<QRingBuffer> outgoingDataBuffer;
QIODevice *copyDevice;
QAbstractNetworkCache *networkCache() const;
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 8d46003..a48a26f 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -226,6 +226,8 @@ QT_BEGIN_NAMESPACE
\omitvalue DownloadBufferAttribute
+ \omitvalue SynchronousRequestAttribute
+
\value User
Special type. Additional information can be passed in
QVariants with types ranging from User to UserMax. The default
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index 586e6ff..b5ef109 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -84,9 +84,7 @@ public:
CookieSaveControlAttribute,
MaximumDownloadBufferSizeAttribute, // internal
DownloadBufferAttribute, // internal
-
- // (DownloadBufferAttribute + 1) is reserved internal for QSynchronousHttpNetworkReply
- // add the enum in 4.8
+ SynchronousRequestAttribute, // internal
User = 1000,
UserMax = 32767
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index 2a46229..9e1eaea 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -52,7 +52,8 @@
QT_BEGIN_NAMESPACE
#define Q_GLOBAL_STATIC_QAPP_DESTRUCTION(TYPE, NAME) \
- Q_GLOBAL_STATIC_INIT(TYPE, NAME); \
+ static QGlobalStatic<TYPE > this_##NAME \
+ = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \
static void NAME##_cleanup() \
{ \
delete this_##NAME.pointer; \
diff --git a/src/network/bearer/qsharednetworksession.cpp b/src/network/bearer/qsharednetworksession.cpp
index 51b3a32..28ca173 100644
--- a/src/network/bearer/qsharednetworksession.cpp
+++ b/src/network/bearer/qsharednetworksession.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index ead9897..2a942cc 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -2136,7 +2136,7 @@ qint64 QAbstractSocket::readData(char *data, qint64 maxSize)
qDebug("QAbstractSocket::readData(%p '%c (0x%.2x)', 1) == 1 [char buffer]",
data, isprint(int(uchar(*data))) ? *data : '?', *data);
#endif
- if (d->readBuffer.isEmpty() && d->socketEngine)
+ if (d->readBuffer.isEmpty() && d->socketEngine && d->socketEngine->isValid())
d->socketEngine->setReadNotificationEnabled(true);
return 1;
}
@@ -2148,7 +2148,8 @@ qint64 QAbstractSocket::readData(char *data, qint64 maxSize)
&& d->readBuffer.size() < maxSize
&& d->readBufferMaxSize > 0
&& maxSize < d->readBufferMaxSize
- && d->socketEngine) {
+ && d->socketEngine
+ && d->socketEngine->isValid()) {
// Our buffer is empty and a read() was requested for a byte amount that is smaller
// than the readBufferMaxSize. This means that we should fill our buffer since we want
// such small reads come from the buffer and not always go to the costly socket engine read()
@@ -2198,6 +2199,10 @@ qint64 QAbstractSocket::readData(char *data, qint64 maxSize)
if (!d->isBuffered) {
if (!d->socketEngine)
return -1; // no socket engine is probably EOF
+ if (!d->socketEngine->isValid())
+ return -1; // This is for unbuffered TCP when we already had been disconnected
+ if (d->state != QAbstractSocket::ConnectedState)
+ return -1; // This is for unbuffered TCP if we're not connected yet
qint64 readBytes = d->socketEngine->read(data, maxSize);
if (readBytes == -2) {
// -2 from the engine means no bytes available (EAGAIN) so read more later
@@ -2624,7 +2629,7 @@ void QAbstractSocket::setReadBufferSize(qint64 size)
// ensure that the read notification is enabled if we've now got
// room in the read buffer
// but only if we're not inside canReadNotification -- that will take care on its own
- if (size == 0 || d->readBuffer.size() < size)
+ if ((size == 0 || d->readBuffer.size() < size) && d->state == QAbstractSocket::ConnectedState) // Do not change the notifier unless we are connected.
d->socketEngine->setReadNotificationEnabled(true);
}
}
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index 4e628f3..6a025f2 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -743,7 +743,10 @@ void QHttpSocketEngine::emitReadNotification()
{
Q_D(QHttpSocketEngine);
d->readNotificationActivated = true;
- if (d->readNotificationEnabled && !d->readNotificationPending) {
+ // if there is a connection notification pending we have to emit the readNotification
+ // incase there is connection error. This is only needed for Windows, but it does not
+ // hurt in other cases.
+ if ((d->readNotificationEnabled && !d->readNotificationPending) || d->connectionNotificationPending) {
d->readNotificationPending = true;
QMetaObject::invokeMethod(this, "emitPendingReadNotification", Qt::QueuedConnection);
}
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 76c9158..940569a 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -337,15 +337,17 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
}
#if !defined(Q_OS_WINCE)
- // enable new behavior using
- // SIO_UDP_CONNRESET
- DWORD dwBytesReturned = 0;
- int bNewBehavior = 1;
- if (::WSAIoctl(socket, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior),
- NULL, 0, &dwBytesReturned, NULL, NULL) == SOCKET_ERROR) {
- // not to worry isBogusUdpReadNotification() should handle this otherwise
- int err = WSAGetLastError();
- WS_ERROR_DEBUG(err);
+ if (socketType == QAbstractSocket::UdpSocket) {
+ // enable new behavior using
+ // SIO_UDP_CONNRESET
+ DWORD dwBytesReturned = 0;
+ int bNewBehavior = 1;
+ if (::WSAIoctl(socket, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior),
+ NULL, 0, &dwBytesReturned, NULL, NULL) == SOCKET_ERROR) {
+ // not to worry isBogusUdpReadNotification() should handle this otherwise
+ int err = WSAGetLastError();
+ WS_ERROR_DEBUG(err);
+ }
}
#endif
@@ -639,6 +641,11 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
socketState = QAbstractSocket::UnconnectedState;
break;
}
+ if (value == WSAEADDRNOTAVAIL) {
+ setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
+ socketState = QAbstractSocket::UnconnectedState;
+ break;
+ }
}
// fall through
}
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 4252123..61f27fe 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -143,6 +143,15 @@
setDefaultCaCertificates().
\endlist
+ \note If available, root certificates on Unix (excluding Mac OS X) will be
+ loaded on demand from the standard certificate directories. If
+ you do not want to load root certificates on demand, you need to call either
+ the static function setDefaultCaCertificates() before the first SSL handshake
+ is made in your application, (e.g. via
+ "QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());"),
+ or call setCaCertificates() on your QSslSocket instance prior to the SSL
+ handshake.
+
For more information about ciphers and certificates, refer to QSslCipher and
QSslCertificate.
@@ -1249,6 +1258,7 @@ void QSslSocket::setCaCertificates(const QList<QSslCertificate> &certificates)
{
Q_D(QSslSocket);
d->configuration.caCertificates = certificates;
+ d->allowRootCertOnDemandLoading = false;
}
/*!
@@ -1258,6 +1268,9 @@ void QSslSocket::setCaCertificates(const QList<QSslCertificate> &certificates)
handshake with addCaCertificate(), addCaCertificates(), and
setCaCertificates().
+ \note On Unix, this method may return an empty list if the root
+ certificates are loaded on demand.
+
\sa addCaCertificate(), addCaCertificates(), setCaCertificates()
*/
QList<QSslCertificate> QSslSocket::caCertificates() const
@@ -1311,10 +1324,9 @@ void QSslSocket::addDefaultCaCertificates(const QList<QSslCertificate> &certific
/*!
Sets the default CA certificate database to \a certificates. The
default CA certificate database is originally set to your system's
- default CA certificate database. If no system default database is
- found, Qt will provide its own default database. You can override
- the default CA certificate database with your own CA certificate
- database using this function.
+ default CA certificate database. You can override the default CA
+ certificate database with your own CA certificate database using
+ this function.
Each SSL socket's CA certificate database is initialized to the
default CA certificate database.
@@ -1336,6 +1348,9 @@ void QSslSocket::setDefaultCaCertificates(const QList<QSslCertificate> &certific
Each SSL socket's CA certificate database is initialized to the
default CA certificate database.
+ \note On Unix, this method may return an empty list if the root
+ certificates are loaded on demand.
+
\sa caCertificates()
*/
QList<QSslCertificate> QSslSocket::defaultCaCertificates()
@@ -1803,6 +1818,7 @@ QSslSocketPrivate::QSslSocketPrivate()
, connectionEncrypted(false)
, ignoreAllSslErrors(false)
, readyReadEmittedPointer(0)
+ , allowRootCertOnDemandLoading(true)
, plainSocket(0)
{
QSslConfigurationPrivate::deepCopyDefaultConfiguration(&configuration);
@@ -1879,6 +1895,7 @@ void QSslSocketPrivate::setDefaultSupportedCiphers(const QList<QSslCipher> &ciph
*/
QList<QSslCertificate> QSslSocketPrivate::defaultCaCertificates()
{
+ // ### Qt5: rename everything containing "caCertificates" to "rootCertificates" or similar
QSslSocketPrivate::ensureInitialized();
QMutexLocker locker(&globalData()->mutex);
return globalData()->config->caCertificates;
@@ -1893,6 +1910,9 @@ void QSslSocketPrivate::setDefaultCaCertificates(const QList<QSslCertificate> &c
QMutexLocker locker(&globalData()->mutex);
globalData()->config.detach();
globalData()->config->caCertificates = certs;
+ // when the certificates are set explicitly, we do not want to
+ // load the system certificates on demand
+ s_loadRootCertsOnDemand = false;
}
/*!
@@ -2192,6 +2212,20 @@ void QSslSocketPrivate::_q_flushReadBuffer()
transmit();
}
+/*!
+ \internal
+*/
+QList<QByteArray> QSslSocketPrivate::unixRootCertDirectories()
+{
+ return QList<QByteArray>() << "/etc/ssl/certs/" // (K)ubuntu, OpenSUSE, Mandriva, MeeGo ...
+ << "/usr/lib/ssl/certs/" // Gentoo, Mandrake
+ << "/usr/share/ssl/" // Centos, Redhat, SuSE
+ << "/usr/local/ssl/" // Normal OpenSSL Tarball
+ << "/var/ssl/certs/" // AIX
+ << "/usr/local/ssl/certs/" // Solaris
+ << "/opt/openssl/certs/"; // HP-UX
+}
+
QT_END_NAMESPACE
// For private slots
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 84e14ff..83714ed 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -80,6 +80,7 @@ QT_BEGIN_NAMESPACE
bool QSslSocketPrivate::s_libraryLoaded = false;
bool QSslSocketPrivate::s_loadedCiphersAndCerts = false;
+bool QSslSocketPrivate::s_loadRootCertsOnDemand = false;
/* \internal
@@ -317,6 +318,13 @@ init_context:
q_X509_STORE_add_cert(ctx->cert_store, (X509 *)caCertificate.handle());
}
+ if (s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
+ // tell OpenSSL the directories where to look up the root certs on demand
+ QList<QByteArray> unixDirs = unixRootCertDirectories();
+ for (int a = 0; a < unixDirs.count(); ++a)
+ q_SSL_CTX_load_verify_locations(ctx, 0, unixDirs.at(a).constData());
+ }
+
// Register a custom callback to get all verification errors.
X509_STORE_set_verify_cb_func(ctx->cert_store, q_X509Callback);
@@ -517,8 +525,22 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
} else {
qWarning("could not load crypt32 library"); // should never happen
}
+#elif defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) && !defined(Q_OS_MAC)
+ // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
+ QList<QByteArray> dirs = unixRootCertDirectories();
+ QStringList symLinkFilter;
+ symLinkFilter << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]");
+ for (int a = 0; a < dirs.count(); ++a) {
+ QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files);
+ if (iterator.hasNext()) {
+ s_loadRootCertsOnDemand = true;
+ break;
+ }
+ }
#endif
- setDefaultCaCertificates(systemCaCertificates());
+ // if on-demand loading was not enabled, load the certs now
+ if (!s_loadRootCertsOnDemand)
+ setDefaultCaCertificates(systemCaCertificates());
}
/*!
@@ -814,15 +836,7 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
}
#elif defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
QSet<QString> certFiles;
- QList<QByteArray> directories;
- directories << "/etc/ssl/certs/"; // (K)ubuntu, OpenSUSE, Mandriva, MeeGo ...
- directories << "/usr/lib/ssl/certs/"; // Gentoo, Mandrake
- directories << "/usr/share/ssl/"; // Centos, Redhat, SuSE
- directories << "/usr/local/ssl/"; // Normal OpenSSL Tarball
- directories << "/var/ssl/certs/"; // AIX
- directories << "/usr/local/ssl/certs/"; // Solaris
- directories << "/opt/openssl/certs/"; // HP-UX
-
+ QList<QByteArray> directories = unixRootCertDirectories();
QDir currentDir;
QStringList nameFilters;
nameFilters << QLatin1String("*.pem") << QLatin1String("*.crt");
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 38598b6..b9a05f3 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -262,6 +262,7 @@ DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c,
#endif
DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
+DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
#ifdef Q_OS_SYMBIAN
#define RESOLVEFUNC(func, ordinal, lib) \
@@ -630,6 +631,7 @@ bool q_resolveOpenSslSymbols()
#endif
RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf, 1153, libs.second )
RESOLVEFUNC(OPENSSL_add_all_algorithms_conf, 1152, libs.second )
+ RESOLVEFUNC(SSL_CTX_load_verify_locations, 34, libs.second )
#else // Q_OS_SYMBIAN
#ifdef SSLEAY_MACROS
RESOLVEFUNC(ASN1_dup)
@@ -754,6 +756,7 @@ bool q_resolveOpenSslSymbols()
#endif
RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
+ RESOLVEFUNC(SSL_CTX_load_verify_locations)
#endif // Q_OS_SYMBIAN
symbolsResolved = true;
delete libs.first;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 954ffba..c05dfe11 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -412,6 +412,7 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
#endif
void q_OPENSSL_add_all_algorithms_noconf();
void q_OPENSSL_add_all_algorithms_conf();
+int q_SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath);
// Helper function
class QDateTime;
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 3a14488..7b92f95 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -112,6 +112,8 @@ public:
// that was used for connecting to.
QString verificationPeerName;
+ bool allowRootCertOnDemandLoading;
+
static bool supportsSsl();
static void ensureInitialized();
static void deinitialize();
@@ -168,6 +170,9 @@ private:
static bool s_libraryLoaded;
static bool s_loadedCiphersAndCerts;
+protected:
+ static bool s_loadRootCertsOnDemand;
+ static QList<QByteArray> unixRootCertDirectories();
};
QT_END_NAMESPACE
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index 04de1bd..db9f8c8 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
-extern const QGLContext* qt_gl_share_context();
+Q_OPENGL_EXPORT extern const QGLContext* qt_gl_share_context();
/*!
\class QGLFramebufferObjectPool
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index cdd3eb9..21b2f09 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -825,11 +825,7 @@ void QGLWindowSurface::updateGeometry() {
ctx->updatePaintDevice();
#endif
-#ifdef Q_WS_QPA
- QSize surfSize = size();
-#else
QSize surfSize = geometry().size();
-#endif
if (surfSize.width() <= 0 || surfSize.height() <= 0)
return;
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index 22cbbf5..f0f198f 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -3134,9 +3134,13 @@ void QVGPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF
if (pm.size().width() <= screenSize.width()
&& pm.size().height() <= screenSize.height())
vgpd->failedToAlloc = false;
- }
- drawImage(r, *(pd->buffer()), sr, Qt::AutoColor);
+ vgpd->source.beginDataAccess();
+ drawImage(r, vgpd->source.imageRef(), sr, Qt::AutoColor);
+ vgpd->source.endDataAccess(true);
+ } else {
+ drawImage(r, *(pd->buffer()), sr, Qt::AutoColor);
+ }
}
void QVGPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
@@ -3162,9 +3166,13 @@ void QVGPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
if (pm.size().width() <= screenSize.width()
&& pm.size().height() <= screenSize.height())
vgpd->failedToAlloc = false;
- }
- drawImage(pos, *(pd->buffer()));
+ vgpd->source.beginDataAccess();
+ drawImage(pos, vgpd->source.imageRef());
+ vgpd->source.endDataAccess();
+ } else {
+ drawImage(pos, *(pd->buffer()));
+ }
}
void QVGPaintEngine::drawImage
diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp
index 732b484..c5da115 100644
--- a/src/openvg/qpixmapdata_vg.cpp
+++ b/src/openvg/qpixmapdata_vg.cpp
@@ -70,7 +70,7 @@ QVGPixmapData::QVGPixmapData(PixelType type)
context = 0;
qt_vg_register_pixmap(this);
#endif
- setSerialNumber(++qt_vg_pixmap_serial);
+ updateSerial();
}
QVGPixmapData::~QVGPixmapData()
@@ -138,25 +138,31 @@ bool QVGPixmapData::isValid() const
return (w > 0 && h > 0);
}
+void QVGPixmapData::updateSerial()
+{
+ setSerialNumber(++qt_vg_pixmap_serial);
+}
+
void QVGPixmapData::resize(int wid, int ht)
{
- if (w == wid && h == ht)
+ if (w == wid && h == ht) {
+ updateSerial();
return;
+ }
w = wid;
h = ht;
d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
is_null = (w <= 0 || h <= 0);
- source = QImage();
+ source = QVolatileImage();
recreate = true;
- setSerialNumber(++qt_vg_pixmap_serial);
+ updateSerial();
}
-void QVGPixmapData::fromImage
- (const QImage &image, Qt::ImageConversionFlags flags)
+void QVGPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
{
- if(image.isNull())
+ if (image.isNull())
return;
QImage img = image;
@@ -200,33 +206,34 @@ bool QVGPixmapData::fromData(const uchar *buffer, uint len, const char *format,
return !isNull();
}
-/*!
- out-of-place conversion (inPlace == false) will always detach()
- */
-void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
+QImage::Format QVGPixmapData::idealFormat(QImage *image, Qt::ImageConversionFlags flags) const
{
- if (image.size() == QSize(w, h))
- setSerialNumber(++qt_vg_pixmap_serial);
- else
- resize(image.width(), image.height());
-
QImage::Format format = sourceFormat();
- int d = image.depth();
- if (d == 1 || d == 16 || d == 24 || (d == 32 && !image.hasAlphaChannel()))
+ int d = image->depth();
+ if (d == 1 || d == 16 || d == 24 || (d == 32 && !image->hasAlphaChannel()))
format = QImage::Format_RGB32;
- else if (!(flags & Qt::NoOpaqueDetection) && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels())
+ else if (!(flags & Qt::NoOpaqueDetection) && image->data_ptr()->checkForAlphaPixels())
format = sourceFormat();
else
- format = image.hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
+ format = image->hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
+ return format;
+}
+
+void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
+{
+ resize(image.width(), image.height());
+
+ QImage::Format format = idealFormat(&image, flags);
if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
- source = image;
+ source = QVolatileImage(image);
} else {
- source = image.convertToFormat(format);
-
- // convertToFormat won't detach the image if format stays the same.
- if (image.format() == format)
- source.detach();
+ QImage convertedImage = image.convertToFormat(format);
+ // convertToFormat won't detach the image if format stays the
+ // same. Detaching is needed to prevent issues with painting
+ // onto this QPixmap later on.
+ convertedImage.detach();
+ source = QVolatileImage(convertedImage);
}
recreate = true;
@@ -238,12 +245,13 @@ void QVGPixmapData::fill(const QColor &color)
return;
if (source.isNull())
- source = QImage(w, h, sourceFormat());
+ source = QVolatileImage(w, h, sourceFormat());
if (source.depth() == 1) {
// Pick the best approximate color in the image's colortable.
int gray = qGray(color.rgba());
- if (qAbs(qGray(source.color(0)) - gray) < qAbs(qGray(source.color(1)) - gray))
+ if (qAbs(qGray(source.imageRef().color(0)) - gray)
+ < qAbs(qGray(source.imageRef().color(1)) - gray))
source.fill(0);
else
source.fill(1);
@@ -266,7 +274,7 @@ bool QVGPixmapData::hasAlphaChannel() const
void QVGPixmapData::setAlphaChannel(const QPixmap &alphaChannel)
{
forceToImage();
- source.setAlphaChannel(alphaChannel.toImage());
+ source.setAlphaChannel(alphaChannel);
}
QImage QVGPixmapData::toImage() const
@@ -275,17 +283,41 @@ QImage QVGPixmapData::toImage() const
return QImage();
if (source.isNull()) {
- source = QImage(w, h, sourceFormat());
+ source = QVolatileImage(w, h, sourceFormat());
recreate = true;
}
- return source;
+ return source.toImage();
+}
+
+void QVGPixmapData::copy(const QPixmapData *data, const QRect &rect)
+{
+ // toImage() is potentially expensive with QVolatileImage so provide a
+ // more efficient implementation of copy() that does not rely on it.
+ if (!data) {
+ return;
+ }
+ if (data->classId() != OpenVGClass) {
+ fromImage(data->toImage(rect), Qt::NoOpaqueDetection);
+ return;
+ }
+ const QVGPixmapData *pd = static_cast<const QVGPixmapData *>(data);
+ QRect r = rect;
+ if (r.isNull() || r.contains(QRect(0, 0, pd->w, pd->h))) {
+ r = QRect(0, 0, pd->w, pd->h);
+ }
+ resize(r.width(), r.height());
+ recreate = true;
+ if (!pd->source.isNull()) {
+ source = QVolatileImage(r.width(), r.height(), pd->source.format());
+ source.copyFrom(&pd->source, r);
+ }
}
QImage *QVGPixmapData::buffer()
{
- forceToImage();
- return &source;
+ // Cannot be safely implemented and QVGPixmapData is not (must not be) RasterClass anyway.
+ return 0;
}
QPaintEngine* QVGPixmapData::paintEngine() const
@@ -329,10 +361,12 @@ VGImage QVGPixmapData::toVGImage()
}
if (!source.isNull() && recreate) {
+ source.beginDataAccess();
vgImageSubData
(vgImage,
source.constBits(), source.bytesPerLine(),
qt_vg_image_to_vg_format(source.format()), 0, 0, w, h);
+ source.endDataAccess(true);
}
recreate = false;
@@ -442,14 +476,14 @@ int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
}
}
-// Force the pixmap data to be in QImage format.
+// Force the pixmap data to be backed by some valid data.
void QVGPixmapData::forceToImage()
{
if (!isValid())
return;
if (source.isNull())
- source = QImage(w, h, sourceFormat());
+ source = QVolatileImage(w, h, sourceFormat());
recreate = true;
}
diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h
index 58e69db..c4fd47f 100644
--- a/src/openvg/qpixmapdata_vg_p.h
+++ b/src/openvg/qpixmapdata_vg_p.h
@@ -54,6 +54,7 @@
//
#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/private/qvolatileimage_p.h>
#include <private/qvg_p.h>
#if defined(Q_OS_SYMBIAN)
@@ -99,6 +100,7 @@ public:
bool hasAlphaChannel() const;
void setAlphaChannel(const QPixmap &alphaChannel);
QImage toImage() const;
+ void copy(const QPixmapData *data, const QRect &rect);
QImage *buffer();
QPaintEngine* paintEngine() const;
@@ -161,7 +163,7 @@ protected:
VGImage vgImage;
VGImage vgImageOpacity;
qreal cachedOpacity;
- mutable QImage source;
+ mutable QVolatileImage source;
mutable bool recreate;
bool inImagePool;
#if !defined(QT_NO_EGL)
@@ -170,6 +172,8 @@ protected:
void forceToImage();
QImage::Format sourceFormat() const;
+ QImage::Format idealFormat(QImage *image, Qt::ImageConversionFlags flags) const;
+ void updateSerial();
void destroyImageAndContext();
void destroyImages();
diff --git a/src/openvg/qvg_symbian.cpp b/src/openvg/qvg_symbian.cpp
index ff0ab13..22cbb3c 100644
--- a/src/openvg/qvg_symbian.cpp
+++ b/src/openvg/qvg_symbian.cpp
@@ -44,7 +44,6 @@
#include <private/qt_s60_p.h>
#include <fbs.h>
-#include <bitdev.h>
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
# include <sgresource/sgimage.h>
@@ -75,34 +74,6 @@ VGImage QVG::vgCreateEGLImageTargetKHR(VGeglImageKHR eglImage)
extern int qt_vg_pixmap_serial;
-static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap)
-{
- CFbsBitmap *copy = new CFbsBitmap;
- Q_CHECK_PTR(copy);
- if(!copy)
- return 0;
-
- if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) {
- delete copy;
- copy = 0;
-
- return 0;
- }
-
- CFbsBitmapDevice* bitmapDevice = 0;
- CFbsBitGc *bitmapGc = 0;
- QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(copy));
- QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
- bitmapGc->Activate(bitmapDevice);
-
- bitmapGc->BitBlt(TPoint(), bitmap);
-
- delete bitmapGc;
- delete bitmapDevice;
-
- return copy;
-}
-
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
static VGImage sgImageToVGImage(QEglContext *context, const RSgImage &sgImage)
{
@@ -137,7 +108,7 @@ void QVGPixmapData::cleanup()
{
is_null = w = h = 0;
recreate = false;
- source = QImage();
+ source = QVolatileImage();
}
void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
@@ -156,55 +127,28 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
}
is_null = (w <= 0 || h <= 0);
- source = QImage(); // vgGetImageSubData() some day?
+ source = QVolatileImage(); // vgGetImageSubData() some day?
recreate = false;
prevSize = QSize(w, h);
- //setSerialNumber(++qt_vg_pixmap_serial);
+ updateSerial();
#endif
- } else if (type == QPixmapData::FbsBitmap) {
- CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
-
- bool deleteSourceBitmap = false;
-#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
-
- // Rasterize extended bitmaps
-
- TUid extendedBitmapType = bitmap->ExtendedBitmapType();
- if (extendedBitmapType != KNullUid) {
- bitmap = createBlitCopy(bitmap);
- deleteSourceBitmap = true;
- }
-#endif
-
- if (bitmap->IsCompressedInRAM()) {
- bitmap = createBlitCopy(bitmap);
- deleteSourceBitmap = true;
- }
-
- TDisplayMode displayMode = bitmap->DisplayMode();
- QImage::Format format = qt_TDisplayMode2Format(displayMode);
-
- TSize size = bitmap->SizeInPixels();
- int bytesPerLine = bitmap->ScanLineLength(size.iWidth, displayMode);
-
- bitmap->BeginDataAccess();
- uchar *bytes = (uchar*)bitmap->DataAddress();
- QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format);
- img = img.copy();
- bitmap->EndDataAccess();
-
- if(displayMode == EGray2) {
- //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
- //So invert mono bitmaps so that masks work correctly.
- img.invertPixels();
- } else if(displayMode == EColor16M) {
- img = img.rgbSwapped(); // EColor16M is BGR
- }
-
- fromImage(img, Qt::AutoColor);
-
- if(deleteSourceBitmap)
- delete bitmap;
+ } else if (type == QPixmapData::FbsBitmap && pixmap) {
+ CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap *>(pixmap);
+ QSize size(bitmap->SizeInPixels().iWidth, bitmap->SizeInPixels().iHeight);
+ resize(size.width(), size.height());
+ source = QVolatileImage(bitmap); // duplicates only, if possible
+ if (source.isNull())
+ return;
+ // Here we may need to copy if the formats do not match.
+ // (e.g. for display modes other than EColor16MAP and EColor16MU)
+ source.ensureFormat(idealFormat(&source.imageRef(), Qt::AutoColor));
+ recreate = true;
+ } else if (type == QPixmapData::VolatileImage && pixmap) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(pixmap);
+ resize(img->width(), img->height());
+ source = *img;
+ source.ensureFormat(idealFormat(&source.imageRef(), Qt::AutoColor));
+ recreate = true;
}
}
@@ -271,27 +215,14 @@ void* QVGPixmapData::toNativeType(NativeType type)
driver.Close();
return reinterpret_cast<void*>(sgImage.take());
#endif
- } else if (type == QPixmapData::FbsBitmap) {
- CFbsBitmap *bitmap = new CFbsBitmap;
- Q_CHECK_PTR(bitmap);
-
- if (bitmap) {
- if (bitmap->Create(TSize(source.width(), source.height()),
- EColor16MAP) == KErrNone) {
- const uchar *sptr = const_cast<const QImage&>(source).bits();
- bitmap->BeginDataAccess();
-
- uchar *dptr = (uchar*)bitmap->DataAddress();
- Mem::Copy(dptr, sptr, source.byteCount());
-
- bitmap->EndDataAccess();
- } else {
- delete bitmap;
- bitmap = 0;
- }
+ } else if (type == QPixmapData::FbsBitmap && isValid()) {
+ if (source.isNull()) {
+ source = QVolatileImage(w, h, sourceFormat());
}
-
- return reinterpret_cast<void*>(bitmap);
+ // Just duplicate the bitmap handle, no data copying happens.
+ return source.duplicateNativeImage();
+ } else if (type == QPixmapData::VolatileImage) {
+ return &source;
}
return 0;
}
diff --git a/src/openvg/qvgfontglyphcache_p.h b/src/openvg/qvgfontglyphcache_p.h
index 9a105ec..ce12301 100644
--- a/src/openvg/qvgfontglyphcache_p.h
+++ b/src/openvg/qvgfontglyphcache_p.h
@@ -56,7 +56,7 @@
#include <QtCore/qvarlengtharray.h>
#include <QtGui/private/qfontengine_p.h>
-#include <qvg_p.h>
+#include "qvg_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/openvg/qvgimagepool.cpp b/src/openvg/qvgimagepool.cpp
index a2b1c4e..7a7ec78 100644
--- a/src/openvg/qvgimagepool.cpp
+++ b/src/openvg/qvgimagepool.cpp
@@ -175,8 +175,19 @@ bool QVGImagePool::reclaimSpace(VGImageFormat format,
void QVGImagePool::hibernate()
{
- // Nothing to do here at the moment since the pool does not
- // retain VGImage's after they have been released.
+ Q_D(QVGImagePool);
+ QVGPixmapData *pd = d->lruLast;
+ while (pd) {
+ QVGPixmapData *prevLRU = pd->prevLRU;
+ pd->inImagePool = false;
+ pd->inLRU = false;
+ pd->nextLRU = 0;
+ pd->prevLRU = 0;
+ pd->hibernate();
+ pd = prevLRU;
+ }
+ d->lruFirst = 0;
+ d->lruLast = 0;
}
void QVGImagePool::moveToHeadOfLRU(QVGPixmapData *data)
diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp
index fc480c2..f367c26 100644
--- a/src/plugins/bearer/symbian/symbianengine.cpp
+++ b/src/plugins/bearer/symbian/symbianengine.cpp
@@ -150,16 +150,15 @@ SymbianEngine::~SymbianEngine()
iConnectionMonitor.CancelNotifications();
iConnectionMonitor.Close();
-
-#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- iCmManager.Close();
-#endif
-
- // CCommsDatabase destructor uses cleanup stack. Since QNetworkConfigurationManager
+
+ // CCommsDatabase destructor and RCmManager.Close() use cleanup stack. Since QNetworkConfigurationManager
// is a global static, but the time we are here, E32Main() has been exited already and
// the thread's default cleanup stack has been deleted. Without this line, a
// 'E32USER-CBase 69' -panic will occur.
CTrapCleanup* cleanup = CTrapCleanup::New();
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ iCmManager.Close();
+#endif
delete ipCommsDB;
delete cleanup;
}
@@ -829,6 +828,7 @@ void SymbianEngine::updateStatesToSnaps()
discovered = true;
}
}
+ snapConfigLocker.unlock();
if (active) {
changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
} else if (discovered) {
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
index a70d232..13eab7f 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
@@ -171,7 +171,7 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handl
return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
} else {
QRasterPixmapData *pmd = new QRasterPixmapData(QPixmapData::PixmapType);
- pmd->fromImage(softImage, Qt::NoOpaqueDetection);
+ pmd->fromImage(softImage, Qt::NoFormatConversion);
// Make sure that the image was not converted in any way
if (pmd->buffer()->data_ptr()->data !=
@@ -335,3 +335,8 @@ void qt_meego_destroy_fence_sync(void* fs)
{
return QMeeGoGraphicsSystem::destroyFenceSync(fs);
}
+
+void qt_meego_invalidate_live_surfaces(void)
+{
+ return QMeeGoLivePixmapData::invalidateSurfaces();
+}
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
index 323ce1f..27a4e7a 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.h
+++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
@@ -103,6 +103,7 @@ extern "C" {
Q_DECL_EXPORT Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap);
Q_DECL_EXPORT void* qt_meego_create_fence_sync(void);
Q_DECL_EXPORT void qt_meego_destroy_fence_sync(void* fs);
+ Q_DECL_EXPORT void qt_meego_invalidate_live_surfaces(void);
}
#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
index e4f1900..2a2a098 100644
--- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
@@ -49,6 +49,8 @@
#include <private/qpixmap_x11_p.h>
#include <stdio.h>
+static QMeeGoLivePixmapDataList all_live_pixmaps;
+
static EGLint lock_attribs[] = {
EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE,
EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR,
@@ -118,21 +120,29 @@ QMeeGoLivePixmapData::QMeeGoLivePixmapData(int w, int h, QImage::Format format)
backingX11Pixmap = new QPixmap(pmd);
initializeThroughEGLImage();
+
+ pos = all_live_pixmaps.insert(all_live_pixmaps.begin(), this);
}
QMeeGoLivePixmapData::QMeeGoLivePixmapData(Qt::HANDLE h) : QGLPixmapData(QPixmapData::PixmapType)
{
backingX11Pixmap = new QPixmap(QPixmap::fromX11Pixmap(h));
initializeThroughEGLImage();
+
+ pos = all_live_pixmaps.insert(all_live_pixmaps.begin(), this);
}
QMeeGoLivePixmapData::~QMeeGoLivePixmapData()
{
delete backingX11Pixmap;
+ all_live_pixmaps.erase(pos);
}
void QMeeGoLivePixmapData::initializeThroughEGLImage()
{
+ if (texture()->id != 0)
+ return;
+
QGLShareContextScope ctx(qt_gl_share_widget()->context());
QMeeGoExtensions::ensureInitialized();
@@ -245,6 +255,8 @@ bool QMeeGoLivePixmapData::scroll(int dx, int dy, const QRect &rect)
EGLSurface QMeeGoLivePixmapData::getSurfaceForBackingPixmap()
{
+ initializeThroughEGLImage();
+
// This code is a crative remix of the stuff that can be found in the
// Qt's TFP implementation in /src/opengl/qgl_x11egl.cpp ::bindiTextureFromNativePixmap
QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(backingX11Pixmap->data_ptr().data());
@@ -290,3 +302,12 @@ void QMeeGoLivePixmapData::destroySurfaceForPixmapData(QPixmapData* pmd)
pixmapData->gl_surface = 0;
}
}
+
+void QMeeGoLivePixmapData::invalidateSurfaces()
+{
+ foreach (QMeeGoLivePixmapData *data, all_live_pixmaps) {
+ QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(data->backingX11Pixmap->data_ptr().data());
+ *data->texture() = QGLTexture();
+ pixmapData->gl_surface = 0;
+ }
+}
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
index 484028e..616b33c 100644
--- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
+++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
@@ -42,9 +42,13 @@
#ifndef MLIVEPIXMAPDATA_H
#define MLIVEPIXMAPDATA_H
+#include <QLinkedList>
#include <private/qpixmapdata_gl_p.h>
#include "qmeegoextensions.h"
+class QMeeGoLivePixmapData;
+typedef QLinkedList<QMeeGoLivePixmapData *> QMeeGoLivePixmapDataList;
+
class QMeeGoLivePixmapData : public QGLPixmapData
{
public:
@@ -66,6 +70,9 @@ public:
QPixmap *backingX11Pixmap;
QImage lockedImage;
+ QMeeGoLivePixmapDataList::Iterator pos;
+
+ static void invalidateSurfaces();
};
#endif
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
index 0c107b5..1da58e1 100644
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
+++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
@@ -42,6 +42,7 @@
#include "qgraphicssystem_vg_p.h"
#include <QtOpenVG/private/qpixmapdata_vg_p.h>
#include <QtOpenVG/private/qwindowsurface_vg_p.h>
+#include <QtOpenVG/private/qvgimagepool_p.h>
#if defined(Q_OS_SYMBIAN) && !defined(Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE)
#include <QtGui/private/qwidget_p.h>
#endif
@@ -77,4 +78,9 @@ QWindowSurface *QVGGraphicsSystem::createWindowSurface(QWidget *widget) const
return new QVGWindowSurface(widget);
}
+void QVGGraphicsSystem::releaseCachedResources()
+{
+ QVGImagePool::instance()->hibernate();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
index d1bce28..9c9b3e2 100644
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
+++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
@@ -64,6 +64,8 @@ public:
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QWindowSurface *createWindowSurface(QWidget *widget) const;
+
+ void releaseCachedResources();
};
QT_END_NAMESPACE
diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def
index dd7d588..5579e5a 100644
--- a/src/s60installs/bwins/QtCoreu.def
+++ b/src/s60installs/bwins/QtCoreu.def
@@ -1380,7 +1380,7 @@ EXPORTS
?create@QAbstractFileEngine@@SAPAV1@ABVQString@@@Z @ 1379 NONAME ; class QAbstractFileEngine * QAbstractFileEngine::create(class QString const &)
?create@QNonContiguousByteDeviceFactory@@SAPAVQNonContiguousByteDevice@@PAVQByteArray@@@Z @ 1380 NONAME ; class QNonContiguousByteDevice * QNonContiguousByteDeviceFactory::create(class QByteArray *)
?create@QNonContiguousByteDeviceFactory@@SAPAVQNonContiguousByteDevice@@PAVQIODevice@@@Z @ 1381 NONAME ; class QNonContiguousByteDevice * QNonContiguousByteDeviceFactory::create(class QIODevice *)
- ?create@QNonContiguousByteDeviceFactory@@SAPAVQNonContiguousByteDevice@@PAVQRingBuffer@@@Z @ 1382 NONAME ; class QNonContiguousByteDevice * QNonContiguousByteDeviceFactory::create(class QRingBuffer *)
+ ?create@QNonContiguousByteDeviceFactory@@SAPAVQNonContiguousByteDevice@@PAVQRingBuffer@@@Z @ 1382 NONAME ABSENT ; class QNonContiguousByteDevice * QNonContiguousByteDeviceFactory::create(class QRingBuffer *)
?create@QSharedMemory@@QAE_NHW4AccessMode@1@@Z @ 1383 NONAME ; bool QSharedMemory::create(int, enum QSharedMemory::AccessMode)
?create@QTextCodecPlugin@@EAEPAVQTextCodec@@ABVQString@@@Z @ 1384 NONAME ; class QTextCodec * QTextCodecPlugin::create(class QString const &)
?create@QVariant@@IAEXHPBX@Z @ 1385 NONAME ; void QVariant::create(int, void const *)
@@ -4605,4 +4605,8 @@ EXPORTS
?hasError@QXmlStreamWriter@@QBE_NXZ @ 4604 NONAME ; bool QXmlStreamWriter::hasError(void) const
?revision@QMetaProperty@@QBEHXZ @ 4605 NONAME ; int QMetaProperty::revision(void) const
?revision@QMetaMethod@@QBEHXZ @ 4606 NONAME ; int QMetaMethod::revision(void) const
+ ?started@QAnimationDriver@@MAEXXZ @ 4607 NONAME ; void QAnimationDriver::started(void)
+ ?stopped@QAnimationDriver@@MAEXXZ @ 4608 NONAME ; void QAnimationDriver::stopped(void)
+ ?isResetDisabled@QNonContiguousByteDevice@@QAE_NXZ @ 4609 NONAME ; bool QNonContiguousByteDevice::isResetDisabled(void)
+ ?create@QNonContiguousByteDeviceFactory@@SAPAVQNonContiguousByteDevice@@V?$QSharedPointer@VQRingBuffer@@@@@Z @ 4610 NONAME ; class QNonContiguousByteDevice * QNonContiguousByteDeviceFactory::create(class QSharedPointer<class QRingBuffer>)
diff --git a/src/s60installs/bwins/QtDeclarativeu.def b/src/s60installs/bwins/QtDeclarativeu.def
index 7d0a83e..8b23b63 100644
--- a/src/s60installs/bwins/QtDeclarativeu.def
+++ b/src/s60installs/bwins/QtDeclarativeu.def
@@ -3,7 +3,7 @@ EXPORTS
?setStored@QMetaPropertyBuilder@@QAEX_N@Z @ 2 NONAME ABSENT ; void QMetaPropertyBuilder::setStored(bool)
?trUtf8@QDeclarativeExpression@@SA?AVQString@@PBD0H@Z @ 3 NONAME ; class QString QDeclarativeExpression::trUtf8(char const *, char const *, int)
?qt_metacast@QDeclarativeComponent@@UAEPAXPBD@Z @ 4 NONAME ; void * QDeclarativeComponent::qt_metacast(char const *)
- ?name@QDeclarativeDebugService@@QBE?AVQString@@XZ @ 5 NONAME ABSENT ; class QString QDeclarativeDebugService::name(void) const
+ ?name@QDeclarativeDebugService@@QBE?AVQString@@XZ @ 5 NONAME ; class QString QDeclarativeDebugService::name(void) const
?debugId@QDeclarativeDebugObjectReference@@QBEHXZ @ 6 NONAME ABSENT ; int QDeclarativeDebugObjectReference::debugId(void) const
?addPluginPath@QDeclarativeEngine@@QAEXABVQString@@@Z @ 7 NONAME ; void QDeclarativeEngine::addPluginPath(class QString const &)
?name@QMetaPropertyBuilder@@QBE?AVQByteArray@@XZ @ 8 NONAME ABSENT ; class QByteArray QMetaPropertyBuilder::name(void) const
@@ -11,7 +11,7 @@ EXPORTS
?propertyOffset@QDeclarativeOpenMetaObjectType@@QBEHXZ @ 10 NONAME ABSENT ; int QDeclarativeOpenMetaObjectType::propertyOffset(void) const
??0QDeclarativeText@@QAE@PAVQDeclarativeItem@@@Z @ 11 NONAME ABSENT ; QDeclarativeText::QDeclarativeText(class QDeclarativeItem *)
?propertyTypeName@QDeclarativeProperty@@QBEPBDXZ @ 12 NONAME ; char const * QDeclarativeProperty::propertyTypeName(void) const
- ?getStaticMetaObject@QDeclarativeDebugService@@SAABUQMetaObject@@XZ @ 13 NONAME ABSENT ; struct QMetaObject const & QDeclarativeDebugService::getStaticMetaObject(void)
+ ?getStaticMetaObject@QDeclarativeDebugService@@SAABUQMetaObject@@XZ @ 13 NONAME ; struct QMetaObject const & QDeclarativeDebugService::getStaticMetaObject(void)
?setLeft@QDeclarativeAnchors@@QAEXABVQDeclarativeAnchorLine@@@Z @ 14 NONAME ABSENT ; void QDeclarativeAnchors::setLeft(class QDeclarativeAnchorLine const &)
?qt_metacall@QDeclarativeExpression@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 15 NONAME ; int QDeclarativeExpression::qt_metacall(enum QMetaObject::Call, int, void * *)
?staticMetaObject@QDeclarativePen@@2UQMetaObject@@B @ 16 NONAME ABSENT ; struct QMetaObject const QDeclarativePen::staticMetaObject
@@ -145,7 +145,7 @@ EXPORTS
?isConnected@QDeclarativeDebugClient@@QBE_NXZ @ 144 NONAME ABSENT ; bool QDeclarativeDebugClient::isConnected(void) const
?enabled@QDeclarativeBinding@@QBE_NXZ @ 145 NONAME ABSENT ; bool QDeclarativeBinding::enabled(void) const
?setSource@QDeclarativeView@@QAEXABVQUrl@@@Z @ 146 NONAME ; void QDeclarativeView::setSource(class QUrl const &)
- ??_EQDeclarativeDebugService@@UAE@I@Z @ 147 NONAME ABSENT ; QDeclarativeDebugService::~QDeclarativeDebugService(unsigned int)
+ ??_EQDeclarativeDebugService@@UAE@I@Z @ 147 NONAME ; QDeclarativeDebugService::~QDeclarativeDebugService(unsigned int)
??0QDeclarativeDomDynamicProperty@@QAE@ABV0@@Z @ 148 NONAME ABSENT ; QDeclarativeDomDynamicProperty::QDeclarativeDomDynamicProperty(class QDeclarativeDomDynamicProperty const &)
?className@QDeclarativeDebugObjectReference@@QBE?AVQString@@XZ @ 149 NONAME ABSENT ; class QString QDeclarativeDebugObjectReference::className(void) const
?indexOfSlot@QMetaObjectBuilder@@QAEHABVQByteArray@@@Z @ 150 NONAME ABSENT ; int QMetaObjectBuilder::indexOfSlot(class QByteArray const &)
@@ -294,7 +294,7 @@ EXPORTS
?attachedPropertiesType@QDeclarativeType@@QBEPBUQMetaObject@@XZ @ 293 NONAME ABSENT ; struct QMetaObject const * QDeclarativeType::attachedPropertiesType(void) const
?setName@QDeclarativeState@@QAEXABVQString@@@Z @ 294 NONAME ; void QDeclarativeState::setName(class QString const &)
?setReversed@QDeclarativeTransition@@QAEX_N@Z @ 295 NONAME ; void QDeclarativeTransition::setReversed(bool)
- ?idForObject@QDeclarativeDebugService@@SAHPAVQObject@@@Z @ 296 NONAME ABSENT ; int QDeclarativeDebugService::idForObject(class QObject *)
+ ?idForObject@QDeclarativeDebugService@@SAHPAVQObject@@@Z @ 296 NONAME ; int QDeclarativeDebugService::idForObject(class QObject *)
?qt_metacall@QDeclarativeDebugWatch@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 297 NONAME ABSENT ; int QDeclarativeDebugWatch::qt_metacall(enum QMetaObject::Call, int, void * *)
?fromState@QDeclarativeTransition@@QBE?AVQString@@XZ @ 298 NONAME ; class QString QDeclarativeTransition::fromState(void) const
??1QDeclarativeExpression@@UAE@XZ @ 299 NONAME ; QDeclarativeExpression::~QDeclarativeExpression(void)
@@ -332,7 +332,7 @@ EXPORTS
??0QDeclarativeCustomParserNode@@QAE@ABV0@@Z @ 331 NONAME ; QDeclarativeCustomParserNode::QDeclarativeCustomParserNode(class QDeclarativeCustomParserNode const &)
??1QDeclarativeImageProvider@@UAE@XZ @ 332 NONAME ; QDeclarativeImageProvider::~QDeclarativeImageProvider(void)
?sync@QDeclarativeListModel@@QAEXXZ @ 333 NONAME ABSENT ; void QDeclarativeListModel::sync(void)
- ?objectForId@QDeclarativeDebugService@@SAPAVQObject@@H@Z @ 334 NONAME ABSENT ; class QObject * QDeclarativeDebugService::objectForId(int)
+ ?objectForId@QDeclarativeDebugService@@SAPAVQObject@@H@Z @ 334 NONAME ; class QObject * QDeclarativeDebugService::objectForId(int)
?hasFocus@QDeclarativeItem@@QBE_NXZ @ 335 NONAME ; bool QDeclarativeItem::hasFocus(void) const
??1QDeclarativeExtensionPlugin@@UAE@XZ @ 336 NONAME ; QDeclarativeExtensionPlugin::~QDeclarativeExtensionPlugin(void)
?qt_metacall@QDeclarativeBehavior@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 337 NONAME ABSENT ; int QDeclarativeBehavior::qt_metacall(enum QMetaObject::Call, int, void * *)
@@ -482,7 +482,7 @@ EXPORTS
?pluginPathList@QDeclarativeEngine@@QBE?AVQStringList@@XZ @ 481 NONAME ; class QStringList QDeclarativeEngine::pluginPathList(void) const
?parentContext@QDeclarativeContext@@QBEPAV1@XZ @ 482 NONAME ; class QDeclarativeContext * QDeclarativeContext::parentContext(void) const
?leftMarginChanged@QDeclarativeAnchors@@IAEXXZ @ 483 NONAME ABSENT ; void QDeclarativeAnchors::leftMarginChanged(void)
- ?staticMetaObject@QDeclarativeDebugService@@2UQMetaObject@@B @ 484 NONAME ABSENT ; struct QMetaObject const QDeclarativeDebugService::staticMetaObject
+ ?staticMetaObject@QDeclarativeDebugService@@2UQMetaObject@@B @ 484 NONAME ; struct QMetaObject const QDeclarativeDebugService::staticMetaObject
?topMargin@QDeclarativeAnchors@@QBEMXZ @ 485 NONAME ABSENT ; float QDeclarativeAnchors::topMargin(void) const
??0QDeclarativeDebugExpressionQuery@@AAE@PAVQObject@@@Z @ 486 NONAME ABSENT ; QDeclarativeDebugExpressionQuery::QDeclarativeDebugExpressionQuery(class QObject *)
??0QPacket@@IAE@ABVQByteArray@@@Z @ 487 NONAME ; QPacket::QPacket(class QByteArray const &)
@@ -559,7 +559,7 @@ EXPORTS
?metaObject@QDeclarativeEngine@@UBEPBUQMetaObject@@XZ @ 558 NONAME ; struct QMetaObject const * QDeclarativeEngine::metaObject(void) const
??_EQDeclarativeDebugContextReference@@QAE@I@Z @ 559 NONAME ABSENT ; QDeclarativeDebugContextReference::~QDeclarativeDebugContextReference(unsigned int)
?propertyWrite@QDeclarativeOpenMetaObject@@MAEXH@Z @ 560 NONAME ABSENT ; void QDeclarativeOpenMetaObject::propertyWrite(int)
- ?qt_metacall@QDeclarativeDebugService@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 561 NONAME ABSENT ; int QDeclarativeDebugService::qt_metacall(enum QMetaObject::Call, int, void * *)
+ ?qt_metacall@QDeclarativeDebugService@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 561 NONAME ; int QDeclarativeDebugService::qt_metacall(enum QMetaObject::Call, int, void * *)
?setVerticalCenterOffset@QDeclarativeAnchors@@QAEXM@Z @ 562 NONAME ABSENT ; void QDeclarativeAnchors::setVerticalCenterOffset(float)
??1QDeclarativeDebugWatch@@UAE@XZ @ 563 NONAME ABSENT ; QDeclarativeDebugWatch::~QDeclarativeDebugWatch(void)
??1QPacketAutoSend@@UAE@XZ @ 564 NONAME ABSENT ; QPacketAutoSend::~QPacketAutoSend(void)
@@ -641,7 +641,7 @@ EXPORTS
?d_func@QDeclarativeItem@@AAEPAVQDeclarativeItemPrivate@@XZ @ 640 NONAME ; class QDeclarativeItemPrivate * QDeclarativeItem::d_func(void)
?binding@QDeclarativeDomValueBinding@@QBE?AVQString@@XZ @ 641 NONAME ABSENT ; class QString QDeclarativeDomValueBinding::binding(void) const
?updateAutoState@QDeclarativeStateGroup@@AAE_NXZ @ 642 NONAME ; bool QDeclarativeStateGroup::updateAutoState(void)
- ?tr@QDeclarativeDebugService@@SA?AVQString@@PBD0@Z @ 643 NONAME ABSENT ; class QString QDeclarativeDebugService::tr(char const *, char const *)
+ ?tr@QDeclarativeDebugService@@SA?AVQString@@PBD0@Z @ 643 NONAME ; class QString QDeclarativeDebugService::tr(char const *, char const *)
?tr@QDeclarativeComponent@@SA?AVQString@@PBD0H@Z @ 644 NONAME ; class QString QDeclarativeComponent::tr(char const *, char const *, int)
??1QDeclarativeProperty@@QAE@XZ @ 645 NONAME ; QDeclarativeProperty::~QDeclarativeProperty(void)
?fontChanged@QDeclarativeText@@IAEXABVQFont@@@Z @ 646 NONAME ABSENT ; void QDeclarativeText::fontChanged(class QFont const &)
@@ -667,14 +667,14 @@ EXPORTS
?getStaticMetaObject@QDeclarativeListModel@@SAABUQMetaObject@@XZ @ 666 NONAME ABSENT ; struct QMetaObject const & QDeclarativeListModel::getStaticMetaObject(void)
?setStdCppSet@QMetaPropertyBuilder@@QAEX_N@Z @ 667 NONAME ABSENT ; void QMetaPropertyBuilder::setStdCppSet(bool)
??0QDeclarativeItemPrivate@@QAE@XZ @ 668 NONAME ; QDeclarativeItemPrivate::QDeclarativeItemPrivate(void)
- ??0QDeclarativeDebugService@@QAE@ABVQString@@PAVQObject@@@Z @ 669 NONAME ABSENT ; QDeclarativeDebugService::QDeclarativeDebugService(class QString const &, class QObject *)
+ ??0QDeclarativeDebugService@@QAE@ABVQString@@PAVQObject@@@Z @ 669 NONAME ; QDeclarativeDebugService::QDeclarativeDebugService(class QString const &, class QObject *)
?load@QDeclarativePixmap@@QAEXPAVQDeclarativeEngine@@ABVQUrl@@_N@Z @ 670 NONAME ABSENT ; void QDeclarativePixmap::load(class QDeclarativeEngine *, class QUrl const &, bool)
??_EQPacketAutoSend@@UAE@I@Z @ 671 NONAME ABSENT ; QPacketAutoSend::~QPacketAutoSend(unsigned int)
?saveValueType@QDeclarativePropertyPrivate@@SA?AVQByteArray@@PBUQMetaObject@@H0H@Z @ 672 NONAME ABSENT ; class QByteArray QDeclarativePropertyPrivate::saveValueType(struct QMetaObject const *, int, struct QMetaObject const *, int)
?resetHeight@QDeclarativeItem@@QAEXXZ @ 673 NONAME ; void QDeclarativeItem::resetHeight(void)
?setVAlign@QDeclarativeText@@QAEXW4VAlignment@1@@Z @ 674 NONAME ABSENT ; void QDeclarativeText::setVAlign(enum QDeclarativeText::VAlignment)
- ??1QDeclarativeDebugService@@UAE@XZ @ 675 NONAME ABSENT ; QDeclarativeDebugService::~QDeclarativeDebugService(void)
- ?trUtf8@QDeclarativeDebugService@@SA?AVQString@@PBD0H@Z @ 676 NONAME ABSENT ; class QString QDeclarativeDebugService::trUtf8(char const *, char const *, int)
+ ??1QDeclarativeDebugService@@UAE@XZ @ 675 NONAME ; QDeclarativeDebugService::~QDeclarativeDebugService(void)
+ ?trUtf8@QDeclarativeDebugService@@SA?AVQString@@PBD0H@Z @ 676 NONAME ; class QString QDeclarativeDebugService::trUtf8(char const *, char const *, int)
?elideMode@QDeclarativeText@@QBE?AW4TextElideMode@1@XZ @ 677 NONAME ABSENT ; enum QDeclarativeText::TextElideMode QDeclarativeText::elideMode(void) const
?baseUrl@QDeclarativeContext@@QBE?AVQUrl@@XZ @ 678 NONAME ; class QUrl QDeclarativeContext::baseUrl(void) const
?qt_metacall@QDeclarativeDebugRootContextQuery@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 679 NONAME ABSENT ; int QDeclarativeDebugRootContextQuery::qt_metacall(enum QMetaObject::Call, int, void * *)
@@ -849,7 +849,7 @@ EXPORTS
??1QDeclarativeBehavior@@UAE@XZ @ 848 NONAME ABSENT ; QDeclarativeBehavior::~QDeclarativeBehavior(void)
?qmlInfo@@YA?AVQDeclarativeInfo@@PBVQObject@@@Z @ 849 NONAME ; class QDeclarativeInfo qmlInfo(class QObject const *)
?qt_metacall@QDeclarativeDebugClient@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 850 NONAME ABSENT ; int QDeclarativeDebugClient::qt_metacall(enum QMetaObject::Call, int, void * *)
- ?d_func@QDeclarativeDebugService@@ABEPBVQDeclarativeDebugServicePrivate@@XZ @ 851 NONAME ABSENT ; class QDeclarativeDebugServicePrivate const * QDeclarativeDebugService::d_func(void) const
+ ?d_func@QDeclarativeDebugService@@ABEPBVQDeclarativeDebugServicePrivate@@XZ @ 851 NONAME ; class QDeclarativeDebugServicePrivate const * QDeclarativeDebugService::d_func(void) const
??1QDeclarativeDebugQuery@@UAE@XZ @ 852 NONAME ABSENT ; QDeclarativeDebugQuery::~QDeclarativeDebugQuery(void)
?data_append@QDeclarativeItemPrivate@@SAXPAV?$QDeclarativeListProperty@VQObject@@@@PAVQObject@@@Z @ 853 NONAME ; void QDeclarativeItemPrivate::data_append(class QDeclarativeListProperty<class QObject> *, class QObject *)
?tr@QDeclarativeState@@SA?AVQString@@PBD0@Z @ 854 NONAME ; class QString QDeclarativeState::tr(char const *, char const *)
@@ -1120,7 +1120,7 @@ EXPORTS
?expression@QDeclarativeDebugExpressionQuery@@QBE?AVQVariant@@XZ @ 1119 NONAME ABSENT ; class QVariant QDeclarativeDebugExpressionQuery::expression(void) const
??4QDeclarativeDomList@@QAEAAV0@ABV0@@Z @ 1120 NONAME ABSENT ; class QDeclarativeDomList & QDeclarativeDomList::operator=(class QDeclarativeDomList const &)
?qt_metacall@QDeclarativeComponent@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1121 NONAME ; int QDeclarativeComponent::qt_metacall(enum QMetaObject::Call, int, void * *)
- ?tr@QDeclarativeDebugService@@SA?AVQString@@PBD0H@Z @ 1122 NONAME ABSENT ; class QString QDeclarativeDebugService::tr(char const *, char const *, int)
+ ?tr@QDeclarativeDebugService@@SA?AVQString@@PBD0H@Z @ 1122 NONAME ; class QString QDeclarativeDebugService::tr(char const *, char const *, int)
?staticMetaObject@QDeclarativeEngine@@2UQMetaObject@@B @ 1123 NONAME ; struct QMetaObject const QDeclarativeEngine::staticMetaObject
?staticMetaObject@QDeclarativeStateOperation@@2UQMetaObject@@B @ 1124 NONAME ; struct QMetaObject const QDeclarativeStateOperation::staticMetaObject
?actions@QDeclarativeStateOperation@@UAE?AV?$QList@VQDeclarativeAction@@@@XZ @ 1125 NONAME ; class QList<class QDeclarativeAction> QDeclarativeStateOperation::actions(void)
@@ -1145,7 +1145,7 @@ EXPORTS
?sourceFile@QDeclarativeExpression@@QBE?AVQString@@XZ @ 1144 NONAME ; class QString QDeclarativeExpression::sourceFile(void) const
??_EQDeclarativeAnchors@@UAE@I@Z @ 1145 NONAME ABSENT ; QDeclarativeAnchors::~QDeclarativeAnchors(unsigned int)
?removeNotifySignal@QMetaPropertyBuilder@@QAEXXZ @ 1146 NONAME ABSENT ; void QMetaPropertyBuilder::removeNotifySignal(void)
- ?trUtf8@QDeclarativeDebugService@@SA?AVQString@@PBD0@Z @ 1147 NONAME ABSENT ; class QString QDeclarativeDebugService::trUtf8(char const *, char const *)
+ ?trUtf8@QDeclarativeDebugService@@SA?AVQString@@PBD0@Z @ 1147 NONAME ; class QString QDeclarativeDebugService::trUtf8(char const *, char const *)
?setImportPathList@QDeclarativeEngine@@QAEXABVQStringList@@@Z @ 1148 NONAME ; void QDeclarativeEngine::setImportPathList(class QStringList const &)
?enabledChanged@QDeclarativeDebugService@@MAEX_N@Z @ 1149 NONAME ABSENT ; void QDeclarativeDebugService::enabledChanged(bool)
?addWatch@QDeclarativeEngineDebug@@QAEPAVQDeclarativeDebugWatch@@ABVQDeclarativeDebugObjectReference@@PAVQObject@@@Z @ 1150 NONAME ABSENT ; class QDeclarativeDebugWatch * QDeclarativeEngineDebug::addWatch(class QDeclarativeDebugObjectReference const &, class QObject *)
@@ -1176,7 +1176,7 @@ EXPORTS
?paint@QDeclarativeRectangle@@UAEXPAVQPainter@@PBVQStyleOptionGraphicsItem@@PAVQWidget@@@Z @ 1175 NONAME ABSENT ; void QDeclarativeRectangle::paint(class QPainter *, class QStyleOptionGraphicsItem const *, class QWidget *)
??6QDeclarativeState@@QAEAAV0@PAVQDeclarativeStateOperation@@@Z @ 1176 NONAME ; class QDeclarativeState & QDeclarativeState::operator<<(class QDeclarativeStateOperation *)
?destroy@QDeclarativeAbstractBinding@@UAEXXZ @ 1177 NONAME ABSENT ; void QDeclarativeAbstractBinding::destroy(void)
- ?qt_metacast@QDeclarativeDebugService@@UAEPAXPBD@Z @ 1178 NONAME ABSENT ; void * QDeclarativeDebugService::qt_metacast(char const *)
+ ?qt_metacast@QDeclarativeDebugService@@UAEPAXPBD@Z @ 1178 NONAME ; void * QDeclarativeDebugService::qt_metacast(char const *)
?qt_metacast@QDeclarativeValueType@@UAEPAXPBD@Z @ 1179 NONAME ABSENT ; void * QDeclarativeValueType::qt_metacast(char const *)
?childAt@QDeclarativeItem@@QBEPAV1@MM@Z @ 1180 NONAME ; class QDeclarativeItem * QDeclarativeItem::childAt(float, float) const
?paintedWidth@QDeclarativeText@@QBEMXZ @ 1181 NONAME ABSENT ; float QDeclarativeText::paintedWidth(void) const
@@ -1297,7 +1297,7 @@ EXPORTS
?value@QDeclarativeOpenMetaObject@@QBE?AVQVariant@@H@Z @ 1296 NONAME ABSENT ; class QVariant QDeclarativeOpenMetaObject::value(int) const
?tr@QDeclarativeDebugRootContextQuery@@SA?AVQString@@PBD0H@Z @ 1297 NONAME ABSENT ; class QString QDeclarativeDebugRootContextQuery::tr(char const *, char const *, int)
?setFromState@QDeclarativeTransition@@QAEXABVQString@@@Z @ 1298 NONAME ; void QDeclarativeTransition::setFromState(class QString const &)
- ?metaObject@QDeclarativeDebugService@@UBEPBUQMetaObject@@XZ @ 1299 NONAME ABSENT ; struct QMetaObject const * QDeclarativeDebugService::metaObject(void) const
+ ?metaObject@QDeclarativeDebugService@@UBEPBUQMetaObject@@XZ @ 1299 NONAME ; struct QMetaObject const * QDeclarativeDebugService::metaObject(void) const
?state@QDeclarativeDebugQuery@@QBE?AW4State@1@XZ @ 1300 NONAME ABSENT ; enum QDeclarativeDebugQuery::State QDeclarativeDebugQuery::state(void) const
?setBottom@QDeclarativeScaleGrid@@QAEXH@Z @ 1301 NONAME ABSENT ; void QDeclarativeScaleGrid::setBottom(int)
?topMarginChanged@QDeclarativeAnchors@@IAEXXZ @ 1302 NONAME ABSENT ; void QDeclarativeAnchors::topMarginChanged(void)
@@ -1305,7 +1305,7 @@ EXPORTS
?position@QDeclarativeDomObject@@QBEHXZ @ 1304 NONAME ABSENT ; int QDeclarativeDomObject::position(void) const
?update@QDeclarativeBinding@@UAEXV?$QFlags@W4WriteFlag@QDeclarativePropertyPrivate@@@@@Z @ 1305 NONAME ABSENT ; void QDeclarativeBinding::update(class QFlags<enum QDeclarativePropertyPrivate::WriteFlag>)
?tr@QDeclarativeBehavior@@SA?AVQString@@PBD0@Z @ 1306 NONAME ABSENT ; class QString QDeclarativeBehavior::tr(char const *, char const *)
- ?isDebuggingEnabled@QDeclarativeDebugService@@SA_NXZ @ 1307 NONAME ABSENT ; bool QDeclarativeDebugService::isDebuggingEnabled(void)
+ ?isDebuggingEnabled@QDeclarativeDebugService@@SA_NXZ @ 1307 NONAME ; bool QDeclarativeDebugService::isDebuggingEnabled(void)
?tr@QDeclarativeText@@SA?AVQString@@PBD0H@Z @ 1308 NONAME ABSENT ; class QString QDeclarativeText::tr(char const *, char const *, int)
?reset@QDeclarativeProperty@@QBE_NXZ @ 1309 NONAME ; bool QDeclarativeProperty::reset(void) const
?objectDebugId@QDeclarativeDebugWatch@@QBEHXZ @ 1310 NONAME ABSENT ; int QDeclarativeDebugWatch::objectDebugId(void) const
@@ -1344,7 +1344,7 @@ EXPORTS
?maximumPacketSize@QPacketProtocol@@QBEHXZ @ 1343 NONAME ; int QPacketProtocol::maximumPacketSize(void) const
??_EQDeclarativeDebuggerStatus@@UAE@I@Z @ 1344 NONAME ABSENT ; QDeclarativeDebuggerStatus::~QDeclarativeDebuggerStatus(unsigned int)
?error@QDeclarativeCustomParser@@IAEXABVQString@@@Z @ 1345 NONAME ; void QDeclarativeCustomParser::error(class QString const &)
- ?messageReceived@QDeclarativeDebugService@@MAEXABVQByteArray@@@Z @ 1346 NONAME ABSENT ; void QDeclarativeDebugService::messageReceived(class QByteArray const &)
+ ?messageReceived@QDeclarativeDebugService@@MAEXABVQByteArray@@@Z @ 1346 NONAME ; void QDeclarativeDebugService::messageReceived(class QByteArray const &)
??0QDeclarativeParserStatus@@QAE@XZ @ 1347 NONAME ; QDeclarativeParserStatus::QDeclarativeParserStatus(void)
?isNumber@Variant@QDeclarativeParser@@QBE_NXZ @ 1348 NONAME ; bool QDeclarativeParser::Variant::isNumber(void) const
?getStaticMetaObject@QDeclarativeEngineDebug@@SAABUQMetaObject@@XZ @ 1349 NONAME ABSENT ; struct QMetaObject const & QDeclarativeEngineDebug::getStaticMetaObject(void)
@@ -1475,7 +1475,7 @@ EXPORTS
?packetWritten@QPacketProtocol@@IAEXXZ @ 1474 NONAME ; void QPacketProtocol::packetWritten(void)
?getStaticMetaObject@QDeclarativeDebugObjectQuery@@SAABUQMetaObject@@XZ @ 1475 NONAME ABSENT ; struct QMetaObject const & QDeclarativeDebugObjectQuery::getStaticMetaObject(void)
?isSignalProperty@QDeclarativeProperty@@QBE_NXZ @ 1476 NONAME ; bool QDeclarativeProperty::isSignalProperty(void) const
- ?d_func@QDeclarativeDebugService@@AAEPAVQDeclarativeDebugServicePrivate@@XZ @ 1477 NONAME ABSENT ; class QDeclarativeDebugServicePrivate * QDeclarativeDebugService::d_func(void)
+ ?d_func@QDeclarativeDebugService@@AAEPAVQDeclarativeDebugServicePrivate@@XZ @ 1477 NONAME ; class QDeclarativeDebugServicePrivate * QDeclarativeDebugService::d_func(void)
?qmlTypeNames@QDeclarativeMetaType@@SA?AV?$QList@VQByteArray@@@@XZ @ 1478 NONAME ABSENT ; class QList<class QByteArray> QDeclarativeMetaType::qmlTypeNames(void)
?componentComplete@QDeclarativeItem@@MAEXXZ @ 1479 NONAME ; void QDeclarativeItem::componentComplete(void)
?creationContext@QDeclarativeComponent@@QBEPAVQDeclarativeContext@@XZ @ 1480 NONAME ; class QDeclarativeContext * QDeclarativeComponent::creationContext(void) const
@@ -1575,7 +1575,7 @@ EXPORTS
?keyCount@QMetaEnumBuilder@@QBEHXZ @ 1574 NONAME ABSENT ; int QMetaEnumBuilder::keyCount(void) const
??1QDeclarativeDomProperty@@QAE@XZ @ 1575 NONAME ABSENT ; QDeclarativeDomProperty::~QDeclarativeDomProperty(void)
?url@QDeclarativePixmap@@QBEABVQUrl@@XZ @ 1576 NONAME ; class QUrl const & QDeclarativePixmap::url(void) const
- ?sendMessage@QDeclarativeDebugService@@QAEXABVQByteArray@@@Z @ 1577 NONAME ABSENT ; void QDeclarativeDebugService::sendMessage(class QByteArray const &)
+ ?sendMessage@QDeclarativeDebugService@@QAEXABVQByteArray@@@Z @ 1577 NONAME ; void QDeclarativeDebugService::sendMessage(class QByteArray const &)
?context@QDeclarativeScriptString@@QBEPAVQDeclarativeContext@@XZ @ 1578 NONAME ; class QDeclarativeContext * QDeclarativeScriptString::context(void) const
?queryObject@QDeclarativeEngineDebug@@QAEPAVQDeclarativeDebugObjectQuery@@ABVQDeclarativeDebugObjectReference@@PAVQObject@@@Z @ 1579 NONAME ABSENT ; class QDeclarativeDebugObjectQuery * QDeclarativeEngineDebug::queryObject(class QDeclarativeDebugObjectReference const &, class QObject *)
?tr@QDeclarativePropertyMap@@SA?AVQString@@PBD0H@Z @ 1580 NONAME ; class QString QDeclarativePropertyMap::tr(char const *, char const *, int)
@@ -1608,7 +1608,7 @@ EXPORTS
??_EQDeclarativeComponent@@UAE@I@Z @ 1607 NONAME ; QDeclarativeComponent::~QDeclarativeComponent(unsigned int)
?get@QDeclarativeItemPrivate@@SAPAV1@PAVQDeclarativeItem@@@Z @ 1608 NONAME ; class QDeclarativeItemPrivate * QDeclarativeItemPrivate::get(class QDeclarativeItem *)
?staticMetaObject@QDeclarativeView@@2UQMetaObject@@B @ 1609 NONAME ; struct QMetaObject const QDeclarativeView::staticMetaObject
- ?objectToString@QDeclarativeDebugService@@SA?AVQString@@PAVQObject@@@Z @ 1610 NONAME ABSENT ; class QString QDeclarativeDebugService::objectToString(class QObject *)
+ ?objectToString@QDeclarativeDebugService@@SA?AVQString@@PAVQObject@@@Z @ 1610 NONAME ; class QString QDeclarativeDebugService::objectToString(class QObject *)
?defaultValue@QDeclarativeDomDynamicProperty@@QBE?AVQDeclarativeDomProperty@@XZ @ 1611 NONAME ABSENT ; class QDeclarativeDomProperty QDeclarativeDomDynamicProperty::defaultValue(void) const
?relatedMetaObject@QMetaObjectBuilder@@QBEPBUQMetaObject@@H@Z @ 1612 NONAME ABSENT ; struct QMetaObject const * QMetaObjectBuilder::relatedMetaObject(int) const
?addKey@QMetaEnumBuilder@@QAEHABVQByteArray@@H@Z @ 1613 NONAME ABSENT ; int QMetaEnumBuilder::addKey(class QByteArray const &, int)
@@ -1633,7 +1633,7 @@ EXPORTS
?tr@QDeclarativeView@@SA?AVQString@@PBD0@Z @ 1632 NONAME ; class QString QDeclarativeView::tr(char const *, char const *)
?qt_metacall@QPacketProtocol@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1633 NONAME ; int QPacketProtocol::qt_metacall(enum QMetaObject::Call, int, void * *)
??0QDeclarativeItem@@QAE@PAV0@@Z @ 1634 NONAME ; QDeclarativeItem::QDeclarativeItem(class QDeclarativeItem *)
- ?hasDebuggingClient@QDeclarativeDebugService@@SA_NXZ @ 1635 NONAME ABSENT ; bool QDeclarativeDebugService::hasDebuggingClient(void)
+ ?hasDebuggingClient@QDeclarativeDebugService@@SA_NXZ @ 1635 NONAME ; bool QDeclarativeDebugService::hasDebuggingClient(void)
?staticMetaObject@QDeclarativeContext@@2UQMetaObject@@B @ 1636 NONAME ; struct QMetaObject const QDeclarativeContext::staticMetaObject
?setContextForObject@QDeclarativeEngine@@SAXPAVQObject@@PAVQDeclarativeContext@@@Z @ 1637 NONAME ; void QDeclarativeEngine::setContextForObject(class QObject *, class QDeclarativeContext *)
?baselineOffsetChanged@QDeclarativeItem@@IAEXM@Z @ 1638 NONAME ; void QDeclarativeItem::baselineOffsetChanged(float)
@@ -1733,7 +1733,7 @@ EXPORTS
?start@QDeclarativeTimer@@QAEXXZ @ 1732 NONAME ABSENT ; void QDeclarativeTimer::start(void)
?transition@QDeclarativeAbstractAnimation@@UAEXAAV?$QList@VQDeclarativeAction@@@@AAV?$QList@VQDeclarativeProperty@@@@W4TransitionDirection@1@@Z @ 1733 NONAME ABSENT ; void QDeclarativeAbstractAnimation::transition(class QList<class QDeclarativeAction> &, class QList<class QDeclarativeProperty> &, enum QDeclarativeAbstractAnimation::TransitionDirection)
?componentComplete@QDeclarativeAbstractAnimation@@UAEXXZ @ 1734 NONAME ABSENT ; void QDeclarativeAbstractAnimation::componentComplete(void)
- ?statusChanged@QDeclarativeDebugService@@MAEXW4Status@1@@Z @ 1735 NONAME ABSENT ; void QDeclarativeDebugService::statusChanged(enum QDeclarativeDebugService::Status)
+ ?statusChanged@QDeclarativeDebugService@@MAEXW4Status@1@@Z @ 1735 NONAME ; void QDeclarativeDebugService::statusChanged(enum QDeclarativeDebugService::Status)
?runningChanged@QDeclarativeAbstractAnimation@@IAEX_N@Z @ 1736 NONAME ABSENT ; void QDeclarativeAbstractAnimation::runningChanged(bool)
?trUtf8@QDeclarativeAbstractAnimation@@SA?AVQString@@PBD0H@Z @ 1737 NONAME ABSENT ; class QString QDeclarativeAbstractAnimation::trUtf8(char const *, char const *, int)
??_EQDeclarativeBasePositioner@@UAE@I@Z @ 1738 NONAME ABSENT ; QDeclarativeBasePositioner::~QDeclarativeBasePositioner(unsigned int)
@@ -1813,7 +1813,7 @@ EXPORTS
?setTarget@QDeclarativeAbstractAnimation@@EAEXABVQDeclarativeProperty@@@Z @ 1812 NONAME ABSENT ; void QDeclarativeAbstractAnimation::setTarget(class QDeclarativeProperty const &)
?alwaysRunToEnd@QDeclarativeAbstractAnimation@@QBE_NXZ @ 1813 NONAME ABSENT ; bool QDeclarativeAbstractAnimation::alwaysRunToEnd(void) const
?tr@QDeclarativeTimer@@SA?AVQString@@PBD0H@Z @ 1814 NONAME ABSENT ; class QString QDeclarativeTimer::tr(char const *, char const *, int)
- ?status@QDeclarativeDebugService@@QBE?AW4Status@1@XZ @ 1815 NONAME ABSENT ; enum QDeclarativeDebugService::Status QDeclarativeDebugService::status(void) const
+ ?status@QDeclarativeDebugService@@QBE?AW4Status@1@XZ @ 1815 NONAME ; enum QDeclarativeDebugService::Status QDeclarativeDebugService::status(void) const
?intervalChanged@QDeclarativeTimer@@IAEXXZ @ 1816 NONAME ABSENT ; void QDeclarativeTimer::intervalChanged(void)
?isPaused@QDeclarativeAbstractAnimation@@QBE_NXZ @ 1817 NONAME ABSENT ; bool QDeclarativeAbstractAnimation::isPaused(void) const
?getStaticMetaObject@QDeclarativeAbstractAnimation@@SAABUQMetaObject@@XZ @ 1818 NONAME ABSENT ; struct QMetaObject const & QDeclarativeAbstractAnimation::getStaticMetaObject(void)
diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def
index 9b4c0f7..a1f1b50 100644
--- a/src/s60installs/bwins/QtGuiu.def
+++ b/src/s60installs/bwins/QtGuiu.def
@@ -13149,3 +13149,58 @@ EXPORTS
?ProcessCommandParametersL@QS60MainAppUi@@UAEHW4TApaCommand@@AAV?$TBuf@$0BAA@@@ABVTDesC8@@@Z @ 13148 NONAME ; int QS60MainAppUi::ProcessCommandParametersL(enum TApaCommand, class TBuf<256> &, class TDesC8 const &)
?openFile@QFileOpenEvent@@QBE_NAAVQFile@@V?$QFlags@W4OpenModeFlag@QIODevice@@@@@Z @ 13149 NONAME ; bool QFileOpenEvent::openFile(class QFile &, class QFlags<enum QIODevice::OpenModeFlag>) const
??0QFileOpenEvent@@QAE@ABVRFile@@@Z @ 13150 NONAME ; QFileOpenEvent::QFileOpenEvent(class RFile const &)
+ ?beginDataAccess@QVolatileImage@@QBEXXZ @ 13151 NONAME ; void QVolatileImage::beginDataAccess(void) const
+ ??1QVolatileImage@@QAE@XZ @ 13152 NONAME ; QVolatileImage::~QVolatileImage(void)
+ ?trUtf8@QInternalMimeData@@SA?AVQString@@PBD0@Z @ 13153 NONAME ; class QString QInternalMimeData::trUtf8(char const *, char const *)
+ ??0QVolatileImage@@QAE@HHW4Format@QImage@@@Z @ 13154 NONAME ; QVolatileImage::QVolatileImage(int, int, enum QImage::Format)
+ ?ensureFormat@QVolatileImage@@QAE_NW4Format@QImage@@@Z @ 13155 NONAME ; bool QVolatileImage::ensureFormat(enum QImage::Format)
+ ?fill@QVolatileImage@@QAEXI@Z @ 13156 NONAME ; void QVolatileImage::fill(unsigned int)
+ ?assignedInputContext@QWidgetPrivate@@QBEPAVQInputContext@@XZ @ 13157 NONAME ; class QInputContext * QWidgetPrivate::assignedInputContext(void) const
+ ?retrieveData@QInternalMimeData@@MBE?AVQVariant@@ABVQString@@W4Type@2@@Z @ 13158 NONAME ; class QVariant QInternalMimeData::retrieveData(class QString const &, enum QVariant::Type) const
+ ?formats@QInternalMimeData@@UBE?AVQStringList@@XZ @ 13159 NONAME ; class QStringList QInternalMimeData::formats(void) const
+ ?isNull@QVolatileImage@@QBE_NXZ @ 13160 NONAME ; bool QVolatileImage::isNull(void) const
+ ?toImage@QVolatileImage@@QBE?AVQImage@@XZ @ 13161 NONAME ; class QImage QVolatileImage::toImage(void) const
+ ??0QVolatileImage@@QAE@ABVQImage@@@Z @ 13162 NONAME ; QVolatileImage::QVolatileImage(class QImage const &)
+ ?tr@QInternalMimeData@@SA?AVQString@@PBD0H@Z @ 13163 NONAME ; class QString QInternalMimeData::tr(char const *, char const *, int)
+ ?resolveFontFamilyAlias@QFontDatabase@@CA?AVQString@@ABV2@@Z @ 13164 NONAME ; class QString QFontDatabase::resolveFontFamilyAlias(class QString const &)
+ ?hasFormat@QInternalMimeData@@UBE_NABVQString@@@Z @ 13165 NONAME ; bool QInternalMimeData::hasFormat(class QString const &) const
+ ?format@QVolatileImage@@QBE?AW4Format@QImage@@XZ @ 13166 NONAME ; enum QImage::Format QVolatileImage::format(void) const
+ ?renderDataHelper@QInternalMimeData@@SA?AVQByteArray@@ABVQString@@PBVQMimeData@@@Z @ 13167 NONAME ; class QByteArray QInternalMimeData::renderDataHelper(class QString const &, class QMimeData const *)
+ ?endDataAccess@QVolatileImage@@QBEX_N@Z @ 13168 NONAME ; void QVolatileImage::endDataAccess(bool) const
+ ?constBits@QVolatileImage@@QBEPBEXZ @ 13169 NONAME ; unsigned char const * QVolatileImage::constBits(void) const
+ ?updateMicroFocus@QLineControl@@IAEXXZ @ 13170 NONAME ; void QLineControl::updateMicroFocus(void)
+ ?height@QVolatileImage@@QBEHXZ @ 13171 NONAME ; int QVolatileImage::height(void) const
+ ?duplicateNativeImage@QVolatileImage@@QBEPAXXZ @ 13172 NONAME ; void * QVolatileImage::duplicateNativeImage(void) const
+ ?formatsHelper@QInternalMimeData@@SA?AVQStringList@@PBVQMimeData@@@Z @ 13173 NONAME ; class QStringList QInternalMimeData::formatsHelper(class QMimeData const *)
+ ?qt_metacast@QInternalMimeData@@UAEPAXPBD@Z @ 13174 NONAME ; void * QInternalMimeData::qt_metacast(char const *)
+ ?bits@QVolatileImage@@QAEPAEXZ @ 13175 NONAME ; unsigned char * QVolatileImage::bits(void)
+ ?paintEngine@QVolatileImage@@QAEPAVQPaintEngine@@XZ @ 13176 NONAME ; class QPaintEngine * QVolatileImage::paintEngine(void)
+ ?bytesPerLine@QVolatileImage@@QBEHXZ @ 13177 NONAME ; int QVolatileImage::bytesPerLine(void) const
+ ?width@QVolatileImage@@QBEHXZ @ 13178 NONAME ; int QVolatileImage::width(void) const
+ ?qt_metacall@QInternalMimeData@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 13179 NONAME ; int QInternalMimeData::qt_metacall(enum QMetaObject::Call, int, void * *)
+ ?lineHeightType@QTextBlockFormat@@QBEHXZ @ 13180 NONAME ; int QTextBlockFormat::lineHeightType(void) const
+ ?trUtf8@QInternalMimeData@@SA?AVQString@@PBD0H@Z @ 13181 NONAME ; class QString QInternalMimeData::trUtf8(char const *, char const *, int)
+ ?copyFrom@QVolatileImage@@QAEXPAV1@ABVQRect@@@Z @ 13182 NONAME ; void QVolatileImage::copyFrom(class QVolatileImage *, class QRect const &)
+ ?lineHeight@QTextBlockFormat@@QBEMMM@Z @ 13183 NONAME ; float QTextBlockFormat::lineHeight(float, float) const
+ ?canReadData@QInternalMimeData@@SA_NABVQString@@@Z @ 13184 NONAME ; bool QInternalMimeData::canReadData(class QString const &)
+ ?releaseCachedResources@QGraphicsSystem@@UAEXXZ @ 13185 NONAME ; void QGraphicsSystem::releaseCachedResources(void)
+ ??0QInternalMimeData@@QAE@XZ @ 13186 NONAME ; QInternalMimeData::QInternalMimeData(void)
+ ?setLineHeight@QTextBlockFormat@@QAEXMH@Z @ 13187 NONAME ; void QTextBlockFormat::setLineHeight(float, int)
+ ?imageRef@QVolatileImage@@QAEAAVQImage@@XZ @ 13188 NONAME ; class QImage & QVolatileImage::imageRef(void)
+ ??0QVolatileImage@@QAE@PAX0@Z @ 13189 NONAME ; QVolatileImage::QVolatileImage(void *, void *)
+ ??4QVolatileImage@@QAEAAV0@ABV0@@Z @ 13190 NONAME ; class QVolatileImage & QVolatileImage::operator=(class QVolatileImage const &)
+ ??0QVolatileImage@@QAE@XZ @ 13191 NONAME ; QVolatileImage::QVolatileImage(void)
+ ?getStaticMetaObject@QInternalMimeData@@SAABUQMetaObject@@XZ @ 13192 NONAME ; struct QMetaObject const & QInternalMimeData::getStaticMetaObject(void)
+ ?lineHeight@QTextBlockFormat@@QBEMXZ @ 13193 NONAME ; float QTextBlockFormat::lineHeight(void) const
+ ?tr@QInternalMimeData@@SA?AVQString@@PBD0@Z @ 13194 NONAME ; class QString QInternalMimeData::tr(char const *, char const *)
+ ?hasAlphaChannel@QVolatileImage@@QBE_NXZ @ 13195 NONAME ; bool QVolatileImage::hasAlphaChannel(void) const
+ ?setAlphaChannel@QVolatileImage@@QAEXABVQPixmap@@@Z @ 13196 NONAME ; void QVolatileImage::setAlphaChannel(class QPixmap const &)
+ ??_EQInternalMimeData@@UAE@I@Z @ 13197 NONAME ; QInternalMimeData::~QInternalMimeData(unsigned int)
+ ?byteCount@QVolatileImage@@QBEHXZ @ 13198 NONAME ; int QVolatileImage::byteCount(void) const
+ ??0QVolatileImage@@QAE@ABV0@@Z @ 13199 NONAME ; QVolatileImage::QVolatileImage(class QVolatileImage const &)
+ ?metaObject@QInternalMimeData@@UBEPBUQMetaObject@@XZ @ 13200 NONAME ; struct QMetaObject const * QInternalMimeData::metaObject(void) const
+ ?depth@QVolatileImage@@QBEHXZ @ 13201 NONAME ; int QVolatileImage::depth(void) const
+ ?hasFormatHelper@QInternalMimeData@@SA_NABVQString@@PBVQMimeData@@@Z @ 13202 NONAME ; bool QInternalMimeData::hasFormatHelper(class QString const &, class QMimeData const *)
+ ??1QInternalMimeData@@UAE@XZ @ 13203 NONAME ; QInternalMimeData::~QInternalMimeData(void)
+ ?staticMetaObject@QInternalMimeData@@2UQMetaObject@@B @ 13204 NONAME ; struct QMetaObject const QInternalMimeData::staticMetaObject
+
diff --git a/src/s60installs/bwins/QtOpenGLu.def b/src/s60installs/bwins/QtOpenGLu.def
index 6ea8635..d16ff06 100644
--- a/src/s60installs/bwins/QtOpenGLu.def
+++ b/src/s60installs/bwins/QtOpenGLu.def
@@ -703,3 +703,134 @@ EXPORTS
?maxTextureWidth@QGLTextureGlyphCache@@UBEHXZ @ 702 NONAME ; int QGLTextureGlyphCache::maxTextureWidth(void) const
?filterMode@QGLTextureGlyphCache@@QBE?AW4FilterMode@1@XZ @ 703 NONAME ; enum QGLTextureGlyphCache::FilterMode QGLTextureGlyphCache::filterMode(void) const
?setFilterMode@QGLTextureGlyphCache@@QAEXW4FilterMode@1@@Z @ 704 NONAME ; void QGLTextureGlyphCache::setFilterMode(enum QGLTextureGlyphCache::FilterMode)
+ ?glVertexAttrib3f@QGLFunctions@@QAEXIMMM@Z @ 705 NONAME ; void QGLFunctions::glVertexAttrib3f(unsigned int, float, float, float)
+ ?glVertexAttrib1fv@QGLFunctions@@QAEXIPBM@Z @ 706 NONAME ; void QGLFunctions::glVertexAttrib1fv(unsigned int, float const *)
+ ?glIsBuffer@QGLFunctions@@QAEEI@Z @ 707 NONAME ; unsigned char QGLFunctions::glIsBuffer(unsigned int)
+ ?glGetActiveAttrib@QGLFunctions@@QAEXIIHPAH0PAIPAD@Z @ 708 NONAME ; void QGLFunctions::glGetActiveAttrib(unsigned int, unsigned int, int, int *, int *, unsigned int *, char *)
+ ?glBindFramebuffer@QGLFunctions@@QAEXII@Z @ 709 NONAME ; void QGLFunctions::glBindFramebuffer(unsigned int, unsigned int)
+ ?glBufferData@QGLFunctions@@QAEXIHPBXI@Z @ 710 NONAME ; void QGLFunctions::glBufferData(unsigned int, int, void const *, unsigned int)
+ ?glValidateProgram@QGLFunctions@@QAEXI@Z @ 711 NONAME ; void QGLFunctions::glValidateProgram(unsigned int)
+ ?glUniform1f@QGLFunctions@@QAEXHM@Z @ 712 NONAME ; void QGLFunctions::glUniform1f(int, float)
+ ?glDetachShader@QGLFunctions@@QAEXII@Z @ 713 NONAME ; void QGLFunctions::glDetachShader(unsigned int, unsigned int)
+ ?glDeleteProgram@QGLFunctions@@QAEXI@Z @ 714 NONAME ; void QGLFunctions::glDeleteProgram(unsigned int)
+ ??_EQGLContextResourceBase@@UAE@I@Z @ 715 NONAME ; QGLContextResourceBase::~QGLContextResourceBase(unsigned int)
+ ?glUniform2f@QGLFunctions@@QAEXHMM@Z @ 716 NONAME ; void QGLFunctions::glUniform2f(int, float, float)
+ ?glIsProgram@QGLFunctions@@QAEEI@Z @ 717 NONAME ; unsigned char QGLFunctions::glIsProgram(unsigned int)
+ ?openGLFeatures@QGLFunctions@@QBE?AV?$QFlags@W4OpenGLFeature@QGLFunctions@@@@XZ @ 718 NONAME ; class QFlags<enum QGLFunctions::OpenGLFeature> QGLFunctions::openGLFeatures(void) const
+ ?toNativeType@QGLPixmapData@@UAEPAXW4NativeType@QPixmapData@@@Z @ 719 NONAME ; void * QGLPixmapData::toNativeType(enum QPixmapData::NativeType)
+ ?glReleaseShaderCompiler@QGLFunctions@@QAEXXZ @ 720 NONAME ; void QGLFunctions::glReleaseShaderCompiler(void)
+ ??0QGLTextureGlyphCache@@QAE@PBVQGLContext@@W4Type@QFontEngineGlyphCache@@ABVQTransform@@@Z @ 721 NONAME ; QGLTextureGlyphCache::QGLTextureGlyphCache(class QGLContext const *, enum QFontEngineGlyphCache::Type, class QTransform const &)
+ ?context@QGLTextureGlyphCache@@QBEPBVQGLContext@@XZ @ 722 NONAME ; class QGLContext const * QGLTextureGlyphCache::context(void) const
+ ?glGenRenderbuffers@QGLFunctions@@QAEXHPAI@Z @ 723 NONAME ; void QGLFunctions::glGenRenderbuffers(int, unsigned int *)
+ ?glBindBuffer@QGLFunctions@@QAEXII@Z @ 724 NONAME ; void QGLFunctions::glBindBuffer(unsigned int, unsigned int)
+ ?glUniformMatrix3fv@QGLFunctions@@QAEXHHEPBM@Z @ 725 NONAME ; void QGLFunctions::glUniformMatrix3fv(int, int, unsigned char, float const *)
+ ?glGenerateMipmap@QGLFunctions@@QAEXI@Z @ 726 NONAME ; void QGLFunctions::glGenerateMipmap(unsigned int)
+ ?hasOpenGLFeature@QGLFunctions@@QBE_NW4OpenGLFeature@1@@Z @ 727 NONAME ; bool QGLFunctions::hasOpenGLFeature(enum QGLFunctions::OpenGLFeature) const
+ ?glGetAttachedShaders@QGLFunctions@@QAEXIHPAHPAI@Z @ 728 NONAME ; void QGLFunctions::glGetAttachedShaders(unsigned int, int, int *, unsigned int *)
+ ?glDeleteShader@QGLFunctions@@QAEXI@Z @ 729 NONAME ; void QGLFunctions::glDeleteShader(unsigned int)
+ ?glLinkProgram@QGLFunctions@@QAEXI@Z @ 730 NONAME ; void QGLFunctions::glLinkProgram(unsigned int)
+ ?glUseProgram@QGLFunctions@@QAEXI@Z @ 731 NONAME ; void QGLFunctions::glUseProgram(unsigned int)
+ ??0QGLFunctions@@QAE@PBVQGLContext@@@Z @ 732 NONAME ; QGLFunctions::QGLFunctions(class QGLContext const *)
+ ?glGetBufferParameteriv@QGLFunctions@@QAEXIIPAH@Z @ 733 NONAME ; void QGLFunctions::glGetBufferParameteriv(unsigned int, unsigned int, int *)
+ ?glGenBuffers@QGLFunctions@@QAEXHPAI@Z @ 734 NONAME ; void QGLFunctions::glGenBuffers(int, unsigned int *)
+ ?glGetShaderiv@QGLFunctions@@QAEXIIPAH@Z @ 735 NONAME ; void QGLFunctions::glGetShaderiv(unsigned int, unsigned int, int *)
+ ?fillTexture@QGLTextureGlyphCache@@UAEXABUCoord@QTextureGlyphCache@@IUQFixed@@@Z @ 736 NONAME ; void QGLTextureGlyphCache::fillTexture(struct QTextureGlyphCache::Coord const &, unsigned int, struct QFixed)
+ ?glUniform2fv@QGLFunctions@@QAEXHHPBM@Z @ 737 NONAME ; void QGLFunctions::glUniform2fv(int, int, float const *)
+ ?fromNativeType@QGLPixmapData@@UAEXPAXW4NativeType@QPixmapData@@@Z @ 738 NONAME ; void QGLPixmapData::fromNativeType(void *, enum QPixmapData::NativeType)
+ ??0QGLContextGroupResourceBase@@QAE@XZ @ 739 NONAME ; QGLContextGroupResourceBase::QGLContextGroupResourceBase(void)
+ ?glGetFramebufferAttachmentParameteriv@QGLFunctions@@QAEXIIIPAH@Z @ 740 NONAME ; void QGLFunctions::glGetFramebufferAttachmentParameteriv(unsigned int, unsigned int, unsigned int, int *)
+ ?cleanup@QGLContextGroupResourceBase@@QAEXPBVQGLContext@@PAX@Z @ 741 NONAME ; void QGLContextGroupResourceBase::cleanup(class QGLContext const *, void *)
+ ?glUniform2iv@QGLFunctions@@QAEXHHPBH@Z @ 742 NONAME ; void QGLFunctions::glUniform2iv(int, int, int const *)
+ ?glCompileShader@QGLFunctions@@QAEXI@Z @ 743 NONAME ; void QGLFunctions::glCompileShader(unsigned int)
+ ?isFlipped@QGLPaintDevice@@UBE_NXZ @ 744 NONAME ; bool QGLPaintDevice::isFlipped(void) const
+ ?glGetProgramiv@QGLFunctions@@QAEXIIPAH@Z @ 745 NONAME ; void QGLFunctions::glGetProgramiv(unsigned int, unsigned int, int *)
+ ?glClearDepthf@QGLFunctions@@QAEXM@Z @ 746 NONAME ; void QGLFunctions::glClearDepthf(float)
+ ?glIsFramebuffer@QGLFunctions@@QAEEI@Z @ 747 NONAME ; unsigned char QGLFunctions::glIsFramebuffer(unsigned int)
+ ?glUniform4f@QGLFunctions@@QAEXHMMMM@Z @ 748 NONAME ; void QGLFunctions::glUniform4f(int, float, float, float, float)
+ ?glUniform3f@QGLFunctions@@QAEXHMMM@Z @ 749 NONAME ; void QGLFunctions::glUniform3f(int, float, float, float)
+ ?glDeleteRenderbuffers@QGLFunctions@@QAEXHPBI@Z @ 750 NONAME ; void QGLFunctions::glDeleteRenderbuffers(int, unsigned int const *)
+ ?glVertexAttrib1f@QGLFunctions@@QAEXIM@Z @ 751 NONAME ; void QGLFunctions::glVertexAttrib1f(unsigned int, float)
+ ?glVertexAttrib4f@QGLFunctions@@QAEXIMMMM@Z @ 752 NONAME ; void QGLFunctions::glVertexAttrib4f(unsigned int, float, float, float, float)
+ ?glSampleCoverage@QGLFunctions@@QAEXME@Z @ 753 NONAME ; void QGLFunctions::glSampleCoverage(float, unsigned char)
+ ?glGetActiveUniform@QGLFunctions@@QAEXIIHPAH0PAIPAD@Z @ 754 NONAME ; void QGLFunctions::glGetActiveUniform(unsigned int, unsigned int, int, int *, int *, unsigned int *, char *)
+ ??_EQGLContextGroupResourceBase@@UAE@I@Z @ 755 NONAME ; QGLContextGroupResourceBase::~QGLContextGroupResourceBase(unsigned int)
+ ?glStencilOpSeparate@QGLFunctions@@QAEXIIII@Z @ 756 NONAME ; void QGLFunctions::glStencilOpSeparate(unsigned int, unsigned int, unsigned int, unsigned int)
+ ?glCheckFramebufferStatus@QGLFunctions@@QAEII@Z @ 757 NONAME ; unsigned int QGLFunctions::glCheckFramebufferStatus(unsigned int)
+ ?glDepthRangef@QGLFunctions@@QAEXMM@Z @ 758 NONAME ; void QGLFunctions::glDepthRangef(float, float)
+ ??1QGLFunctions@@QAE@XZ @ 759 NONAME ; QGLFunctions::~QGLFunctions(void)
+ ?glStencilMaskSeparate@QGLFunctions@@QAEXII@Z @ 760 NONAME ; void QGLFunctions::glStencilMaskSeparate(unsigned int, unsigned int)
+ ?glBlendColor@QGLFunctions@@QAEXMMMM@Z @ 761 NONAME ; void QGLFunctions::glBlendColor(float, float, float, float)
+ ?glUniform1fv@QGLFunctions@@QAEXHHPBM@Z @ 762 NONAME ; void QGLFunctions::glUniform1fv(int, int, float const *)
+ ??1QGLContextResourceBase@@UAE@XZ @ 763 NONAME ; QGLContextResourceBase::~QGLContextResourceBase(void)
+ ?glCreateProgram@QGLFunctions@@QAEIXZ @ 764 NONAME ; unsigned int QGLFunctions::glCreateProgram(void)
+ ?glVertexAttrib2f@QGLFunctions@@QAEXIMM@Z @ 765 NONAME ; void QGLFunctions::glVertexAttrib2f(unsigned int, float, float)
+ ?glUniformMatrix2fv@QGLFunctions@@QAEXHHEPBM@Z @ 766 NONAME ; void QGLFunctions::glUniformMatrix2fv(int, int, unsigned char, float const *)
+ ?glBufferSubData@QGLFunctions@@QAEXIHHPBX@Z @ 767 NONAME ; void QGLFunctions::glBufferSubData(unsigned int, int, int, void const *)
+ ?glUniform1iv@QGLFunctions@@QAEXHHPBH@Z @ 768 NONAME ; void QGLFunctions::glUniform1iv(int, int, int const *)
+ ?qt_resolve_buffer_extensions@@YA_NPAVQGLContext@@@Z @ 769 NONAME ; bool qt_resolve_buffer_extensions(class QGLContext *)
+ ?glUniform1i@QGLFunctions@@QAEXHH@Z @ 770 NONAME ; void QGLFunctions::glUniform1i(int, int)
+ ?glVertexAttrib4fv@QGLFunctions@@QAEXIPBM@Z @ 771 NONAME ; void QGLFunctions::glVertexAttrib4fv(unsigned int, float const *)
+ ?glDeleteFramebuffers@QGLFunctions@@QAEXHPBI@Z @ 772 NONAME ; void QGLFunctions::glDeleteFramebuffers(int, unsigned int const *)
+ ?glGetVertexAttribfv@QGLFunctions@@QAEXIIPAM@Z @ 773 NONAME ; void QGLFunctions::glGetVertexAttribfv(unsigned int, unsigned int, float *)
+ ?glGetProgramInfoLog@QGLFunctions@@QAEXIHPAHPAD@Z @ 774 NONAME ; void QGLFunctions::glGetProgramInfoLog(unsigned int, int, int *, char *)
+ ?glGetShaderInfoLog@QGLFunctions@@QAEXIHPAHPAD@Z @ 775 NONAME ; void QGLFunctions::glGetShaderInfoLog(unsigned int, int, int *, char *)
+ ?glEnableVertexAttribArray@QGLFunctions@@QAEXI@Z @ 776 NONAME ; void QGLFunctions::glEnableVertexAttribArray(unsigned int)
+ ?glGetVertexAttribiv@QGLFunctions@@QAEXIIPAH@Z @ 777 NONAME ; void QGLFunctions::glGetVertexAttribiv(unsigned int, unsigned int, int *)
+ ?swapBehavior@QGLWindowSurface@@2W4SwapMode@1@A @ 778 NONAME ; enum QGLWindowSurface::SwapMode QGLWindowSurface::swapBehavior
+ ?glCompressedTexImage2D@QGLFunctions@@QAEXIHIHHHHPBX@Z @ 779 NONAME ; void QGLFunctions::glCompressedTexImage2D(unsigned int, int, unsigned int, int, int, int, int, void const *)
+ ?glGetAttribLocation@QGLFunctions@@QAEHIPBD@Z @ 780 NONAME ; int QGLFunctions::glGetAttribLocation(unsigned int, char const *)
+ ?glActiveTexture@QGLFunctions@@QAEXI@Z @ 781 NONAME ; void QGLFunctions::glActiveTexture(unsigned int)
+ ?glUniform4fv@QGLFunctions@@QAEXHHPBM@Z @ 782 NONAME ; void QGLFunctions::glUniform4fv(int, int, float const *)
+ ?glCreateShader@QGLFunctions@@QAEII@Z @ 783 NONAME ; unsigned int QGLFunctions::glCreateShader(unsigned int)
+ ?glAttachShader@QGLFunctions@@QAEXII@Z @ 784 NONAME ; void QGLFunctions::glAttachShader(unsigned int, unsigned int)
+ ?glRenderbufferStorage@QGLFunctions@@QAEXIIHH@Z @ 785 NONAME ; void QGLFunctions::glRenderbufferStorage(unsigned int, unsigned int, int, int)
+ ?glVertexAttribPointer@QGLFunctions@@QAEXIHIEHPBX@Z @ 786 NONAME ; void QGLFunctions::glVertexAttribPointer(unsigned int, int, unsigned int, unsigned char, int, void const *)
+ ?glUniform4iv@QGLFunctions@@QAEXHHPBH@Z @ 787 NONAME ; void QGLFunctions::glUniform4iv(int, int, int const *)
+ ?glDisableVertexAttribArray@QGLFunctions@@QAEXI@Z @ 788 NONAME ; void QGLFunctions::glDisableVertexAttribArray(unsigned int)
+ ?glIsShader@QGLFunctions@@QAEEI@Z @ 789 NONAME ; unsigned char QGLFunctions::glIsShader(unsigned int)
+ ?glShaderBinary@QGLFunctions@@QAEXHPBIIPBXH@Z @ 790 NONAME ; void QGLFunctions::glShaderBinary(int, unsigned int const *, unsigned int, void const *, int)
+ ?glGenFramebuffers@QGLFunctions@@QAEXHPAI@Z @ 791 NONAME ; void QGLFunctions::glGenFramebuffers(int, unsigned int *)
+ ?glVertexAttrib3fv@QGLFunctions@@QAEXIPBM@Z @ 792 NONAME ; void QGLFunctions::glVertexAttrib3fv(unsigned int, float const *)
+ ?glGetVertexAttribPointerv@QGLFunctions@@QAEXIIPAPAX@Z @ 793 NONAME ; void QGLFunctions::glGetVertexAttribPointerv(unsigned int, unsigned int, void * *)
+ ?glUniformMatrix4fv@QGLFunctions@@QAEXHHEPBM@Z @ 794 NONAME ; void QGLFunctions::glUniformMatrix4fv(int, int, unsigned char, float const *)
+ ?setContext@QGLTextureGlyphCache@@QAEXPBVQGLContext@@@Z @ 795 NONAME ; void QGLTextureGlyphCache::setContext(class QGLContext const *)
+ ?glDeleteBuffers@QGLFunctions@@QAEXHPBI@Z @ 796 NONAME ; void QGLFunctions::glDeleteBuffers(int, unsigned int const *)
+ ?glBindRenderbuffer@QGLFunctions@@QAEXII@Z @ 797 NONAME ; void QGLFunctions::glBindRenderbuffer(unsigned int, unsigned int)
+ ?glStencilFuncSeparate@QGLFunctions@@QAEXIIHI@Z @ 798 NONAME ; void QGLFunctions::glStencilFuncSeparate(unsigned int, unsigned int, int, unsigned int)
+ ?createPixmapForImage@QGLPixmapData@@AAEXAAVQImage@@V?$QFlags@W4ImageConversionFlag@Qt@@@@_N@Z @ 799 NONAME ; void QGLPixmapData::createPixmapForImage(class QImage &, class QFlags<enum Qt::ImageConversionFlag>, bool)
+ ?glGetUniformLocation@QGLFunctions@@QAEHIPBD@Z @ 800 NONAME ; int QGLFunctions::glGetUniformLocation(unsigned int, char const *)
+ ?glGetRenderbufferParameteriv@QGLFunctions@@QAEXIIPAH@Z @ 801 NONAME ; void QGLFunctions::glGetRenderbufferParameteriv(unsigned int, unsigned int, int *)
+ ?glBindAttribLocation@QGLFunctions@@QAEXIIPBD@Z @ 802 NONAME ; void QGLFunctions::glBindAttribLocation(unsigned int, unsigned int, char const *)
+ ?glGetShaderSource@QGLFunctions@@QAEXIHPAHPAD@Z @ 803 NONAME ; void QGLFunctions::glGetShaderSource(unsigned int, int, int *, char *)
+ ?setMipmap@QGLFramebufferObjectFormat@@QAEX_N@Z @ 804 NONAME ; void QGLFramebufferObjectFormat::setMipmap(bool)
+ ??1QGLContextGroupResourceBase@@UAE@XZ @ 805 NONAME ; QGLContextGroupResourceBase::~QGLContextGroupResourceBase(void)
+ ?glFramebufferTexture2D@QGLFunctions@@QAEXIIIIH@Z @ 806 NONAME ; void QGLFunctions::glFramebufferTexture2D(unsigned int, unsigned int, unsigned int, unsigned int, int)
+ ?glBlendEquationSeparate@QGLFunctions@@QAEXII@Z @ 807 NONAME ; void QGLFunctions::glBlendEquationSeparate(unsigned int, unsigned int)
+ ?insert@QGLContextResourceBase@@QAEXPBVQGLContext@@PAX@Z @ 808 NONAME ; void QGLContextResourceBase::insert(class QGLContext const *, void *)
+ ?glUniform2i@QGLFunctions@@QAEXHHH@Z @ 809 NONAME ; void QGLFunctions::glUniform2i(int, int, int)
+ ?glGetUniformfv@QGLFunctions@@QAEXIHPAM@Z @ 810 NONAME ; void QGLFunctions::glGetUniformfv(unsigned int, int, float *)
+ ?glUniform3i@QGLFunctions@@QAEXHHHH@Z @ 811 NONAME ; void QGLFunctions::glUniform3i(int, int, int, int)
+ ?glIsRenderbuffer@QGLFunctions@@QAEEI@Z @ 812 NONAME ; unsigned char QGLFunctions::glIsRenderbuffer(unsigned int)
+ ?initializeGLFunctions@QGLFunctions@@QAEXPBVQGLContext@@@Z @ 813 NONAME ; void QGLFunctions::initializeGLFunctions(class QGLContext const *)
+ ??0QGLFunctions@@QAE@XZ @ 814 NONAME ; QGLFunctions::QGLFunctions(void)
+ ?glVertexAttrib2fv@QGLFunctions@@QAEXIPBM@Z @ 815 NONAME ; void QGLFunctions::glVertexAttrib2fv(unsigned int, float const *)
+ ?isInitialized@QGLFunctions@@CA_NPBUQGLFunctionsPrivate@@@Z @ 816 NONAME ; bool QGLFunctions::isInitialized(struct QGLFunctionsPrivate const *)
+ ?glGetUniformiv@QGLFunctions@@QAEXIHPAH@Z @ 817 NONAME ; void QGLFunctions::glGetUniformiv(unsigned int, int, int *)
+ ?glBlendEquation@QGLFunctions@@QAEXI@Z @ 818 NONAME ; void QGLFunctions::glBlendEquation(unsigned int)
+ ?glFramebufferRenderbuffer@QGLFunctions@@QAEXIIII@Z @ 819 NONAME ; void QGLFunctions::glFramebufferRenderbuffer(unsigned int, unsigned int, unsigned int, unsigned int)
+ ?glUniform4i@QGLFunctions@@QAEXHHHHH@Z @ 820 NONAME ; void QGLFunctions::glUniform4i(int, int, int, int, int)
+ ?glUniform3fv@QGLFunctions@@QAEXHHPBM@Z @ 821 NONAME ; void QGLFunctions::glUniform3fv(int, int, float const *)
+ ?value@QGLContextResourceBase@@QAEPAXPBVQGLContext@@@Z @ 822 NONAME ; void * QGLContextResourceBase::value(class QGLContext const *)
+ ?glBlendFuncSeparate@QGLFunctions@@QAEXIIII@Z @ 823 NONAME ; void QGLFunctions::glBlendFuncSeparate(unsigned int, unsigned int, unsigned int, unsigned int)
+ ?glCompressedTexSubImage2D@QGLFunctions@@QAEXIHHHHHIHPBX@Z @ 824 NONAME ; void QGLFunctions::glCompressedTexSubImage2D(unsigned int, int, int, int, int, int, unsigned int, int, void const *)
+ ?freeResource@QGLTextureGlyphCache@@UAEXPAX@Z @ 825 NONAME ; void QGLTextureGlyphCache::freeResource(void *)
+ ?value@QGLContextGroupResourceBase@@QAEPAXPBVQGLContext@@@Z @ 826 NONAME ; void * QGLContextGroupResourceBase::value(class QGLContext const *)
+ ?glUniform3iv@QGLFunctions@@QAEXHHPBH@Z @ 827 NONAME ; void QGLFunctions::glUniform3iv(int, int, int const *)
+ ?mipmap@QGLFramebufferObjectFormat@@QBE_NXZ @ 828 NONAME ; bool QGLFramebufferObjectFormat::mipmap(void) const
+ ?serialNumber@QGLTextureGlyphCache@@QBEHXZ @ 829 NONAME ; int QGLTextureGlyphCache::serialNumber(void) const
+ ?fromImageReader@QGLPixmapData@@UAEXPAVQImageReader@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 830 NONAME ; void QGLPixmapData::fromImageReader(class QImageReader *, class QFlags<enum Qt::ImageConversionFlag>)
+ ?qt_extensionFuncs@QGLContextPrivate@@2UQGLExtensionFuncs@@A @ 831 NONAME ; struct QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs
+ ?glShaderSource@QGLFunctions@@QAEXIHPAPBDPBH@Z @ 832 NONAME ; void QGLFunctions::glShaderSource(unsigned int, int, char const * *, int const *)
+ ?glGetShaderPrecisionFormat@QGLFunctions@@QAEXIIPAH0@Z @ 833 NONAME ; void QGLFunctions::glGetShaderPrecisionFormat(unsigned int, unsigned int, int *, int *)
+ ?insert@QGLContextGroupResourceBase@@QAEXPBVQGLContext@@PAX@Z @ 834 NONAME ; void QGLContextGroupResourceBase::insert(class QGLContext const *, void *)
+
diff --git a/src/s60installs/bwins/QtOpenVGu.def b/src/s60installs/bwins/QtOpenVGu.def
index 87b9c7f..4767d93 100644
--- a/src/s60installs/bwins/QtOpenVGu.def
+++ b/src/s60installs/bwins/QtOpenVGu.def
@@ -176,4 +176,7 @@ EXPORTS
?fromData@QVGPixmapData@@UAE_NPBEIPBDV?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 175 NONAME ; bool QVGPixmapData::fromData(unsigned char const *, unsigned int, char const *, class QFlags<enum Qt::ImageConversionFlag>)
?fromImageReader@QVGPixmapData@@UAEXPAVQImageReader@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 176 NONAME ; void QVGPixmapData::fromImageReader(class QImageReader *, class QFlags<enum Qt::ImageConversionFlag>)
?canVgWritePixels@QVGPaintEngine@@ABE_NABVQImage@@@Z @ 177 NONAME ; bool QVGPaintEngine::canVgWritePixels(class QImage const &) const
+ ?updateSerial@QVGPixmapData@@IAEXXZ @ 178 NONAME ; void QVGPixmapData::updateSerial(void)
+ ?copy@QVGPixmapData@@UAEXPBVQPixmapData@@ABVQRect@@@Z @ 179 NONAME ; void QVGPixmapData::copy(class QPixmapData const *, class QRect const &)
+ ?idealFormat@QVGPixmapData@@IBE?AW4Format@QImage@@PAV3@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 180 NONAME ; enum QImage::Format QVGPixmapData::idealFormat(class QImage *, class QFlags<enum Qt::ImageConversionFlag>) const
diff --git a/src/s60installs/bwins/QtTestu.def b/src/s60installs/bwins/QtTestu.def
index a7bb9cd..60a7a4c 100644
--- a/src/s60installs/bwins/QtTestu.def
+++ b/src/s60installs/bwins/QtTestu.def
@@ -77,4 +77,93 @@ EXPORTS
?staticMetaObject@QTestEventLoop@@2UQMetaObject@@B @ 76 NONAME ; struct QMetaObject const QTestEventLoop::staticMetaObject
?setBenchmarkResult@QTest@@YAXMW4QBenchmarkMetric@1@@Z @ 77 NONAME ; void QTest::setBenchmarkResult(float, enum QTest::QBenchmarkMetric)
?endBenchmarkMeasurement@QTest@@YA_KXZ @ 78 NONAME ; unsigned long long QTest::endBenchmarkMeasurement(void)
+ ?addBenchmarkResult@QTestLog@@SAXABVQBenchmarkResult@@@Z @ 79 NONAME ; void QTestLog::addBenchmarkResult(class QBenchmarkResult const &)
+ ?currentTestLocation@QTestResult@@SA?AW4TestLocation@1@XZ @ 80 NONAME ; enum QTestResult::TestLocation QTestResult::currentTestLocation(void)
+ ?setCurrentTestLocation@QTestResult@@SAXW4TestLocation@1@@Z @ 81 NONAME ; void QTestResult::setCurrentTestLocation(enum QTestResult::TestLocation)
+ ?testFailed@QTestResult@@SA_NXZ @ 82 NONAME ; bool QTestResult::testFailed(void)
+ ?setVerboseLevel@QTestLog@@SAXH@Z @ 83 NONAME ; void QTestLog::setVerboseLevel(int)
+ ?setCurrentTestObject@QTestResult@@SAXPBD@Z @ 84 NONAME ; void QTestResult::setCurrentTestObject(char const *)
+ ?isEmpty@QTestTable@@QBE_NXZ @ 85 NONAME ; bool QTestTable::isEmpty(void) const
+ ?reset@QTestResult@@SAXXZ @ 86 NONAME ; void QTestResult::reset(void)
+ ?info@QTestLog@@SAXPBD0H@Z @ 87 NONAME ; void QTestLog::info(char const *, char const *, int)
+ ?adjustMedianIterationCount@QBenchmarkGlobalData@@QAEHXZ @ 88 NONAME ; int QBenchmarkGlobalData::adjustMedianIterationCount(void)
+ ?addColumn@QTestTable@@QAEXHPBD@Z @ 89 NONAME ; void QTestTable::addColumn(int, char const *)
+ ?setMode@QBenchmarkGlobalData@@QAEXW4Mode@1@@Z @ 90 NONAME ; void QBenchmarkGlobalData::setMode(enum QBenchmarkGlobalData::Mode)
+ ?addFailure@QTestResult@@SAXPBD0H@Z @ 91 NONAME ; void QTestResult::addFailure(char const *, char const *, int)
+ ?indexOf@QTestTable@@QBEHPBD@Z @ 92 NONAME ; int QTestTable::indexOf(char const *) const
+ ?warn@QTestLog@@SAXPBD@Z @ 93 NONAME ; void QTestLog::warn(char const *)
+ ?currentTestData@QTestResult@@SAPAVQTestData@@XZ @ 94 NONAME ; class QTestData * QTestResult::currentTestData(void)
+ ?startLogging@QTestLog@@SAXI@Z @ 95 NONAME ; void QTestLog::startLogging(unsigned int)
+ ?endDataRun@QBenchmarkTestMethodData@@QAEXXZ @ 96 NONAME ; void QBenchmarkTestMethodData::endDataRun(void)
+ ?globalTestTable@QTestTable@@SAPAV1@XZ @ 97 NONAME ; class QTestTable * QTestTable::globalTestTable(void)
+ ?elementCount@QTestTable@@QBEHXZ @ 98 NONAME ; int QTestTable::elementCount(void) const
+ ??0QTestLog@@AAE@XZ @ 99 NONAME ; QTestLog::QTestLog(void)
+ ?allDataPassed@QTestResult@@SA_NXZ @ 100 NONAME ; bool QTestResult::allDataPassed(void)
+ ??0QBenchmarkTestMethodData@@QAE@XZ @ 101 NONAME ; QBenchmarkTestMethodData::QBenchmarkTestMethodData(void)
+ ?qtest_qParseArgs@QTest@@YAXHQAPAD_N@Z @ 102 NONAME ; void QTest::qtest_qParseArgs(int, char * * const, bool)
+ ?unhandledIgnoreMessages@QTestLog@@SAHXZ @ 103 NONAME ; int QTestLog::unhandledIgnoreMessages(void)
+ ?setCurrentTestFunction@QTestResult@@SAXPBD@Z @ 104 NONAME ; void QTestResult::setCurrentTestFunction(char const *)
+ ?enterTestFunction@QTestLog@@SAXPBD@Z @ 105 NONAME ; void QTestLog::enterTestFunction(char const *)
+ ?testFunctions@QTest@@3VQStringList@@A @ 106 NONAME ; class QStringList QTest::testFunctions
+ ?addSkip@QTestResult@@SAXPBDW4SkipMode@QTest@@0H@Z @ 107 NONAME ; void QTestResult::addSkip(char const *, enum QTest::SkipMode, char const *, int)
+ ?currentGlobalDataTag@QTestResult@@SAPBDXZ @ 108 NONAME ; char const * QTestResult::currentGlobalDataTag(void)
+ ?stopLogging@QTestLog@@SAXXZ @ 109 NONAME ; void QTestLog::stopLogging(void)
+ ??1QTestLog@@AAE@XZ @ 110 NONAME ; QTestLog::~QTestLog(void)
+ ?skipCount@QTestResult@@SAHXZ @ 111 NONAME ; int QTestResult::skipCount(void)
+ ?setCurrentGlobalTestData@QTestResult@@SAXPAVQTestData@@@Z @ 112 NONAME ; void QTestResult::setCurrentGlobalTestData(class QTestData *)
+ ?elementTypeId@QTestTable@@QBEHH@Z @ 113 NONAME ; int QTestTable::elementTypeId(int) const
+ ?dataTag@QTestTable@@QBEPBDH@Z @ 114 NONAME ; char const * QTestTable::dataTag(int) const
+ ?dataCount@QTestTable@@QBEHXZ @ 115 NONAME ; int QTestTable::dataCount(void) const
+ ?printUnhandledIgnoreMessages@QTestLog@@SAXXZ @ 116 NONAME ; void QTestLog::printUnhandledIgnoreMessages(void)
+ ??1QBenchmarkTestMethodData@@QAE@XZ @ 117 NONAME ; QBenchmarkTestMethodData::~QBenchmarkTestMethodData(void)
+ ??1QTestTable@@QAE@XZ @ 118 NONAME ; QTestTable::~QTestTable(void)
+ ?current@QBenchmarkGlobalData@@2PAV1@A @ 119 NONAME ; class QBenchmarkGlobalData * QBenchmarkGlobalData::current
+ ?setFlushMode@QTestLog@@SAXW4FlushMode@1@@Z @ 120 NONAME ; void QTestLog::setFlushMode(enum QTestLog::FlushMode)
+ ?ignoreMessage@QTestResult@@SAXW4QtMsgType@@PBD@Z @ 121 NONAME ; void QTestResult::ignoreMessage(enum QtMsgType, char const *)
+ ?failCount@QTestResult@@SAHXZ @ 122 NONAME ; int QTestResult::failCount(void)
+ ?mode@QBenchmarkGlobalData@@QBE?AW4Mode@1@XZ @ 123 NONAME ; enum QBenchmarkGlobalData::Mode QBenchmarkGlobalData::mode(void) const
+ ?addSkip@QTestLog@@SAXPBDW4SkipMode@QTest@@0H@Z @ 124 NONAME ; void QTestLog::addSkip(char const *, enum QTest::SkipMode, char const *, int)
+ ?outputFileName@QTestLog@@SAPBDXZ @ 125 NONAME ; char const * QTestLog::outputFileName(void)
+ ?expectFail@QTestResult@@SA_NPBD0W4TestFailMode@QTest@@0H@Z @ 126 NONAME ; bool QTestResult::expectFail(char const *, char const *, enum QTest::TestFailMode, char const *, int)
+ ?passCount@QTestResult@@SAHXZ @ 127 NONAME ; int QTestResult::passCount(void)
+ ?logMode@QTestLog@@SA?AW4LogMode@1@XZ @ 128 NONAME ; enum QTestLog::LogMode QTestLog::logMode(void)
+ ?skipCurrentTest@QTestResult@@SA_NXZ @ 129 NONAME ; bool QTestResult::skipCurrentTest(void)
+ ?addXPass@QTestLog@@SAXPBD0H@Z @ 130 NONAME ; void QTestLog::addXPass(char const *, char const *, int)
+ ?testTags@QTest@@3VQStringList@@A @ 131 NONAME ; class QStringList QTest::testTags
+ ?isBenchmark@QBenchmarkTestMethodData@@QBE_NXZ @ 132 NONAME ; bool QBenchmarkTestMethodData::isBenchmark(void) const
+ ?adjustIterationCount@QBenchmarkTestMethodData@@QAEHH@Z @ 133 NONAME ; int QBenchmarkTestMethodData::adjustIterationCount(int)
+ ??1QBenchmarkGlobalData@@QAE@XZ @ 134 NONAME ; QBenchmarkGlobalData::~QBenchmarkGlobalData(void)
+ ?printAvailableFunctions@QTest@@3_NA @ 135 NONAME ; bool QTest::printAvailableFunctions
+ ?testData@QTestTable@@QBEPAVQTestData@@H@Z @ 136 NONAME ; class QTestData * QTestTable::testData(int) const
+ ?setCurrentTestData@QTestResult@@SAXPAVQTestData@@@Z @ 137 NONAME ; void QTestResult::setCurrentTestData(class QTestData *)
+ ?compare@QTestResult@@SA_N_NPBD1H@Z @ 138 NONAME ; bool QTestResult::compare(bool, char const *, char const *, int)
+ ?currentTestFailed@QTestResult@@SA_NXZ @ 139 NONAME ; bool QTestResult::currentTestFailed(void)
+ ?compare@QTestResult@@SA_N_NPBDPAD2111H@Z @ 140 NONAME ; bool QTestResult::compare(bool, char const *, char *, char *, char const *, char const *, char const *, int)
+ ?addXFail@QTestLog@@SAXPBD0H@Z @ 141 NONAME ; void QTestLog::addXFail(char const *, char const *, int)
+ ??0QBenchmarkGlobalData@@QAE@XZ @ 142 NONAME ; QBenchmarkGlobalData::QBenchmarkGlobalData(void)
+ ?beginDataRun@QBenchmarkTestMethodData@@QAEXXZ @ 143 NONAME ; void QBenchmarkTestMethodData::beginDataRun(void)
+ ?resultsAccepted@QBenchmarkTestMethodData@@QBE_NXZ @ 144 NONAME ; bool QBenchmarkTestMethodData::resultsAccepted(void) const
+ ?addIgnoreMessage@QTestLog@@SAXW4QtMsgType@@PBD@Z @ 145 NONAME ; void QTestLog::addIgnoreMessage(enum QtMsgType, char const *)
+ ?startLogging@QTestLog@@SAXXZ @ 146 NONAME ; void QTestLog::startLogging(void)
+ ?currentDataTag@QTestResult@@SAPBDXZ @ 147 NONAME ; char const * QTestResult::currentDataTag(void)
+ ?redirectOutput@QTestLog@@SAXPBD@Z @ 148 NONAME ; void QTestLog::redirectOutput(char const *)
+ ?currentTestObjectName@QTestResult@@SAPBDXZ @ 149 NONAME ; char const * QTestResult::currentTestObjectName(void)
+ ?newData@QTestTable@@QAEPAVQTestData@@PBD@Z @ 150 NONAME ; class QTestData * QTestTable::newData(char const *)
+ ?addPass@QTestLog@@SAXPBD@Z @ 151 NONAME ; void QTestLog::addPass(char const *)
+ ?verboseLevel@QTestLog@@SAHXZ @ 152 NONAME ; int QTestLog::verboseLevel(void)
+ ?createMeasurer@QBenchmarkGlobalData@@QAEPAVQBenchmarkMeasurerBase@@XZ @ 153 NONAME ; class QBenchmarkMeasurerBase * QBenchmarkGlobalData::createMeasurer(void)
+ ?currentGlobalTestData@QTestResult@@SAPAVQTestData@@XZ @ 154 NONAME ; class QTestData * QTestResult::currentGlobalTestData(void)
+ ?setSkipCurrentTest@QTestResult@@SAX_N@Z @ 155 NONAME ; void QTestResult::setSkipCurrentTest(bool)
+ ?setResult@QBenchmarkTestMethodData@@QAEXMW4QBenchmarkMetric@QTest@@_N@Z @ 156 NONAME ; void QBenchmarkTestMethodData::setResult(float, enum QTest::QBenchmarkMetric, bool)
+ ?verify@QTestResult@@SA_N_NPBD11H@Z @ 157 NONAME ; bool QTestResult::verify(bool, char const *, char const *, char const *, int)
+ ?leaveTestFunction@QTestLog@@SAXXZ @ 158 NONAME ; void QTestLog::leaveTestFunction(void)
+ ?finishedCurrentTestFunction@QTestResult@@SAXXZ @ 159 NONAME ; void QTestResult::finishedCurrentTestFunction(void)
+ ?currentTestTable@QTestTable@@SAPAV1@XZ @ 160 NONAME ; class QTestTable * QTestTable::currentTestTable(void)
+ ?currentTestFunction@QTestResult@@SAPBDXZ @ 161 NONAME ; char const * QTestResult::currentTestFunction(void)
+ ?setLogMode@QTestLog@@SAXW4LogMode@1@@Z @ 162 NONAME ; void QTestLog::setLogMode(enum QTestLog::LogMode)
+ ?clearGlobalTestTable@QTestTable@@SAXXZ @ 163 NONAME ; void QTestTable::clearGlobalTestTable(void)
+ ?addFail@QTestLog@@SAXPBD0H@Z @ 164 NONAME ; void QTestLog::addFail(char const *, char const *, int)
+ ??0QTestTable@@QAE@XZ @ 165 NONAME ; QTestTable::QTestTable(void)
+ ?setMaxWarnings@QTestLog@@SAXH@Z @ 166 NONAME ; void QTestLog::setMaxWarnings(int)
+ ?current@QBenchmarkTestMethodData@@2PAV1@A @ 167 NONAME ; class QBenchmarkTestMethodData * QBenchmarkTestMethodData::current
diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def
index 207447f..cfdd9ee 100644
--- a/src/s60installs/eabi/QtCoreu.def
+++ b/src/s60installs/eabi/QtCoreu.def
@@ -1439,7 +1439,7 @@ EXPORTS
_ZN31QAbstractEventDispatcherPrivate4initEv @ 1438 NONAME
_ZN31QNonContiguousByteDeviceFactory4wrapEP24QNonContiguousByteDevice @ 1439 NONAME
_ZN31QNonContiguousByteDeviceFactory6createEP10QByteArray @ 1440 NONAME
- _ZN31QNonContiguousByteDeviceFactory6createEP11QRingBuffer @ 1441 NONAME
+ _ZN31QNonContiguousByteDeviceFactory6createEP11QRingBuffer @ 1441 NONAME ABSENT
_ZN31QNonContiguousByteDeviceFactory6createEP9QIODevice @ 1442 NONAME
_ZN4QDir10setCurrentERK7QString @ 1443 NONAME
_ZN4QDir10setSortingE6QFlagsINS_8SortFlagEE @ 1444 NONAME
@@ -3806,4 +3806,7 @@ EXPORTS
_ZNK13QElapsedTimer12nsecsElapsedEv @ 3805 NONAME
_ZNK11QMetaMethod8revisionEv @ 3806 NONAME
_ZNK13QMetaProperty8revisionEv @ 3807 NONAME
+ _ZN16QAnimationDriverC1EP7QObject @ 3808 NONAME
+ _ZN16QAnimationDriverC1ER23QAnimationDriverPrivateP7QObject @ 3809 NONAME
+ _ZN31QNonContiguousByteDeviceFactory6createE14QSharedPointerI11QRingBufferE @ 3810 NONAME
diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def
index 95180d4..130e2d5 100644
--- a/src/s60installs/eabi/QtDeclarativeu.def
+++ b/src/s60installs/eabi/QtDeclarativeu.def
@@ -761,20 +761,20 @@ EXPORTS
_ZN24QDeclarativeCustomParser5errorERK28QDeclarativeCustomParserNodeRK7QString @ 760 NONAME
_ZN24QDeclarativeCustomParser5errorERK32QDeclarativeCustomParserPropertyRK7QString @ 761 NONAME
_ZN24QDeclarativeCustomParser5errorERK7QString @ 762 NONAME
- _ZN24QDeclarativeDebugService11idForObjectEP7QObject @ 763 NONAME ABSENT
- _ZN24QDeclarativeDebugService11objectForIdEi @ 764 NONAME ABSENT
- _ZN24QDeclarativeDebugService11qt_metacallEN11QMetaObject4CallEiPPv @ 765 NONAME ABSENT
- _ZN24QDeclarativeDebugService11qt_metacastEPKc @ 766 NONAME ABSENT
- _ZN24QDeclarativeDebugService11sendMessageERK10QByteArray @ 767 NONAME ABSENT
+ _ZN24QDeclarativeDebugService11idForObjectEP7QObject @ 763 NONAME
+ _ZN24QDeclarativeDebugService11objectForIdEi @ 764 NONAME
+ _ZN24QDeclarativeDebugService11qt_metacallEN11QMetaObject4CallEiPPv @ 765 NONAME
+ _ZN24QDeclarativeDebugService11qt_metacastEPKc @ 766 NONAME
+ _ZN24QDeclarativeDebugService11sendMessageERK10QByteArray @ 767 NONAME
_ZN24QDeclarativeDebugService14enabledChangedEb @ 768 NONAME ABSENT
- _ZN24QDeclarativeDebugService14objectToStringEP7QObject @ 769 NONAME ABSENT
- _ZN24QDeclarativeDebugService15messageReceivedERK10QByteArray @ 770 NONAME ABSENT
- _ZN24QDeclarativeDebugService16staticMetaObjectE @ 771 NONAME DATA 16 ABSENT
- _ZN24QDeclarativeDebugService18hasDebuggingClientEv @ 772 NONAME ABSENT
- _ZN24QDeclarativeDebugService18isDebuggingEnabledEv @ 773 NONAME ABSENT
- _ZN24QDeclarativeDebugService19getStaticMetaObjectEv @ 774 NONAME ABSENT
- _ZN24QDeclarativeDebugServiceC1ERK7QStringP7QObject @ 775 NONAME ABSENT
- _ZN24QDeclarativeDebugServiceC2ERK7QStringP7QObject @ 776 NONAME ABSENT
+ _ZN24QDeclarativeDebugService14objectToStringEP7QObject @ 769 NONAME
+ _ZN24QDeclarativeDebugService15messageReceivedERK10QByteArray @ 770 NONAME
+ _ZN24QDeclarativeDebugService16staticMetaObjectE @ 771 NONAME DATA 16
+ _ZN24QDeclarativeDebugService18hasDebuggingClientEv @ 772 NONAME
+ _ZN24QDeclarativeDebugService18isDebuggingEnabledEv @ 773 NONAME
+ _ZN24QDeclarativeDebugService19getStaticMetaObjectEv @ 774 NONAME
+ _ZN24QDeclarativeDebugServiceC1ERK7QStringP7QObject @ 775 NONAME
+ _ZN24QDeclarativeDebugServiceC2ERK7QStringP7QObject @ 776 NONAME
_ZN24QDeclarativeDomComponentC1ERKS_ @ 777 NONAME ABSENT
_ZN24QDeclarativeDomComponentC1Ev @ 778 NONAME ABSENT
_ZN24QDeclarativeDomComponentC2ERKS_ @ 779 NONAME ABSENT
@@ -1425,8 +1425,8 @@ EXPORTS
_ZNK23QDeclarativePropertyMapixERK7QString @ 1424 NONAME
_ZNK24QDeclarativeCustomParser11resolveTypeERK10QByteArray @ 1425 NONAME
_ZNK24QDeclarativeCustomParser12evaluateEnumERK10QByteArray @ 1426 NONAME
- _ZNK24QDeclarativeDebugService10metaObjectEv @ 1427 NONAME ABSENT
- _ZNK24QDeclarativeDebugService4nameEv @ 1428 NONAME ABSENT
+ _ZNK24QDeclarativeDebugService10metaObjectEv @ 1427 NONAME
+ _ZNK24QDeclarativeDebugService4nameEv @ 1428 NONAME
_ZNK24QDeclarativeDebugService9isEnabledEv @ 1429 NONAME ABSENT
_ZNK24QDeclarativeDomComponent13componentRootEv @ 1430 NONAME ABSENT
_ZNK24QDeclarativeScriptString11scopeObjectEv @ 1431 NONAME
@@ -1554,7 +1554,7 @@ EXPORTS
_ZTI23QDeclarativeItemPrivate @ 1553 NONAME
_ZTI23QDeclarativePropertyMap @ 1554 NONAME
_ZTI24QDeclarativeCustomParser @ 1555 NONAME
- _ZTI24QDeclarativeDebugService @ 1556 NONAME ABSENT
+ _ZTI24QDeclarativeDebugService @ 1556 NONAME
_ZTI24QDeclarativeParserStatus @ 1557 NONAME
_ZTI25QDeclarativeImageProvider @ 1558 NONAME
_ZTI26QDeclarativeDebuggerStatus @ 1559 NONAME ABSENT
@@ -1604,7 +1604,7 @@ EXPORTS
_ZTV23QDeclarativeItemPrivate @ 1603 NONAME
_ZTV23QDeclarativePropertyMap @ 1604 NONAME
_ZTV24QDeclarativeCustomParser @ 1605 NONAME
- _ZTV24QDeclarativeDebugService @ 1606 NONAME ABSENT
+ _ZTV24QDeclarativeDebugService @ 1606 NONAME
_ZTV24QDeclarativeParserStatus @ 1607 NONAME
_ZTV25QDeclarativeImageProvider @ 1608 NONAME
_ZTV26QDeclarativeDebuggerStatus @ 1609 NONAME ABSENT
@@ -1777,10 +1777,10 @@ EXPORTS
_ZN23QDeclarativeDebugClientD1Ev @ 1776 NONAME ABSENT
_ZN23QDeclarativeDebugClientD2Ev @ 1777 NONAME ABSENT
_ZN23QDeclarativeEngineDebug13statusChangedENS_6StatusE @ 1778 NONAME ABSENT
- _ZN24QDeclarativeDebugService13statusChangedENS_6StatusE @ 1779 NONAME ABSENT
- _ZN24QDeclarativeDebugServiceD0Ev @ 1780 NONAME ABSENT
- _ZN24QDeclarativeDebugServiceD1Ev @ 1781 NONAME ABSENT
- _ZN24QDeclarativeDebugServiceD2Ev @ 1782 NONAME ABSENT
+ _ZN24QDeclarativeDebugService13statusChangedENS_6StatusE @ 1779 NONAME
+ _ZN24QDeclarativeDebugServiceD0Ev @ 1780 NONAME
+ _ZN24QDeclarativeDebugServiceD1Ev @ 1781 NONAME
+ _ZN24QDeclarativeDebugServiceD2Ev @ 1782 NONAME
_ZN26QDeclarativeBasePositioner10addChangedEv @ 1783 NONAME ABSENT
_ZN26QDeclarativeBasePositioner10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant @ 1784 NONAME ABSENT
_ZN26QDeclarativeBasePositioner10setSpacingEi @ 1785 NONAME ABSENT
@@ -1851,7 +1851,7 @@ EXPORTS
_ZNK17QDeclarativeTimer9isRunningEv @ 1850 NONAME ABSENT
_ZNK23QDeclarativeDebugClient6statusEv @ 1851 NONAME ABSENT
_ZNK23QDeclarativeEngineDebug6statusEv @ 1852 NONAME ABSENT
- _ZNK24QDeclarativeDebugService6statusEv @ 1853 NONAME ABSENT
+ _ZNK24QDeclarativeDebugService6statusEv @ 1853 NONAME
_ZNK26QDeclarativeBasePositioner10metaObjectEv @ 1854 NONAME ABSENT
_ZNK26QDeclarativeBasePositioner3addEv @ 1855 NONAME ABSENT
_ZNK26QDeclarativeBasePositioner4moveEv @ 1856 NONAME ABSENT
diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def
index 722dee8..ef1d67c 100644
--- a/src/s60installs/eabi/QtGuiu.def
+++ b/src/s60installs/eabi/QtGuiu.def
@@ -12337,4 +12337,59 @@ EXPORTS
_ZN12QTextControl23setWordSelectionEnabledEb @ 12336 NONAME
_ZNK12QTextControl13isDragEnabledEv @ 12337 NONAME
_ZNK12QTextControl22isWordSelectionEnabledEv @ 12338 NONAME
+ _ZN12QLineControl16updateMicroFocusEv @ 12339 NONAME
+ _ZN13QFontDatabase22resolveFontFamilyAliasERK7QString @ 12340 NONAME
+ _ZN14QVolatileImage11paintEngineEv @ 12341 NONAME
+ _ZN14QVolatileImage12ensureFormatEN6QImage6FormatE @ 12342 NONAME
+ _ZN14QVolatileImage15setAlphaChannelERK7QPixmap @ 12343 NONAME
+ _ZN14QVolatileImage4bitsEv @ 12344 NONAME
+ _ZN14QVolatileImage4fillEj @ 12345 NONAME
+ _ZN14QVolatileImage8copyFromEPS_RK5QRect @ 12346 NONAME
+ _ZN14QVolatileImage8imageRefEv @ 12347 NONAME
+ _ZN14QVolatileImageC1EPvS0_ @ 12348 NONAME
+ _ZN14QVolatileImageC1ERK6QImage @ 12349 NONAME
+ _ZN14QVolatileImageC1ERKS_ @ 12350 NONAME
+ _ZN14QVolatileImageC1EiiN6QImage6FormatE @ 12351 NONAME
+ _ZN14QVolatileImageC1Ev @ 12352 NONAME
+ _ZN14QVolatileImageC2EPvS0_ @ 12353 NONAME
+ _ZN14QVolatileImageC2ERK6QImage @ 12354 NONAME
+ _ZN14QVolatileImageC2ERKS_ @ 12355 NONAME
+ _ZN14QVolatileImageC2EiiN6QImage6FormatE @ 12356 NONAME
+ _ZN14QVolatileImageC2Ev @ 12357 NONAME
+ _ZN14QVolatileImageD1Ev @ 12358 NONAME
+ _ZN14QVolatileImageD2Ev @ 12359 NONAME
+ _ZN14QVolatileImageaSERKS_ @ 12360 NONAME
+ _ZN15QGraphicsSystem22releaseCachedResourcesEv @ 12361 NONAME
+ _ZN17QInternalMimeData11canReadDataERK7QString @ 12362 NONAME
+ _ZN17QInternalMimeData11qt_metacallEN11QMetaObject4CallEiPPv @ 12363 NONAME
+ _ZN17QInternalMimeData11qt_metacastEPKc @ 12364 NONAME
+ _ZN17QInternalMimeData13formatsHelperEPK9QMimeData @ 12365 NONAME
+ _ZN17QInternalMimeData15hasFormatHelperERK7QStringPK9QMimeData @ 12366 NONAME
+ _ZN17QInternalMimeData16renderDataHelperERK7QStringPK9QMimeData @ 12367 NONAME
+ _ZN17QInternalMimeData16staticMetaObjectE @ 12368 NONAME DATA 16
+ _ZN17QInternalMimeData19getStaticMetaObjectEv @ 12369 NONAME
+ _ZN17QInternalMimeDataC2Ev @ 12370 NONAME
+ _ZN17QInternalMimeDataD0Ev @ 12371 NONAME
+ _ZN17QInternalMimeDataD1Ev @ 12372 NONAME
+ _ZN17QInternalMimeDataD2Ev @ 12373 NONAME
+ _ZNK14QVolatileImage12bytesPerLineEv @ 12374 NONAME
+ _ZNK14QVolatileImage13endDataAccessEb @ 12375 NONAME
+ _ZNK14QVolatileImage15beginDataAccessEv @ 12376 NONAME
+ _ZNK14QVolatileImage15hasAlphaChannelEv @ 12377 NONAME
+ _ZNK14QVolatileImage20duplicateNativeImageEv @ 12378 NONAME
+ _ZNK14QVolatileImage5depthEv @ 12379 NONAME
+ _ZNK14QVolatileImage5widthEv @ 12380 NONAME
+ _ZNK14QVolatileImage6formatEv @ 12381 NONAME
+ _ZNK14QVolatileImage6heightEv @ 12382 NONAME
+ _ZNK14QVolatileImage6isNullEv @ 12383 NONAME
+ _ZNK14QVolatileImage7toImageEv @ 12384 NONAME
+ _ZNK14QVolatileImage9byteCountEv @ 12385 NONAME
+ _ZNK14QVolatileImage9constBitsEv @ 12386 NONAME
+ _ZNK14QWidgetPrivate20assignedInputContextEv @ 12387 NONAME
+ _ZNK17QInternalMimeData10metaObjectEv @ 12388 NONAME
+ _ZNK17QInternalMimeData12retrieveDataERK7QStringN8QVariant4TypeE @ 12389 NONAME
+ _ZNK17QInternalMimeData7formatsEv @ 12390 NONAME
+ _ZNK17QInternalMimeData9hasFormatERK7QString @ 12391 NONAME
+ _ZTI17QInternalMimeData @ 12392 NONAME
+ _ZTV17QInternalMimeData @ 12393 NONAME
diff --git a/src/s60installs/eabi/QtOpenGLu.def b/src/s60installs/eabi/QtOpenGLu.def
index 794d43d..4977959 100644
--- a/src/s60installs/eabi/QtOpenGLu.def
+++ b/src/s60installs/eabi/QtOpenGLu.def
@@ -707,4 +707,36 @@ EXPORTS
_ZNK20QGLTextureGlyphCache16maxTextureHeightEv @ 706 NONAME
_ZThn8_NK20QGLTextureGlyphCache15maxTextureWidthEv @ 707 NONAME ABSENT
_ZThn8_NK20QGLTextureGlyphCache16maxTextureHeightEv @ 708 NONAME ABSENT
+ _Z28qt_resolve_buffer_extensionsP10QGLContext @ 709 NONAME
+ _ZN12QGLFunctions21initializeGLFunctionsEPK10QGLContext @ 710 NONAME
+ _ZN12QGLFunctionsC1EPK10QGLContext @ 711 NONAME
+ _ZN12QGLFunctionsC1Ev @ 712 NONAME
+ _ZN12QGLFunctionsC2EPK10QGLContext @ 713 NONAME
+ _ZN12QGLFunctionsC2Ev @ 714 NONAME
+ _ZN13QGLPixmapData12toNativeTypeEN11QPixmapData10NativeTypeE @ 715 NONAME
+ _ZN13QGLPixmapData14fromNativeTypeEPvN11QPixmapData10NativeTypeE @ 716 NONAME
+ _ZN13QGLPixmapData15fromImageReaderEP12QImageReader6QFlagsIN2Qt19ImageConversionFlagEE @ 717 NONAME
+ _ZN13QGLPixmapData20createPixmapForImageER6QImage6QFlagsIN2Qt19ImageConversionFlagEEb @ 718 NONAME
+ _ZN16QGLWindowSurface12swapBehaviorE @ 719 NONAME DATA 4
+ _ZN17QGLContextPrivate17qt_extensionFuncsE @ 720 NONAME DATA 60
+ _ZN20QGLTextureGlyphCache10setContextEPK10QGLContext @ 721 NONAME
+ _ZN20QGLTextureGlyphCache11fillTextureERKN18QTextureGlyphCache5CoordEj6QFixed @ 722 NONAME
+ _ZN20QGLTextureGlyphCacheC1EPK10QGLContextN21QFontEngineGlyphCache4TypeERK10QTransform @ 723 NONAME
+ _ZN20QGLTextureGlyphCacheC2EPK10QGLContextN21QFontEngineGlyphCache4TypeERK10QTransform @ 724 NONAME
+ _ZN26QGLFramebufferObjectFormat9setMipmapEb @ 725 NONAME
+ _ZN27QGLContextGroupResourceBase5valueEPK10QGLContext @ 726 NONAME
+ _ZN27QGLContextGroupResourceBase6insertEPK10QGLContextPv @ 727 NONAME
+ _ZN27QGLContextGroupResourceBase7cleanupEPK10QGLContextPv @ 728 NONAME
+ _ZN27QGLContextGroupResourceBaseC2Ev @ 729 NONAME
+ _ZN27QGLContextGroupResourceBaseD0Ev @ 730 NONAME
+ _ZN27QGLContextGroupResourceBaseD1Ev @ 731 NONAME
+ _ZN27QGLContextGroupResourceBaseD2Ev @ 732 NONAME
+ _ZNK12QGLFunctions14openGLFeaturesEv @ 733 NONAME
+ _ZNK12QGLFunctions16hasOpenGLFeatureENS_13OpenGLFeatureE @ 734 NONAME
+ _ZNK14QGLPaintDevice9isFlippedEv @ 735 NONAME
+ _ZNK26QGLFramebufferObjectFormat6mipmapEv @ 736 NONAME
+ _ZTI27QGLContextGroupResourceBase @ 737 NONAME
+ _ZTV27QGLContextGroupResourceBase @ 738 NONAME
+ _ZThn104_N20QGLTextureGlyphCacheD0Ev @ 739 NONAME
+ _ZThn104_N20QGLTextureGlyphCacheD1Ev @ 740 NONAME
diff --git a/src/s60installs/eabi/QtOpenVGu.def b/src/s60installs/eabi/QtOpenVGu.def
index e1828c1..e05cc79 100644
--- a/src/s60installs/eabi/QtOpenVGu.def
+++ b/src/s60installs/eabi/QtOpenVGu.def
@@ -206,4 +206,7 @@ EXPORTS
_ZN13QVGPixmapData8fromDataEPKhjPKc6QFlagsIN2Qt19ImageConversionFlagEE @ 205 NONAME
_ZN13QVGPixmapData8fromFileERK7QStringPKc6QFlagsIN2Qt19ImageConversionFlagEE @ 206 NONAME
_ZNK14QVGPaintEngine16canVgWritePixelsERK6QImage @ 207 NONAME
+ _ZN13QVGPixmapData12updateSerialEv @ 208 NONAME ABSENT
+ _ZN13QVGPixmapData4copyEPK11QPixmapDataRK5QRect @ 209 NONAME ABSENT
+ _ZNK13QVGPixmapData11idealFormatEP6QImage6QFlagsIN2Qt19ImageConversionFlagEE @ 210 NONAME ABSENT
diff --git a/src/s60installs/eabi/QtTestu.def b/src/s60installs/eabi/QtTestu.def
index 5cb95ba..370466b 100644
--- a/src/s60installs/eabi/QtTestu.def
+++ b/src/s60installs/eabi/QtTestu.def
@@ -70,4 +70,98 @@ EXPORTS
_ZTI14QTestEventLoop @ 69 NONAME
_ZTV14QTestEventLoop @ 70 NONAME
_ZN5QTest18setBenchmarkResultEfNS_16QBenchmarkMetricE @ 71 NONAME
+ _ZN10QTestTable15globalTestTableEv @ 72 NONAME
+ _ZN10QTestTable16currentTestTableEv @ 73 NONAME
+ _ZN10QTestTable20clearGlobalTestTableEv @ 74 NONAME
+ _ZN10QTestTable7newDataEPKc @ 75 NONAME
+ _ZN10QTestTable9addColumnEiPKc @ 76 NONAME
+ _ZN10QTestTableC1Ev @ 77 NONAME
+ _ZN10QTestTableC2Ev @ 78 NONAME
+ _ZN10QTestTableD1Ev @ 79 NONAME
+ _ZN10QTestTableD2Ev @ 80 NONAME
+ _ZN11QTestResult10addFailureEPKcS1_i @ 81 NONAME
+ _ZN11QTestResult10expectFailEPKcS1_N5QTest12TestFailModeES1_i @ 82 NONAME
+ _ZN11QTestResult10testFailedEv @ 83 NONAME
+ _ZN11QTestResult13allDataPassedEv @ 84 NONAME
+ _ZN11QTestResult13ignoreMessageE9QtMsgTypePKc @ 85 NONAME
+ _ZN11QTestResult14currentDataTagEv @ 86 NONAME
+ _ZN11QTestResult15currentTestDataEv @ 87 NONAME
+ _ZN11QTestResult15skipCurrentTestEv @ 88 NONAME
+ _ZN11QTestResult17currentTestFailedEv @ 89 NONAME
+ _ZN11QTestResult18setCurrentTestDataEP9QTestData @ 90 NONAME
+ _ZN11QTestResult18setSkipCurrentTestEb @ 91 NONAME
+ _ZN11QTestResult19currentTestFunctionEv @ 92 NONAME
+ _ZN11QTestResult19currentTestLocationEv @ 93 NONAME
+ _ZN11QTestResult20currentGlobalDataTagEv @ 94 NONAME
+ _ZN11QTestResult20setCurrentTestObjectEPKc @ 95 NONAME
+ _ZN11QTestResult21currentGlobalTestDataEv @ 96 NONAME
+ _ZN11QTestResult21currentTestObjectNameEv @ 97 NONAME
+ _ZN11QTestResult22setCurrentTestFunctionEPKc @ 98 NONAME
+ _ZN11QTestResult22setCurrentTestLocationENS_12TestLocationE @ 99 NONAME
+ _ZN11QTestResult24setCurrentGlobalTestDataEP9QTestData @ 100 NONAME
+ _ZN11QTestResult27finishedCurrentTestFunctionEv @ 101 NONAME
+ _ZN11QTestResult5resetEv @ 102 NONAME
+ _ZN11QTestResult6verifyEbPKcS1_S1_i @ 103 NONAME
+ _ZN11QTestResult7addSkipEPKcN5QTest8SkipModeES1_i @ 104 NONAME
+ _ZN11QTestResult7compareEbPKcPcS2_S1_S1_S1_i @ 105 NONAME
+ _ZN11QTestResult7compareEbPKcS1_i @ 106 NONAME
+ _ZN11QTestResult9failCountEv @ 107 NONAME
+ _ZN11QTestResult9passCountEv @ 108 NONAME
+ _ZN11QTestResult9skipCountEv @ 109 NONAME
+ _ZN20QBenchmarkGlobalData14createMeasurerEv @ 110 NONAME
+ _ZN20QBenchmarkGlobalData26adjustMedianIterationCountEv @ 111 NONAME
+ _ZN20QBenchmarkGlobalData7currentE @ 112 NONAME DATA 4
+ _ZN20QBenchmarkGlobalData7setModeENS_4ModeE @ 113 NONAME
+ _ZN20QBenchmarkGlobalDataC1Ev @ 114 NONAME
+ _ZN20QBenchmarkGlobalDataC2Ev @ 115 NONAME
+ _ZN20QBenchmarkGlobalDataD1Ev @ 116 NONAME
+ _ZN20QBenchmarkGlobalDataD2Ev @ 117 NONAME
+ _ZN24QBenchmarkTestMethodData10endDataRunEv @ 118 NONAME
+ _ZN24QBenchmarkTestMethodData12beginDataRunEv @ 119 NONAME
+ _ZN24QBenchmarkTestMethodData20adjustIterationCountEi @ 120 NONAME
+ _ZN24QBenchmarkTestMethodData7currentE @ 121 NONAME DATA 4
+ _ZN24QBenchmarkTestMethodData9setResultEfN5QTest16QBenchmarkMetricEb @ 122 NONAME
+ _ZN24QBenchmarkTestMethodDataC1Ev @ 123 NONAME
+ _ZN24QBenchmarkTestMethodDataC2Ev @ 124 NONAME
+ _ZN24QBenchmarkTestMethodDataD1Ev @ 125 NONAME
+ _ZN24QBenchmarkTestMethodDataD2Ev @ 126 NONAME
+ _ZN5QTest13testFunctionsE @ 127 NONAME DATA 4
+ _ZN5QTest16qtest_qParseArgsEiPPcb @ 128 NONAME
+ _ZN5QTest23printAvailableFunctionsE @ 129 NONAME DATA 1
+ _ZN5QTest8testTagsE @ 130 NONAME DATA 4
+ _ZN8QTestLog10setLogModeENS_7LogModeE @ 131 NONAME
+ _ZN8QTestLog11stopLoggingEv @ 132 NONAME
+ _ZN8QTestLog12setFlushModeENS_9FlushModeE @ 133 NONAME
+ _ZN8QTestLog12startLoggingEj @ 134 NONAME
+ _ZN8QTestLog12startLoggingEv @ 135 NONAME
+ _ZN8QTestLog12verboseLevelEv @ 136 NONAME
+ _ZN8QTestLog14outputFileNameEv @ 137 NONAME
+ _ZN8QTestLog14redirectOutputEPKc @ 138 NONAME
+ _ZN8QTestLog14setMaxWarningsEi @ 139 NONAME
+ _ZN8QTestLog15setVerboseLevelEi @ 140 NONAME
+ _ZN8QTestLog16addIgnoreMessageE9QtMsgTypePKc @ 141 NONAME
+ _ZN8QTestLog17enterTestFunctionEPKc @ 142 NONAME
+ _ZN8QTestLog17leaveTestFunctionEv @ 143 NONAME
+ _ZN8QTestLog18addBenchmarkResultERK16QBenchmarkResult @ 144 NONAME
+ _ZN8QTestLog23unhandledIgnoreMessagesEv @ 145 NONAME
+ _ZN8QTestLog28printUnhandledIgnoreMessagesEv @ 146 NONAME
+ _ZN8QTestLog4infoEPKcS1_i @ 147 NONAME
+ _ZN8QTestLog4warnEPKc @ 148 NONAME
+ _ZN8QTestLog7addFailEPKcS1_i @ 149 NONAME
+ _ZN8QTestLog7addPassEPKc @ 150 NONAME
+ _ZN8QTestLog7addSkipEPKcN5QTest8SkipModeES1_i @ 151 NONAME
+ _ZN8QTestLog7logModeEv @ 152 NONAME
+ _ZN8QTestLog8addXFailEPKcS1_i @ 153 NONAME
+ _ZN8QTestLog8addXPassEPKcS1_i @ 154 NONAME
+ _ZN8QTestLogC1Ev @ 155 NONAME
+ _ZN8QTestLogC2Ev @ 156 NONAME
+ _ZN8QTestLogD1Ev @ 157 NONAME
+ _ZN8QTestLogD2Ev @ 158 NONAME
+ _ZNK10QTestTable12elementCountEv @ 159 NONAME
+ _ZNK10QTestTable13elementTypeIdEi @ 160 NONAME
+ _ZNK10QTestTable7dataTagEi @ 161 NONAME
+ _ZNK10QTestTable7indexOfEPKc @ 162 NONAME
+ _ZNK10QTestTable7isEmptyEv @ 163 NONAME
+ _ZNK10QTestTable8testDataEi @ 164 NONAME
+ _ZNK10QTestTable9dataCountEv @ 165 NONAME
diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp
index 2468a46..5454df5 100644
--- a/src/script/api/qscriptcontext.cpp
+++ b/src/script/api/qscriptcontext.cpp
@@ -268,8 +268,14 @@ QScriptValue QScriptContext::argument(int index) const
QScriptValue QScriptContext::callee() const
{
const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
- QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
- return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(frame->callee());
+ QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(frame);
+ QScript::APIShim shim(eng);
+ if (frame->callee() == eng->originalGlobalObject()) {
+ // This is a pushContext()-created context; the callee is a lie.
+ Q_ASSERT(QScriptEnginePrivate::contextFlags(const_cast<JSC::CallFrame*>(frame)) & QScriptEnginePrivate::NativeContext);
+ return QScriptValue();
+ }
+ return eng->scriptValueFromJSCValue(frame->callee());
}
/*!
diff --git a/src/script/api/qscriptcontextinfo.cpp b/src/script/api/qscriptcontextinfo.cpp
index 0f9de1d..182bc4a 100644
--- a/src/script/api/qscriptcontextinfo.cpp
+++ b/src/script/api/qscriptcontextinfo.cpp
@@ -159,12 +159,20 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *conte
JSC::CodeBlock *codeBlock = frame->codeBlock();
if (returnPC && codeBlock && QScriptEnginePrivate::hasValidCodeBlockRegister(frame)) {
#if ENABLE(JIT)
- unsigned bytecodeOffset = codeBlock->getBytecodeIndex(frame, JSC::ReturnAddressPtr(returnPC));
+ JSC::JITCode code = codeBlock->getJITCode();
+ unsigned jitOffset = code.offsetOf(JSC::ReturnAddressPtr(returnPC).value());
+ // We can only use the JIT code offset if it's smaller than the JIT size;
+ // otherwise calling getBytecodeIndex() is meaningless.
+ if (jitOffset < code.size()) {
+ unsigned bytecodeOffset = codeBlock->getBytecodeIndex(frame, JSC::ReturnAddressPtr(returnPC));
#else
unsigned bytecodeOffset = returnPC - codeBlock->instructions().begin();
#endif
bytecodeOffset--; //because returnPC is on the next instruction. We want the current one
lineNumber = codeBlock->lineNumberForBytecodeOffset(const_cast<JSC::ExecState *>(frame), bytecodeOffset);
+#if ENABLE(JIT)
+ }
+#endif
}
}
}
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 14ab2eb..ceb1b03 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -955,8 +955,11 @@ static QScriptValue __setupPackage__(QScriptContext *ctx, QScriptEngine *eng)
} // namespace QScript
QScriptEnginePrivate::QScriptEnginePrivate()
- : registeredScriptValues(0), freeScriptValues(0), freeScriptValuesCount(0),
- registeredScriptStrings(0), inEval(false)
+ : originalGlobalObjectProxy(0), currentFrame(0),
+ qobjectPrototype(0), qmetaobjectPrototype(0), variantPrototype(0),
+ activeAgent(0), agentLineNumber(-1),
+ registeredScriptValues(0), freeScriptValues(0), freeScriptValuesCount(0),
+ registeredScriptStrings(0), processEventsInterval(-1), inEval(false)
{
qMetaTypeId<QScriptValue>();
qMetaTypeId<QList<int> >();
@@ -1002,10 +1005,6 @@ QScriptEnginePrivate::QScriptEnginePrivate()
currentFrame = exec;
- originalGlobalObjectProxy = 0;
- activeAgent = 0;
- agentLineNumber = -1;
- processEventsInterval = -1;
cachedTranslationUrl = JSC::UString();
cachedTranslationContext = JSC::UString();
JSC::setCurrentIdentifierTable(oldTable);
@@ -1253,10 +1252,12 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack)
{
Q_Q(QScriptEngine);
- markStack.append(originalGlobalObject());
- markStack.append(globalObject());
- if (originalGlobalObjectProxy)
- markStack.append(originalGlobalObjectProxy);
+ if (originalGlobalObject()) {
+ markStack.append(originalGlobalObject());
+ markStack.append(globalObject());
+ if (originalGlobalObjectProxy)
+ markStack.append(originalGlobalObjectProxy);
+ }
if (qobjectPrototype)
markStack.append(qobjectPrototype);
@@ -1281,7 +1282,7 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack)
}
}
- {
+ if (q) {
QScriptContext *context = q->currentContext();
while (context) {
@@ -2728,6 +2729,14 @@ JSC::CallFrame *QScriptEnginePrivate::pushContext(JSC::CallFrame *exec, JSC::JSV
bool clearScopeChain)
{
JSC::JSValue thisObject = _thisObject;
+ if (!callee) {
+ // callee can't be zero, as this can cause JSC to crash during GC
+ // marking phase if the context's Arguments object has been created.
+ // Fake it by using the global object. Note that this is also handled
+ // in QScriptContext::callee(), as that function should still return
+ // an invalid value.
+ callee = originalGlobalObject();
+ }
if (calledAsConstructor) {
//JSC doesn't create default created object for native functions. so we do it
JSC::JSValue prototype = callee->get(exec, exec->propertyNames().prototype);
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index e0dc385..079cf92 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -254,6 +254,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, int val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsNumber(exec, val));
} else
@@ -271,6 +272,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, uint val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsNumber(exec, val));
} else
@@ -288,6 +290,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, qsreal val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsNumber(exec, val));
} else
@@ -305,6 +308,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, const QString &val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsString(exec, val));
} else {
@@ -325,6 +329,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, const char *val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsString(exec, val));
} else {
@@ -531,7 +536,12 @@ void QScriptValue::setPrototype(const QScriptValue &prototype)
Q_D(QScriptValue);
if (!d || !d->isObject())
return;
- if (prototype.isValid() && QScriptValuePrivate::getEngine(prototype)
+
+ JSC::JSValue other = d->engine->scriptValueToJSCValue(prototype);
+ if (!other || !(other.isObject() || other.isNull()))
+ return;
+
+ if (QScriptValuePrivate::getEngine(prototype)
&& (QScriptValuePrivate::getEngine(prototype) != d->engine)) {
qWarning("QScriptValue::setPrototype() failed: "
"cannot set a prototype created in "
@@ -539,7 +549,6 @@ void QScriptValue::setPrototype(const QScriptValue &prototype)
return;
}
JSC::JSObject *thisObject = JSC::asObject(d->jscValue);
- JSC::JSValue other = d->engine->scriptValueToJSCValue(prototype);
// check for cycle
JSC::JSValue nextPrototypeValue = other;
diff --git a/src/script/script.pro b/src/script/script.pro
index ce5c778..c558ba8 100644
--- a/src/script/script.pro
+++ b/src/script/script.pro
@@ -73,7 +73,7 @@ INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/generated
# This line copied from WebCore.pro
DEFINES += WTF_USE_JAVASCRIPTCORE_BINDINGS=1 WTF_CHANGES=1
-DEFINES += NDEBUG
+CONFIG(release, debug|release):DEFINES += NDEBUG
solaris-g++:isEqual(QT_ARCH,sparc) {
CONFIG -= separate_debug_info
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 2cf2412..74b1ace 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -685,10 +685,13 @@ void Moc::parse()
if (parseEnum(&enumDef))
def.enumList += enumDef;
} break;
+ case SEMIC:
+ case COLON:
+ break;
default:
FunctionDef funcDef;
funcDef.access = access;
- int rewind = index;
+ int rewind = index--;
if (parseMaybeFunction(&def, &funcDef)) {
if (funcDef.isConstructor) {
if ((access == FunctionDef::Public) && funcDef.isInvokable) {
diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp
index 8aaa8ff..d3710ac 100644
--- a/tests/arthur/baselineserver/src/baselineserver.cpp
+++ b/tests/arthur/baselineserver/src/baselineserver.cpp
@@ -178,7 +178,7 @@ bool BaselineHandler::establishConnection()
if (branch.isEmpty()) {
// Not run by Pulse, i.e. ad hoc run: Ok.
}
- else if (branch != QLS("master-integration") || !plat.value(PI_GitCommit).contains(QLS("Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into master-integration"))) {
+ else if (branch != QLS("master-integration") || !plat.value(PI_GitCommit).contains(QLS("Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-fire-staging into master-integration"))) {
qDebug() << runId << logtime() << "Did not pass branch/staging repo filter, disconnecting.";
proto.sendBlock(BaselineProtocol::Abort, QByteArray("This branch/staging repo is not assigned to be tested."));
proto.socket.disconnectFromHost();
@@ -426,27 +426,25 @@ QString BaselineHandler::clearAllBaselines(const QString &context)
return QString(QLS("%1 of %2 baselines cleared from context ")).arg((tot-failed)/2).arg(tot/2) + context;
}
-QString BaselineHandler::updateSingleBaseline(const QString &oldBaseline, const QString &newBaseline)
+QString BaselineHandler::updateBaselines(const QString &context, const QString &mismatchContext, const QString &itemFile)
{
- QString res;
- QString basePath(BaselineServer::storagePath() + QLC('/'));
- QString srcBase(basePath + newBaseline.left(newBaseline.length() - 3));
- QString dstDir(basePath + oldBaseline.left(oldBaseline.lastIndexOf(QLC('/'))));
-
- QProcess proc;
- proc.setProcessChannelMode(QProcess::MergedChannels);
- proc.start(QLS("cp"), QStringList() << QLS("-f") << srcBase + QLS(FileFormat) << srcBase + QLS(MetadataFileExt) << dstDir);
- proc.waitForFinished();
- if (proc.exitCode() == 0)
- res = QString("Successfully updated '%1'").arg(oldBaseline);
- else
- res = QString("Error updating baseline: %1<br>"
- "Command output: <pre>%2</pre>").arg(proc.errorString(), proc.readAll().constData());
-
- return res;
+ int tot = 0;
+ int failed = 0;
+ QString storagePrefix = BaselineServer::storagePath() + QLC('/');
+ // If itemId is set, update just that one, otherwise, update all:
+ QString filter = itemFile.isEmpty() ? QLS("*_????.") : itemFile;
+ QDirIterator it(storagePrefix + mismatchContext, QStringList() << filter + QLS(FileFormat) << filter + QLS(MetadataFileExt));
+ while (it.hasNext()) {
+ tot++;
+ it.next();
+ QString oldFile = storagePrefix + context + QLC('/') + it.fileName();
+ QFile::remove(oldFile); // Remove existing baseline file
+ if (!QFile::copy(it.filePath(), oldFile)) // and replace it with the mismatch
+ failed++;
+ }
+ return QString(QLS("%1 of %2 baselines updated in context %3 from context %4")).arg((tot-failed)/2).arg(tot/2).arg(context, mismatchContext);
}
-
QString BaselineHandler::blacklistTest(const QString &context, const QString &itemId, bool removeFromBlacklist)
{
QFile file(BaselineServer::storagePath() + QLC('/') + context + QLS("/BLACKLIST"));
diff --git a/tests/arthur/baselineserver/src/baselineserver.h b/tests/arthur/baselineserver/src/baselineserver.h
index a5683b2..33b2ed7 100644
--- a/tests/arthur/baselineserver/src/baselineserver.h
+++ b/tests/arthur/baselineserver/src/baselineserver.h
@@ -109,7 +109,7 @@ public:
// CGI callbacks:
static QString view(const QString &baseline, const QString &rendered, const QString &compared);
static QString clearAllBaselines(const QString &context);
- static QString updateSingleBaseline(const QString &oldBaseline, const QString &newBaseline);
+ static QString updateBaselines(const QString &context, const QString &mismatchContext, const QString &itemFile);
static QString blacklistTest(const QString &context, const QString &itemId, bool removeFromBlacklist = false);
private slots:
diff --git a/tests/arthur/baselineserver/src/report.cpp b/tests/arthur/baselineserver/src/report.cpp
index c85f144..88b5625 100644
--- a/tests/arthur/baselineserver/src/report.cpp
+++ b/tests/arthur/baselineserver/src/report.cpp
@@ -154,10 +154,14 @@ void Report::writeFunctionResults(const ImageItemList &list)
QString testFunction = list.at(0).testFunction;
QString pageUrl = BaselineServer::baseUrl() + path;
QString ctx = handler->pathForItem(list.at(0), true, false).section(QLC('/'), 0, -2);
+ QString misCtx = handler->pathForItem(list.at(0), false, false).section(QLC('/'), 0, -2);
+
out << "\n<p>&nbsp;</p><h3>Test function: " << testFunction << "</h3>\n";
out << "<p><a href=\"/cgi-bin/server.cgi?cmd=clearAllBaselines&context=" << ctx << "&url=" << pageUrl
- << "\"><b><big>Clear all baselines</big></b></a></h3> (They will be recreated by the next run)</p>\n\n";
+ << "\"><b>Clear all baselines</b></a> for this testfunction (They will be recreated by the next run)</p>\n";
+ out << "<p><a href=\"/cgi-bin/server.cgi?cmd=updateAllBaselines&context=" << ctx << "&mismatchContext=" << misCtx << "&url=" << pageUrl
+ << "\"><b>Let these mismatching images be the new baselines</b></a> for this testfunction</p>\n\n";
out << "<table border=\"2\">\n"
"<tr>\n"
@@ -176,7 +180,8 @@ void Report::writeFunctionResults(const ImageItemList &list)
QString metadata = prefix + QLS(MetadataFileExt);
if (item.status == ImageItem::Mismatch) {
QString rendered = handler->pathForItem(item, false, false) + QLS(FileFormat);
- writeItem(baseline, rendered, item, ctx, metadata);
+ QString itemFile = prefix.section(QLC('/'), -1);
+ writeItem(baseline, rendered, item, itemFile, ctx, misCtx, metadata);
}
else {
out << "<td align=center><a href=\"/" << baseline << "\">image</a> <a href=\"/" << metadata << "\">info</a></td>\n"
@@ -207,7 +212,8 @@ void Report::writeFunctionResults(const ImageItemList &list)
out << "</table>\n";
}
-void Report::writeItem(const QString &baseline, const QString &rendered, const ImageItem &item, const QString &ctx, const QString &metadata)
+void Report::writeItem(const QString &baseline, const QString &rendered, const ImageItem &item,
+ const QString &itemFile, const QString &ctx, const QString &misCtx, const QString &metadata)
{
QString compared = generateCompared(baseline, rendered);
QString pageUrl = BaselineServer::baseUrl() + path;
@@ -219,8 +225,8 @@ void Report::writeItem(const QString &baseline, const QString &rendered, const I
out << "<td align=center>\n"
<< "<p><span style=\"color:red\">Mismatch reported</span></p>\n"
<< "<p><a href=\"/" << metadata << "\">Baseline Info</a>\n"
- << "<p><a href=\"/cgi-bin/server.cgi?cmd=updateSingleBaseline&oldBaseline=" << baseline
- << "&newBaseline=" << rendered << "&url=" << pageUrl << "\">Replace baseline with rendered</a></p>\n"
+ << "<p><a href=\"/cgi-bin/server.cgi?cmd=updateSingleBaseline&context=" << ctx << "&mismatchContext=" << misCtx
+ << "&itemFile=" << itemFile << "&url=" << pageUrl << "\">Let this be the new baseline</a></p>\n"
<< "<p><a href=\"/cgi-bin/server.cgi?cmd=blacklist&context=" << ctx
<< "&itemId=" << item.itemName << "&url=" << pageUrl << "\">Blacklist this item</a></p>\n"
<< "<p><a href=\"/cgi-bin/server.cgi?cmd=view&baseline=" << baseline << "&rendered=" << rendered
@@ -280,8 +286,13 @@ void Report::handleCGIQuery(const QString &query)
cgiUrl.queryItemValue(QLS("compared")));
}
else if (command == QLS("updateSingleBaseline")) {
- s << BaselineHandler::updateSingleBaseline(cgiUrl.queryItemValue(QLS("oldBaseline")),
- cgiUrl.queryItemValue(QLS("newBaseline")));
+ s << BaselineHandler::updateBaselines(cgiUrl.queryItemValue(QLS("context")),
+ cgiUrl.queryItemValue(QLS("mismatchContext")),
+ cgiUrl.queryItemValue(QLS("itemFile")));
+ } else if (command == QLS("updateAllBaselines")) {
+ s << BaselineHandler::updateBaselines(cgiUrl.queryItemValue(QLS("context")),
+ cgiUrl.queryItemValue(QLS("mismatchContext")),
+ QString());
} else if (command == QLS("clearAllBaselines")) {
s << BaselineHandler::clearAllBaselines(cgiUrl.queryItemValue(QLS("context")));
} else if (command == QLS("blacklist")) {
diff --git a/tests/arthur/baselineserver/src/report.h b/tests/arthur/baselineserver/src/report.h
index a56aafb..685539e 100644
--- a/tests/arthur/baselineserver/src/report.h
+++ b/tests/arthur/baselineserver/src/report.h
@@ -67,7 +67,8 @@ public:
private:
void write();
void writeFunctionResults(const ImageItemList &list);
- void writeItem(const QString &baseline, const QString &rendered, const ImageItem &item, const QString &ctx, const QString &metadata);
+ void writeItem(const QString &baseline, const QString &rendered, const ImageItem &item,
+ const QString &itemFile, const QString &ctx, const QString &misCtx, const QString &metadata);
void writeHeader();
void writeFooter();
QString generateCompared(const QString &baseline, const QString &rendered, bool fuzzy = false);
diff --git a/tests/arthur/common/baselineprotocol.cpp b/tests/arthur/common/baselineprotocol.cpp
index e4445bd..cff74cc 100644
--- a/tests/arthur/common/baselineprotocol.cpp
+++ b/tests/arthur/common/baselineprotocol.cpp
@@ -310,7 +310,7 @@ bool BaselineProtocol::connect(const QString &testCase, bool *dryrun)
}
if (cmd == Abort) {
- errMsg += QLS("Server aborted connection. Reason: ") + QString::fromLatin1(block);
+ errMsg += QLS("Server rejected connection. Reason: ") + QString::fromLatin1(block);
return false;
}
diff --git a/tests/auto/baselineexample/baselineexample.pro b/tests/auto/baselineexample/baselineexample.pro
index 30feecc..13f03b8 100644
--- a/tests/auto/baselineexample/baselineexample.pro
+++ b/tests/auto/baselineexample/baselineexample.pro
@@ -15,4 +15,4 @@ TEMPLATE = app
SOURCES += tst_baselineexample.cpp
DEFINES += SRCDIR=\\\"$$PWD/\\\"
-include($$QT_SOURCE_TREE/tests/arthur/common/qbaselinetest.pri)
+include($$PWD/../../arthur/common/qbaselinetest.pri)
diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
index 736f8f4..65ba316 100644
--- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
+++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
@@ -267,8 +267,8 @@ void tst_qdeclarativeflickable::nestedPressDelay()
QVERIFY(outer->property("pressed").toBool() == false);
// The outer pressDelay will prevail (50ms, vs. 10sec)
- QTest::qWait(300);
- QVERIFY(outer->property("pressed").toBool() == true);
+ // QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec.
+ QTRY_VERIFY(outer->property("pressed").toBool() == true);
QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(150, 150)));
diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp b/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp
index a62ea31..ffd5d38 100644
--- a/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp
@@ -62,14 +62,24 @@ class tst_qdeclarativefolderlistmodel : public QObject
{
Q_OBJECT
public:
- tst_qdeclarativefolderlistmodel() {}
+ tst_qdeclarativefolderlistmodel() : removeStart(0), removeEnd(0) {}
+
+public slots:
+ void removed(const QModelIndex &, int start, int end) {
+ removeStart = start;
+ removeEnd = end;
+ }
private slots:
void basicProperties();
+ void refresh();
private:
void checkNoErrors(const QDeclarativeComponent& component);
QDeclarativeEngine engine;
+
+ int removeStart;
+ int removeEnd;
};
void tst_qdeclarativefolderlistmodel::checkNoErrors(const QDeclarativeComponent& component)
@@ -115,6 +125,28 @@ void tst_qdeclarativefolderlistmodel::basicProperties()
QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile(""));
}
+void tst_qdeclarativefolderlistmodel::refresh()
+{
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/basic.qml"));
+ checkNoErrors(component);
+
+ QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create());
+ QVERIFY(flm != 0);
+
+ flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data"));
+ QTRY_COMPARE(flm->property("count").toInt(),2); // wait for refresh
+
+ int count = flm->rowCount();
+
+ connect(flm, SIGNAL(rowsRemoved(const QModelIndex&,int,int)),
+ this, SLOT(removed(const QModelIndex&,int,int)));
+
+ flm->setProperty("sortReversed", true);
+
+ QCOMPARE(removeStart, 0);
+ QCOMPARE(removeEnd, count-1);
+}
+
QTEST_MAIN(tst_qdeclarativefolderlistmodel)
#include "tst_qdeclarativefolderlistmodel.moc"
diff --git a/tests/auto/declarative/qdeclarativelistview/data/listview-sections_delegate.qml b/tests/auto/declarative/qdeclarativelistview/data/listview-sections_delegate.qml
index 9d9cda8..b2d9213 100644
--- a/tests/auto/declarative/qdeclarativelistview/data/listview-sections_delegate.qml
+++ b/tests/auto/declarative/qdeclarativelistview/data/listview-sections_delegate.qml
@@ -1,6 +1,7 @@
import QtQuick 1.0
Rectangle {
+ property string sectionProperty: "number"
width: 240
height: 320
color: "#ffffff"
@@ -56,7 +57,7 @@ Rectangle {
height: 320
model: testModel
delegate: myDelegate
- section.property: "number"
+ section.property: sectionProperty
section.delegate: Rectangle {
objectName: "sect_" + section
color: "#99bb99"
diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
index c7f90da..e326136 100644
--- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
+++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
@@ -1091,6 +1091,52 @@ void tst_QDeclarativeListView::sectionsDelegate()
QList<QDeclarativeItem*> items = findItems<QDeclarativeItem>(contentItem, "sect_1");
QCOMPARE(items.count(), 1);
+ // QTBUG-17759
+ model.modifyItem(0, "One", "aaa");
+ model.modifyItem(1, "One", "aaa");
+ model.modifyItem(2, "One", "aaa");
+ model.modifyItem(3, "Four", "aaa");
+ model.modifyItem(4, "Four", "aaa");
+ model.modifyItem(5, "Four", "aaa");
+ model.modifyItem(6, "Five", "aaa");
+ model.modifyItem(7, "Five", "aaa");
+ model.modifyItem(8, "Five", "aaa");
+ model.modifyItem(9, "Two", "aaa");
+ model.modifyItem(10, "Two", "aaa");
+ model.modifyItem(11, "Two", "aaa");
+ QTRY_COMPARE(findItems<QDeclarativeItem>(contentItem, "sect_aaa").count(), 1);
+ canvas->rootObject()->setProperty("sectionProperty", "name");
+ // ensure view has settled.
+ QTRY_COMPARE(findItems<QDeclarativeItem>(contentItem, "sect_Four").count(), 1);
+ for (int i = 0; i < 4; ++i) {
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem,
+ "sect_" + model.name(i*3));
+ QVERIFY(item);
+ QTRY_COMPARE(item->y(), qreal(i*20*4));
+ }
+
+ // QTBUG-17769
+ model.removeItems(10, 20);
+ // ensure view has settled.
+ QTRY_COMPARE(findItems<QDeclarativeItem>(contentItem, "wrapper").count(), 10);
+ // Drag view up beyond bounds
+ QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20,20)));
+ {
+ QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,0)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+ QApplication::sendEvent(canvas->viewport(), &mv);
+ }
+ {
+ QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,-50)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+ QApplication::sendEvent(canvas->viewport(), &mv);
+ }
+ {
+ QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,-200)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+ QApplication::sendEvent(canvas->viewport(), &mv);
+ }
+ QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20,-200)));
+ // view should settle back at 0
+ QTRY_COMPARE(listview->contentY(), 0.0);
+
delete canvas;
}
@@ -2421,7 +2467,7 @@ QList<T*> tst_QDeclarativeListView::findItems(QGraphicsObject *parent, const QSt
//qDebug() << parent->childItems().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
- if(!item)
+ if(!item || !item->isVisible())
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
diff --git a/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp b/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp
index 7d746a7..e3a4723 100644
--- a/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp
+++ b/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp
@@ -76,6 +76,40 @@ void tst_QDeclarativePropertyMap::insert()
map.insert(QLatin1String("key1"),"Hello World");
QCOMPARE(map.value(QLatin1String("key1")), QVariant("Hello World"));
+
+ //inserting property names same with existing method(signal, slot, method) names is not allowed
+ //QDeclarativePropertyMap has an invokable keys() method
+ QTest::ignoreMessage(QtWarningMsg, "Creating property with name \"keys\" is not permitted, conflicts with internal symbols. ");
+ map.insert(QLatin1String("keys"), 1);
+ QVERIFY(map.keys().count() == 2);
+ QVERIFY(!map.contains(QLatin1String("keys")));
+ QVERIFY(map.value(QLatin1String("keys")).isNull());
+
+ //QDeclarativePropertyMap has a deleteLater() slot
+ QTest::ignoreMessage(QtWarningMsg, "Creating property with name \"deleteLater\" is not permitted, conflicts with internal symbols. ");
+ map.insert(QLatin1String("deleteLater"), 1);
+ QVERIFY(map.keys().count() == 2);
+ QVERIFY(!map.contains(QLatin1String("deleteLater")));
+ QVERIFY(map.value(QLatin1String("deleteLater")).isNull());
+
+ //QDeclarativePropertyMap has an valueChanged() signal
+ QTest::ignoreMessage(QtWarningMsg, "Creating property with name \"valueChanged\" is not permitted, conflicts with internal symbols. ");
+ map.insert(QLatin1String("valueChanged"), 1);
+ QVERIFY(map.keys().count() == 2);
+ QVERIFY(!map.contains(QLatin1String("valueChanged")));
+ QVERIFY(map.value(QLatin1String("valueChanged")).isNull());
+
+ //but 'valueChange' should be ok
+ map.insert(QLatin1String("valueChange"), 1);
+ QVERIFY(map.keys().count() == 3);
+ QVERIFY(map.contains(QLatin1String("valueChange")));
+ QCOMPARE(map.value(QLatin1String("valueChange")), QVariant(1));
+
+ //'valueCHANGED' should be ok, too
+ map.insert(QLatin1String("valueCHANGED"), 1);
+ QVERIFY(map.keys().count() == 4);
+ QVERIFY(map.contains(QLatin1String("valueCHANGED")));
+ QCOMPARE(map.value(QLatin1String("valueCHANGED")), QVariant(1));
}
void tst_QDeclarativePropertyMap::operatorInsert()
diff --git a/tests/auto/declarative/qdeclarativetext/data/qtbug_14734.qml b/tests/auto/declarative/qdeclarativetext/data/qtbug_14734.qml
new file mode 100644
index 0000000..bd07d66
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetext/data/qtbug_14734.qml
@@ -0,0 +1,10 @@
+import QtQuick 1.0
+
+Rectangle {
+ width: 640
+ height: 480
+
+ Text {
+ text: "í "
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp
index a3bba3b..dbb822b 100644
--- a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp
+++ b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp
@@ -109,6 +109,7 @@ private slots:
void testQtQuick11Attributes();
void testQtQuick11Attributes_data();
+ void qtbug_14734();
private:
QStringList standard;
QStringList richText;
@@ -1204,6 +1205,19 @@ void tst_qdeclarativetext::testQtQuick11Attributes_data()
<< "";
}
+void tst_qdeclarativetext::qtbug_14734()
+{
+ QDeclarativeView *canvas = createView(SRCDIR "/data/qtbug_14734.qml");
+ QVERIFY(canvas);
+
+ canvas->show();
+ QApplication::setActiveWindow(canvas);
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
+
+ delete canvas;
+}
+
QTEST_MAIN(tst_qdeclarativetext)
#include "tst_qdeclarativetext.moc"
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/navigation.qml b/tests/auto/declarative/qdeclarativetextedit/data/navigation.qml
index 9ee8a93..0e1caf6 100644
--- a/tests/auto/declarative/qdeclarativetextedit/data/navigation.qml
+++ b/tests/auto/declarative/qdeclarativetextedit/data/navigation.qml
@@ -15,6 +15,7 @@ Rectangle {
KeyNavigation.right: lastItem
KeyNavigation.up: firstItem
KeyNavigation.down: lastItem
+ text: "a"
}
Item {
id: lastItem
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/positionAt.qml b/tests/auto/declarative/qdeclarativetextedit/data/positionAt.qml
new file mode 100644
index 0000000..e010135
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetextedit/data/positionAt.qml
@@ -0,0 +1,9 @@
+import QtQuick 1.0
+
+TextEdit {
+ focus: true
+ objectName: "myInput"
+ width: 50
+ height: 25
+ text: "This is\n a long piece of text"
+}
diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index 2c3ec7c..f642947 100644
--- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
+++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
@@ -110,6 +110,7 @@ private slots:
void persistentSelection();
void focusOnPress();
void selection();
+ void keySelection();
void moveCursorSelection_data();
void moveCursorSelection();
void moveCursorSelectionSequence_data();
@@ -121,6 +122,8 @@ private slots:
void dragMouseSelection();
void inputMethodHints();
+ void positionAt();
+
void cursorDelegate();
void cursorVisible();
void delegateLoading_data();
@@ -128,6 +131,8 @@ private slots:
void navigation();
void readOnly();
void copyAndPaste();
+ void canPaste();
+ void canPasteEmpty();
void textInput();
void openInputPanelOnClick();
void openInputPanelOnFocus();
@@ -140,9 +145,10 @@ private slots:
void preeditMicroFocus();
void inputContextMouseHandler();
+ void inputMethodComposing();
private:
- void simulateKey(QDeclarativeView *, int key);
+ void simulateKey(QDeclarativeView *, int key, Qt::KeyboardModifiers modifiers = 0);
QDeclarativeView *createView(const QString &filename);
QStringList standard;
@@ -757,6 +763,53 @@ void tst_qdeclarativetextedit::selection()
QVERIFY(textEditObject->selectedText().isNull());
}
+void tst_qdeclarativetextedit::keySelection()
+{
+ QDeclarativeView *canvas = createView(SRCDIR "/data/navigation.qml");
+ canvas->show();
+ canvas->setFocus();
+
+ QVERIFY(canvas->rootObject() != 0);
+
+ QDeclarativeTextEdit *input = qobject_cast<QDeclarativeTextEdit *>(qvariant_cast<QObject *>(canvas->rootObject()->property("myInput")));
+
+ QVERIFY(input != 0);
+ QTRY_VERIFY(input->hasActiveFocus() == true);
+
+ QSignalSpy spy(input, SIGNAL(selectionChanged()));
+
+ simulateKey(canvas, Qt::Key_Right, Qt::ShiftModifier);
+ QVERIFY(input->hasActiveFocus() == true);
+ QCOMPARE(input->selectedText(), QString("a"));
+ QCOMPARE(spy.count(), 1);
+ simulateKey(canvas, Qt::Key_Right);
+ QVERIFY(input->hasActiveFocus() == true);
+ QCOMPARE(input->selectedText(), QString());
+ QCOMPARE(spy.count(), 2);
+ simulateKey(canvas, Qt::Key_Right);
+ QVERIFY(input->hasActiveFocus() == false);
+ QCOMPARE(input->selectedText(), QString());
+ QCOMPARE(spy.count(), 2);
+
+ simulateKey(canvas, Qt::Key_Left);
+ QVERIFY(input->hasActiveFocus() == true);
+ QCOMPARE(spy.count(), 2);
+ simulateKey(canvas, Qt::Key_Left, Qt::ShiftModifier);
+ QVERIFY(input->hasActiveFocus() == true);
+ QCOMPARE(input->selectedText(), QString("a"));
+ QCOMPARE(spy.count(), 3);
+ simulateKey(canvas, Qt::Key_Left);
+ QVERIFY(input->hasActiveFocus() == true);
+ QCOMPARE(input->selectedText(), QString());
+ QCOMPARE(spy.count(), 4);
+ simulateKey(canvas, Qt::Key_Left);
+ QVERIFY(input->hasActiveFocus() == false);
+ QCOMPARE(input->selectedText(), QString());
+ QCOMPARE(spy.count(), 4);
+
+ delete canvas;
+}
+
void tst_qdeclarativetextedit::moveCursorSelection_data()
{
QTest::addColumn<QString>("testStr");
@@ -1250,6 +1303,56 @@ void tst_qdeclarativetextedit::inputMethodHints()
delete canvas;
}
+void tst_qdeclarativetextedit::positionAt()
+{
+ QDeclarativeView *canvas = createView(SRCDIR "/data/positionAt.qml");
+ QVERIFY(canvas->rootObject() != 0);
+ canvas->show();
+ canvas->setFocus();
+ QApplication::setActiveWindow(canvas);
+ QTest::qWaitForWindowShown(canvas);
+
+ QDeclarativeTextEdit *texteditObject = qobject_cast<QDeclarativeTextEdit *>(canvas->rootObject());
+ QVERIFY(texteditObject != 0);
+
+ QFontMetrics fm(texteditObject->font());
+ const int y0 = fm.height() / 2;
+ const int y1 = fm.height() * 3 / 2;
+
+ int pos = texteditObject->positionAt(texteditObject->width()/2, y0);
+ int diff = abs(int(fm.width(texteditObject->text().left(pos))-texteditObject->width()/2));
+
+ // some tollerance for different fonts.
+#ifdef Q_OS_LINUX
+ QVERIFY(diff < 2);
+#else
+ QVERIFY(diff < 5);
+#endif
+
+ const qreal x0 = texteditObject->positionToRectangle(pos).x();
+ const qreal x1 = texteditObject->positionToRectangle(pos + 1).x();
+
+ QString preeditText = texteditObject->text().mid(0, pos);
+ texteditObject->setText(texteditObject->text().mid(pos));
+ texteditObject->setCursorPosition(0);
+
+ QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
+ QApplication::sendEvent(canvas, &inputEvent);
+
+ // Check all points within the preedit text return the same position.
+ QCOMPARE(texteditObject->positionAt(0, y0), 0);
+ QCOMPARE(texteditObject->positionAt(x0 / 2, y0), 0);
+ QCOMPARE(texteditObject->positionAt(x0, y0), 0);
+
+ // Verify positioning returns to normal after the preedit text.
+ QCOMPARE(texteditObject->positionAt(x1, y0), 1);
+ QCOMPARE(texteditObject->positionToRectangle(1).x(), x1);
+
+ QVERIFY(texteditObject->positionAt(x0 / 2, y1) > 0);
+
+ delete canvas;
+}
+
void tst_qdeclarativetextedit::cursorDelegate()
{
QDeclarativeView* view = createView(SRCDIR "/data/cursorTest.qml");
@@ -1425,6 +1528,8 @@ void tst_qdeclarativetextedit::navigation()
simulateKey(canvas, Qt::Key_Right);
QVERIFY(input->hasActiveFocus() == true);
simulateKey(canvas, Qt::Key_Right);
+ QVERIFY(input->hasActiveFocus() == true);
+ simulateKey(canvas, Qt::Key_Right);
QVERIFY(input->hasActiveFocus() == false);
simulateKey(canvas, Qt::Key_Left);
QVERIFY(input->hasActiveFocus() == true);
@@ -1492,6 +1597,42 @@ void tst_qdeclarativetextedit::copyAndPaste() {
#endif
}
+void tst_qdeclarativetextedit::canPaste() {
+#ifndef QT_NO_CLIPBOARD
+
+ QApplication::clipboard()->setText("Some text");
+
+ QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"Hello world!\" }";
+ QDeclarativeComponent textEditComponent(&engine);
+ textEditComponent.setData(componentStr.toLatin1(), QUrl());
+ QDeclarativeTextEdit *textEdit = qobject_cast<QDeclarativeTextEdit*>(textEditComponent.create());
+ QVERIFY(textEdit != 0);
+
+ // check initial value - QTBUG-17765
+ QTextControl tc;
+ QCOMPARE(textEdit->canPaste(), tc.canPaste());
+
+#endif
+}
+
+void tst_qdeclarativetextedit::canPasteEmpty() {
+#ifndef QT_NO_CLIPBOARD
+
+ QApplication::clipboard()->clear();
+
+ QString componentStr = "import QtQuick 1.0\nTextEdit { text: \"Hello world!\" }";
+ QDeclarativeComponent textEditComponent(&engine);
+ textEditComponent.setData(componentStr.toLatin1(), QUrl());
+ QDeclarativeTextEdit *textEdit = qobject_cast<QDeclarativeTextEdit*>(textEditComponent.create());
+ QVERIFY(textEdit != 0);
+
+ // check initial value - QTBUG-17765
+ QTextControl tc;
+ QCOMPARE(textEdit->canPaste(), tc.canPaste());
+
+#endif
+}
+
void tst_qdeclarativetextedit::readOnly()
{
QDeclarativeView *canvas = createView(SRCDIR "/data/readOnly.qml");
@@ -1516,10 +1657,10 @@ void tst_qdeclarativetextedit::readOnly()
delete canvas;
}
-void tst_qdeclarativetextedit::simulateKey(QDeclarativeView *view, int key)
+void tst_qdeclarativetextedit::simulateKey(QDeclarativeView *view, int key, Qt::KeyboardModifiers modifiers)
{
- QKeyEvent press(QKeyEvent::KeyPress, key, 0);
- QKeyEvent release(QKeyEvent::KeyRelease, key, 0);
+ QKeyEvent press(QKeyEvent::KeyPress, key, modifiers);
+ QKeyEvent release(QKeyEvent::KeyRelease, key, modifiers);
QApplication::sendEvent(view, &press);
QApplication::sendEvent(view, &release);
@@ -2079,6 +2220,43 @@ void tst_qdeclarativetextedit::inputContextMouseHandler()
ic.eventType = QEvent::None;
}
+void tst_qdeclarativetextedit::inputMethodComposing()
+{
+ QString text = "supercalifragisiticexpialidocious!";
+
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ MyInputContext ic;
+ view.setInputContext(&ic);
+ QDeclarativeTextEdit edit;
+ edit.setWidth(200);
+ edit.setText(text.mid(0, 12));
+ edit.setCursorPosition(12);
+ edit.setPos(0, 0);
+ edit.setFocus(true);
+ scene.addItem(&edit);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QTest::qWaitForWindowShown(&view);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+
+ QSignalSpy spy(&edit, SIGNAL(inputMethodComposingChanged()));
+
+ QCOMPARE(edit.isInputMethodComposing(), false);
+
+ ic.sendEvent(QInputMethodEvent(text.mid(3), QList<QInputMethodEvent::Attribute>()));
+ QCOMPARE(edit.isInputMethodComposing(), true);
+ QCOMPARE(spy.count(), 1);
+
+ ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
+ QCOMPARE(edit.isInputMethodComposing(), true);
+ QCOMPARE(spy.count(), 1);
+
+ ic.sendEvent(QInputMethodEvent());
+ QCOMPARE(edit.isInputMethodComposing(), false);
+ QCOMPARE(spy.count(), 2);
+}
+
QTEST_MAIN(tst_qdeclarativetextedit)
#include "tst_qdeclarativetextedit.moc"
diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
index 49a05a3..a7a4e5e 100644
--- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
+++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
@@ -111,8 +111,11 @@ private slots:
void passwordCharacter();
void cursorDelegate();
void cursorVisible();
+ void cursorRectangle();
void navigation();
void copyAndPaste();
+ void canPasteEmpty();
+ void canPaste();
void readOnly();
void openInputPanelOnClick();
@@ -128,6 +131,7 @@ private slots:
void preeditAutoScroll();
void preeditMicroFocus();
void inputContextMouseHandler();
+ void inputMethodComposing();
private:
void simulateKey(QDeclarativeView *, int key);
@@ -143,7 +147,8 @@ tst_qdeclarativetextinput::tst_qdeclarativetextinput()
standard << "the quick brown fox jumped over the lazy dog"
<< "It's supercalifragisiticexpialidocious!"
<< "Hello, world!"
- << "!dlrow ,olleH";
+ << "!dlrow ,olleH"
+ << " spacey text ";
colorStrings << "aliceblue"
<< "antiquewhite"
@@ -444,6 +449,9 @@ void tst_qdeclarativetextinput::moveCursorSelection_data()
QTest::addColumn<int>("selectionEnd");
QTest::addColumn<bool>("reversible");
+ // () contains the text selected by the cursor.
+ // <> contains the actual selection.
+
QTest::newRow("(t)he|characters")
<< standard[0] << 0 << 1 << QDeclarativeTextInput::SelectCharacters << 0 << 1 << true;
QTest::newRow("do(g)|characters")
@@ -581,6 +589,24 @@ void tst_qdeclarativetextinput::moveCursorSelection_data()
<< standard[3] << 0 << 0 << QDeclarativeTextInput::SelectWords << 0 << 0 << true;
QTest::newRow("!<()>dlrow|words")
<< standard[3] << 1 << 1 << QDeclarativeTextInput::SelectWords << 1 << 1 << true;
+
+ QTest::newRow(" <s(pac)ey> text |words")
+ << standard[4] << 1 << 4 << QDeclarativeTextInput::SelectWords << 1 << 7 << true;
+ QTest::newRow(" spacey <t(ex)t> |words")
+ << standard[4] << 11 << 13 << QDeclarativeTextInput::SelectWords << 10 << 14 << false; // Should be reversible. QTBUG-11365
+ QTest::newRow("<( )>spacey text |words|ltr")
+ << standard[4] << 0 << 1 << QDeclarativeTextInput::SelectWords << 0 << 1 << false;
+ QTest::newRow("<( )spacey> text |words|rtl")
+ << standard[4] << 1 << 0 << QDeclarativeTextInput::SelectWords << 0 << 7 << false;
+ QTest::newRow("spacey <text( )>|words|ltr")
+ << standard[4] << 14 << 15 << QDeclarativeTextInput::SelectWords << 10 << 15 << false;
+// QTBUG-11365
+// QTest::newRow("spacey text<( )>|words|rtl")
+// << standard[4] << 15 << 14 << QDeclarativeTextInput::SelectWords << 14 << 15 << false;
+ QTest::newRow("<()> spacey text |words")
+ << standard[4] << 0 << 0 << QDeclarativeTextInput::SelectWords << 0 << 0 << false;
+ QTest::newRow(" spacey text <()>|words")
+ << standard[4] << 15 << 15 << QDeclarativeTextInput::SelectWords << 15 << 15 << false;
}
void tst_qdeclarativetextinput::moveCursorSelection()
@@ -627,6 +653,11 @@ void tst_qdeclarativetextinput::moveCursorSelectionSequence_data()
QTest::addColumn<int>("selection2Start");
QTest::addColumn<int>("selection2End");
+ // () contains the text selected by the cursor.
+ // <> contains the actual selection.
+ // ^ is the revised cursor position.
+ // {} contains the revised selection.
+
QTest::newRow("the {<quick( bro)wn> f^ox} jumped|ltr")
<< standard[0]
<< 9 << 13 << 17
@@ -739,6 +770,50 @@ void tst_qdeclarativetextinput::moveCursorSelectionSequence_data()
<< 11 << 9 << 5
<< 8 << 13
<< 1 << 13;
+
+ QTest::newRow("{<(^} sp)acey> text |ltr")
+ << standard[4]
+ << 0 << 3 << 0
+ << 0 << 7
+ << 0 << 0;
+ QTest::newRow("{<( ^}sp)acey> text |ltr")
+ << standard[4]
+ << 0 << 3 << 1
+ << 0 << 7
+ << 0 << 1;
+ QTest::newRow("<( {s^p)acey>} text |rtl")
+ << standard[4]
+ << 3 << 0 << 2
+ << 0 << 7
+ << 1 << 7;
+ QTest::newRow("<( {^sp)acey>} text |rtl")
+ << standard[4]
+ << 3 << 0 << 1
+ << 0 << 7
+ << 1 << 7;
+
+ QTest::newRow(" spacey <te(xt {^)>}|rtl")
+ << standard[4]
+ << 15 << 12 << 15
+ << 10 << 15
+ << 15 << 15;
+// QTBUG-11365
+// QTest::newRow(" spacey <te(xt{^ )>}|rtl")
+// << standard[4]
+// << 15 << 12 << 14
+// << 10 << 15
+// << 14 << 15;
+ QTest::newRow(" spacey {<te(x^t} )>|ltr")
+ << standard[4]
+ << 12 << 15 << 13
+ << 10 << 15
+ << 10 << 14;
+// QTBUG-11365
+// QTest::newRow(" spacey {<te(xt^} )>|ltr")
+// << standard[4]
+// << 12 << 15 << 14
+// << 10 << 15
+// << 10 << 14;
}
void tst_qdeclarativetextinput::moveCursorSelectionSequence()
@@ -955,6 +1030,10 @@ void tst_qdeclarativetextinput::positionAt()
QVERIFY(diff < 5);
#endif
+ int x = textinputObject->positionToRectangle(pos + 1).x() - 1;
+ QCOMPARE(textinputObject->positionAt(x, QDeclarativeTextInput::CursorBetweenCharacters), pos + 1);
+ QCOMPARE(textinputObject->positionAt(x, QDeclarativeTextInput::CursorOnCharacter), pos);
+
// Check without autoscroll...
textinputObject->setAutoScroll(false);
pos = textinputObject->positionAt(textinputObject->width()/2);
@@ -967,6 +1046,29 @@ void tst_qdeclarativetextinput::positionAt()
QVERIFY(diff < 5);
#endif
+ x = textinputObject->positionToRectangle(pos + 1).x() - 1;
+ QCOMPARE(textinputObject->positionAt(x, QDeclarativeTextInput::CursorBetweenCharacters), pos + 1);
+ QCOMPARE(textinputObject->positionAt(x, QDeclarativeTextInput::CursorOnCharacter), pos);
+
+ const qreal x0 = textinputObject->positionToRectangle(pos).x();
+ const qreal x1 = textinputObject->positionToRectangle(pos + 1).x();
+
+ QString preeditText = textinputObject->text().mid(0, pos);
+ textinputObject->setText(textinputObject->text().mid(pos));
+ textinputObject->setCursorPosition(0);
+
+ QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
+ QApplication::sendEvent(canvas, &inputEvent);
+
+ // Check all points within the preedit text return the same position.
+ QCOMPARE(textinputObject->positionAt(0), 0);
+ QCOMPARE(textinputObject->positionAt(x0 / 2), 0);
+ QCOMPARE(textinputObject->positionAt(x0), 0);
+
+ // Verify positioning returns to normal after the preedit text.
+ QCOMPARE(textinputObject->positionAt(x1), 1);
+ QCOMPARE(textinputObject->positionToRectangle(1).x(), x1);
+
delete canvas;
}
@@ -1145,6 +1247,24 @@ void tst_qdeclarativetextinput::inputMethods()
QApplication::sendEvent(canvas, &event);
QCOMPARE(input->text(), QString("My Hello world!"));
+ input->setCursorPosition(2);
+ event.setCommitString("Your", -2, 2);
+ QApplication::sendEvent(canvas, &event);
+ QCOMPARE(input->text(), QString("Your Hello world!"));
+ QCOMPARE(input->cursorPosition(), 4);
+
+ input->setCursorPosition(7);
+ event.setCommitString("Goodbye", -2, 5);
+ QApplication::sendEvent(canvas, &event);
+ QCOMPARE(input->text(), QString("Your Goodbye world!"));
+ QCOMPARE(input->cursorPosition(), 12);
+
+ input->setCursorPosition(8);
+ event.setCommitString("Our", -8, 4);
+ QApplication::sendEvent(canvas, &event);
+ QCOMPARE(input->text(), QString("Our Goodbye world!"));
+ QCOMPARE(input->cursorPosition(), 7);
+
delete canvas;
}
@@ -1273,6 +1393,42 @@ void tst_qdeclarativetextinput::copyAndPaste() {
#endif
}
+void tst_qdeclarativetextinput::canPasteEmpty() {
+#ifndef QT_NO_CLIPBOARD
+
+ QApplication::clipboard()->clear();
+
+ QString componentStr = "import QtQuick 1.0\nTextInput { text: \"Hello world!\" }";
+ QDeclarativeComponent textInputComponent(&engine);
+ textInputComponent.setData(componentStr.toLatin1(), QUrl());
+ QDeclarativeTextInput *textInput = qobject_cast<QDeclarativeTextInput*>(textInputComponent.create());
+ QVERIFY(textInput != 0);
+
+ QLineControl lc;
+ bool cp = !lc.isReadOnly() && QApplication::clipboard()->text().length() != 0;
+ QCOMPARE(textInput->canPaste(), cp);
+
+#endif
+}
+
+void tst_qdeclarativetextinput::canPaste() {
+#ifndef QT_NO_CLIPBOARD
+
+ QApplication::clipboard()->setText("Some text");
+
+ QString componentStr = "import QtQuick 1.0\nTextInput { text: \"Hello world!\" }";
+ QDeclarativeComponent textInputComponent(&engine);
+ textInputComponent.setData(componentStr.toLatin1(), QUrl());
+ QDeclarativeTextInput *textInput = qobject_cast<QDeclarativeTextInput*>(textInputComponent.create());
+ QVERIFY(textInput != 0);
+
+ QLineControl lc;
+ bool cp = !lc.isReadOnly() && QApplication::clipboard()->text().length() != 0;
+ QCOMPARE(textInput->canPaste(), cp);
+
+#endif
+}
+
void tst_qdeclarativetextinput::passwordCharacter()
{
QString componentStr = "import QtQuick 1.0\nTextInput { text: \"Hello world!\"; font.family: \"Helvetica\"; echoMode: TextInput.Password }";
@@ -1386,6 +1542,45 @@ void tst_qdeclarativetextinput::cursorVisible()
#endif
}
+void tst_qdeclarativetextinput::cursorRectangle()
+{
+ QString text = "Hello World!";
+
+ QDeclarativeTextInput input;
+ input.setText(text);
+ QFontMetricsF fm(input.font());
+ input.setWidth(fm.width(text.mid(0, 5)));
+
+ QRect r;
+
+ for (int i = 0; i <= 5; ++i) {
+ input.setCursorPosition(i);
+ r = input.cursorRectangle();
+ int textWidth = fm.width(text.mid(0, i));
+
+ QVERIFY(r.left() < textWidth);
+ QVERIFY(r.right() > textWidth);
+ QCOMPARE(input.inputMethodQuery(Qt::ImMicroFocus).toRect(), r);
+ }
+
+ // Check the cursor rectangle remains within the input bounding rect when auto scrolling.
+ QVERIFY(r.left() < input.boundingRect().width());
+ QVERIFY(r.right() >= input.width());
+
+ for (int i = 6; i < text.length(); ++i) {
+ input.setCursorPosition(i);
+ QCOMPARE(r, input.cursorRectangle());
+ QCOMPARE(input.inputMethodQuery(Qt::ImMicroFocus).toRect(), r);
+ }
+
+ for (int i = text.length() - 2; i >= 0; --i) {
+ input.setCursorPosition(i);
+ r = input.cursorRectangle();
+ QVERIFY(r.right() >= 0);
+ QCOMPARE(input.inputMethodQuery(Qt::ImMicroFocus).toRect(), r);
+ }
+}
+
void tst_qdeclarativetextinput::readOnly()
{
QDeclarativeView *canvas = createView(SRCDIR "/data/readOnly.qml");
@@ -1840,7 +2035,8 @@ void tst_qdeclarativetextinput::preeditAutoScroll()
MyInputContext ic;
view.setInputContext(&ic);
QDeclarativeTextInput input;
- input.setWidth(QFontMetricsF(input.font()).width(committedText));
+ QFontMetricsF fm(input.font());
+ input.setWidth(fm.width(committedText));
input.setText(committedText);
input.setPos(0, 0);
input.setFocus(true);
@@ -1853,7 +2049,7 @@ void tst_qdeclarativetextinput::preeditAutoScroll()
// test the text is scrolled so the preedit is visible.
ic.sendPreeditText(preeditText.mid(0, 3), 1);
QVERIFY(input.positionAt(0) != 0);
- QCOMPARE(input.positionAt(input.width()), 8);
+ QVERIFY(input.cursorRectangle().left() < input.boundingRect().width());
// test the text is scrolled back when the preedit is removed.
ic.sendEvent(QInputMethodEvent());
@@ -1862,26 +2058,31 @@ void tst_qdeclarativetextinput::preeditAutoScroll()
// test if the preedit is larger than the text input that the
// character preceding the cursor is still visible.
+ qreal x = input.positionToRectangle(0).x();
for (int i = 0; i < 3; ++i) {
ic.sendPreeditText(preeditText, i + 1);
- QCOMPARE(input.positionAt(0), 5 + i);
+ QVERIFY(input.cursorRectangle().right() >= fm.width(preeditText.at(i)));
+ QVERIFY(input.positionToRectangle(0).x() < x);
+ x = input.positionToRectangle(0).x();
}
for (int i = 1; i >= 0; --i) {
ic.sendPreeditText(preeditText, i + 1);
- QCOMPARE(input.positionAt(0), 5 + i);
+ QVERIFY(input.cursorRectangle().right() >= fm.width(preeditText.at(i)));
+ QVERIFY(input.positionToRectangle(0).x() > x);
+ x = input.positionToRectangle(0).x();
}
// Test incrementing the preedit cursor doesn't cause further
// scrolling when right most text is visible.
ic.sendPreeditText(preeditText, preeditText.length() - 3);
- int position = input.positionAt(0);
+ x = input.positionToRectangle(0).x();
for (int i = 2; i >= 0; --i) {
ic.sendPreeditText(preeditText, preeditText.length() - i);
- QCOMPARE(input.positionAt(0), position);
+ QCOMPARE(input.positionToRectangle(0).x(), x);
}
for (int i = 1; i < 3; ++i) {
ic.sendPreeditText(preeditText, preeditText.length() - i);
- QCOMPARE(input.positionAt(0), position);
+ QCOMPARE(input.positionToRectangle(0).x(), x);
}
// Test disabling auto scroll.
@@ -1903,6 +2104,7 @@ void tst_qdeclarativetextinput::preeditMicroFocus()
view.setInputContext(&ic);
QDeclarativeTextInput input;
input.setPos(0, 0);
+ input.setAutoScroll(false);
input.setFocus(true);
scene.addItem(&input);
view.show();
@@ -2066,6 +2268,43 @@ void tst_qdeclarativetextinput::inputContextMouseHandler()
ic.eventType = QEvent::None;
}
+void tst_qdeclarativetextinput::inputMethodComposing()
+{
+ QString text = "supercalifragisiticexpialidocious!";
+
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ MyInputContext ic;
+ view.setInputContext(&ic);
+ QDeclarativeTextInput input;
+ input.setWidth(200);
+ input.setText(text.mid(0, 12));
+ input.setCursorPosition(12);
+ input.setPos(0, 0);
+ input.setFocus(true);
+ scene.addItem(&input);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QTest::qWaitForWindowShown(&view);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+
+ QSignalSpy spy(&input, SIGNAL(inputMethodComposingChanged()));
+
+ QCOMPARE(input.isInputMethodComposing(), false);
+
+ ic.sendEvent(QInputMethodEvent(text.mid(3), QList<QInputMethodEvent::Attribute>()));
+ QCOMPARE(input.isInputMethodComposing(), true);
+ QCOMPARE(spy.count(), 1);
+
+ ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
+ QCOMPARE(input.isInputMethodComposing(), true);
+ QCOMPARE(spy.count(), 1);
+
+ ic.sendEvent(QInputMethodEvent());
+ QCOMPARE(input.isInputMethodComposing(), false);
+ QCOMPARE(spy.count(), 2);
+}
+
QTEST_MAIN(tst_qdeclarativetextinput)
#include "tst_qdeclarativetextinput.moc"
diff --git a/tests/auto/gui.pro b/tests/auto/gui.pro
index 07dc5ef..186f00c 100644
--- a/tests/auto/gui.pro
+++ b/tests/auto/gui.pro
@@ -112,6 +112,7 @@ SUBDIRS=\
qmimedata \
qmouseevent_modal \
qmovie \
+ qvolatileimage \
qnetworkaccessmanager_and_qprogressdialog \
qnetworkcachemetadata \
qnetworkdiskcache \
diff --git a/tests/auto/lancelot/lancelot.pro b/tests/auto/lancelot/lancelot.pro
index 93841a3..11beb7e 100644
--- a/tests/auto/lancelot/lancelot.pro
+++ b/tests/auto/lancelot/lancelot.pro
@@ -3,11 +3,11 @@ QT += xml svg
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2):QT += opengl
SOURCES += tst_lancelot.cpp \
- $$QT_SOURCE_TREE/tests/arthur/common/paintcommands.cpp
-HEADERS += $$QT_SOURCE_TREE/tests/arthur/common/paintcommands.h
-RESOURCES += $$QT_SOURCE_TREE/tests/arthur/common/images.qrc
+ $$PWD/../../arthur/common/paintcommands.cpp
+HEADERS += $$PWD/../../arthur/common/paintcommands.h
+RESOURCES += $$PWD/../../arthur/common/images.qrc
-include($$QT_SOURCE_TREE/tests/arthur/common/qbaselinetest.pri)
+include($$PWD/../../arthur/common/qbaselinetest.pri)
!symbian:!wince*:DEFINES += SRCDIR=\\\"$$PWD\\\"
linux-g++-maemo:DEFINES += USE_RUNTIME_DIR
diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp
index 56a3107..203f0ae 100644
--- a/tests/auto/moc/tst_moc.cpp
+++ b/tests/auto/moc/tst_moc.cpp
@@ -493,6 +493,7 @@ private slots:
void QTBUG5590_dummyProperty();
void QTBUG12260_defaultTemplate();
void notifyError();
+ void QTBUG17635_invokableAndProperty();
void revisions();
void warnings_data();
void warnings();
@@ -1390,6 +1391,31 @@ void tst_Moc::notifyError()
#endif
}
+class QTBUG_17635_InvokableAndProperty : public QObject
+{
+ Q_OBJECT
+public:
+ Q_PROPERTY(int numberOfEggs READ numberOfEggs)
+ Q_PROPERTY(int numberOfChickens READ numberOfChickens)
+ Q_INVOKABLE QString getEgg(int index) { return QString::fromLatin1("Egg"); }
+ Q_INVOKABLE QString getChicken(int index) { return QString::fromLatin1("Chicken"); }
+ int numberOfEggs() { return 2; }
+ int numberOfChickens() { return 4; }
+};
+
+void tst_Moc::QTBUG17635_invokableAndProperty()
+{
+ //Moc used to fail parsing Q_INVOKABLE if they were dirrectly following a Q_PROPERTY;
+ QTBUG_17635_InvokableAndProperty mc;
+ QString val;
+ QMetaObject::invokeMethod(&mc, "getEgg", Q_RETURN_ARG(QString, val), Q_ARG(int, 10));
+ QCOMPARE(val, QString::fromLatin1("Egg"));
+ QMetaObject::invokeMethod(&mc, "getChicken", Q_RETURN_ARG(QString, val), Q_ARG(int, 10));
+ QCOMPARE(val, QString::fromLatin1("Chicken"));
+ QVERIFY(mc.metaObject()->indexOfProperty("numberOfEggs") != -1);
+ QVERIFY(mc.metaObject()->indexOfProperty("numberOfChickens") != -1);
+}
+
// If changed, update VersionTestNotify below
class VersionTest : public QObject
{
diff --git a/tests/auto/network.pro b/tests/auto/network.pro
index 7d83054..b427f1c 100644
--- a/tests/auto/network.pro
+++ b/tests/auto/network.pro
@@ -35,6 +35,8 @@ SUBDIRS=\
qsslerror \
qsslkey \
qsslsocket \
+ qsslsocket_onDemandCertificates_member \
+ qsslsocket_onDemandCertificates_static \
# qnetworkproxyfactory \ # Uses a hardcoded proxy configuration
!contains(QT_CONFIG, private_tests): SUBDIRS -= \
diff --git a/tests/auto/networkselftest/tst_networkselftest.cpp b/tests/auto/networkselftest/tst_networkselftest.cpp
index cfcafc0..64de64a 100644
--- a/tests/auto/networkselftest/tst_networkselftest.cpp
+++ b/tests/auto/networkselftest/tst_networkselftest.cpp
@@ -967,7 +967,7 @@ void tst_NetworkSelfTest::smbServer()
QVERIFY2(f, qt_error_string().toLocal8Bit());
char buf[128];
- size_t ret = fread(buf, sizeof buf, 1, f);
+ size_t ret = fread(buf, 1, sizeof buf, f);
fclose(f);
QCOMPARE(ret, strlen(contents));
diff --git a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp
index 6331db7..db0d0a7 100644
--- a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp
+++ b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp
@@ -331,7 +331,7 @@ void tst_QAbstractNetworkCache::checkSynchronous()
QNetworkRequest request(realUrl);
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(QNetworkRequest::DownloadBufferAttribute + 1),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
// prime the cache
diff --git a/tests/auto/qfont/tst_qfont.cpp b/tests/auto/qfont/tst_qfont.cpp
index 82c8f65..dabe3fa 100644
--- a/tests/auto/qfont/tst_qfont.cpp
+++ b/tests/auto/qfont/tst_qfont.cpp
@@ -150,6 +150,13 @@ void tst_QFont::exactMatch()
return;
#endif
+#ifdef Q_WS_X11
+ QVERIFY(QFont("sans").exactMatch());
+ QVERIFY(QFont("sans-serif").exactMatch());
+ QVERIFY(QFont("serif").exactMatch());
+ QVERIFY(QFont("monospace").exactMatch());
+#endif
+
QSKIP("This test is bogus on Unix with support for font aliases in fontconfig", SkipAll);
return;
diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp
index 0c89013..91dfe47 100644
--- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp
+++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp
@@ -171,16 +171,16 @@ void tst_QNetworkCookie::parseSingleCookie_data()
QTest::newRow("with-value7") << "a = b" << cookie;
QTest::newRow("with-value8") << "a = b " << cookie;
- cookie.setValue(",");
+ cookie.setValue("\",\"");
QTest::newRow("with-value-with-special1") << "a = \",\" " << cookie;
- cookie.setValue(";");
+ cookie.setValue("\";\"");
QTest::newRow("with-value-with-special2") << "a = \";\" " << cookie;
- cookie.setValue(" ");
+ cookie.setValue("\" \"");
QTest::newRow("with-value-with-special3") << "a = \" \" " << cookie;
- cookie.setValue("\"");
- QTest::newRow("with-value-with-special3") << "a = \"\\\"\" " << cookie;
- cookie.setValue("\"a, b; c\"");
- QTest::newRow("with-value-with-special4") << "a = \"\\\"a, b; c\\\"\"" << cookie;
+ cookie.setValue("\"\\\"\"");
+ QTest::newRow("with-value-with-special4") << "a = \"\\\"\" " << cookie;
+ cookie.setValue("\"\\\"a, b; c\\\"\"");
+ QTest::newRow("with-value-with-special5") << "a = \"\\\"a, b; c\\\"\"" << cookie;
cookie.setValue("b");
cookie.setSecure(true);
@@ -568,10 +568,18 @@ void tst_QNetworkCookie::parseSingleCookie_data()
cookie.setDomain("mail.yahoo.com");
QTest::newRow("network3") << "YM.LC=v=2&m=9993_262838_159_1558_1063_0_5649_4012_3776161073,9426_260205_549_1295_1336_0_5141_4738_3922731647,6733_258196_952_1364_643_0_3560_-1_0,3677_237633_1294_1294_19267_0_3244_29483_4102206176,1315_235149_1693_1541_941_0_3224_1691_1861378060,1858_214311_2100_1298_19538_0_2873_30900_716411652,6258_212007_2506_1285_1017_0_2868_3606_4288540264,3743_207884_2895_1362_2759_0_2545_7114_3388520216,2654_205253_3257_1297_1332_0_2504_4682_3048534803,1891_184881_3660_1291_19079_0_978_29178_2592538685&f=1&n=20&s=date&o=down&e=1196548712&b=Inbox&u=removed; path=/; domain=mail.yahoo.com" << cookie;
- cookie = QNetworkCookie("__ac", "c2hhdXNtYW46U2FTYW80Wm8%3D");
+ cookie = QNetworkCookie("__ac", "\"c2hhdXNtYW46U2FTYW80Wm8%3D\"");
cookie.setPath("/");
cookie.setExpirationDate(QDateTime(QDate(2008, 8, 30), QTime(20, 21, 49), Qt::UTC));
QTest::newRow("network4") << "__ac=\"c2hhdXNtYW46U2FTYW80Wm8%3D\"; Path=/; Expires=Sat, 30 Aug 2008 20:21:49 +0000" << cookie;
+
+ // linkedin.com sends cookies in quotes and expects the cookie in quotes
+ cookie = QNetworkCookie("leo_auth_token", "\"GST:UroVXaxYA3sVSkoVjMNH9bj4dZxVzK2yekgrAUxMfUsyLTNyPjoP60:1298974875:b675566ae32ab36d7a708c0efbf446a5c22b9fca\"");
+ cookie.setPath("/");
+ cookie.setExpirationDate(QDateTime(QDate(2011, 3, 1), QTime(10, 51, 14), Qt::UTC));
+ QTest::newRow("network5") << "leo_auth_token=\"GST:UroVXaxYA3sVSkoVjMNH9bj4dZxVzK2yekgrAUxMfUsyLTNyPjoP60:1298974875:b675566ae32ab36d7a708c0efbf446a5c22b9fca\"; Version=1; Max-Age=1799; Expires=Tue, 01-Mar-2011 10:51:14 GMT; Path=/" << cookie;
+
+
}
void tst_QNetworkCookie::parseSingleCookie()
diff --git a/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp b/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp
index 10fa7c6..41da16e 100644
--- a/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp
+++ b/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp
@@ -60,8 +60,8 @@ QString tst_QNetworkProxyFactory::formatProxyName(const QNetworkProxy & proxy) c
QString proxyName;
if (!proxy.user().isNull())
proxyName.append("%1:%2@").arg(proxy.user(), proxy.password());
- proxyName.append("%1:%2").arg(proxy.hostName(), proxy.port());
- proxyName.append(" (type=%1, capabilities=%2)").arg(proxy.type(), proxy.capabilities());
+ proxyName.append(QString("%1:%2").arg(proxy.hostName()).arg(proxy.port()));
+ proxyName.append(QString(" (type=%1, capabilities=%2)").arg(proxy.type()).arg(proxy.capabilities()));
return proxyName;
}
diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
index 3715162..93e3051 100644
--- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
@@ -84,8 +84,6 @@ Q_DECLARE_METATYPE(QList<QNetworkProxy>)
Q_DECLARE_METATYPE(QNetworkReply::NetworkError)
Q_DECLARE_METATYPE(QBuffer*)
-const int SynchronousRequestAttribute = QNetworkRequest::DownloadBufferAttribute + 1;
-
class QNetworkReplyPtr: public QSharedPointer<QNetworkReply>
{
public:
@@ -327,6 +325,7 @@ private Q_SLOTS:
void ioGetFromHttpBrokenChunkedEncoding();
void qtbug12908compressedHttpReply();
+ void compressedHttpReplyBrokenGzip();
void getFromUnreachableIp();
@@ -340,7 +339,9 @@ private Q_SLOTS:
void synchronousRequest_data();
void synchronousRequest();
+#ifndef QT_NO_OPENSSL
void synchronousRequestSslFailure();
+#endif
void httpAbort();
@@ -457,6 +458,7 @@ private:
{
//qDebug() << "connectSocketSignals" << client;
connect(client, SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
+ connect(client, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot()));
connect(client, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(slotError(QAbstractSocket::SocketError)));
}
@@ -484,15 +486,19 @@ public slots:
if (multiple)
receivedData.remove(0, doubleEndlPos+4);
- client->write(dataToTransmit);
- while (client->bytesToWrite() > 0)
- client->waitForBytesWritten();
+ // we need to emulate the bytesWrittenSlot call if the data is empty.
+ if (dataToTransmit.size() == 0)
+ QMetaObject::invokeMethod(this, "bytesWrittenSlot", Qt::QueuedConnection);
+ else
+ client->write(dataToTransmit);
+ }
+ }
- if (doClose) {
- client->disconnectFromHost();
- disconnect(client, 0, this, 0);
- client = 0;
- }
+ void bytesWrittenSlot() {
+ if (doClose && client->bytesToWrite() == 0) {
+ client->disconnectFromHost();
+ disconnect(client, 0, this, 0);
+ client = 0;
}
}
};
@@ -961,7 +967,9 @@ tst_QNetworkReply::tst_QNetworkReply()
qRegisterMetaType<QNetworkReply *>(); // for QSignalSpy
qRegisterMetaType<QAuthenticator *>();
qRegisterMetaType<QNetworkProxy>();
+#ifndef QT_NO_OPENSSL
qRegisterMetaType<QList<QSslError> >();
+#endif
Q_SET_DEFAULT_IAP
@@ -1057,7 +1065,7 @@ QString tst_QNetworkReply::runSimpleRequest(QNetworkAccessManager::Operation op,
returnCode = Timeout;
int code = Success;
- if (request.attribute(static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute)).toBool()) {
+ if (request.attribute(QNetworkRequest::SynchronousRequestAttribute).toBool()) {
if (reply->isFinished())
code = reply->error() != QNetworkReply::NoError ? Failure : Success;
else
@@ -1494,6 +1502,12 @@ void tst_QNetworkReply::getErrors()
{
QFETCH(QString, url);
QNetworkRequest request(url);
+
+#if defined(Q_OS_WIN) || defined (Q_OS_SYMBIAN)
+ if (qstrcmp(QTest::currentDataTag(), "empty-scheme-host") == 0)
+ QTest::ignoreMessage(QtWarningMsg, "QNetworkAccessFileBackendFactory: URL has no schema set, use file:// for files");
+#endif
+
QNetworkReplyPtr reply = manager.get(request);
reply->setParent(this); // we have expect-fails
@@ -1508,6 +1522,9 @@ void tst_QNetworkReply::getErrors()
//qDebug() << reply->errorString();
QFETCH(int, error);
+#if defined(Q_OS_WIN) || defined (Q_OS_SYMBIAN)
+ QEXPECT_FAIL("empty-scheme-host", "this is expected to fail on Windows and Symbian, QTBUG-17731", Abort);
+#endif
QEXPECT_FAIL("ftp-is-dir", "QFtp cannot provide enough detail", Abort);
// the line below is not necessary
QEXPECT_FAIL("ftp-dir-not-readable", "QFtp cannot provide enough detail", Abort);
@@ -1680,7 +1697,7 @@ void tst_QNetworkReply::putToHttpSynchronous()
QFETCH(QByteArray, data);
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::PutOperation, request, reply, data));
@@ -1740,7 +1757,7 @@ void tst_QNetworkReply::postToHttpSynchronous()
QNetworkRequest request(url);
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QNetworkReplyPtr reply;
@@ -2255,7 +2272,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth()
// now check with synchronous calls:
{
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)));
@@ -2279,7 +2296,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuthSynchronous()
QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt"));
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)));
@@ -2364,7 +2381,7 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth()
reference.seek(0);
{
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
@@ -2390,7 +2407,7 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuthSynchronous()
QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
manager.setProxy(proxy);
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
@@ -3503,7 +3520,7 @@ void tst_QNetworkReply::ioPostToHttpFromSocketSynchronous()
QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi");
QNetworkRequest request(url);
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QNetworkReplyPtr reply = manager.post(request, socketpair.endPoints[1]);
@@ -3695,12 +3712,12 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress()
incomingSocket->setReadBufferSize(1*1024);
QTestEventLoop::instance().enterLoop(2);
// some progress should have been made
+ QVERIFY(!spy.isEmpty());
QList<QVariant> args = spy.last();
qDebug() << "tst_QNetworkReply::ioPostToHttpsUploadProgress"
<< args.at(0).toLongLong()
<< sourceFile.size()
<< spy.size();
- QVERIFY(!args.isEmpty());
QVERIFY(args.at(0).toLongLong() > 0);
// FIXME this is where it messes up
@@ -3711,16 +3728,16 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress()
incomingSocket->read(16*1024);
QTestEventLoop::instance().enterLoop(2);
// some more progress than before
+ QVERIFY(!spy.isEmpty());
QList<QVariant> args2 = spy.last();
- QVERIFY(!args2.isEmpty());
QVERIFY(args2.at(0).toLongLong() > args.at(0).toLongLong());
// set the read buffer to unlimited
incomingSocket->setReadBufferSize(0);
QTestEventLoop::instance().enterLoop(10);
// progress should be finished
+ QVERIFY(!spy.isEmpty());
QList<QVariant> args3 = spy.last();
- QVERIFY(!args3.isEmpty());
QVERIFY(args3.at(0).toLongLong() > args2.at(0).toLongLong());
QCOMPARE(args3.at(0).toLongLong(), args3.at(1).toLongLong());
QCOMPARE(args3.at(0).toLongLong(), sourceFile.size());
@@ -3810,6 +3827,8 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp()
if (reader.data.size() < testData.size()) { // oops?
QCOMPARE(reader.data, testData.mid(0, reader.data.size()));
qDebug() << "The data is incomplete, the last" << testData.size() - reader.data.size() << "bytes are missing";
+ QEXPECT_FAIL("http+limited", "Limiting is broken right now, check QTBUG-15065", Abort);
+ QEXPECT_FAIL("https+limited", "Limiting is broken right now, check QTBUG-15065", Abort);
}
QCOMPARE(reader.data.size(), testData.size());
QCOMPARE(reader.data, testData);
@@ -3822,8 +3841,8 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp()
const int maxRate = rate * 1024 * (100+allowedDeviation) / 100;
qDebug() << minRate << "<="<< server.transferRate << "<=" << maxRate << "?";
QVERIFY(server.transferRate >= minRate);
- QEXPECT_FAIL("http+limited", "Limiting is broken right now", Continue);
- QEXPECT_FAIL("https+limited", "Limiting is broken right now", Continue);
+ QEXPECT_FAIL("http+limited", "Limiting is broken right now, check QTBUG-15065", Continue);
+ QEXPECT_FAIL("https+limited", "Limiting is broken right now, check QTBUG-15065", Continue);
QVERIFY(server.transferRate <= maxRate);
}
}
@@ -4274,7 +4293,7 @@ void tst_QNetworkReply::receiveCookiesFromHttpSynchronous()
QNetworkRequest request(url);
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QNetworkReplyPtr reply;
@@ -4366,7 +4385,7 @@ void tst_QNetworkReply::sendCookiesSynchronous()
QNetworkRequest request(url);
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QNetworkReplyPtr reply;
@@ -4508,7 +4527,7 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous()
// send synchronous request
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QNetworkReplyPtr reply = manager.get(request);
@@ -5234,6 +5253,7 @@ void tst_QNetworkReply::qtbug12908compressedHttpReply()
// dd if=/dev/zero of=qtbug-12908 bs=16384 count=1 && gzip qtbug-12908 && base64 -w 0 qtbug-12908.gz
QString encodedFile("H4sICDdDaUwAA3F0YnVnLTEyOTA4AO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA");
QByteArray decodedFile = QByteArray::fromBase64(encodedFile.toAscii());
+ QCOMPARE(decodedFile.size(), 63);
MiniHttpServer server(header.toAscii() + decodedFile);
server.doClose = true;
@@ -5246,6 +5266,31 @@ void tst_QNetworkReply::qtbug12908compressedHttpReply()
QVERIFY(!QTestEventLoop::instance().timeout());
QCOMPARE(reply->error(), QNetworkReply::NoError);
+ QCOMPARE(reply->size(), qint64(16384));
+ QCOMPARE(reply->readAll(), QByteArray(16384, '\0'));
+}
+
+void tst_QNetworkReply::compressedHttpReplyBrokenGzip()
+{
+ QString header("HTTP/1.0 200 OK\r\nContent-Encoding: gzip\r\nContent-Length: 63\r\n\r\n");
+
+ // dd if=/dev/zero of=qtbug-12908 bs=16384 count=1 && gzip qtbug-12908 && base64 -w 0 qtbug-12908.gz
+ // Then change "BMQ" to "BMX"
+ QString encodedFile("H4sICDdDaUwAA3F0YnVnLTEyOTA4AO3BMXEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA");
+ QByteArray decodedFile = QByteArray::fromBase64(encodedFile.toAscii());
+ QCOMPARE(decodedFile.size(), 63);
+
+ MiniHttpServer server(header.toAscii() + decodedFile);
+ server.doClose = true;
+
+ QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort())));
+ QNetworkReplyPtr reply = manager.get(request);
+
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(reply->error(), QNetworkReply::ProtocolFailure);
}
// TODO add similar test for FTP
@@ -5454,7 +5499,7 @@ void tst_QNetworkReply::synchronousRequest()
#endif
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QNetworkReplyPtr reply;
@@ -5485,6 +5530,7 @@ void tst_QNetworkReply::synchronousRequest()
reply->deleteLater();
}
+#ifndef QT_NO_OPENSSL
void tst_QNetworkReply::synchronousRequestSslFailure()
{
// test that SSL won't be accepted with self-signed certificate,
@@ -5494,7 +5540,7 @@ void tst_QNetworkReply::synchronousRequestSslFailure()
QUrl url("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt");
QNetworkRequest request(url);
request.setAttribute(
- static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute),
+ QNetworkRequest::SynchronousRequestAttribute,
true);
QNetworkReplyPtr reply;
QSignalSpy sslErrorsSpy(&manager, SIGNAL(sslErrors(QNetworkReply *, const QList<QSslError> &)));
@@ -5503,6 +5549,7 @@ void tst_QNetworkReply::synchronousRequestSslFailure()
QCOMPARE(reply->error(), QNetworkReply::SslHandshakeFailedError);
QCOMPARE(sslErrorsSpy.count(), 0);
}
+#endif
void tst_QNetworkReply::httpAbort()
{
diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
index 9d7e896..457188c 100644
--- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
+++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
@@ -725,10 +725,7 @@ void tst_QScriptContext::backtrace_data()
expected << "<native>('hey') at -1"
<< "<eval>() at 3"
- << QString::fromLatin1("foo(arg1 = 'hello', arg2 = 456) at testfile:%0")
- // interpreter unfortunately doesn't provide line number for eval()
- .arg(qt_script_isJITEnabled() ? 2 : -1);
- expected
+ << "foo(arg1 = 'hello', arg2 = 456) at testfile:2"
<< "<global>() at testfile:4";
QTest::newRow("eval") << source << expected;
@@ -787,10 +784,7 @@ void tst_QScriptContext::backtrace_data()
expected << "<native>('hey') at -1"
<< "<eval>() at 3"
- << QString::fromLatin1("plop('hello', 456) at testfile:%0")
- // interpreter unfortunately doesn't provide line number for eval()
- .arg(qt_script_isJITEnabled() ? 3 : -1);
- expected
+ << "plop('hello', 456) at testfile:3"
<< "<global>() at testfile:5";
QTest::newRow("eval in member") << source << expected;
@@ -987,6 +981,8 @@ void tst_QScriptContext::backtrace()
QVERIFY(!eng.hasUncaughtException());
QVERIFY(ret.isArray());
QStringList slist = qscriptvalue_cast<QStringList>(ret);
+ QEXPECT_FAIL("eval", "QTBUG-17842: Missing line number in backtrace when function calls eval()", Continue);
+ QEXPECT_FAIL("eval in member", "QTBUG-17842: Missing line number in backtrace when function calls eval()", Continue);
QCOMPARE(slist, expectedbacktrace);
}
diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp
index 2d7feee..bc4091d 100644
--- a/tests/auto/qscriptengine/tst_qscriptengine.cpp
+++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp
@@ -157,6 +157,7 @@ private slots:
void reportAdditionalMemoryCost();
void gcWithNestedDataStructure();
void processEventsWhileRunning();
+ void throwErrorFromProcessEvents_data();
void throwErrorFromProcessEvents();
void disableProcessEventsInterval();
void stacktrace();
@@ -164,6 +165,7 @@ private slots:
void numberParsing();
void automaticSemicolonInsertion();
void abortEvaluation_notEvaluating();
+ void abortEvaluation_data();
void abortEvaluation();
void abortEvaluation_tryCatch();
void abortEvaluation_fromNative();
@@ -235,6 +237,7 @@ private slots:
void evaluateProgram_multipleEngines();
void evaluateProgram_empty();
void collectGarbageAfterConnect();
+ void collectGarbageAfterNativeArguments();
void promoteThisObjectToQObjectInConstructor();
void scriptValueFromQMetaObject();
@@ -2961,17 +2964,42 @@ public:
QScriptEngine *engine;
};
+void tst_QScriptEngine::throwErrorFromProcessEvents_data()
+{
+ QTest::addColumn<QString>("script");
+ QTest::addColumn<QString>("error");
+
+ QTest::newRow("while (1)")
+ << QString::fromLatin1("while (1) { }")
+ << QString::fromLatin1("Error: Killed");
+ QTest::newRow("while (1) i++")
+ << QString::fromLatin1("i = 0; while (1) { i++; }")
+ << QString::fromLatin1("Error: Killed");
+ // Unlike abortEvaluation(), scripts should be able to catch the
+ // exception.
+ QTest::newRow("try catch")
+ << QString::fromLatin1("try {"
+ " while (1) { }"
+ "} catch(e) {"
+ " throw new Error('Caught');"
+ "}")
+ << QString::fromLatin1("Error: Caught");
+}
+
void tst_QScriptEngine::throwErrorFromProcessEvents()
{
+ QFETCH(QString, script);
+ QFETCH(QString, error);
+
QScriptEngine eng;
EventReceiver2 receiver(&eng);
QCoreApplication::postEvent(&receiver, new QEvent(QEvent::Type(QEvent::User+1)));
eng.setProcessEventsInterval(100);
- QScriptValue ret = eng.evaluate(QString::fromLatin1("while (1) { }"));
+ QScriptValue ret = eng.evaluate(script);
QVERIFY(ret.isError());
- QCOMPARE(ret.toString(), QString::fromLatin1("Error: Killed"));
+ QCOMPARE(ret.toString(), error);
}
void tst_QScriptEngine::disableProcessEventsInterval()
@@ -3386,8 +3414,26 @@ void tst_QScriptEngine::abortEvaluation_notEvaluating()
}
}
+void tst_QScriptEngine::abortEvaluation_data()
+{
+ QTest::addColumn<QString>("script");
+
+ QTest::newRow("while (1)")
+ << QString::fromLatin1("while (1) { }");
+ QTest::newRow("while (1) i++")
+ << QString::fromLatin1("i = 0; while (1) { i++; }");
+ QTest::newRow("try catch")
+ << QString::fromLatin1("try {"
+ " while (1) { }"
+ "} catch(e) {"
+ " throw new Error('Caught');"
+ "}");
+}
+
void tst_QScriptEngine::abortEvaluation()
{
+ QFETCH(QString, script);
+
QScriptEngine eng;
EventReceiver3 receiver(&eng);
@@ -3395,7 +3441,7 @@ void tst_QScriptEngine::abortEvaluation()
for (int x = 0; x < 4; ++x) {
QCoreApplication::postEvent(&receiver, new QEvent(QEvent::Type(QEvent::User+1)));
receiver.resultType = EventReceiver3::AbortionResult(x);
- QScriptValue ret = eng.evaluate(QString::fromLatin1("while (1) { }"));
+ QScriptValue ret = eng.evaluate(script);
switch (receiver.resultType) {
case EventReceiver3::None:
QVERIFY(!eng.hasUncaughtException());
@@ -5643,6 +5689,16 @@ void tst_QScriptEngine::collectGarbageAfterConnect()
QVERIFY(widget == 0);
}
+void tst_QScriptEngine::collectGarbageAfterNativeArguments()
+{
+ // QTBUG-17788
+ QScriptEngine eng;
+ QScriptContext *ctx = eng.pushContext();
+ QScriptValue arguments = ctx->argumentsObject();
+ // Shouldn't crash when marking the arguments object.
+ collectGarbage_helper(eng);
+}
+
static QScriptValue constructQObjectFromThisObject(QScriptContext *ctx, QScriptEngine *eng)
{
Q_ASSERT(ctx->isCalledAsConstructor());
diff --git a/tests/auto/qscriptjstestsuite/expect_fail.txt b/tests/auto/qscriptjstestsuite/expect_fail.txt
new file mode 100644
index 0000000..7f93378
--- /dev/null
+++ b/tests/auto/qscriptjstestsuite/expect_fail.txt
@@ -0,0 +1,198 @@
+ecma/Array/15.4.3.1-2.js | var props = ''; for ( p in Array ) { props += p } props
+
+ecma/Boolean/15.6.3.1-1.js | var str='';for ( p in Boolean ) { str += p } str;
+
+ecma/Expressions/11.4.1.js | var abc; delete(abc)
+
+ecma/FunctionObjects/15.3.3.1-2.js | var str='';for (prop in Function ) str += prop; str;
+
+ecma/ObjectObjects/15.2.3.1-1.js | var str = '';for ( p in Object ) { str += p; }; str
+
+ecma/Statements/12.6.3-11.js | result = ""; for ( p in Number ) { result += String(p) };
+ecma/Statements/12.6.3-2.js | Boolean.prototype.foo = 34; for ( j in Boolean ) Boolean[j]
+
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4256) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4257) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4258) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4259) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4260) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4261) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4262) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4263) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4264) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4265) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4266) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4267) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4268) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4269) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4270) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4271) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4272) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4273) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4274) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4275) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4276) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4277) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4278) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4279) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4280) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4281) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4282) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4283) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4284) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4285) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4286) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4287) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4288) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4289) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4290) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4291) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4292) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4293) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-5.js | var s = new String( String.fromCharCode(1024) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.11-5.js | var s = new String( String.fromCharCode(1037) ); s.toLowerCase().charCodeAt(0)
+ecma/String/15.5.4.12-1.js | var s = new String( String.fromCharCode(181) ); s.toUpperCase().charCodeAt(0)
+ecma/String/15.5.4.12-1.js | var s = new String( String.fromCharCode(329) ); s.toUpperCase().charCodeAt(0)
+ecma/String/15.5.4.12-4.js | var s = new String( String.fromCharCode(1104) ); s.toUpperCase().charCodeAt(0)
+ecma/String/15.5.4.12-4.js | var s = new String( String.fromCharCode(1117) ); s.toUpperCase().charCodeAt(0)
+ecma/String/15.5.4.12-5.js | var s = new String( String.fromCharCode(1415) ); s.toUpperCase().charCodeAt(0)
+
+ecma/TypeConversion/9.3.1-3.js | -"\u20001234\u2001"
+ecma/TypeConversion/9.3.1-3.js | - "-0x123456789abcde8"
+
+ecma/extensions/15.1.2.1-1.js | var PROPS = ''; for ( p in eval ) { PROPS += p }; PROPS
+
+ecma/GlobalObject/15.1.2.2-1.js | var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS
+ecma/GlobalObject/15.1.2.3-1.js | var MYPROPS=''; for ( var p in parseFloat ) { MYPROPS += p }; MYPROPS
+ecma/GlobalObject/15.1.2.4.js | var MYPROPS=''; for ( var p in escape ) { MYPROPS+= p}; MYPROPS
+ecma/GlobalObject/15.1.2.5-1.js | var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS
+ecma/GlobalObject/15.1.2.6.js | var MYPROPS=''; for ( var p in isNaN ) { MYPROPS+= p }; MYPROPS
+ecma/GlobalObject/15.1.2.7.js | var MYPROPS=''; for ( p in isFinite ) { MYPROPS+= p }; MYPROPS
+
+ecma_3/Array/15.4.5.1-01.js | 15.4.5.1 - array.length coverage
+
+ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 0
+ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 1
+ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 2
+ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 3
+ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 4
+ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 5
+ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 6
+ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 7
+ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 8
+ecma_3/extensions/regress-368516.js | Treat unicode BOM characters as whitespace: 0
+ecma_3/extensions/regress-368516.js | Treat unicode BOM characters as whitespace: 1
+
+ecma_3/Date/15.9.4.3.js | 15.9.4.3 - Date.UTC edge-case arguments.: date Infinity
+ecma_3/Date/15.9.4.3.js | 15.9.4.3 - Date.UTC edge-case arguments.: hours Infinity
+ecma_3/Date/15.9.4.3.js | 15.9.4.3 - Date.UTC edge-case arguments.: minutes Infinity
+ecma_3/Date/15.9.4.3.js | 15.9.4.3 - Date.UTC edge-case arguments.: seconds Infinity
+ecma_3/Function/regress-131964.js | Section 1 of test -
+ecma_3/Function/regress-313570.js | length of objects whose prototype chain includes a function: immutable
+ecma_3/FunExpr/fe-001.js | Both functions were defined.
+
+ecma_3/LexicalConventions/7.9.1.js | Automatic Semicolon insertion in postfix expressions: expr\n++
+ecma_3/LexicalConventions/7.9.1.js | Automatic Semicolon insertion in postfix expressions: expr\n--
+ecma_3/LexicalConventions/7.9.1.js | Automatic Semicolon insertion in postfix expressions: (x\n)-- y
+ecma_3/LexicalConventions/7.9.1.js | Automatic Semicolon insertion in postfix expressions: (x)-- y
+
+ecma_3/Object/8.6.1-01.js | In strict mode, setting a read-only property should generate a warning: Throw if STRICT and WERROR is enabled
+
+ecma_3/Operators/order-01.js | operator evaluation order: 11.8.2 >
+ecma_3/Operators/order-01.js | operator evaluation order: 11.8.4 >=
+
+ecma_3/RegExp/15.10.2-1.js | Section 7 of test - \nregexp = /(z)((a+)?(b+)?(c))*/\nstring = 'zaacbbbcac'\nERROR !!! regexp failed to give expected match array:\nExpect: ["zaacbbbcac", "z", "ac", "a", , "c"]\nActual: ["zaacbbbcac", "z", "ac", "a", "bbb", "c"]\n
+ecma_3/RegExp/15.10.2-1.js | Section 8 of test - \nregexp = /(a*)*/\nstring = 'b'\nERROR !!! regexp failed to give expected match array:\nExpect: ["", , ]\nActual: ["", ""]\n
+ecma_3/RegExp/15.10.2-1.js | Section 12 of test - \nregexp = /(.*?)a(?!(a+)b\2c)\2(.*)/\nstring = 'baaabaac'\nERROR !!! regexp failed to give expected match array:\nExpect: ["baaabaac", "ba", , "abaac"]\nActual: ["baaabaac", "ba", "aa", "abaac"]\n
+ecma_3/RegExp/perlstress-001.js | Section 218 of test - \nregexp = /((foo)|(bar))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: ["foobar", "bar", , "bar"]\nActual: ["foobar", "bar", "foo", "bar"]\n
+ecma_3/RegExp/perlstress-001.js | Section 234 of test - \nregexp = /(?:(f)(o)(o)|(b)(a)(r))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: ["foobar", , , , "b", "a", "r"]\nActual: ["foobar", "f", "o", "o", "b", "a", "r"]\n
+ecma_3/RegExp/perlstress-001.js | Section 241 of test - \nregexp = /^(?:b|a(?=(.)))*\1/\nstring = 'abc'\nERROR !!! regexp failed to give expected match array:\nExpect: ["ab", , ]\nActual: ["ab", "b"]\n
+ecma_3/RegExp/perlstress-001.js | Section 412 of test - \nregexp = /^(a(b)?)+$/\nstring = 'aba'\nERROR !!! regexp failed to give expected match array:\nExpect: ["aba", "a", , ]\nActual: ["aba", "a", "b"]\n
+ecma_3/RegExp/perlstress-001.js | Section 413 of test - \nregexp = /^(aa(bb)?)+$/\nstring = 'aabbaa'\nERROR !!! regexp failed to give expected match array:\nExpect: ["aabbaa", "aa", , ]\nActual: ["aabbaa", "aa", "bb"]\n
+
+ecma_3/RegExp/regress-209919.js | Section 1 of test - \nregexp = /(a|b*)*/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: ["a", "a"]\nActual: ["a", ""]\n
+ecma_3/RegExp/regress-209919.js | Section 3 of test - \nregexp = /(b*)*/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: ["", , ]\nActual: ["", ""]\n
+ecma_3/RegExp/regress-209919.js | Section 5 of test - \nregexp = /^\-?(\d{1,}|\.{0,})*(\,\d{1,})?$/\nstring = '100.00'\nERROR !!! regexp failed to give expected match array:\nExpect: ["100.00", "00", , ]\nActual: ["100.00", "", , ]\n
+ecma_3/RegExp/regress-209919.js | Section 6 of test - \nregexp = /^\-?(\d{1,}|\.{0,})*(\,\d{1,})?$/\nstring = '100,00'\nERROR !!! regexp failed to give expected match array:\nExpect: ["100,00", "100", ",00"]\nActual: ["100,00", "", ",00"]\n
+ecma_3/RegExp/regress-209919.js | Section 7 of test - \nregexp = /^\-?(\d{1,}|\.{0,})*(\,\d{1,})?$/\nstring = '1.000,00'\nERROR !!! regexp failed to give expected match array:\nExpect: ["1.000,00", "000", ",00"]\nActual: ["1.000,00", "", ",00"]\n
+
+ecma_3/String/15.5.4.11.js | Section 7
+ecma_3/String/15.5.4.11.js | Section 24
+ecma_3/String/15.5.4.11.js | Section 26
+ecma_3/String/15.5.4.11.js | Section 28
+ecma_3/String/15.5.4.11.js | Section 30
+ecma_3/String/15.5.4.14.js | 15.5.4.14 - String.prototype.split(/()/)
+
+ecma_3/Unicode/regress-352044-01.js | issues with Unicode escape sequences in JavaScript source code
+ecma_3/Unicode/uc-001.js | Unicode format-control character test (Category Cf.)
+
+ecma_2/RegExp/exec-001.js | NO TESTS EXIST
+ecma_2/String/replace-001.js | NO TESTS EXIST
+
+[Q_CC_MSVC]
+ecma_3/Expressions/11.7.3-01.js | 11.7.3 - >>> should evaluate operands in order: order | QTBUG-8056
+ecma_3/Operators/order-01.js | operator evaluation order: 11.7.3 >>> | QTBUG-8056
+ecma_3/Operators/order-01.js | operator evaluation order: 11.13.2 >>>= | QTBUG-8056
+
+[Q_CC_MINGW]
+ecma/Math/15.8.2.13.js | Math.pow(NaN,0)
+ecma/Math/15.8.2.13.js | Math.pow(NaN,-0)
+ecma/Math/15.8.2.5.js | Math.atan2(Infinity, Infinity)
+ecma/Math/15.8.2.5.js | Math.atan2(Infinity, -Infinity)
+ecma/Math/15.8.2.5.js | Math.atan2(-Infinity, Infinity)
+ecma/Math/15.8.2.5.js | Math.atan2(-Infinity, -Infinity)
+
+[Q_OS_SOLARIS]
+ecma/Expressions/11.13.2-2.js | VAR1 = -0; VAR2= Infinity; VAR2 /= VAR1
+ecma/Expressions/11.13.2-2.js | VAR1 = -0; VAR2= -Infinity; VAR2 /= VAR1
+ecma/Expressions/11.13.2-2.js | VAR1 = 1; VAR2= -0; VAR1 /= VAR2
+ecma/Expressions/11.13.2-2.js | VAR1 = -1; VAR2= -0; VAR1 /= VAR2
+ecma/Expressions/11.5.2.js | Number.POSITIVE_INFINITY / -0
+ecma/Expressions/11.5.2.js | Number.NEGATIVE_INFINITY / -0
+ecma/Expressions/11.5.2.js | 1 / -0
+ecma/Expressions/11.5.2.js | -1 / -0
+ecma/Math/15.8.2.10.js | Math.log(-0.0000001)
+ecma/Math/15.8.2.10.js | Math.log(-1)
+ecma/Math/15.8.2.11.js | Infinity/Math.max(-0,-0)
+ecma/Math/15.8.2.12.js | Infinity/Math.min(0,-0)
+ecma/Math/15.8.2.12.js | Infinity/Math.min(-0,-0)
+ecma/Math/15.8.2.13.js | Math.pow(NaN,0)
+ecma/Math/15.8.2.13.js | Math.pow(NaN,-0)
+ecma/Math/15.8.2.13.js | Infinity/Math.pow(-Infinity, -1)
+ecma/Math/15.8.2.13.js | Math.pow(0, -1)
+ecma/Math/15.8.2.13.js | Math.pow(0, -0.5)
+ecma/Math/15.8.2.13.js | Math.pow(0, -1000)
+ecma/Math/15.8.2.13.js | Infinity/Math.pow(-0, 1)
+ecma/Math/15.8.2.13.js | Infinity/Math.pow(-0, 3)
+ecma/Math/15.8.2.13.js | Math.pow(-0, -2)
+ecma/Math/15.8.2.15.js | Infinity/Math.round(-0)
+ecma/Math/15.8.2.15.js | Infinity/Math.round(-0.49)
+ecma/Math/15.8.2.15.js | Infinity/Math.round(-0.5)
+ecma/Math/15.8.2.17.js | Infinity/Math.sqrt(-0)
+ecma/Math/15.8.2.18.js | Infinity/Math.tan(-0)
+ecma/Math/15.8.2.2.js | Math.acos(1.00000001)
+ecma/Math/15.8.2.2.js | Math.acos(11.00000001)
+ecma/Math/15.8.2.3.js | Math.asin(1.000001)
+ecma/Math/15.8.2.3.js | Math.asin(-1.000001)
+ecma/Math/15.8.2.3.js | Infinity/Math.asin(-0)
+ecma/Math/15.8.2.4.js | Infinity/Math.atan(-0)
+ecma/Math/15.8.2.5.js | Math.atan2(0, -0)
+ecma/Math/15.8.2.5.js | Infinity/Math.atan2(-0, 1)
+ecma/Math/15.8.2.5.js | Math.atan2(-0,\t-0)
+ecma/Math/15.8.2.5.js | Math.atan2(-0,\t-1)
+ecma/Math/15.8.2.6.js | Infinity/Math.ceil('-0')
+ecma/Math/15.8.2.6.js | Infinity/Math.ceil(-0)
+ecma/Math/15.8.2.6.js | Infinity/Math.ceil(-Number.MIN_VALUE)
+ecma/Math/15.8.2.6.js | Infinity/Math.ceil(-0.9)
+ecma/Math/15.8.2.9.js | Infinity/Math.floor(-0)
+ecma/TypeConversion/9.3.1-3.js | var z = 0; print(1/-z)
+ecma/TypeConversion/9.3.1-3.js | 1/-1e-2000
+
+[Q_OS_SYMBIAN]
+ecma/Math/15.8.2.13.js | Math.pow(-1, 0.5)
+ecma/Math/15.8.2.13.js | Math.pow(-1, -0.5)
+ecma_3/Operators/order-01.js | operator evaluation order: 11.5.1 *
+ecma_3/Operators/order-01.js | operator evaluation order: 11.5.2 /
+ecma_3/Operators/order-01.js | operator evaluation order: 11.6.2 -
+ecma_3/Operators/order-01.js | operator evaluation order: 11.13.2 *=
+ecma_3/Operators/order-01.js | operator evaluation order: 11.13.2 /=
diff --git a/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro
index b1ddd64..471aa02 100644
--- a/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro
+++ b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro
@@ -1,6 +1,8 @@
load(qttest_p4)
QT = core script
SOURCES += tst_qscriptjstestsuite.cpp
+RESOURCES += qscriptjstestsuite.qrc
+include(../qscriptv8testsuite/abstracttestsuite.pri)
!symbian: DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/auto/qscriptjstestsuite/qscriptjstestsuite.qrc b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.qrc
new file mode 100644
index 0000000..4a4eb60
--- /dev/null
+++ b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>expect_fail.txt</file>
+ <file>skip.txt</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/qscriptjstestsuite/skip.txt b/tests/auto/qscriptjstestsuite/skip.txt
new file mode 100644
index 0000000..2dc0ccb
--- /dev/null
+++ b/tests/auto/qscriptjstestsuite/skip.txt
@@ -0,0 +1,9 @@
+.+/15\.9\.2\..+ | unstable on slow machines
+.+/15\.9\.5\..+ | too slooow
+regress-130451.js | asserts
+regress-322135-01.js | asserts
+regress-322135-02.js | asserts
+regress-322135-03.js | takes forever
+regress-322135-04.js | takes forever
+ecma_3/RegExp/regress-375715-04.js | bug
+ecma_3/RegExp/regress-289669.js | Can fail due to relying on wall-clock time
diff --git a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp
index 43a6dba..e042dfe 100644
--- a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp
+++ b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp
@@ -40,44 +40,18 @@
****************************************************************************/
+#include "abstracttestsuite.h"
#include <QtTest/QtTest>
#include <QtScript>
#if defined(Q_OS_SYMBIAN)
-# define SRCDIR ""
+# define SRCDIR "."
#endif
//TESTED_CLASS=
//TESTED_FILES=
-// Uncomment the following define to have the autotest generate
-// addExpectedFailure() code for all the tests that fail.
-// This is useful when a whole new test (sub)suite is added.
-// The code is stored in addexpectedfailures.cpp.
-// Paste the contents into this file after the existing
-// addExpectedFailure() calls.
-
-//#define GENERATE_ADDEXPECTEDFAILURE_CODE
-
-static QString readFile(const QString &filename)
-{
- QFile file(filename);
- if (!file.open(QFile::ReadOnly))
- return QString();
- QTextStream stream(&file);
- return stream.readAll();
-}
-
-static void appendCString(QVector<char> *v, const char *s)
-{
- char c;
- do {
- c = *(s++);
- *v << c;
- } while (c != '\0');
-}
-
struct TestRecord
{
TestRecord() : lineNumber(-1) { }
@@ -120,17 +94,18 @@ struct FailureItem
QString message;
};
-class tst_Suite : public QObject
+class tst_QScriptJSTestSuite : public AbstractTestSuite
{
public:
- tst_Suite();
- virtual ~tst_Suite();
+ tst_QScriptJSTestSuite();
+ virtual ~tst_QScriptJSTestSuite();
- static QMetaObject staticMetaObject;
- virtual const QMetaObject *metaObject() const;
- virtual void *qt_metacast(const char *);
- virtual int qt_metacall(QMetaObject::Call, int, void **argv);
+protected:
+ virtual void configData(TestConfig::Mode mode, const QStringList &parts);
+ virtual void writeSkipConfigFile(QTextStream &);
+ virtual void writeExpectFailConfigFile(QTextStream &);
+ virtual void runTestFunction(int testIndex);
private:
void addExpectedFailure(const QString &fileName, const QString &description, const QString &message);
@@ -143,33 +118,11 @@ private:
void addFileExclusion(const QRegExp &rx, const QString &message);
bool isExcludedFile(const QString &fileName, QString *message) const;
- QDir testsDir;
QList<QString> subSuitePaths;
QList<FailureItem> expectedFailures;
QList<QPair<QRegExp, QString> > fileExclusions;
-#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE
- QString generatedAddExpectedFailureCode;
-#endif
};
-QMetaObject tst_Suite::staticMetaObject;
-
-Q_GLOBAL_STATIC(QVector<uint>, qt_meta_data_tst_Suite)
-Q_GLOBAL_STATIC(QVector<char>, qt_meta_stringdata_tst_Suite)
-
-const QMetaObject *tst_Suite::metaObject() const
-{
- return &staticMetaObject;
-}
-
-void *tst_Suite::qt_metacast(const char *_clname)
-{
- if (!_clname) return 0;
- if (!strcmp(_clname, qt_meta_stringdata_tst_Suite()->constData()))
- return static_cast<void*>(const_cast<tst_Suite*>(this));
- return QObject::qt_metacast(_clname);
-}
-
static QScriptValue qscript_void(QScriptContext *, QScriptEngine *eng)
{
return eng->undefinedValue();
@@ -222,625 +175,245 @@ static QScriptValue qscript_TestCase(QScriptContext *ctx, QScriptEngine *eng)
return ret;
}
-int tst_Suite::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+void tst_QScriptJSTestSuite::runTestFunction(int testIndex)
{
- _id = QObject::qt_metacall(_c, _id, _a);
- if (_id < 0)
- return _id;
- if (_c == QMetaObject::InvokeMetaMethod) {
- if (!(_id & 1)) {
- // data
- QTest::addColumn<TestRecord>("record");
- bool hasData = false;
-
- QString testsShellPath = testsDir.absoluteFilePath("shell.js");
- QString testsShellContents = readFile(testsShellPath);
-
- QDir subSuiteDir(subSuitePaths.at(_id / 2));
- QString subSuiteShellPath = subSuiteDir.absoluteFilePath("shell.js");
- QString subSuiteShellContents = readFile(subSuiteShellPath);
-
- QDir testSuiteDir(subSuiteDir);
- testSuiteDir.cdUp();
- QString suiteJsrefPath = testSuiteDir.absoluteFilePath("jsref.js");
- QString suiteJsrefContents = readFile(suiteJsrefPath);
- QString suiteShellPath = testSuiteDir.absoluteFilePath("shell.js");
- QString suiteShellContents = readFile(suiteShellPath);
-
- QFileInfoList testFileInfos = subSuiteDir.entryInfoList(QStringList() << "*.js", QDir::Files);
- foreach (QFileInfo tfi, testFileInfos) {
- if ((tfi.fileName() == "shell.js") || (tfi.fileName() == "browser.js"))
- continue;
-
- QString abspath = tfi.absoluteFilePath();
- QString relpath = testsDir.relativeFilePath(abspath);
- QString excludeMessage;
- if (isExcludedFile(relpath, &excludeMessage)) {
- QTest::newRow(relpath.toLatin1()) << TestRecord(excludeMessage, relpath);
- continue;
- }
+ if (!(testIndex & 1)) {
+ // data
+ QTest::addColumn<TestRecord>("record");
+ bool hasData = false;
+
+ QString testsShellPath = testsDir.absoluteFilePath("shell.js");
+ QString testsShellContents = readFile(testsShellPath);
+
+ QDir subSuiteDir(subSuitePaths.at(testIndex / 2));
+ QString subSuiteShellPath = subSuiteDir.absoluteFilePath("shell.js");
+ QString subSuiteShellContents = readFile(subSuiteShellPath);
+
+ QDir testSuiteDir(subSuiteDir);
+ testSuiteDir.cdUp();
+ QString suiteJsrefPath = testSuiteDir.absoluteFilePath("jsref.js");
+ QString suiteJsrefContents = readFile(suiteJsrefPath);
+ QString suiteShellPath = testSuiteDir.absoluteFilePath("shell.js");
+ QString suiteShellContents = readFile(suiteShellPath);
+
+ QFileInfoList testFileInfos = subSuiteDir.entryInfoList(QStringList() << "*.js", QDir::Files);
+ foreach (QFileInfo tfi, testFileInfos) {
+ if ((tfi.fileName() == "shell.js") || (tfi.fileName() == "browser.js"))
+ continue;
+
+ QString abspath = tfi.absoluteFilePath();
+ QString relpath = testsDir.relativeFilePath(abspath);
+ QString excludeMessage;
+ if (isExcludedFile(relpath, &excludeMessage)) {
+ QTest::newRow(relpath.toLatin1()) << TestRecord(excludeMessage, relpath);
+ continue;
+ }
- QScriptEngine eng;
- QScriptValue global = eng.globalObject();
- global.setProperty("print", eng.newFunction(qscript_void));
- global.setProperty("quit", eng.newFunction(qscript_quit));
- global.setProperty("options", eng.newFunction(qscript_options));
-
- eng.evaluate(testsShellContents, testsShellPath);
- if (eng.hasUncaughtException()) {
- QStringList bt = eng.uncaughtExceptionBacktrace();
- QString err = eng.uncaughtException().toString();
- qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
- break;
- }
+ QScriptEngine eng;
+ QScriptValue global = eng.globalObject();
+ global.setProperty("print", eng.newFunction(qscript_void));
+ global.setProperty("quit", eng.newFunction(qscript_quit));
+ global.setProperty("options", eng.newFunction(qscript_options));
+
+ eng.evaluate(testsShellContents, testsShellPath);
+ if (eng.hasUncaughtException()) {
+ QStringList bt = eng.uncaughtExceptionBacktrace();
+ QString err = eng.uncaughtException().toString();
+ qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
+ break;
+ }
- eng.evaluate(suiteJsrefContents, suiteJsrefPath);
- if (eng.hasUncaughtException()) {
- QStringList bt = eng.uncaughtExceptionBacktrace();
- QString err = eng.uncaughtException().toString();
- qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
- break;
- }
+ eng.evaluate(suiteJsrefContents, suiteJsrefPath);
+ if (eng.hasUncaughtException()) {
+ QStringList bt = eng.uncaughtExceptionBacktrace();
+ QString err = eng.uncaughtException().toString();
+ qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
+ break;
+ }
- eng.evaluate(suiteShellContents, suiteShellPath);
- if (eng.hasUncaughtException()) {
- QStringList bt = eng.uncaughtExceptionBacktrace();
- QString err = eng.uncaughtException().toString();
- qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
- break;
- }
+ eng.evaluate(suiteShellContents, suiteShellPath);
+ if (eng.hasUncaughtException()) {
+ QStringList bt = eng.uncaughtExceptionBacktrace();
+ QString err = eng.uncaughtException().toString();
+ qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
+ break;
+ }
- eng.evaluate(subSuiteShellContents, subSuiteShellPath);
- if (eng.hasUncaughtException()) {
- QStringList bt = eng.uncaughtExceptionBacktrace();
- QString err = eng.uncaughtException().toString();
- qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
- break;
- }
+ eng.evaluate(subSuiteShellContents, subSuiteShellPath);
+ if (eng.hasUncaughtException()) {
+ QStringList bt = eng.uncaughtExceptionBacktrace();
+ QString err = eng.uncaughtException().toString();
+ qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
+ break;
+ }
- QScriptValue origTestCaseCtor = global.property("TestCase");
- QScriptValue myTestCaseCtor = eng.newFunction(qscript_TestCase);
- myTestCaseCtor.setData(origTestCaseCtor);
- global.setProperty("TestCase", myTestCaseCtor);
+ QScriptValue origTestCaseCtor = global.property("TestCase");
+ QScriptValue myTestCaseCtor = eng.newFunction(qscript_TestCase);
+ myTestCaseCtor.setData(origTestCaseCtor);
+ global.setProperty("TestCase", myTestCaseCtor);
- global.setProperty("gTestfile", tfi.fileName());
- global.setProperty("gTestsuite", testSuiteDir.dirName());
- global.setProperty("gTestsubsuite", subSuiteDir.dirName());
- QString testFileContents = readFile(abspath);
+ global.setProperty("gTestfile", tfi.fileName());
+ global.setProperty("gTestsuite", testSuiteDir.dirName());
+ global.setProperty("gTestsubsuite", subSuiteDir.dirName());
+ QString testFileContents = readFile(abspath);
// qDebug() << relpath;
- eng.evaluate(testFileContents, abspath);
- if (eng.hasUncaughtException() && !relpath.endsWith("-n.js")) {
- QStringList bt = eng.uncaughtExceptionBacktrace();
- QString err = eng.uncaughtException().toString();
- qWarning("%s\n%s\n", qPrintable(err), qPrintable(bt.join("\n")));
- continue;
- }
+ eng.evaluate(testFileContents, abspath);
+ if (eng.hasUncaughtException() && !relpath.endsWith("-n.js")) {
+ QStringList bt = eng.uncaughtExceptionBacktrace();
+ QString err = eng.uncaughtException().toString();
+ qWarning("%s\n%s\n", qPrintable(err), qPrintable(bt.join("\n")));
+ continue;
+ }
- QScriptValue testcases = global.property("testcases");
- if (!testcases.isArray())
- testcases = global.property("gTestcases");
- int count = testcases.property("length").toInt32();
- if (count == 0)
- continue;
-
- hasData = true;
- QString title = global.property("TITLE").toString();
- for (int i = 0; i < count; ++i) {
- QScriptValue kase = testcases.property(i);
- QString description = kase.property("description").toString();
- QScriptValue expect = kase.property("expect");
- QScriptValue actual = kase.property("actual");
- bool passed = kase.property("passed").toBoolean();
- int lineNumber = kase.property("__lineNumber__").toInt32();
-
- TestRecord rec(description, passed,
- actual.toString(), expect.toString(),
- relpath, lineNumber);
-
- QTest::newRow(description.toLatin1()) << rec;
- }
+ QScriptValue testcases = global.property("testcases");
+ if (!testcases.isArray())
+ testcases = global.property("gTestcases");
+ int count = testcases.property("length").toInt32();
+ if (count == 0)
+ continue;
+
+ hasData = true;
+ QString title = global.property("TITLE").toString();
+ for (int i = 0; i < count; ++i) {
+ QScriptValue kase = testcases.property(i);
+ QString description = kase.property("description").toString();
+ QScriptValue expect = kase.property("expect");
+ QScriptValue actual = kase.property("actual");
+ bool passed = kase.property("passed").toBoolean();
+ int lineNumber = kase.property("__lineNumber__").toInt32();
+
+ TestRecord rec(description, passed,
+ actual.toString(), expect.toString(),
+ relpath, lineNumber);
+
+ QTest::newRow(description.toLatin1()) << rec;
}
- if (!hasData)
- QTest::newRow("") << TestRecord(); // dummy
+ }
+ if (!hasData)
+ QTest::newRow("") << TestRecord(); // dummy
+ } else {
+ QFETCH(TestRecord, record);
+ if ((record.lineNumber == -1) && (record.actual == "QSKIP")) {
+ QTest::qSkip(record.description.toLatin1(), QTest::SkipAll, record.fileName.toLatin1(), -1);
} else {
- QFETCH(TestRecord, record);
- if ((record.lineNumber == -1) && (record.actual == "QSKIP")) {
- QTest::qSkip(record.description.toLatin1(), QTest::SkipAll, record.fileName.toLatin1(), -1);
- } else {
- QString msg;
- FailureItem::Action failAct;
- bool expectFail = isExpectedFailure(record.fileName, record.description, &msg, &failAct);
- if (expectFail) {
- switch (failAct) {
- case FailureItem::ExpectFail:
- QTest::qExpectFail("", msg.toLatin1(),
- QTest::Continue, record.fileName.toLatin1(),
- record.lineNumber);
- break;
- case FailureItem::Skip:
- QTest::qSkip(msg.toLatin1(), QTest::SkipSingle,
- record.fileName.toLatin1(), record.lineNumber);
- break;
- }
+ QString msg;
+ FailureItem::Action failAct;
+ bool expectFail = isExpectedFailure(record.fileName, record.description, &msg, &failAct);
+ if (expectFail) {
+ switch (failAct) {
+ case FailureItem::ExpectFail:
+ QTest::qExpectFail("", msg.toLatin1(),
+ QTest::Continue, record.fileName.toLatin1(),
+ record.lineNumber);
+ break;
+ case FailureItem::Skip:
+ QTest::qSkip(msg.toLatin1(), QTest::SkipSingle,
+ record.fileName.toLatin1(), record.lineNumber);
+ break;
}
- if (!expectFail || (failAct == FailureItem::ExpectFail)) {
- if (!record.passed) {
-#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE
- if (!expectFail) {
- QString escapedDescription = record.description;
- escapedDescription.replace("\\", "\\\\");
- escapedDescription.replace("\n", "\\n");
- escapedDescription.replace("\"", "\\\"");
- generatedAddExpectedFailureCode.append(
- " addExpectedFailure(\"" + record.fileName
- + "\", \"" + escapedDescription +
- "\", willFixInNextReleaseMessage);\n");
- }
-#endif
- QTest::qCompare(record.actual, record.expected, "actual", "expect",
- record.fileName.toLatin1(), record.lineNumber);
- } else {
- QTest::qCompare(record.actual, record.actual, "actual", "expect",
- record.fileName.toLatin1(), record.lineNumber);
+ }
+ if (!expectFail || (failAct == FailureItem::ExpectFail)) {
+ if (!record.passed) {
+ if (!expectFail && shouldGenerateExpectedFailures) {
+ addExpectedFailure(record.fileName,
+ record.description,
+ QString());
}
+ QTest::qCompare(record.actual, record.expected, "actual", "expect",
+ record.fileName.toLatin1(), record.lineNumber);
+ } else {
+ QTest::qCompare(record.actual, record.actual, "actual", "expect",
+ record.fileName.toLatin1(), record.lineNumber);
}
}
}
- _id -= subSuitePaths.size()*2;
}
- return _id;
}
-tst_Suite::tst_Suite()
+tst_QScriptJSTestSuite::tst_QScriptJSTestSuite()
+ : AbstractTestSuite("tst_QScriptJsTestSuite",
+ QString::fromLatin1("%0/tests").arg(SRCDIR),
+ ":/")
{
- testsDir = QDir(SRCDIR);
- bool testsFound = testsDir.cd("tests");
- if (!testsFound) {
- qWarning("*** no tests/ dir!");
- }
-
- QString willFixInNextReleaseMessage = QString::fromLatin1("Will fix in next release");
- QString fromCharCodeMessage = QString::fromLatin1("Test is wrong?");
- for (int i = 4256; i < 4294; ++i) {
- addExpectedFailure("ecma/String/15.5.4.11-2.js", QString::fromLatin1("var s = new String( String.fromCharCode(%0) ); s.toLowerCase().charCodeAt(0)").arg(i), fromCharCodeMessage);
- }
- addExpectedFailure("ecma/String/15.5.4.11-5.js", "var s = new String( String.fromCharCode(1024) ); s.toLowerCase().charCodeAt(0)", fromCharCodeMessage);
- addExpectedFailure("ecma/String/15.5.4.11-5.js", "var s = new String( String.fromCharCode(1037) ); s.toLowerCase().charCodeAt(0)", fromCharCodeMessage);
- addExpectedFailure("ecma/String/15.5.4.12-1.js", "var s = new String( String.fromCharCode(181) ); s.toUpperCase().charCodeAt(0)", fromCharCodeMessage);
- addExpectedFailure("ecma/String/15.5.4.12-1.js", "var s = new String( String.fromCharCode(329) ); s.toUpperCase().charCodeAt(0)", fromCharCodeMessage);
- addExpectedFailure("ecma/String/15.5.4.12-4.js", "var s = new String( String.fromCharCode(1104) ); s.toUpperCase().charCodeAt(0)", fromCharCodeMessage);
- addExpectedFailure("ecma/String/15.5.4.12-4.js", "var s = new String( String.fromCharCode(1117) ); s.toUpperCase().charCodeAt(0)", fromCharCodeMessage);
- addExpectedFailure("ecma/String/15.5.4.12-5.js", "var s = new String( String.fromCharCode(1415) ); s.toUpperCase().charCodeAt(0)", fromCharCodeMessage);
-
- addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "- \"-0x123456789abcde8\"", willFixInNextReleaseMessage);
-
- addExpectedFailure("ecma/extensions/15.1.2.1-1.js", "var PROPS = ''; for ( p in eval ) { PROPS += p }; PROPS", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/GlobalObject/15.1.2.2-1.js", "var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS", willFixInNextReleaseMessage);
-
- addExpectedFailure("ecma/GlobalObject/15.1.2.3-1.js", "var MYPROPS=''; for ( var p in parseFloat ) { MYPROPS += p }; MYPROPS", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/GlobalObject/15.1.2.4.js", "var MYPROPS=''; for ( var p in escape ) { MYPROPS+= p}; MYPROPS", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/GlobalObject/15.1.2.5-1.js", "var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/GlobalObject/15.1.2.6.js", "var MYPROPS=''; for ( var p in isNaN ) { MYPROPS+= p }; MYPROPS", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/GlobalObject/15.1.2.7.js", "var MYPROPS=''; for ( p in isFinite ) { MYPROPS+= p }; MYPROPS", willFixInNextReleaseMessage);
-
- addExpectedFailure(QRegExp(), "NO TESTS EXIST", willFixInNextReleaseMessage);
-
- addExpectedFailure("ecma_3/Array/15.4.5.1-01.js", "15.4.5.1 - array.length coverage", willFixInNextReleaseMessage);
-
- addExpectedFailure("ecma_3/extensions/regress-228087-002.js",
- "Section 1 of test - \nregexp = /{1.*}/g\n"
- "string = 'foo {1} foo {2} foo'\n"
- "ERROR !!! match arrays have different lengths:\n"
- "Expect: [\"{1} foo {2}\"]\n"
- "Actual: []", willFixInNextReleaseMessage);
-
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js",
- "Section 1 of test - \n"
- "regexp = /a|ab/\n"
- "string = 'abc'\n"
- "ERROR !!! regexp failed to give expected match array:\n"
- "Expect: [\"a\"]\n"
- "Actual: [\"ab\"]\n", willFixInNextReleaseMessage);
-
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js",
- "Section 2 of test - \n"
- "regexp = /((a)|(ab))((c)|(bc))/\n"
- "string = 'abc'\n"
- "ERROR !!! regexp failed to give expected match array:\n"
- "Expect: [\"abc\", \"a\", \"a\", , \"bc\", , \"bc\"]\n"
- "Actual: [\"abc\", \"ab\", \"\", \"ab\", \"c\", \"c\", \"\"]\n", willFixInNextReleaseMessage);
-
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js",
- "Section 4 of test - \n"
- "regexp = /a[a-z]{2,4}?/\n"
- "string = 'abcdefghi'\n"
- "ERROR !!! regexp FAILED to match anything !!!\n"
- "Expect: abc\n"
- "Actual: null\n", willFixInNextReleaseMessage);
-
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js(317)",
- "Section 5 of test - \n"
- "regexp = /(aa|aabaac|ba|b|c)*/\n"
- "string = 'aabaac'\n"
- "ERROR !!! regexp failed to give expected match array:\n"
- "Expect: [\"aaba\", \"ba\"]\n"
- "Actual: [\"aabaac\", \"aabaac\"]\n", willFixInNextReleaseMessage);
-
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 1 of test - \nregexp = /{1.*}/g\nstring = 'foo {1} foo {2} foo'\nERROR !!! match arrays have different lengths:\nExpect: [\"{1} foo {2}\"]\nActual: []\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 2 of test - \nregexp = /{1.*}/g\nstring = 'foo {1} foo {2} foo'\nERROR !!! match arrays have different lengths:\nExpect: [\"{1} foo {2}\"]\nActual: []\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 3 of test - \nregexp = /{1[.!}]*}/g\nstring = 'foo {1} foo {2} foo'\nERROR !!! match arrays have different lengths:\nExpect: [\"{1}\"]\nActual: []\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 4 of test - \nregexp = /{1[.!}]*}/g\nstring = 'foo {1} foo {2} foo'\nERROR !!! match arrays have different lengths:\nExpect: [\"{1}\"]\nActual: []\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 6 of test - \nregexp = /c{3 }/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 }\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 7 of test - \nregexp = /c{3.}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 }\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 8 of test - \nregexp = /c{3\\s}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 }\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 9 of test - \nregexp = /c{3[ ]}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 }\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 10 of test - \nregexp = /c{ 3}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{ 3}\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 12 of test - \nregexp = /c{3, }/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3, }\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 13 of test - \nregexp = /c{3 ,}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 ,}\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 15 of test - \nregexp = /c{3 ,4}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 ,4}\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 16 of test - \nregexp = /c{3, 4}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3, 4}\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 17 of test - \nregexp = /c{3,4 }/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3,4 }\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 0", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 1", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 2", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 3", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 4", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 5", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 6", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 7", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 8", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-368516.js", "Treat unicode BOM characters as whitespace: 0", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/extensions/regress-368516.js", "Treat unicode BOM characters as whitespace: 1", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/FunExpr/fe-001-n.js", "Previous statement should have thrown a ReferenceError", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/LexicalConventions/7.9.1.js", "Automatic Semicolon insertion in postfix expressions: expr\n++", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/LexicalConventions/7.9.1.js", "Automatic Semicolon insertion in postfix expressions: expr\n--", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/LexicalConventions/7.9.1.js", "Automatic Semicolon insertion in postfix expressions: (x\n)-- y", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/LexicalConventions/7.9.1.js", "Automatic Semicolon insertion in postfix expressions: (x)-- y", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Object/8.6.1-01.js", "In strict mode, setting a read-only property should generate a warning: Throw if STRICT and WERROR is enabled", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.8.2 >", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.8.4 >=", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 5 of test - \nregexp = /(aa|aabaac|ba|b|c)*/\nstring = 'aabaac'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aaba\", \"ba\"]\nActual: [\"aabaac\", \"aabaac\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 6 of test - \nregexp = /^(a+)\\1*,\\1+$/\nstring = 'aaaaaaaaaa,aaaaaaaaaaaaaaa'\nERROR !!! regexp FAILED to match anything !!!\nExpect: aaaaaaaaaa,aaaaaaaaaaaaaaa,aaaaa\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 7 of test - \nregexp = /(z)((a+)?(b+)?(c))*/\nstring = 'zaacbbbcac'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"zaacbbbcac\", \"z\", \"ac\", \"a\", , \"c\"]\nActual: [\"zaacbbbcac\", \"z\", \"ac\", \"a\", \"\", \"c\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 8 of test - \nregexp = /(a*)*/\nstring = 'b'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\", , ]\nActual: [\"\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 10 of test - \nregexp = /(?=(a+))/\nstring = 'baaabac'\nERROR !!! match arrays have different lengths:\nExpect: [\"\", \"aaa\"]\nActual: [\"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 11 of test - \nregexp = /(?=(a+))a*b\\1/\nstring = 'baaabac'\nERROR !!! match arrays have different lengths:\nExpect: [\"aba\", \"a\"]\nActual: [\"aaab\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 12 of test - \nregexp = /(.*?)a(?!(a+)b\\2c)\\2(.*)/\nstring = 'baaabaac'\nERROR !!! regexp FAILED to match anything !!!\nExpect: baaabaac,ba,,abaac\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 13 of test - \nregexp = /(?=(a+))/\nstring = 'baaabac'\nERROR !!! match arrays have different lengths:\nExpect: [\"\", \"aaa\"]\nActual: [\"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 34 of test - \nregexp = /a]/\nstring = 'a]'\nERROR !!! regexp FAILED to match anything !!!\nExpect: a]\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 66 of test - \nregexp = /a.+?c/\nstring = 'abcabc'\nERROR !!! regexp FAILED to match anything !!!\nExpect: abc\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 94 of test - \nregexp = /^a(bc+|b[eh])g|.h$/\nstring = 'abh'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"bh\", , ]\nActual: [\"bh\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 95 of test - \nregexp = /(bc+d$|ef*g.|h?i(j|k))/\nstring = 'effgz'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"effgz\", \"effgz\", , ]\nActual: [\"effgz\", \"effgz\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 97 of test - \nregexp = /(bc+d$|ef*g.|h?i(j|k))/\nstring = 'reffgz'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"effgz\", \"effgz\", , ]\nActual: [\"effgz\", \"effgz\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 109 of test - \nregexp = /(([a-c])b*?\\2)*/\nstring = 'ababbbcbc'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ababb,bb,b\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 110 of test - \nregexp = /(([a-c])b*?\\2){3}/\nstring = 'ababbbcbc'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ababbbcbc,cbc,c\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 119 of test - \nregexp = /ab*?bc/i\nstring = 'ABBBBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBBBC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 120 of test - \nregexp = /ab{0,}?bc/i\nstring = 'ABBBBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBBBC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 121 of test - \nregexp = /ab+?bc/i\nstring = 'ABBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 123 of test - \nregexp = /ab{1,}?bc/i\nstring = 'ABBBBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBBBC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 124 of test - \nregexp = /ab{1,3}?bc/i\nstring = 'ABBBBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBBBC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 125 of test - \nregexp = /ab{3,4}?bc/i\nstring = 'ABBBBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBBBC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 126 of test - \nregexp = /ab??bc/i\nstring = 'ABBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 127 of test - \nregexp = /ab??bc/i\nstring = 'ABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 128 of test - \nregexp = /ab{0,1}?bc/i\nstring = 'ABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 129 of test - \nregexp = /ab??c/i\nstring = 'ABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 130 of test - \nregexp = /ab{0,1}?c/i\nstring = 'ABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 138 of test - \nregexp = /a.*?c/i\nstring = 'AXYZC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: AXYZC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 144 of test - \nregexp = /a]/i\nstring = 'A]'\nERROR !!! regexp FAILED to match anything !!!\nExpect: A]\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 160 of test - \nregexp = /a.+?c/i\nstring = 'ABCABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 161 of test - \nregexp = /a.*?c/i\nstring = 'ABCABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 162 of test - \nregexp = /a.{0,5}?c/i\nstring = 'ABCABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 169 of test - \nregexp = /(a+|b){0,1}?/i\nstring = 'AB'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ,\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 191 of test - \nregexp = /^a(bc+|b[eh])g|.h$/i\nstring = 'ABH'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"BH\", , ]\nActual: [\"BH\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 192 of test - \nregexp = /(bc+d$|ef*g.|h?i(j|k))/i\nstring = 'EFFGZ'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"EFFGZ\", \"EFFGZ\", , ]\nActual: [\"EFFGZ\", \"EFFGZ\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 194 of test - \nregexp = /(bc+d$|ef*g.|h?i(j|k))/i\nstring = 'REFFGZ'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"EFFGZ\", \"EFFGZ\", , ]\nActual: [\"EFFGZ\", \"EFFGZ\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 212 of test - \nregexp = /a(?:b|c|d)+?(.)/\nstring = 'ace'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ace,e\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 213 of test - \nregexp = /a(?:b|c|d)+?(.)/\nstring = 'acdbcdbe'\nERROR !!! regexp FAILED to match anything !!!\nExpect: acd,d\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 217 of test - \nregexp = /a(?:b|c|d){4,5}?(.)/\nstring = 'acdbcdbe'\nERROR !!! regexp FAILED to match anything !!!\nExpect: acdbcd,d\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 218 of test - \nregexp = /((foo)|(bar))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"foobar\", \"bar\", , \"bar\"]\nActual: [\"foobar\", \"bar\", \"\", \"bar\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 220 of test - \nregexp = /a(?:b|c|d){6,7}?(.)/\nstring = 'acdbcdbe'\nERROR !!! regexp FAILED to match anything !!!\nExpect: acdbcdbe,e\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 222 of test - \nregexp = /a(?:b|c|d){5,6}?(.)/\nstring = 'acdbcdbe'\nERROR !!! regexp FAILED to match anything !!!\nExpect: acdbcdb,b\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 224 of test - \nregexp = /a(?:b|c|d){5,7}?(.)/\nstring = 'acdbcdbe'\nERROR !!! regexp FAILED to match anything !!!\nExpect: acdbcdb,b\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 225 of test - \nregexp = /a(?:b|(c|e){1,2}?|d)+?(.)/\nstring = 'ace'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ace,c,e\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 227 of test - \nregexp = /^([^a-z])|(\\^)$/\nstring = '.'\nERROR !!! regexp failed to give expected match array:\nExpect: [\".\", \".\", , ]\nActual: [\".\", \".\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 234 of test - \nregexp = /(?:(f)(o)(o)|(b)(a)(r))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"foobar\", , , , \"b\", \"a\", \"r\"]\nActual: [\"foobar\", \"\", \"\", \"\", \"b\", \"a\", \"r\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 240 of test - \nregexp = /(?:..)*?a/\nstring = 'aba'\nERROR !!! regexp FAILED to match anything !!!\nExpect: a\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 241 of test - \nregexp = /^(?:b|a(?=(.)))*\\1/\nstring = 'abc'\nERROR !!! match arrays have different lengths:\nExpect: [\"ab\", , ]\nActual: [\"ab\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 246 of test - \nregexp = /(a|x)*ab/\nstring = 'cab'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"ab\", , ]\nActual: [\"ab\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 247 of test - \nregexp = /(a)*ab/\nstring = 'cab'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"ab\", , ]\nActual: [\"ab\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 300 of test - \nregexp = /(?=(a+?))(\\1ab)/\nstring = 'aaab'\nERROR !!! regexp FAILED to match anything !!!\nExpect: aab,a,aab\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 303 of test - \nregexp = /(?=(a+?))(\\1ab)/\nstring = 'aaab'\nERROR !!! regexp FAILED to match anything !!!\nExpect: aab,a,aab\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 304 of test - \nregexp = /([\\w:]+::)?(\\w+)$/\nstring = 'abcd'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"abcd\", , \"abcd\"]\nActual: [\"abcd\", \"\", \"abcd\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 308 of test - \nregexp = /([\\w:]+::)?(\\w+)$/\nstring = 'abcd'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"abcd\", , \"abcd\"]\nActual: [\"abcd\", \"\", \"abcd\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 342 of test - \nregexp = /a$/m\nstring = 'a\\nb\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: a\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 344 of test - \nregexp = /a$/m\nstring = 'b\\na\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: a\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 353 of test - \nregexp = /aa$/m\nstring = 'aa\\nb\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: aa\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 355 of test - \nregexp = /aa$/m\nstring = 'b\\naa\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: aa\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 364 of test - \nregexp = /ab$/m\nstring = 'ab\\nb\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ab\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 366 of test - \nregexp = /ab$/m\nstring = 'b\\nab\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ab\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 375 of test - \nregexp = /abb$/m\nstring = 'abb\\nb\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: abb\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 377 of test - \nregexp = /abb$/m\nstring = 'b\\nabb\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: abb\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 383 of test - \nregexp = /^d[x][x][x]/m\nstring = 'abcd\\ndxxx'\nERROR !!! regexp FAILED to match anything !!!\nExpect: dxxx\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 391 of test - \nregexp = /\\.c(pp|xx|c)?$/i\nstring = 'IO.c'\nERROR !!! regexp failed to give expected match array:\nExpect: [\".c\", , ]\nActual: [\".c\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 392 of test - \nregexp = /(\\.c(pp|xx|c)?$)/i\nstring = 'IO.c'\nERROR !!! regexp failed to give expected match array:\nExpect: [\".c\", \".c\", , ]\nActual: [\".c\", \".c\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 394 of test - \nregexp = /^([ab]*?)(b)?(c)$/\nstring = 'abac'\nERROR !!! regexp FAILED to match anything !!!\nExpect: abac,aba,,c\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 412 of test - \nregexp = /^(a(b)?)+$/\nstring = 'aba'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aba\", \"a\", , ]\nActual: [\"aba\", \"a\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 413 of test - \nregexp = /^(aa(bb)?)+$/\nstring = 'aabbaa'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aabbaa\", \"aa\", , ]\nActual: [\"aabbaa\", \"aa\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 414 of test - \nregexp = /^.{9}abc.*\\n/m\nstring = '123\\nabcabcabcabc\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: abcabcabcabc\n\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 415 of test - \nregexp = /^(a)?a$/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", , ]\nActual: [\"a\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 416 of test - \nregexp = /^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$/\nstring = 'aaaaaa'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aaaaaa\", \"a\", \"aa\", \"a\", \"aa\"]\nActual: [\"aaaaaa\", \"aa\", \"a\", \"aa\", \"a\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 418 of test - \nregexp = /^(0+)?(?:x(1))?/\nstring = 'x1'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"x1\", , \"1\"]\nActual: [\"x1\", \"\", \"1\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 419 of test - \nregexp = /^([0-9a-fA-F]+)(?:x([0-9a-fA-F]+)?)(?:x([0-9a-fA-F]+))?/\nstring = '012cxx0190'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"012cxx0190\", \"012c\", , \"0190\"]\nActual: [\"012cxx0190\", \"012c\", \"\", \"0190\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 420 of test - \nregexp = /^(b+?|a){1,2}c/\nstring = 'bbbac'\nERROR !!! regexp FAILED to match anything !!!\nExpect: bbbac,a\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 421 of test - \nregexp = /^(b+?|a){1,2}c/\nstring = 'bbbbac'\nERROR !!! regexp FAILED to match anything !!!\nExpect: bbbbac,a\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-002.js", "Section 40 of test - \nregexp = /(a)|\\1/\nstring = 'x'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\", , ]\nActual: [\"\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-105972.js", "Section 1 of test - \nregexp = /^.*?$/\nstring = 'Hello World'\nERROR !!! regexp FAILED to match anything !!!\nExpect: Hello World\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-105972.js", "Section 2 of test - \nregexp = /^.*?/\nstring = 'Hello World'\nERROR !!! regexp FAILED to match anything !!!\nExpect: \nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-105972.js", "Section 3 of test - \nregexp = /^.*?(:|$)/\nstring = 'Hello: World'\nERROR !!! regexp FAILED to match anything !!!\nExpect: Hello:,:\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-123437.js", "Section 1 of test - \nregexp = /(a)?a/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", , ]\nActual: [\"a\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-123437.js", "Section 2 of test - \nregexp = /a|(b)/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", , ]\nActual: [\"a\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-123437.js", "Section 3 of test - \nregexp = /(a)?(a)/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", , \"a\"]\nActual: [\"a\", \"\", \"a\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-165353.js", "Section 1 of test - \nregexp = /^([a-z]+)*[a-z]$/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", , ]\nActual: [\"a\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-169497.js", "Section 1 of test - \nregexp = /<body.*>((.*\\n?)*?)<\\/body>/i\nstring = '<html>\\n<body onXXX=\"alert(event.type);\">\\n<p>Kibology for all</p>\\n<p>All for Kibology</p>\\n</body>\\n</html>'\nERROR !!! regexp FAILED to match anything !!!\nExpect: <body onXXX=\"alert(event.type);\">\n<p>Kibology for all</p>\n<p>All for Kibology</p>\n</body>,\n<p>Kibology for all</p>\n<p>All for Kibology</p>\n,<p>All for Kibology</p>\n\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-187133.js", "Section 5 of test - \nregexp = /(?!a|b)|c/\nstring = 'bc'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\"]\nActual: [\"c\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 1 of test - \nregexp = /(\\d|\\d\\s){2,}/\nstring = '12 3 45'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"12\", \"2\"]\nActual: [\"12 3 45\", \"5\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 3 of test - \nregexp = /(\\d|\\d\\s)+/\nstring = '12 3 45'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"12\", \"2\"]\nActual: [\"12 3 45\", \"5\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 8 of test - \nregexp = /(\\d|\\d\\s){2,}?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 12,2\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 9 of test - \nregexp = /(\\d|\\d\\s){4,}?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 12 3 4,4\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 10 of test - \nregexp = /(\\d|\\d\\s)+?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 1,1\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 11 of test - \nregexp = /(\\d\\s?){4,}?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 12 3 4,4\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 12 of test - \nregexp = /(\\d\\s|\\d){2,}?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 12 ,2 \nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 13 of test - \nregexp = /(\\d\\s|\\d){4,}?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 12 3 4,4\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 14 of test - \nregexp = /(\\d\\s|\\d)+?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 1,1\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-202564.js", "Section 1 of test - \nregexp = /(?:(.+), )?(.+), (..) to (?:(.+), )?(.+), (..)/\nstring = 'Seattle, WA to Buckley, WA'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"Seattle, WA to Buckley, WA\", , \"Seattle\", \"WA\", , \"Buckley\", \"WA\"]\nActual: [\"Seattle, WA to Buckley, WA\", \"\", \"Seattle\", \"WA\", \"\", \"Buckley\", \"WA\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 2 of test - \nregexp = /(a|b*){5,}/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", \"\"]\nActual: [\"a\", \"a\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 3 of test - \nregexp = /(b*)*/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\", , ]\nActual: [\"\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 5 of test - \nregexp = /^\\-?(\\d{1,}|\\.{0,})*(\\,\\d{1,})?$/\nstring = '100.00'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"100.00\", \"00\", , ]\nActual: [\"100.00\", \"00\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-216591.js", "Section 1 of test - \nregexp = /\\{(([a-z0-9\\-_]+?\\.)+?)([a-z0-9\\-_]+?)\\}/i\nstring = 'a {result.data.DATA} b'\nERROR !!! regexp FAILED to match anything !!!\nExpect: {result.data.DATA},result.data.,data.,DATA\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-216591.js", "Section 2 of test - \nregexp = /\\{(([a-z0-9\\-_]+?\\.)+?)([a-z0-9\\-_]+?)\\}/gi\nstring = 'a {result.data.DATA} b'\nERROR !!! match arrays have different lengths:\nExpect: [\"{result.data.DATA}\"]\nActual: []\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-220367-001.js", "Section 1 of test - \nregexp = /(a)|(b)/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", \"a\", , ]\nActual: [\"a\", \"a\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-220367-001.js", "Section 2 of test - \nregexp = /(a)|(b)/\nstring = 'b'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"b\", , \"b\"]\nActual: [\"b\", \"\", \"b\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-223535.js", "Section 2 of test - \nregexp = /|a/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\"]\nActual: [\"a\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-223535.js", "Section 6 of test - \nregexp = /(|a)/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\", \"\"]\nActual: [\"a\", \"a\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-223535.js", "Section 7 of test - \nregexp = /(|a|)/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\", \"\"]\nActual: [\"a\", \"a\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-224676.js", "Section 17 of test - \nregexp = /[x]b|(a)/\nstring = 'ZZZxbZZZ'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"xb\", , ]\nActual: [\"xb\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-224676.js", "Section 18 of test - \nregexp = /[x]b|()a/\nstring = 'ZZZxbZZZ'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"xb\", , ]\nActual: [\"xb\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-225289.js", "Section 7 of test - \nregexp = /(a)|([^a])/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", \"a\", , ]\nActual: [\"a\", \"a\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-225289.js", "Section 9 of test - \nregexp = /(a)|([^a])/\nstring = '()'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"(\", , \"(\"]\nActual: [\"(\", \"\", \"(\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-225289.js", "Section 10 of test - \nregexp = /((?:a|[^a])*)/g\nstring = 'a'\nERROR !!! match arrays have different lengths:\nExpect: [\"a\", \"\"]\nActual: [\"a\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-225289.js", "Section 11 of test - \nregexp = /((?:a|[^a])*)/g\nstring = ''\nERROR !!! match arrays have different lengths:\nExpect: [\"\"]\nActual: []\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-225289.js", "Section 12 of test - \nregexp = /((?:a|[^a])*)/g\nstring = '()'\nERROR !!! match arrays have different lengths:\nExpect: [\"()\", \"\"]\nActual: [\"()\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-31316.js", "Section 1 of test - \nregexp = /<([^\\/<>][^<>]*[^\\/])>|<([^\\/<>])>/\nstring = '<p>Some<br />test</p>'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"<p>\", , \"p\"]\nActual: [\"<p>\", \"\", \"p\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-330684.js", "Do not hang on RegExp", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-375711.js", "Do not assert with /[Q-b]/i.exec(\"\"): /[q-b]/.exec(\"\")", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-375711.js", "Do not assert with /[Q-b]/i.exec(\"\"): /[q-b]/i.exec(\"\")", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(?)'and flag 'i'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(?)'and flag 'g'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(?)'and flag 'm'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(?)'and flag 'undefined'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(a'and flag 'i'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(a'and flag 'g'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(a'and flag 'm'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(a'and flag 'undefined'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '( ]'and flag 'i'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '( ]'and flag 'g'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '( ]'and flag 'm'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '( ]'and flag 'undefined'", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-78156.js", "Section 1 of test - \nregexp = /^\\d/gm\nstring = 'aaa\\n789\\r\\nccc\\r\\n345'\nERROR !!! match arrays have different lengths:\nExpect: [\"7\", \"3\"]\nActual: []\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-78156.js", "Section 2 of test - \nregexp = /\\d$/gm\nstring = 'aaa\\n789\\r\\nccc\\r\\n345'\nERROR !!! match arrays have different lengths:\nExpect: [\"9\", \"5\"]\nActual: [\"5\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-78156.js", "Section 3 of test - \nregexp = /^\\d/gm\nstring = 'aaa\\n789\\r\\nccc\\r\\nddd'\nERROR !!! match arrays have different lengths:\nExpect: [\"7\"]\nActual: []\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-78156.js", "Section 4 of test - \nregexp = /\\d$/gm\nstring = 'aaa\\n789\\r\\nccc\\r\\nddd'\nERROR !!! match arrays have different lengths:\nExpect: [\"9\"]\nActual: []\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-85721.js", "Section 2 of test - \nregexp = /<sql:connection id=\"([^\\r\\n]*?)\">\\s*<sql:url>\\s*([^\\r\\n]*?)\\s*<\\/sql:url>\\s*<sql:driver>\\s*([^\\r\\n]*?)\\s*<\\/sql:driver>\\s*(\\s*<sql:userId>\\s*([^\\r\\n]*?)\\s*<\\/sql:userId>\\s*)?\\s*(\\s*<sql:password>\\s*([^\\r\\n]*?)\\s*<\\/sql:password>\\s*)?\\s*<\\/sql:connection>/\nstring = '<sql:connection id=\"conn1\"> <sql:url>www.m.com</sql:url> <sql:driver>drive.class</sql:driver>\\n<sql:userId>foo</sql:userId> <sql:password>goo</sql:password> </sql:connection>'\nERROR !!! regexp FAILED to match anything !!!\nExpect: <sql:connection id=\"conn1\"> <sql:url>www.m.com</sql:url> <sql:driver>drive.class</sql:driver>\n<sql:userId>foo</sql:userId> <sql:password>goo</sql:password> </sql:connection>,conn1,www.m.com,drive.class,<sql:userId>foo</sql:userId> ,foo,<sql:password>goo</sql:password> ,goo\nActual: null\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-87231.js", "Section 3 of test - \nregexp = /^(A)?(A.*)$/\nstring = 'A'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"A\", , \"A\"]\nActual: [\"A\", \"\", \"A\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-87231.js", "Section 6 of test - \nregexp = /(A)?(A.*)/\nstring = 'zxcasd;fl\\ ^AaaAAaaaf;lrlrzs'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"AaaAAaaaf;lrlrzs\", , \"AaaAAaaaf;lrlrzs\"]\nActual: [\"AaaAAaaaf;lrlrzs\", \"\", \"AaaAAaaaf;lrlrzs\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 24", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 28", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 30", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/String/15.5.4.14.js", "15.5.4.14 - String.prototype.split(/()/)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Unicode/regress-352044-01.js", "issues with Unicode escape sequences in JavaScript source code", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Unicode/uc-001.js", "Unicode format-control character test (Category Cf.)", willFixInNextReleaseMessage);
-
- addFileExclusion(".+/15\\.9\\.2\\..+", "unstable on slow machines");
- addFileExclusion(".+/15\\.9\\.5\\..+", "too slooow");
- addFileExclusion("regress-130451.js", "asserts");
- addFileExclusion("regress-322135-01.js", "asserts");
- addFileExclusion("regress-322135-02.js", "asserts");
- addFileExclusion("regress-322135-03.js", "takes forever");
- addFileExclusion("regress-322135-04.js", "takes forever");
- addFileExclusion("ecma_3/RegExp/regress-375715-04.js", "bug");
-
- addFileExclusion("ecma_3/RegExp/regress-289669.js", "Can fail due to relying on wall-clock time");
-
- // Failures due to switch to JSC as back-end
- addExpectedFailure("ecma/Array/15.4.3.1-2.js", "var props = ''; for ( p in Array ) { props += p } props", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Boolean/15.6.3.1-1.js", "var str='';for ( p in Boolean ) { str += p } str;", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Expressions/11.4.1.js", "var abc; delete(abc)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/FunctionObjects/15.3.3.1-2.js", "var str='';for (prop in Function ) str += prop; str;", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/ObjectObjects/15.2.3.1-1.js", "var str = '';for ( p in Object ) { str += p; }; str", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Statements/12.6.3-11.js", "result = \"\"; for ( p in Number ) { result += String(p) };", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Statements/12.6.3-2.js", "Boolean.prototype.foo = 34; for ( j in Boolean ) Boolean[j]", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "-\"\\u20001234\\u2001\"", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_2/RegExp/properties-001.js", "//.toString()", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Date/15.9.4.3.js", "15.9.4.3 - Date.UTC edge-case arguments.: date Infinity", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Date/15.9.4.3.js", "15.9.4.3 - Date.UTC edge-case arguments.: hours Infinity", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Date/15.9.4.3.js", "15.9.4.3 - Date.UTC edge-case arguments.: minutes Infinity", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Date/15.9.4.3.js", "15.9.4.3 - Date.UTC edge-case arguments.: seconds Infinity", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Function/regress-131964.js", "Section 1 of test - ", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Function/regress-313570.js", "length of objects whose prototype chain includes a function: immutable", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/FunExpr/fe-001.js", "Both functions were defined.", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 7 of test - \nregexp = /(z)((a+)?(b+)?(c))*/\nstring = 'zaacbbbcac'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"zaacbbbcac\", \"z\", \"ac\", \"a\", , \"c\"]\nActual: [\"zaacbbbcac\", \"z\", \"ac\", \"a\", \"bbb\", \"c\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 12 of test - \nregexp = /(.*?)a(?!(a+)b\\2c)\\2(.*)/\nstring = 'baaabaac'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"baaabaac\", \"ba\", , \"abaac\"]\nActual: [\"baaabaac\", \"ba\", \"aa\", \"abaac\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 218 of test - \nregexp = /((foo)|(bar))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"foobar\", \"bar\", , \"bar\"]\nActual: [\"foobar\", \"bar\", \"foo\", \"bar\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 234 of test - \nregexp = /(?:(f)(o)(o)|(b)(a)(r))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"foobar\", , , , \"b\", \"a\", \"r\"]\nActual: [\"foobar\", \"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 241 of test - \nregexp = /^(?:b|a(?=(.)))*\\1/\nstring = 'abc'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"ab\", , ]\nActual: [\"ab\", \"b\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 412 of test - \nregexp = /^(a(b)?)+$/\nstring = 'aba'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aba\", \"a\", , ]\nActual: [\"aba\", \"a\", \"b\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 413 of test - \nregexp = /^(aa(bb)?)+$/\nstring = 'aabbaa'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aabbaa\", \"aa\", , ]\nActual: [\"aabbaa\", \"aa\", \"bb\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 1 of test - \nregexp = /(a|b*)*/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", \"a\"]\nActual: [\"a\", \"\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 5 of test - \nregexp = /^\\-?(\\d{1,}|\\.{0,})*(\\,\\d{1,})?$/\nstring = '100.00'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"100.00\", \"00\", , ]\nActual: [\"100.00\", \"\", , ]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 6 of test - \nregexp = /^\\-?(\\d{1,}|\\.{0,})*(\\,\\d{1,})?$/\nstring = '100,00'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"100,00\", \"100\", \",00\"]\nActual: [\"100,00\", \"\", \",00\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 7 of test - \nregexp = /^\\-?(\\d{1,}|\\.{0,})*(\\,\\d{1,})?$/\nstring = '1.000,00'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"1.000,00\", \"000\", \",00\"]\nActual: [\"1.000,00\", \"\", \",00\"]\n", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/RegExp/regress-311414.js", "RegExp captured tail match should be O(N) BigO 2 < 2", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 7", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 26", willFixInNextReleaseMessage);
-
-#ifdef Q_CC_MSVC
- addExpectedFailure("ecma_3/Expressions/11.7.3-01.js", "11.7.3 - >>> should evaluate operands in order: order", "QTBUG-8056");
- addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.7.3 >>>", "QTBUG-8056");
- addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 >>>=", "QTBUG-8056");
-#endif
-
-#ifdef Q_CC_MINGW
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(Infinity, Infinity)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(Infinity, -Infinity)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-Infinity, Infinity)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-Infinity, -Infinity)", willFixInNextReleaseMessage);
-#endif
-
-#ifdef Q_OS_SOLARIS
- addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -0; VAR2= Infinity; VAR2 /= VAR1", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -0; VAR2= -Infinity; VAR2 /= VAR1", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = 1; VAR2= -0; VAR1 /= VAR2", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -1; VAR2= -0; VAR1 /= VAR2", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Expressions/11.5.2.js", "Number.POSITIVE_INFINITY / -0", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Expressions/11.5.2.js", "Number.NEGATIVE_INFINITY / -0", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Expressions/11.5.2.js", "1 / -0", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Expressions/11.5.2.js", "-1 / -0", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.10.js", "Math.log(-0.0000001)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.10.js", "Math.log(-1)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.11.js", "Infinity/Math.max(-0,-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.12.js", "Infinity/Math.min(0,-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.12.js", "Infinity/Math.min(-0,-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-Infinity, -1)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -1)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -0.5)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -1000)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-0, 1)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-0, 3)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(-0, -2)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0.49)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0.5)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.17.js", "Infinity/Math.sqrt(-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.18.js", "Infinity/Math.tan(-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.2.js", "Math.acos(1.00000001)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.2.js", "Math.acos(11.00000001)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.3.js", "Math.asin(1.000001)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.3.js", "Math.asin(-1.000001)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.3.js", "Infinity/Math.asin(-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.4.js", "Infinity/Math.atan(-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(0, -0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.5.js", "Infinity/Math.atan2(-0, 1)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-0,\t-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-0,\t-1)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil('-0')", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-Number.MIN_VALUE)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-0.9)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.9.js", "Infinity/Math.floor(-0)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "var z = 0; print(1/-z)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "1/-1e-2000", willFixInNextReleaseMessage);
-#endif
-
-#ifdef Q_OS_SYMBIAN
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(-1, 0.5)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(-1, -0.5)", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.5.1 *", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.5.2 /", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.6.2 -", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 *=", willFixInNextReleaseMessage);
- addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 /=", willFixInNextReleaseMessage);
-#endif
-
- static const char klass[] = "tst_QScriptJsTestSuite";
-
- QVector<uint> *data = qt_meta_data_tst_Suite();
- // content:
- *data << 1 // revision
- << 0 // classname
- << 0 << 0 // classinfo
- << 0 << 10 // methods (backpatched later)
- << 0 << 0 // properties
- << 0 << 0 // enums/sets
- ;
-
- QVector<char> *stringdata = qt_meta_stringdata_tst_Suite();
- appendCString(stringdata, klass);
- appendCString(stringdata, "");
-
// don't execute any tests on slow machines
#if !defined(Q_OS_IRIX)
// do all the test suites
- QFileInfoList testSuiteDirInfos;
- if (testsFound)
- testSuiteDirInfos = testsDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
+ QFileInfoList testSuiteDirInfos = testsDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
foreach (QFileInfo tsdi, testSuiteDirInfos) {
QDir testSuiteDir(tsdi.absoluteFilePath());
// do all the dirs in the test suite
QFileInfoList subSuiteDirInfos = testSuiteDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
foreach (QFileInfo ssdi, subSuiteDirInfos) {
subSuitePaths.append(ssdi.absoluteFilePath());
- // slot: signature, parameters, type, tag, flags
- QString data_slot = QString::fromLatin1("%0/%1_data()")
- .arg(testSuiteDir.dirName()).arg(ssdi.fileName());
- static const int nullbyte = sizeof(klass);
- *data << stringdata->size() << nullbyte << nullbyte << nullbyte << 0x08;
- appendCString(stringdata, data_slot.toLatin1());
- QString slot = QString::fromLatin1("%0/%1()")
- .arg(testSuiteDir.dirName()).arg(ssdi.fileName());
- *data << stringdata->size() << nullbyte << nullbyte << nullbyte << 0x08;
- appendCString(stringdata, slot.toLatin1());
+ QString function = QString::fromLatin1("%0/%1")
+ .arg(testSuiteDir.dirName()).arg(ssdi.fileName());
+ addTestFunction(function, CreateDataFunction);
}
}
#endif
- (*data)[4] = subSuitePaths.size() * 2;
+ finalizeMetaObject();
+}
+
+tst_QScriptJSTestSuite::~tst_QScriptJSTestSuite()
+{
+}
- *data << 0; // eod
+void tst_QScriptJSTestSuite::configData(TestConfig::Mode mode, const QStringList &parts)
+{
+ switch (mode) {
+ case TestConfig::Skip:
+ addFileExclusion(parts.at(0), parts.value(1));
+ break;
+
+ case TestConfig::ExpectFail:
+ addExpectedFailure(parts.at(0), parts.value(1), parts.value(2));
+ break;
+ }
+}
- // initialize staticMetaObject
- staticMetaObject.d.superdata = &QObject::staticMetaObject;
- staticMetaObject.d.stringdata = stringdata->constData();
- staticMetaObject.d.data = data->constData();
- staticMetaObject.d.extradata = 0;
+void tst_QScriptJSTestSuite::writeSkipConfigFile(QTextStream &stream)
+{
+ stream << QString::fromLatin1("# testcase | message") << endl;
}
-tst_Suite::~tst_Suite()
+void tst_QScriptJSTestSuite::writeExpectFailConfigFile(QTextStream &stream)
{
-#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE
- if (!generatedAddExpectedFailureCode.isEmpty()) {
- QFile file("addexpectedfailures.cpp");
- file.open(QFile::WriteOnly);
- QTextStream ts(&file);
- ts << generatedAddExpectedFailureCode;
+ stream << QString::fromLatin1("# testcase | description | message") << endl;
+ for (int i = 0; i < expectedFailures.size(); ++i) {
+ const FailureItem &fail = expectedFailures.at(i);
+ if (fail.pathRegExp.pattern().isEmpty())
+ continue;
+ stream << QString::fromLatin1("%0 | %1")
+ .arg(fail.pathRegExp.pattern())
+ .arg(escape(fail.description));
+ if (!fail.message.isEmpty())
+ stream << QString::fromLatin1(" | %0").arg(escape(fail.message));
+ stream << endl;
}
-#endif
}
-void tst_Suite::addExpectedFailure(const QRegExp &path, const QString &description, const QString &message)
+void tst_QScriptJSTestSuite::addExpectedFailure(const QRegExp &path, const QString &description, const QString &message)
{
expectedFailures.append(FailureItem(FailureItem::ExpectFail, path, description, message));
}
-void tst_Suite::addExpectedFailure(const QString &fileName, const QString &description, const QString &message)
+void tst_QScriptJSTestSuite::addExpectedFailure(const QString &fileName, const QString &description, const QString &message)
{
expectedFailures.append(FailureItem(FailureItem::ExpectFail, QRegExp(fileName), description, message));
}
-void tst_Suite::addSkip(const QRegExp &path, const QString &description, const QString &message)
+void tst_QScriptJSTestSuite::addSkip(const QRegExp &path, const QString &description, const QString &message)
{
expectedFailures.append(FailureItem(FailureItem::Skip, path, description, message));
}
-void tst_Suite::addSkip(const QString &fileName, const QString &description, const QString &message)
+void tst_QScriptJSTestSuite::addSkip(const QString &fileName, const QString &description, const QString &message)
{
expectedFailures.append(FailureItem(FailureItem::Skip, QRegExp(fileName), description, message));
}
-bool tst_Suite::isExpectedFailure(const QString &fileName, const QString &description,
+bool tst_QScriptJSTestSuite::isExpectedFailure(const QString &fileName, const QString &description,
QString *message, FailureItem::Action *action) const
{
for (int i = 0; i < expectedFailures.size(); ++i) {
@@ -857,17 +430,17 @@ bool tst_Suite::isExpectedFailure(const QString &fileName, const QString &descri
return false;
}
-void tst_Suite::addFileExclusion(const QString &fileName, const QString &message)
+void tst_QScriptJSTestSuite::addFileExclusion(const QString &fileName, const QString &message)
{
fileExclusions.append(qMakePair(QRegExp(fileName), message));
}
-void tst_Suite::addFileExclusion(const QRegExp &rx, const QString &message)
+void tst_QScriptJSTestSuite::addFileExclusion(const QRegExp &rx, const QString &message)
{
fileExclusions.append(qMakePair(rx, message));
}
-bool tst_Suite::isExcludedFile(const QString &fileName, QString *message) const
+bool tst_QScriptJSTestSuite::isExcludedFile(const QString &fileName, QString *message) const
{
for (int i = 0; i < fileExclusions.size(); ++i) {
if (fileExclusions.at(i).first.indexIn(fileName) != -1) {
@@ -879,4 +452,4 @@ bool tst_Suite::isExcludedFile(const QString &fileName, QString *message) const
return false;
}
-QTEST_MAIN(tst_Suite)
+QTEST_MAIN(tst_QScriptJSTestSuite)
diff --git a/tests/auto/qscriptv8testsuite/abstracttestsuite.cpp b/tests/auto/qscriptv8testsuite/abstracttestsuite.cpp
new file mode 100644
index 0000000..d47eb24
--- /dev/null
+++ b/tests/auto/qscriptv8testsuite/abstracttestsuite.cpp
@@ -0,0 +1,481 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 "abstracttestsuite.h"
+#include <QtTest/QtTest>
+#include <QtCore/qset.h>
+#include <QtCore/qtextstream.h>
+
+/*!
+ AbstractTestSuite provides a way of building QtTest test objects
+ dynamically. The use case is integration of JavaScript test suites
+ into QtTest autotests.
+
+ Subclasses add their tests functions with addTestFunction() in the
+ constructor, and must reimplement runTestFunction(). Additionally,
+ subclasses can reimplement initTestCase() and cleanupTestCase()
+ (but make sure to call the base implementation).
+
+ AbstractTestSuite uses configuration files for getting information
+ about skipped tests (skip.txt) and expected test failures
+ (expect_fail.txt). Subclasses must reimplement
+ createSkipConfigFile() and createExpectFailConfigFile() for
+ creating these files, and configData() for processing an entry of
+ such a file.
+
+ The config file format is as follows:
+ - Lines starting with '#' are skipped.
+ - Lines of the form [SYMBOL] means that the upcoming data
+ should only be processed if the given SYMBOL is defined on
+ this platform.
+ - Any other line is split on ' | ' and handed off to the client.
+
+ Subclasses must provide a default tests directory (where the
+ subclass expects to find the script files to run as tests), and a
+ default config file directory. Some environment variables can be
+ used to affect where AbstractTestSuite will look for files:
+
+ - QTSCRIPT_TEST_CONFIG_DIR: Overrides the default test config path.
+
+ - QTSCRIPT_TEST_CONFIG_SUFFIX: Is appended to "skip" and
+ "expect_fail" to create the test config name. This makes it easy to
+ maintain skip- and expect_fail-files corresponding to different
+ revisions of a test suite, and switch between them.
+
+ - QTSCRIPT_TEST_DIR: Overrides the default test dir.
+
+ AbstractTestSuite does _not_ define how the test dir itself is
+ processed or how tests are run; this is left up to the subclass.
+
+ If no config files are found, AbstractTestSuite will ask the
+ subclass to create a default skip file. Also, the
+ shouldGenerateExpectedFailures variable will be set to true. The
+ subclass should check for this when a test fails, and add an entry
+ to its set of expected failures. When all tests have been run,
+ AbstractTestSuite will ask the subclass to create the expect_fail
+ file based on the tests that failed. The next time the autotest is
+ run, the created config files will be used.
+
+ The reason for skipping a test is usually that it takes a very long
+ time to complete (or even hangs completely), or it crashes. It's
+ not possible for the test runner to know in advance which tests are
+ problematic, which is why the entries to the skip file are
+ typically added manually. When running tests for the first time, it
+ can be useful to run the autotest with the -v1 command line option,
+ so you can see the name of each test before it's run, and can add a
+ skip entry if appropriate.
+*/
+
+// Helper class for constructing the test class's QMetaObject contents
+// at runtime.
+class TestMetaObjectBuilder
+{
+public:
+ TestMetaObjectBuilder(const QByteArray &className,
+ const QMetaObject *superClass);
+
+ void appendPrivateVoidSlot(const char *signature);
+ void appendPrivateVoidSlot(const QString &signature)
+ { appendPrivateVoidSlot(signature.toLatin1().constData()); }
+
+ void assignContents(QMetaObject &);
+
+private:
+ void appendString(const char *);
+ void finalize();
+
+ const QByteArray m_className;
+ const QMetaObject *m_superClass;
+ QVector<uint> m_data;
+ QVector<char> m_stringdata;
+ int m_emptyStringOffset;
+ bool m_finalized;
+};
+
+TestMetaObjectBuilder::TestMetaObjectBuilder(
+ const QByteArray &className,
+ const QMetaObject *superClass)
+ : m_className(className), m_superClass(superClass),
+ m_finalized(false)
+{
+ // header
+ m_data << 1 // revision
+ << 0 // classname
+ << 0 << 0 // classinfo
+ << 0 << 10 // methods (backpatched later)
+ << 0 << 0 // properties
+ << 0 << 0 // enums/sets
+ ;
+
+ appendString(className.constData());
+ m_emptyStringOffset = m_stringdata.size();
+ appendString("");
+}
+
+void TestMetaObjectBuilder::appendString(const char *s)
+{
+ char c;
+ do {
+ c = *(s++);
+ m_stringdata << c;
+ } while (c != '\0');
+}
+
+void TestMetaObjectBuilder::appendPrivateVoidSlot(const char *signature)
+{
+ static const int methodCountOffset = 4;
+ // signature, parameters, type, tag, flags
+ m_data << m_stringdata.size()
+ << m_emptyStringOffset
+ << m_emptyStringOffset
+ << m_emptyStringOffset
+ << 0x08;
+ appendString(signature);
+ ++m_data[methodCountOffset];
+}
+
+void TestMetaObjectBuilder::finalize()
+{
+ if (m_finalized)
+ return;
+ m_data << 0; // eod
+ m_finalized = true;
+}
+
+/**
+ Assigns this builder's contents to the meta-object \a mo. It's up
+ to the caller to ensure that this builder (and hence, its data)
+ stays alive as long as needed.
+*/
+void TestMetaObjectBuilder::assignContents(QMetaObject &mo)
+{
+ finalize();
+ mo.d.superdata = m_superClass;
+ mo.d.stringdata = m_stringdata.constData();
+ mo.d.data = m_data.constData();
+ mo.d.extradata = 0;
+}
+
+
+class TestConfigClientInterface;
+// For parsing information about skipped tests and expected failures.
+class TestConfigParser
+{
+public:
+ static void parse(const QString &path,
+ TestConfig::Mode mode,
+ TestConfigClientInterface *client);
+
+private:
+ static QString unescape(const QString &);
+ static bool isKnownSymbol(const QString &);
+ static bool isDefined(const QString &);
+
+ static QSet<QString> knownSymbols;
+ static QSet<QString> definedSymbols;
+};
+
+QSet<QString> TestConfigParser::knownSymbols;
+QSet<QString> TestConfigParser::definedSymbols;
+
+/**
+ Parses the config file at the given \a path in the given \a mode.
+ Handling of errors and data is delegated to the given \a client.
+*/
+void TestConfigParser::parse(const QString &path,
+ TestConfig::Mode mode,
+ TestConfigClientInterface *client)
+{
+ QFile file(path);
+ if (!file.open(QIODevice::ReadOnly))
+ return;
+ QTextStream stream(&file);
+ int lineNumber = 0;
+ QString predicate;
+ const QString separator = QString::fromLatin1(" | ");
+ while (!stream.atEnd()) {
+ ++lineNumber;
+ QString line = stream.readLine();
+ if (line.isEmpty())
+ continue;
+ if (line.startsWith('#')) // Comment
+ continue;
+ if (line.startsWith('[')) { // Predicate
+ if (!line.endsWith(']')) {
+ client->configError(path, "malformed predicate", lineNumber);
+ return;
+ }
+ QString symbol = line.mid(1, line.size()-2);
+ if (isKnownSymbol(symbol)) {
+ predicate = symbol;
+ } else {
+ qWarning("symbol %s is not known -- add it to TestConfigParser!", qPrintable(symbol));
+ predicate = QString();
+ }
+ } else {
+ if (predicate.isEmpty() || isDefined(predicate)) {
+ QStringList parts = line.split(separator, QString::KeepEmptyParts);
+ for (int i = 0; i < parts.size(); ++i)
+ parts[i] = unescape(parts[i]);
+ client->configData(mode, parts);
+ }
+ }
+ }
+}
+
+QString TestConfigParser::unescape(const QString &str)
+{
+ return QString(str).replace("\\n", "\n");
+}
+
+bool TestConfigParser::isKnownSymbol(const QString &symbol)
+{
+ if (knownSymbols.isEmpty()) {
+ knownSymbols
+ // If you add a symbol here, add a case for it in
+ // isDefined() as well.
+ << "Q_OS_LINUX"
+ << "Q_OS_SOLARIS"
+ << "Q_OS_WINCE"
+ << "Q_OS_SYMBIAN"
+ << "Q_CC_MSVC"
+ << "Q_CC_MINGW"
+ ;
+ }
+ return knownSymbols.contains(symbol);
+}
+
+bool TestConfigParser::isDefined(const QString &symbol)
+{
+ if (definedSymbols.isEmpty()) {
+ definedSymbols
+#ifdef Q_OS_LINUX
+ << "Q_OS_LINUX"
+#endif
+#ifdef Q_OS_SOLARIS
+ << "Q_OS_SOLARIS"
+#endif
+#ifdef Q_OS_WINCE
+ << "Q_OS_WINCE"
+#endif
+#ifdef Q_OS_SYMBIAN
+ << "Q_OS_SYMBIAN"
+#endif
+#ifdef Q_CC_MSVC
+ << "Q_CC_MSVC"
+#endif
+#ifdef Q_CC_MINGW
+ << "Q_CC_MINGW"
+#endif
+ ;
+ }
+ return definedSymbols.contains(symbol);
+}
+
+
+QMetaObject AbstractTestSuite::staticMetaObject;
+
+const QMetaObject *AbstractTestSuite::metaObject() const
+{
+ return &staticMetaObject;
+}
+
+void *AbstractTestSuite::qt_metacast(const char *_clname)
+{
+ if (!_clname) return 0;
+ if (!strcmp(_clname, staticMetaObject.d.stringdata))
+ return static_cast<void*>(const_cast<AbstractTestSuite*>(this));
+ return QObject::qt_metacast(_clname);
+}
+
+int AbstractTestSuite::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ _id = QObject::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ if (_c == QMetaObject::InvokeMetaMethod) {
+ switch (_id) {
+ case 0:
+ initTestCase();
+ break;
+ case 1:
+ cleanupTestCase();
+ break;
+ default:
+ // If another method is added above, this offset must be adjusted.
+ runTestFunction(_id - 2);
+ }
+ _id -= staticMetaObject.methodCount() - staticMetaObject.methodOffset();
+ }
+ return _id;
+}
+
+AbstractTestSuite::AbstractTestSuite(const QByteArray &className,
+ const QString &defaultTestsPath,
+ const QString &defaultConfigPath)
+ : shouldGenerateExpectedFailures(false),
+ metaBuilder(new TestMetaObjectBuilder(className, &QObject::staticMetaObject))
+{
+ QString testConfigPath = qgetenv("QTSCRIPT_TEST_CONFIG_DIR");
+ if (testConfigPath.isEmpty())
+ testConfigPath = defaultConfigPath;
+ QString configSuffix = qgetenv("QTSCRIPT_TEST_CONFIG_SUFFIX");
+ skipConfigPath = QString::fromLatin1("%0/skip%1.txt")
+ .arg(testConfigPath).arg(configSuffix);
+ expectFailConfigPath = QString::fromLatin1("%0/expect_fail%1.txt")
+ .arg(testConfigPath).arg(configSuffix);
+
+ QString testsPath = qgetenv("QTSCRIPT_TEST_DIR");
+ if (testsPath.isEmpty())
+ testsPath = defaultTestsPath;
+ testsDir = QDir(testsPath);
+
+ addTestFunction("initTestCase");
+ addTestFunction("cleanupTestCase");
+
+ // Subclass constructors should add their custom test functions to
+ // the meta-object and call finalizeMetaObject().
+}
+
+AbstractTestSuite::~AbstractTestSuite()
+{
+ delete metaBuilder;
+}
+
+void AbstractTestSuite::addTestFunction(const QString &name,
+ DataFunctionCreation dfc)
+{
+ if (dfc == CreateDataFunction) {
+ QString dataSignature = QString::fromLatin1("%0_data()").arg(name);
+ metaBuilder->appendPrivateVoidSlot(dataSignature);
+ }
+ QString signature = QString::fromLatin1("%0()").arg(name);
+ metaBuilder->appendPrivateVoidSlot(signature);
+}
+
+void AbstractTestSuite::finalizeMetaObject()
+{
+ metaBuilder->assignContents(staticMetaObject);
+}
+
+void AbstractTestSuite::initTestCase()
+{
+ if (!testsDir.exists()) {
+ QString message = QString::fromLatin1("tests directory (%0) doesn't exist.")
+ .arg(testsDir.path());
+ QFAIL(qPrintable(message));
+ return;
+ }
+
+ if (QFileInfo(skipConfigPath).exists())
+ TestConfigParser::parse(skipConfigPath, TestConfig::Skip, this);
+ else
+ createSkipConfigFile();
+
+ if (QFileInfo(expectFailConfigPath).exists())
+ TestConfigParser::parse(expectFailConfigPath, TestConfig::ExpectFail, this);
+ else
+ shouldGenerateExpectedFailures = true;
+}
+
+void AbstractTestSuite::cleanupTestCase()
+{
+ if (shouldGenerateExpectedFailures)
+ createExpectFailConfigFile();
+}
+
+void AbstractTestSuite::configError(const QString &path, const QString &message, int lineNumber)
+{
+ QString output;
+ output.append(path);
+ if (lineNumber != -1)
+ output.append(":").append(QString::number(lineNumber));
+ output.append(": ").append(message);
+ QFAIL(qPrintable(output));
+}
+
+void AbstractTestSuite::createSkipConfigFile()
+{
+ QFile file(skipConfigPath);
+ if (!file.open(QIODevice::WriteOnly))
+ return;
+ QWARN(qPrintable(QString::fromLatin1("creating %0").arg(skipConfigPath)));
+ QTextStream stream(&file);
+
+ writeSkipConfigFile(stream);
+
+ file.close();
+}
+
+void AbstractTestSuite::createExpectFailConfigFile()
+{
+ QFile file(expectFailConfigPath);
+ if (!file.open(QFile::WriteOnly))
+ return;
+ QWARN(qPrintable(QString::fromLatin1("creating %0").arg(expectFailConfigPath)));
+ QTextStream stream(&file);
+
+ writeExpectFailConfigFile(stream);
+
+ file.close();
+}
+
+/*!
+ Convenience function for reading all contents of a file.
+ */
+QString AbstractTestSuite::readFile(const QString &filename)
+{
+ QFile file(filename);
+ if (!file.open(QFile::ReadOnly))
+ return QString();
+ QTextStream stream(&file);
+ stream.setCodec("UTF-8");
+ return stream.readAll();
+}
+
+/*!
+ Escapes characters in the string \a str so it's suitable for writing
+ to a config file.
+ */
+QString AbstractTestSuite::escape(const QString &str)
+{
+ return QString(str).replace("\n", "\\n");
+}
diff --git a/tests/auto/qscriptv8testsuite/abstracttestsuite.h b/tests/auto/qscriptv8testsuite/abstracttestsuite.h
new file mode 100644
index 0000000..b13c61a
--- /dev/null
+++ b/tests/auto/qscriptv8testsuite/abstracttestsuite.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTTESTSUITE_H
+#define ABSTRACTTESTSUITE_H
+
+#include <QtCore/qobject.h>
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qtextstream.h>
+
+class TestMetaObjectBuilder;
+
+namespace TestConfig {
+enum Mode {
+ Skip,
+ ExpectFail
+};
+}
+
+// For receiving callbacks from the config parser.
+class TestConfigClientInterface
+{
+public:
+ virtual ~TestConfigClientInterface() {}
+ virtual void configData(TestConfig::Mode mode,
+ const QStringList &parts) = 0;
+ virtual void configError(const QString &path,
+ const QString &message,
+ int lineNumber) = 0;
+};
+
+class AbstractTestSuite : public QObject,
+ public TestConfigClientInterface
+{
+// No Q_OBJECT macro, we implement the meta-object ourselves.
+public:
+ AbstractTestSuite(const QByteArray &className,
+ const QString &defaultTestsPath,
+ const QString &defaultConfigPath);
+ virtual ~AbstractTestSuite();
+
+ static QMetaObject staticMetaObject;
+ virtual const QMetaObject *metaObject() const;
+ virtual void *qt_metacast(const char *);
+ virtual int qt_metacall(QMetaObject::Call, int, void **argv);
+
+ static QString readFile(const QString &);
+ static QString escape(const QString &);
+
+protected:
+ enum DataFunctionCreation {
+ DontCreateDataFunction,
+ CreateDataFunction
+ };
+
+ void addTestFunction(const QString &,
+ DataFunctionCreation = DontCreateDataFunction);
+ void finalizeMetaObject();
+
+ virtual void initTestCase();
+ virtual void cleanupTestCase();
+
+ virtual void writeSkipConfigFile(QTextStream &) = 0;
+ virtual void writeExpectFailConfigFile(QTextStream &) = 0;
+
+ virtual void runTestFunction(int index) = 0;
+
+ virtual void configError(const QString &path, const QString &message, int lineNumber);
+
+ QDir testsDir;
+ bool shouldGenerateExpectedFailures;
+
+private:
+ TestMetaObjectBuilder *metaBuilder;
+ QString skipConfigPath, expectFailConfigPath;
+
+private:
+ void createSkipConfigFile();
+ void createExpectFailConfigFile();
+};
+
+#endif
diff --git a/tests/auto/qscriptv8testsuite/abstracttestsuite.pri b/tests/auto/qscriptv8testsuite/abstracttestsuite.pri
new file mode 100644
index 0000000..1de5b93
--- /dev/null
+++ b/tests/auto/qscriptv8testsuite/abstracttestsuite.pri
@@ -0,0 +1,4 @@
+SOURCES += $$PWD/abstracttestsuite.cpp
+HEADERS += $$PWD/abstracttestsuite.h
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
diff --git a/tests/auto/qscriptv8testsuite/expect_fail.txt b/tests/auto/qscriptv8testsuite/expect_fail.txt
new file mode 100644
index 0000000..a4eee73
--- /dev/null
+++ b/tests/auto/qscriptv8testsuite/expect_fail.txt
@@ -0,0 +1,16 @@
+# testcase | actual | expected | message
+arguments-enum | 2 | 0
+const-redecl | undefined | TypeError | local:'const x; var x'
+date-parse | NaN | 946713600000 | Sat, 01-Jan-2000 08:00:00 GMT+00:00
+delete-global-properties | true | false
+delete | false | true | delete 100
+function-arguments-null | false | true
+function-caller | null | function eval() {\n [native code]\n}
+function-prototype | prototype | disconnectconnect
+global-const-var-conflicts | false | true
+number-tostring | 0 | 0.0000a7c5ac471b4788
+parse-int-float | 1e+21 | 1
+regexp | false | true
+string-lastindexof | 0 | -1
+string-split | 4 | 3 | 19 - array length
+substr | abcdefghijklmn |
diff --git a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro
index 00e2e01..e1c6234 100644
--- a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro
+++ b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro
@@ -2,3 +2,4 @@ load(qttest_p4)
QT = core script
SOURCES += tst_qscriptv8testsuite.cpp
RESOURCES += qscriptv8testsuite.qrc
+include(abstracttestsuite.pri)
diff --git a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc
index a894ee5..150ccf0 100644
--- a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc
+++ b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc
@@ -1,5 +1,7 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>tests</file>
+ <file>expect_fail.txt</file>
+ <file>skip.txt</file>
</qresource>
</RCC>
diff --git a/tests/auto/qscriptv8testsuite/skip.txt b/tests/auto/qscriptv8testsuite/skip.txt
new file mode 100644
index 0000000..3c2cc53
--- /dev/null
+++ b/tests/auto/qscriptv8testsuite/skip.txt
@@ -0,0 +1,17 @@
+# testcase | message
+debug-* | not applicable
+mirror-* | not applicable
+array-concat | Hangs on JSC backend
+array-splice | Hangs on JSC backend
+sparse-array-reverse | Hangs on JSC backend
+string-case | V8-specific behavior? (Doesn't pass on SpiderMonkey either)
+
+[Q_OS_WINCE]
+deep-recursion | Demands too much memory on WinCE
+nested-repetition-count-overflow | Demands too much memory on WinCE
+unicode-test | Demands too much memory on WinCE
+mul-exhaustive | Demands too much memory on WinCE
+
+[Q_OS_SYMBIAN]
+nested-repetition-count-overflow | Demands too much memory on Symbian
+unicode-test | Demands too much memory on Symbian
diff --git a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp
index 7d0858e..b35fd06 100644
--- a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp
+++ b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp
@@ -40,68 +40,33 @@
****************************************************************************/
+#include "abstracttestsuite.h"
#include <QtTest/QtTest>
-#include <QByteArray>
-
#include <QtScript>
//TESTED_CLASS=
//TESTED_FILES=
-// Uncomment the following define to have the autotest generate
-// addExpectedFailure() code for all the tests that fail.
-// This is useful when a whole new test (sub)suite is added.
-// The code is stored in addexpectedfailures.cpp.
-// Paste the contents into this file after the existing
-// addExpectedFailure() calls.
-
-//#define GENERATE_ADDEXPECTEDFAILURE_CODE
-
-static QString readFile(const QString &filename)
-{
- QFile file(filename);
- if (!file.open(QFile::ReadOnly))
- return QString();
- QTextStream stream(&file);
- stream.setCodec("UTF-8");
- return stream.readAll();
-}
-
-static void appendCString(QVector<char> *v, const char *s)
-{
- char c;
- do {
- c = *(s++);
- *v << c;
- } while (c != '\0');
-}
-
-struct ExpectedFailure
+class tst_QScriptV8TestSuite : public AbstractTestSuite
{
- ExpectedFailure(const QString &name, const QString &act,
- const QString &exp, const QString &msg)
- : testName(name), actual(act), expected(exp), message(msg)
- { }
-
- QString testName;
- QString actual;
- QString expected;
- QString message;
-};
-
-class tst_Suite : public QObject
-{
-
public:
- tst_Suite();
- virtual ~tst_Suite();
+ tst_QScriptV8TestSuite();
+ virtual ~tst_QScriptV8TestSuite();
+
+protected:
+ struct ExpectedFailure
+ {
+ ExpectedFailure(const QString &name, const QString &act,
+ const QString &exp, const QString &msg)
+ : testName(name), actual(act), expected(exp), message(msg)
+ { }
+
+ QString testName;
+ QString actual;
+ QString expected;
+ QString message;
+ };
- static QMetaObject staticMetaObject;
- virtual const QMetaObject *metaObject() const;
- virtual void *qt_metacast(const char *);
- virtual int qt_metacall(QMetaObject::Call, int, void **argv);
-
-private:
void addExpectedFailure(const QString &testName, const QString &actual,
const QString &expected, const QString &message);
bool isExpectedFailure(const QString &testName, const QString &actual,
@@ -110,34 +75,23 @@ private:
void addTestExclusion(const QRegExp &rx, const QString &message);
bool isExcludedTest(const QString &testName, QString *message) const;
- QDir testsDir;
+ virtual void initTestCase();
+ virtual void configData(TestConfig::Mode mode, const QStringList &parts);
+ virtual void writeSkipConfigFile(QTextStream &);
+ virtual void writeExpectFailConfigFile(QTextStream &);
+ virtual void runTestFunction(int testIndex);
+
QStringList testNames;
QList<ExpectedFailure> expectedFailures;
QList<QPair<QRegExp, QString> > testExclusions;
QString mjsunitContents;
-#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE
- QString generatedAddExpectedFailureCode;
-#endif
};
-QMetaObject tst_Suite::staticMetaObject;
-
-Q_GLOBAL_STATIC(QVector<uint>, qt_meta_data_tst_Suite)
-Q_GLOBAL_STATIC(QVector<char>, qt_meta_stringdata_tst_Suite)
-
-const QMetaObject *tst_Suite::metaObject() const
-{
- return &staticMetaObject;
-}
-
-void *tst_Suite::qt_metacast(const char *_clname)
-{
- if (!_clname) return 0;
- if (!strcmp(_clname, qt_meta_stringdata_tst_Suite()->constData()))
- return static_cast<void*>(const_cast<tst_Suite*>(this));
- return QObject::qt_metacast(_clname);
-}
-
+// We expect failing tests to call the fail() function (defined in
+// mjsunit.js) with arguments expected, actual, message_opt. This
+// function intercepts the call, calls the real fail() function (which
+// will throw an exception), and sets the original arguments on the
+// exception object so that we can process them later.
static QScriptValue qscript_fail(QScriptContext *ctx, QScriptEngine *eng)
{
QScriptValue realFail = ctx->callee().data();
@@ -146,193 +100,141 @@ static QScriptValue qscript_fail(QScriptContext *ctx, QScriptEngine *eng)
Q_ASSERT(eng->hasUncaughtException());
ret.setProperty("expected", ctx->argument(0));
ret.setProperty("actual", ctx->argument(1));
+ ret.setProperty("message", ctx->argument(2));
QScriptContextInfo info(ctx->parentContext()->parentContext());
ret.setProperty("lineNumber", info.lineNumber());
return ret;
}
-int tst_Suite::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+void tst_QScriptV8TestSuite::writeSkipConfigFile(QTextStream &stream)
{
- _id = QObject::qt_metacall(_c, _id, _a);
- if (_id < 0)
- return _id;
- if (_c == QMetaObject::InvokeMetaMethod) {
- QString name = testNames.at(_id);
- QString path = testsDir.absoluteFilePath(name + ".js");
- QString excludeMessage;
- if (isExcludedTest(name, &excludeMessage)) {
- QTest::qSkip(excludeMessage.toLatin1(), QTest::SkipAll, path.toLatin1(), -1);
- } else {
- QScriptEngine engine;
- engine.evaluate(mjsunitContents).toString();
- if (engine.hasUncaughtException()) {
- QStringList bt = engine.uncaughtExceptionBacktrace();
- QString err = engine.uncaughtException().toString();
- qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
- } else {
- QScriptValue fakeFail = engine.newFunction(qscript_fail);
- fakeFail.setData(engine.globalObject().property("fail"));
- engine.globalObject().setProperty("fail", fakeFail);
- QString contents = readFile(path);
- QScriptValue ret = engine.evaluate(contents);
- if (engine.hasUncaughtException()) {
- if (!ret.isError()) {
- Q_ASSERT(ret.instanceOf(engine.globalObject().property("MjsUnitAssertionError")));
- QString actual = ret.property("actual").toString();
- QString expected = ret.property("expected").toString();
- int lineNumber = ret.property("lineNumber").toInt32();
- QString failMessage;
- if (isExpectedFailure(name, actual, expected, &failMessage)) {
- QTest::qExpectFail("", failMessage.toLatin1(),
- QTest::Continue, path.toLatin1(),
- lineNumber);
- }
-#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE
- else {
- generatedAddExpectedFailureCode.append(
- " addExpectedFailure(\"" + name
- + "\", \"" + actual + "\", \"" + expected
- + "\", willFixInNextReleaseMessage);\n");
- }
-#endif
- QTest::qCompare(actual, expected, "actual", "expect",
- path.toLatin1(), lineNumber);
- } else {
- int lineNumber = ret.property("lineNumber").toInt32();
- QTest::qExpectFail("", ret.toString().toLatin1(),
- QTest::Continue, path.toLatin1(), lineNumber);
- QTest::qVerify(false, ret.toString().toLatin1(), "", path.toLatin1(), lineNumber);
- }
- }
- }
- }
- _id -= testNames.size();
- }
- return _id;
+ stream << QString::fromLatin1("# testcase | message") << endl;
}
-tst_Suite::tst_Suite()
+void tst_QScriptV8TestSuite::writeExpectFailConfigFile(QTextStream &stream)
{
- testsDir = QDir(":/tests");
- if (!testsDir.exists()) {
- qWarning("*** no tests/ dir!");
- } else {
- if (!testsDir.exists("mjsunit.js"))
- qWarning("*** no tests/mjsunit.js file!");
- else {
- mjsunitContents = readFile(testsDir.absoluteFilePath("mjsunit.js"));
- if (mjsunitContents.isEmpty())
- qWarning("*** tests/mjsunit.js is empty!");
- }
+ stream << QString::fromLatin1("# testcase | actual | expected | message") << endl;
+ for (int i = 0; i < expectedFailures.size(); ++i) {
+ const ExpectedFailure &fail = expectedFailures.at(i);
+ stream << QString::fromLatin1("%0 | %1 | %2")
+ .arg(fail.testName)
+ .arg(escape(fail.actual))
+ .arg(escape(fail.expected));
+ if (!fail.message.isEmpty())
+ stream << QString::fromLatin1(" | %0").arg(escape(fail.message));
+ stream << endl;
}
- QString willFixInNextReleaseMessage = QString::fromLatin1("Will fix in next release");
- addExpectedFailure("arguments-enum", "2", "0", willFixInNextReleaseMessage);
- addExpectedFailure("const-redecl", "undefined", "TypeError", willFixInNextReleaseMessage);
- addExpectedFailure("global-const-var-conflicts", "false", "true", willFixInNextReleaseMessage);
- addExpectedFailure("string-lastindexof", "0", "-1", "test is wrong?");
-
-#ifndef Q_OS_LINUX
- addExpectedFailure("to-precision", "1.235e+27", "1.234e+27", "QTBUG-8053: toPrecision(4) gives wrong result on Mac");
-#endif
-
-#ifdef Q_OS_SOLARIS
- addExpectedFailure("math-min-max", "Infinity", "-Infinity", willFixInNextReleaseMessage);
- addExpectedFailure("negate-zero", "false", "true", willFixInNextReleaseMessage);
- addExpectedFailure("str-to-num", "Infinity", "-Infinity", willFixInNextReleaseMessage);
-#endif
-
- addTestExclusion("debug-*", "not applicable");
- addTestExclusion("mirror-*", "not applicable");
-
- addTestExclusion("array-concat", "Hangs on JSC backend");
- addTestExclusion("array-splice", "Hangs on JSC backend");
- addTestExclusion("sparse-array-reverse", "Hangs on JSC backend");
-
- addTestExclusion("string-case", "V8-specific behavior? (Doesn't pass on SpiderMonkey either)");
-
-#ifdef Q_OS_WINCE
- addTestExclusion("deep-recursion", "Demands too much memory on WinCE");
- addTestExclusion("nested-repetition-count-overflow", "Demands too much memory on WinCE");
- addTestExclusion("unicode-test", "Demands too much memory on WinCE");
- addTestExclusion("mul-exhaustive", "Demands too much memory on WinCE");
-#endif
-
-#ifdef Q_OS_SYMBIAN
- addTestExclusion("nested-repetition-count-overflow", "Demands too much memory on Symbian");
- addTestExclusion("unicode-test", "Demands too much memory on Symbian");
-#endif
- // Failures due to switch to JSC as back-end
- addExpectedFailure("date-parse", "NaN", "946713600000", willFixInNextReleaseMessage);
- addExpectedFailure("delete-global-properties", "true", "false", willFixInNextReleaseMessage);
- addExpectedFailure("delete", "false", "true", willFixInNextReleaseMessage);
- addExpectedFailure("function-arguments-null", "false", "true", willFixInNextReleaseMessage);
- addExpectedFailure("function-caller", "null", "function eval() {\n [native code]\n}", willFixInNextReleaseMessage);
- addExpectedFailure("function-prototype", "prototype", "disconnectconnect", willFixInNextReleaseMessage);
- addExpectedFailure("number-tostring", "0", "0.0000a7c5ac471b4788", willFixInNextReleaseMessage);
- addExpectedFailure("parse-int-float", "1e+21", "1", willFixInNextReleaseMessage);
- addExpectedFailure("regexp", "false", "true", willFixInNextReleaseMessage);
- addExpectedFailure("smi-negative-zero", "-Infinity", "Infinity", willFixInNextReleaseMessage);
- addExpectedFailure("string-split", "4", "3", willFixInNextReleaseMessage);
- addExpectedFailure("substr", "abcdefghijklmn", "", willFixInNextReleaseMessage);
+}
- static const char klass[] = "tst_QScriptV8TestSuite";
+void tst_QScriptV8TestSuite::runTestFunction(int testIndex)
+{
+ QString name = testNames.at(testIndex);
+ QString path = testsDir.absoluteFilePath(name + ".js");
- QVector<uint> *data = qt_meta_data_tst_Suite();
- // content:
- *data << 1 // revision
- << 0 // classname
- << 0 << 0 // classinfo
- << 0 << 10 // methods (backpatched later)
- << 0 << 0 // properties
- << 0 << 0 // enums/sets
- ;
+ QString excludeMessage;
+ if (isExcludedTest(name, &excludeMessage)) {
+ QTest::qSkip(excludeMessage.toLatin1(), QTest::SkipAll, path.toLatin1(), -1);
+ return;
+ }
- QVector<char> *stringdata = qt_meta_stringdata_tst_Suite();
- appendCString(stringdata, klass);
- appendCString(stringdata, "");
+ QScriptEngine engine;
+ engine.evaluate(mjsunitContents);
+ if (engine.hasUncaughtException()) {
+ QStringList bt = engine.uncaughtExceptionBacktrace();
+ QString err = engine.uncaughtException().toString();
+ qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
+ } else {
+ // Prepare to intercept calls to mjsunit's fail() function.
+ QScriptValue fakeFail = engine.newFunction(qscript_fail);
+ fakeFail.setData(engine.globalObject().property("fail"));
+ engine.globalObject().setProperty("fail", fakeFail);
+
+ QString contents = readFile(path);
+ QScriptValue ret = engine.evaluate(contents);
+ if (engine.hasUncaughtException()) {
+ if (!ret.isError()) {
+ Q_ASSERT(ret.instanceOf(engine.globalObject().property("MjsUnitAssertionError")));
+ QString actual = ret.property("actual").toString();
+ QString expected = ret.property("expected").toString();
+ int lineNumber = ret.property("lineNumber").toInt32();
+ QString failMessage;
+ if (shouldGenerateExpectedFailures) {
+ if (ret.property("message").isString())
+ failMessage = ret.property("message").toString();
+ addExpectedFailure(name, actual, expected, failMessage);
+ } else if (isExpectedFailure(name, actual, expected, &failMessage)) {
+ QTest::qExpectFail("", failMessage.toLatin1(),
+ QTest::Continue, path.toLatin1(),
+ lineNumber);
+ }
+ QTest::qCompare(actual, expected, "actual", "expect",
+ path.toLatin1(), lineNumber);
+ } else {
+ int lineNumber = ret.property("lineNumber").toInt32();
+ QTest::qExpectFail("", ret.toString().toLatin1(),
+ QTest::Continue, path.toLatin1(), lineNumber);
+ QTest::qVerify(false, ret.toString().toLatin1(), "", path.toLatin1(), lineNumber);
+ }
+ }
+ }
+}
+tst_QScriptV8TestSuite::tst_QScriptV8TestSuite()
+ : AbstractTestSuite("tst_QScriptV8TestSuite",
+ ":/tests", ":/")
+{
+ // One test function per test file.
QFileInfoList testFileInfos;
testFileInfos = testsDir.entryInfoList(QStringList() << "*.js", QDir::Files);
foreach (QFileInfo tfi, testFileInfos) {
QString name = tfi.baseName();
- // slot: signature, parameters, type, tag, flags
- QString slot = QString::fromLatin1("%0()").arg(name);
- static const int nullbyte = sizeof(klass);
- *data << stringdata->size() << nullbyte << nullbyte << nullbyte << 0x08;
- appendCString(stringdata, slot.toLatin1());
+ addTestFunction(name);
testNames.append(name);
}
- (*data)[4] = testFileInfos.size();
+ finalizeMetaObject();
+}
- *data << 0; // eod
+tst_QScriptV8TestSuite::~tst_QScriptV8TestSuite()
+{
+}
- // initialize staticMetaObject
- staticMetaObject.d.superdata = &QObject::staticMetaObject;
- staticMetaObject.d.stringdata = stringdata->constData();
- staticMetaObject.d.data = data->constData();
- staticMetaObject.d.extradata = 0;
+void tst_QScriptV8TestSuite::initTestCase()
+{
+ AbstractTestSuite::initTestCase();
+
+ // FIXME: These warnings should be QFAIL, but that would make the
+ // test fail right now.
+ if (!testsDir.exists("mjsunit.js"))
+ qWarning("*** no tests/mjsunit.js file!");
+ else {
+ mjsunitContents = readFile(testsDir.absoluteFilePath("mjsunit.js"));
+ if (mjsunitContents.isEmpty())
+ qWarning("*** tests/mjsunit.js is empty!");
+ }
}
-tst_Suite::~tst_Suite()
+void tst_QScriptV8TestSuite::configData(TestConfig::Mode mode, const QStringList &parts)
{
-#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE
- if (!generatedAddExpectedFailureCode.isEmpty()) {
- QFile file("addexpectedfailures.cpp");
- file.open(QFile::WriteOnly);
- QTextStream ts(&file);
- ts << generatedAddExpectedFailureCode;
+ switch (mode) {
+ case TestConfig::Skip:
+ addTestExclusion(parts.at(0), parts.value(1));
+ break;
+
+ case TestConfig::ExpectFail:
+ addExpectedFailure(parts.at(0), parts.value(1),
+ parts.value(2), parts.value(3));
+ break;
}
-#endif
}
-void tst_Suite::addExpectedFailure(const QString &testName, const QString &actual,
+void tst_QScriptV8TestSuite::addExpectedFailure(const QString &testName, const QString &actual,
const QString &expected, const QString &message)
{
expectedFailures.append(ExpectedFailure(testName, actual, expected, message));
}
-bool tst_Suite::isExpectedFailure(const QString &testName, const QString &actual,
+bool tst_QScriptV8TestSuite::isExpectedFailure(const QString &testName, const QString &actual,
const QString &expected, QString *message) const
{
for (int i = 0; i < expectedFailures.size(); ++i) {
@@ -346,17 +248,17 @@ bool tst_Suite::isExpectedFailure(const QString &testName, const QString &actual
return false;
}
-void tst_Suite::addTestExclusion(const QString &testName, const QString &message)
+void tst_QScriptV8TestSuite::addTestExclusion(const QString &testName, const QString &message)
{
testExclusions.append(qMakePair(QRegExp(testName), message));
}
-void tst_Suite::addTestExclusion(const QRegExp &rx, const QString &message)
+void tst_QScriptV8TestSuite::addTestExclusion(const QRegExp &rx, const QString &message)
{
testExclusions.append(qMakePair(rx, message));
}
-bool tst_Suite::isExcludedTest(const QString &testName, QString *message) const
+bool tst_QScriptV8TestSuite::isExcludedTest(const QString &testName, QString *message) const
{
for (int i = 0; i < testExclusions.size(); ++i) {
if (testExclusions.at(i).first.indexIn(testName) != -1) {
@@ -368,4 +270,4 @@ bool tst_Suite::isExcludedTest(const QString &testName, QString *message) const
return false;
}
-QTEST_MAIN(tst_Suite)
+QTEST_MAIN(tst_QScriptV8TestSuite)
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
index 9014241..6686e2d 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
@@ -2328,8 +2328,7 @@ void tst_QScriptValue::getSetPrototype_invalidPrototype()
inv.setPrototype(object);
QCOMPARE(inv.prototype().isValid(), false);
object.setPrototype(inv);
- // FIXME should it be invalid or proto?
- QVERIFY(object.prototype().strictlyEquals(inv));
+ QVERIFY(object.prototype().strictlyEquals(proto));
}
void tst_QScriptValue::getSetPrototype_twoEngines()
@@ -2367,8 +2366,6 @@ void tst_QScriptValue::getSetPrototype_notObjectOrNull()
QScriptValue object = eng.newObject();
QScriptValue originalProto = object.prototype();
- QEXPECT_FAIL("", "QTBUG-15154: QScriptValue::setPrototype() allows a non-Object value to be set as prototype", Abort);
-
// bool
object.setPrototype(true);
QVERIFY(object.prototype().equals(originalProto));
diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
index 6bb971d..d26f0cd 100644
--- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
@@ -144,6 +144,8 @@ private slots:
void taskQTBUG_7537_appearsAndSort();
void taskQTBUG_7716_unnecessaryDynamicSorting();
void taskQTBUG_10287_unnecessaryMapCreation();
+ void taskQTBUG_17812_resetInvalidate_data();
+ void taskQTBUG_17812_resetInvalidate();
void testMultipleProxiesWithSelection();
void mapSelectionFromSource();
@@ -3351,5 +3353,60 @@ void tst_QSortFilterProxyModel::filteredColumns()
insertCommand->doCommand();
}
+void tst_QSortFilterProxyModel::taskQTBUG_17812_resetInvalidate_data()
+{
+ QTest::addColumn<int>("test");
+ QTest::addColumn<bool>("works");
+
+ QTest::newRow("nothing") << 0 << false;
+ QTest::newRow("reset") << 1 << true;
+ QTest::newRow("invalidate") << 2 << true;
+ QTest::newRow("invalidate_filter") << 3 << true;
+}
+
+void tst_QSortFilterProxyModel::taskQTBUG_17812_resetInvalidate()
+{
+ QFETCH(int, test);
+ QFETCH(bool, works);
+
+ struct Proxy : QSortFilterProxyModel {
+ QString pattern;
+ virtual bool filterAcceptsRow(int source_row, const QModelIndex&) const {
+ return sourceModel()->data(sourceModel()->index(source_row, 0)).toString().contains(pattern);
+ }
+ void notifyChange(int test) {
+ switch (test) {
+ case 0: break;
+ case 1: reset(); break;
+ case 2: invalidate(); break;
+ case 3: invalidateFilter(); break;
+ }
+ }
+ };
+
+ QStringListModel sourceModel(QStringList() << "Poisson" << "Vache" << "Brebis"
+ << "Elephant" << "Cochon" << "Serpent"
+ << "Mouton" << "Ecureuil" << "Mouche");
+ Proxy proxy;
+ proxy.pattern = QString::fromLatin1("n");
+ proxy.setSourceModel(&sourceModel);
+
+ QCOMPARE(proxy.rowCount(), 5);
+ for (int i = 0; i < proxy.rowCount(); i++) {
+ QVERIFY(proxy.data(proxy.index(i,0)).toString().contains('n'));
+ }
+
+ proxy.pattern = QString::fromLatin1("o");
+ proxy.notifyChange(test);
+
+ QCOMPARE(proxy.rowCount(), works ? 4 : 5);
+ bool ok = true;
+ for (int i = 0; i < proxy.rowCount(); i++) {
+ if (!proxy.data(proxy.index(i,0)).toString().contains('o'))
+ ok = false;
+ }
+ QCOMPARE(ok, works);
+}
+
QTEST_MAIN(tst_QSortFilterProxyModel)
#include "tst_qsortfilterproxymodel.moc"
diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp
index 8177d29..739f902 100644
--- a/tests/auto/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp
@@ -390,6 +390,9 @@ void tst_QSslSocket::constructing()
QSslConfiguration savedDefault = QSslConfiguration::defaultConfiguration();
// verify that changing the default config doesn't affect this socket
+ // (on Unix, the ca certs might be empty, depending on whether we load
+ // them on demand or not, so set them explicitly)
+ socket.setCaCertificates(QSslSocket::systemCaCertificates());
QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>());
QSslSocket::setDefaultCiphers(QList<QSslCipher>());
QVERIFY(!socket.caCertificates().isEmpty());
@@ -518,11 +521,6 @@ void tst_QSslSocket::sslErrors_data()
<< 993
<< (SslErrorList() << QSslError::HostNameMismatch
<< QSslError::SelfSignedCertificate);
-
- QTest::newRow("imap.trolltech.com")
- << "imap.trolltech.com"
- << 993
- << (SslErrorList() << QSslError::SelfSignedCertificateInChain);
}
void tst_QSslSocket::sslErrors()
diff --git a/tests/auto/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro b/tests/auto/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro
new file mode 100644
index 0000000..ea62865
--- /dev/null
+++ b/tests/auto/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro
@@ -0,0 +1,36 @@
+load(qttest_p4)
+
+SOURCES += tst_qsslsocket_onDemandCertificates_member.cpp
+!wince*:win32:LIBS += -lws2_32
+QT += network
+QT -= gui
+
+TARGET = tst_qsslsocket_onDemandCertificates_member
+
+win32 {
+ CONFIG(debug, debug|release) {
+ DESTDIR = debug
+} else {
+ DESTDIR = release
+ }
+}
+
+wince* {
+ DEFINES += SRCDIR=\\\"./\\\"
+
+ certFiles.files = certs ssl.tar.gz
+ certFiles.path = .
+ DEPLOYMENT += certFiles
+} else:symbian {
+ TARGET.EPOCHEAPSIZE="0x100 0x1000000"
+ TARGET.CAPABILITY=NetworkServices
+
+ certFiles.files = certs ssl.tar.gz
+ certFiles.path = .
+ DEPLOYMENT += certFiles
+ INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE # Needed for e32svr.h in S^3 envs
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
+requires(contains(QT_CONFIG,private_tests))
diff --git a/tests/auto/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp b/tests/auto/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp
new file mode 100644
index 0000000..2a1358d
--- /dev/null
+++ b/tests/auto/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp
@@ -0,0 +1,225 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 <QtNetwork>
+#include <QtTest/QtTest>
+
+#include <QNetworkProxy>
+#include <QAuthenticator>
+
+#include "private/qhostinfo_p.h"
+
+#include "../network-settings.h"
+
+#ifdef Q_OS_SYMBIAN
+#define SRCDIR ""
+#endif
+
+#ifndef QT_NO_OPENSSL
+class QSslSocketPtr: public QSharedPointer<QSslSocket>
+{
+public:
+ inline QSslSocketPtr(QSslSocket *ptr = 0)
+ : QSharedPointer<QSslSocket>(ptr)
+ { }
+
+ inline operator QSslSocket *() const { return data(); }
+};
+#endif
+
+class tst_QSslSocket_onDemandCertificates_member : public QObject
+{
+ Q_OBJECT
+
+ int proxyAuthCalled;
+
+public:
+ tst_QSslSocket_onDemandCertificates_member();
+ virtual ~tst_QSslSocket_onDemandCertificates_member();
+
+#ifndef QT_NO_OPENSSL
+ QSslSocketPtr newSocket();
+#endif
+
+public slots:
+ void initTestCase_data();
+ void init();
+ void cleanup();
+ void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
+
+#ifndef QT_NO_OPENSSL
+private slots:
+ void onDemandRootCertLoadingMemberMethods();
+
+private:
+ QSslSocket *socket;
+#endif // QT_NO_OPENSSL
+};
+
+tst_QSslSocket_onDemandCertificates_member::tst_QSslSocket_onDemandCertificates_member()
+{
+ Q_SET_DEFAULT_IAP
+}
+
+tst_QSslSocket_onDemandCertificates_member::~tst_QSslSocket_onDemandCertificates_member()
+{
+}
+
+enum ProxyTests {
+ NoProxy = 0x00,
+ Socks5Proxy = 0x01,
+ HttpProxy = 0x02,
+ TypeMask = 0x0f,
+
+ NoAuth = 0x00,
+ AuthBasic = 0x10,
+ AuthNtlm = 0x20,
+ AuthMask = 0xf0
+};
+
+void tst_QSslSocket_onDemandCertificates_member::initTestCase_data()
+{
+ QTest::addColumn<bool>("setProxy");
+ QTest::addColumn<int>("proxyType");
+
+ QTest::newRow("WithoutProxy") << false << 0;
+ QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy);
+ QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic);
+
+ QTest::newRow("WithHttpProxy") << true << int(HttpProxy);
+ QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic);
+ // uncomment the line below when NTLM works
+// QTest::newRow("WithHttpProxyNtlmAuth") << true << int(HttpProxy | AuthNtlm);
+}
+
+void tst_QSslSocket_onDemandCertificates_member::init()
+{
+ QFETCH_GLOBAL(bool, setProxy);
+ if (setProxy) {
+ QFETCH_GLOBAL(int, proxyType);
+ QString testServer = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString();
+ QNetworkProxy proxy;
+
+ switch (proxyType) {
+ case Socks5Proxy:
+ proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1080);
+ break;
+
+ case Socks5Proxy | AuthBasic:
+ proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1081);
+ break;
+
+ case HttpProxy | NoAuth:
+ proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3128);
+ break;
+
+ case HttpProxy | AuthBasic:
+ proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3129);
+ break;
+
+ case HttpProxy | AuthNtlm:
+ proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3130);
+ break;
+ }
+ QNetworkProxy::setApplicationProxy(proxy);
+ }
+
+ qt_qhostinfo_clear_cache();
+}
+
+void tst_QSslSocket_onDemandCertificates_member::cleanup()
+{
+ QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
+}
+
+#ifndef QT_NO_OPENSSL
+QSslSocketPtr tst_QSslSocket_onDemandCertificates_member::newSocket()
+{
+ QSslSocket *socket = new QSslSocket;
+
+ proxyAuthCalled = 0;
+ connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
+ SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
+ Qt::DirectConnection);
+
+ return QSslSocketPtr(socket);
+}
+#endif
+
+void tst_QSslSocket_onDemandCertificates_member::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
+{
+ ++proxyAuthCalled;
+ auth->setUser("qsockstest");
+ auth->setPassword("password");
+}
+
+#ifndef QT_NO_OPENSSL
+
+void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMethods()
+{
+ QString host("qt.nokia.com");
+
+ // not using any root certs -> should not work
+ QSslSocketPtr socket2 = newSocket();
+ this->socket = socket2;
+ socket2->setCaCertificates(QList<QSslCertificate>());
+ socket2->connectToHostEncrypted(host, 443);
+ QVERIFY(!socket2->waitForEncrypted());
+
+ // default: using on demand loading -> should work
+ QSslSocketPtr socket = newSocket();
+ this->socket = socket;
+ socket->connectToHostEncrypted(host, 443);
+ QVERIFY(socket->waitForEncrypted());
+
+ // not using any root certs again -> should not work
+ QSslSocketPtr socket3 = newSocket();
+ this->socket = socket3;
+ socket3->setCaCertificates(QList<QSslCertificate>());
+ socket3->connectToHostEncrypted(host, 443);
+ QVERIFY(!socket3->waitForEncrypted());
+}
+
+#endif // QT_NO_OPENSSL
+
+QTEST_MAIN(tst_QSslSocket_onDemandCertificates_member)
+#include "tst_qsslsocket_onDemandCertificates_member.moc"
diff --git a/tests/auto/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro b/tests/auto/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro
new file mode 100644
index 0000000..13990cb
--- /dev/null
+++ b/tests/auto/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro
@@ -0,0 +1,36 @@
+load(qttest_p4)
+
+SOURCES += tst_qsslsocket_onDemandCertificates_static.cpp
+!wince*:win32:LIBS += -lws2_32
+QT += network
+QT -= gui
+
+TARGET = tst_qsslsocket_onDemandCertificates_static
+
+win32 {
+ CONFIG(debug, debug|release) {
+ DESTDIR = debug
+} else {
+ DESTDIR = release
+ }
+}
+
+wince* {
+ DEFINES += SRCDIR=\\\"./\\\"
+
+ certFiles.files = certs ssl.tar.gz
+ certFiles.path = .
+ DEPLOYMENT += certFiles
+} else:symbian {
+ TARGET.EPOCHEAPSIZE="0x100 0x1000000"
+ TARGET.CAPABILITY=NetworkServices
+
+ certFiles.files = certs ssl.tar.gz
+ certFiles.path = .
+ DEPLOYMENT += certFiles
+ INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE # Needed for e32svr.h in S^3 envs
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
+requires(contains(QT_CONFIG,private_tests))
diff --git a/tests/auto/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp b/tests/auto/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp
new file mode 100644
index 0000000..8259977
--- /dev/null
+++ b/tests/auto/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 <QtNetwork>
+#include <QtTest/QtTest>
+
+#include <QNetworkProxy>
+#include <QAuthenticator>
+
+#include "private/qhostinfo_p.h"
+
+#include "../network-settings.h"
+
+#ifdef Q_OS_SYMBIAN
+#define SRCDIR ""
+#endif
+
+#ifndef QT_NO_OPENSSL
+class QSslSocketPtr: public QSharedPointer<QSslSocket>
+{
+public:
+ inline QSslSocketPtr(QSslSocket *ptr = 0)
+ : QSharedPointer<QSslSocket>(ptr)
+ { }
+
+ inline operator QSslSocket *() const { return data(); }
+};
+#endif
+
+class tst_QSslSocket_onDemandCertificates_static : public QObject
+{
+ Q_OBJECT
+
+ int proxyAuthCalled;
+
+public:
+ tst_QSslSocket_onDemandCertificates_static();
+ virtual ~tst_QSslSocket_onDemandCertificates_static();
+
+#ifndef QT_NO_OPENSSL
+ QSslSocketPtr newSocket();
+#endif
+
+public slots:
+ void initTestCase_data();
+ void init();
+ void cleanup();
+ void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
+
+#ifndef QT_NO_OPENSSL
+private slots:
+ void onDemandRootCertLoadingStaticMethods();
+
+private:
+ QSslSocket *socket;
+#endif // QT_NO_OPENSSL
+};
+
+tst_QSslSocket_onDemandCertificates_static::tst_QSslSocket_onDemandCertificates_static()
+{
+ Q_SET_DEFAULT_IAP
+}
+
+tst_QSslSocket_onDemandCertificates_static::~tst_QSslSocket_onDemandCertificates_static()
+{
+}
+
+enum ProxyTests {
+ NoProxy = 0x00,
+ Socks5Proxy = 0x01,
+ HttpProxy = 0x02,
+ TypeMask = 0x0f,
+
+ NoAuth = 0x00,
+ AuthBasic = 0x10,
+ AuthNtlm = 0x20,
+ AuthMask = 0xf0
+};
+
+void tst_QSslSocket_onDemandCertificates_static::initTestCase_data()
+{
+ QTest::addColumn<bool>("setProxy");
+ QTest::addColumn<int>("proxyType");
+
+ QTest::newRow("WithoutProxy") << false << 0;
+ QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy);
+ QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic);
+
+ QTest::newRow("WithHttpProxy") << true << int(HttpProxy);
+ QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic);
+ // uncomment the line below when NTLM works
+// QTest::newRow("WithHttpProxyNtlmAuth") << true << int(HttpProxy | AuthNtlm);
+}
+
+void tst_QSslSocket_onDemandCertificates_static::init()
+{
+ QFETCH_GLOBAL(bool, setProxy);
+ if (setProxy) {
+ QFETCH_GLOBAL(int, proxyType);
+ QString testServer = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString();
+ QNetworkProxy proxy;
+
+ switch (proxyType) {
+ case Socks5Proxy:
+ proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1080);
+ break;
+
+ case Socks5Proxy | AuthBasic:
+ proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1081);
+ break;
+
+ case HttpProxy | NoAuth:
+ proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3128);
+ break;
+
+ case HttpProxy | AuthBasic:
+ proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3129);
+ break;
+
+ case HttpProxy | AuthNtlm:
+ proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3130);
+ break;
+ }
+ QNetworkProxy::setApplicationProxy(proxy);
+ }
+
+ qt_qhostinfo_clear_cache();
+}
+
+void tst_QSslSocket_onDemandCertificates_static::cleanup()
+{
+ QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
+}
+
+#ifndef QT_NO_OPENSSL
+QSslSocketPtr tst_QSslSocket_onDemandCertificates_static::newSocket()
+{
+ QSslSocket *socket = new QSslSocket;
+
+ proxyAuthCalled = 0;
+ connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
+ SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
+ Qt::DirectConnection);
+
+ return QSslSocketPtr(socket);
+}
+#endif
+
+void tst_QSslSocket_onDemandCertificates_static::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
+{
+ ++proxyAuthCalled;
+ auth->setUser("qsockstest");
+ auth->setPassword("password");
+}
+
+#ifndef QT_NO_OPENSSL
+
+void tst_QSslSocket_onDemandCertificates_static::onDemandRootCertLoadingStaticMethods()
+{
+ QString host("qt.nokia.com");
+
+ // not using any root certs -> should not work
+ QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>());
+ QSslSocketPtr socket = newSocket();
+ this->socket = socket;
+ socket->connectToHostEncrypted(host, 443);
+ QVERIFY(!socket->waitForEncrypted());
+
+ // using system root certs -> should work
+ QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());
+ QSslSocketPtr socket2 = newSocket();
+ this->socket = socket2;
+ socket2->connectToHostEncrypted(host, 443);
+ QVERIFY(socket2->waitForEncrypted());
+
+ // not using any root certs again -> should not work
+ QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>());
+ QSslSocketPtr socket3 = newSocket();
+ this->socket = socket3;
+ socket3->connectToHostEncrypted(host, 443);
+ QVERIFY(!socket3->waitForEncrypted());
+}
+
+#endif // QT_NO_OPENSSL
+
+QTEST_MAIN(tst_QSslSocket_onDemandCertificates_static)
+#include "tst_qsslsocket_onDemandCertificates_static.moc"
diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp
index d1b615e..0a14e4a 100644
--- a/tests/auto/qtextlayout/tst_qtextlayout.cpp
+++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp
@@ -124,8 +124,8 @@ private slots:
void testLineBreakingAllSpaces();
void lineWidthFromBOM();
void textWidthVsWIdth();
-
void textWithSurrogates_qtbug15679();
+ void textWidthWithStackedTextEngine();
private:
QFont testFont;
@@ -1432,5 +1432,16 @@ void tst_QTextLayout::textWithSurrogates_qtbug15679()
QCOMPARE(x[2] - x[0], x[5] - x[3]);
}
+void tst_QTextLayout::textWidthWithStackedTextEngine()
+{
+ QString text = QString::fromUtf8("คลิก ถัดไป เพื่อดำเนินการต่อ");
+ QTextLayout layout(text);
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ layout.endLayout();
+ QFontMetricsF fm(layout.font());
+ QCOMPARE(line.naturalTextWidth(), fm.width(text));
+}
+
QTEST_MAIN(tst_QTextLayout)
#include "tst_qtextlayout.moc"
diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp
index 6cff7c53..c2acc18 100644
--- a/tests/auto/qtimer/tst_qtimer.cpp
+++ b/tests/auto/qtimer/tst_qtimer.cpp
@@ -50,6 +50,8 @@
#include <unistd.h>
#endif
+#include "../../shared/util.h"
+
//TESTED_CLASS=
//TESTED_FILES=
@@ -272,9 +274,9 @@ void tst_QTimer::livelock()
QFETCH(int, interval);
LiveLockTester tester(interval);
QTest::qWait(180); // we have to use wait here, since we're testing timers with a non-zero timeout
- QCOMPARE(tester.timeoutsForFirst, 1);
+ QTRY_COMPARE(tester.timeoutsForFirst, 1);
QCOMPARE(tester.timeoutsForExtra, 0);
- QCOMPARE(tester.timeoutsForSecond, 1);
+ QTRY_COMPARE(tester.timeoutsForSecond, 1);
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
if (QSysInfo::WindowsVersion < QSysInfo::WV_XP)
QEXPECT_FAIL("non-zero timer", "Multimedia timers are not available on Windows 2000", Continue);
@@ -724,7 +726,7 @@ void tst_QTimer::QTBUG13633_dontBlockEvents()
{
DontBlockEvents t;
QTest::qWait(60);
- QVERIFY(t.total > 2);
+ QTRY_VERIFY(t.total > 2);
}
class SlotRepeater : public QObject {
diff --git a/tests/auto/qvolatileimage/qvolatileimage.pro b/tests/auto/qvolatileimage/qvolatileimage.pro
new file mode 100644
index 0000000..5a0a613
--- /dev/null
+++ b/tests/auto/qvolatileimage/qvolatileimage.pro
@@ -0,0 +1,7 @@
+load(qttest_p4)
+SOURCES += tst_qvolatileimage.cpp
+
+symbian {
+ TARGET.EPOCHEAPSIZE = 0x200000 0x800000
+ LIBS += -lfbscli
+}
diff --git a/tests/auto/qvolatileimage/tst_qvolatileimage.cpp b/tests/auto/qvolatileimage/tst_qvolatileimage.cpp
new file mode 100644
index 0000000..b91a150
--- /dev/null
+++ b/tests/auto/qvolatileimage/tst_qvolatileimage.cpp
@@ -0,0 +1,403 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 <QtTest/QtTest>
+#include <QtGui/qpainter.h>
+#include <QtGui/qpaintengine.h>
+#include <QtGui/private/qvolatileimage_p.h>
+#ifdef Q_OS_SYMBIAN
+#include <fbs.h>
+#endif
+
+class tst_QVolatileImage : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QVolatileImage() { }
+
+private slots:
+ void create();
+ void ensureFormat();
+ void dataAccess();
+ void sharing();
+ void paint();
+ void fill();
+ void copy();
+ void bitmap();
+};
+
+void tst_QVolatileImage::create()
+{
+ QVolatileImage nullImg;
+ QVERIFY(nullImg.isNull());
+
+ QVolatileImage img(100, 200, QImage::Format_ARGB32);
+ QVERIFY(!img.isNull());
+ QCOMPARE(img.width(), 100);
+ QCOMPARE(img.height(), 200);
+ QCOMPARE(img.format(), QImage::Format_ARGB32);
+ QCOMPARE(img.byteCount(), img.bytesPerLine() * img.height());
+ QCOMPARE(img.hasAlphaChannel(), true);
+ QCOMPARE(img.depth(), 32);
+
+ QImage source(12, 23, QImage::Format_ARGB32_Premultiplied);
+ img = QVolatileImage(source);
+ QVERIFY(!img.isNull());
+ QCOMPARE(img.width(), 12);
+ QCOMPARE(img.height(), 23);
+ QCOMPARE(img.format(), source.format());
+ QCOMPARE(img.byteCount(), img.bytesPerLine() * img.height());
+ QVERIFY(img.imageRef() == source);
+ QVERIFY(img.toImage() == source);
+ QCOMPARE(img.hasAlphaChannel(), true);
+ QCOMPARE(img.hasAlphaChannel(), img.imageRef().hasAlphaChannel());
+ QCOMPARE(img.hasAlphaChannel(), img.toImage().hasAlphaChannel());
+ QCOMPARE(img.depth(), 32);
+
+#ifdef Q_OS_SYMBIAN
+ CFbsBitmap *bmp = new CFbsBitmap;
+ QVERIFY(bmp->Create(TSize(100, 50), EColor16MAP) == KErrNone);
+ QVolatileImage bmpimg(bmp);
+ QVERIFY(!bmpimg.isNull());
+ QCOMPARE(bmpimg.width(), 100);
+ QCOMPARE(bmpimg.height(), 50);
+ // Verify that we only did handle duplication, not pixel data copying.
+ QCOMPARE(bmpimg.constBits(), (const uchar *) bmp->DataAddress());
+ delete bmp;
+ // Check if content is still valid.
+ QImage copyimg = bmpimg.toImage();
+ QCOMPARE(copyimg.format(), QImage::Format_ARGB32_Premultiplied);
+#endif
+}
+
+void tst_QVolatileImage::ensureFormat()
+{
+ QImage source(12, 23, QImage::Format_ARGB32_Premultiplied);
+ QVolatileImage img(source);
+ QVERIFY(!img.isNull());
+ QVERIFY(img.imageRef() == source);
+ QVERIFY(img.toImage() == source);
+
+ QVERIFY(img.ensureFormat(QImage::Format_ARGB32_Premultiplied)); // no-op
+ QVERIFY(img.imageRef() == source);
+ QVERIFY(img.toImage() == source);
+ QVERIFY(img.format() == QImage::Format_ARGB32_Premultiplied);
+
+ QVERIFY(img.ensureFormat(QImage::Format_RGB32)); // new data under-the-hood
+ QVERIFY(img.imageRef() != source);
+ QVERIFY(img.toImage() != source);
+ QVERIFY(img.format() == QImage::Format_RGB32);
+
+#ifdef Q_OS_SYMBIAN
+ CFbsBitmap *bmp = new CFbsBitmap;
+ QVERIFY(bmp->Create(TSize(100, 50), EColor16MAP) == KErrNone);
+ QVolatileImage bmpimg(bmp);
+ QVERIFY(bmpimg.ensureFormat(QImage::Format_ARGB32_Premultiplied)); // no-op
+ QCOMPARE(bmpimg.constBits(), (const uchar *) bmp->DataAddress());
+
+ // A different format should cause data copying.
+ QVERIFY(bmpimg.ensureFormat(QImage::Format_RGB32));
+ QVERIFY(bmpimg.constBits() != (const uchar *) bmp->DataAddress());
+ const uchar *prevBits = bmpimg.constBits();
+
+ QVERIFY(bmpimg.ensureFormat(QImage::Format_RGB16));
+ QVERIFY(bmpimg.constBits() != (const uchar *) bmp->DataAddress());
+ QVERIFY(bmpimg.constBits() != prevBits);
+ prevBits = bmpimg.constBits();
+
+ QVERIFY(bmpimg.ensureFormat(QImage::Format_MonoLSB));
+ QVERIFY(bmpimg.constBits() != (const uchar *) bmp->DataAddress());
+ QVERIFY(bmpimg.constBits() != prevBits);
+
+ delete bmp;
+#endif
+}
+
+void tst_QVolatileImage::dataAccess()
+{
+ QImage source(12, 23, QImage::Format_ARGB32_Premultiplied);
+ QVolatileImage img(source);
+ QVERIFY(!img.isNull());
+ img.beginDataAccess();
+ QVERIFY(img.constBits());
+ QVERIFY(img.imageRef().constBits());
+ QVERIFY(img.bits());
+ QVERIFY(img.imageRef().bits());
+ img.endDataAccess();
+
+ img = QVolatileImage(12, 23, QImage::Format_ARGB32);
+ img.beginDataAccess();
+ QVERIFY(img.constBits() && img.bits());
+ img.endDataAccess();
+}
+
+void tst_QVolatileImage::sharing()
+{
+ QVolatileImage img1(100, 100, QImage::Format_ARGB32);
+ QVolatileImage img2 = img1;
+ img1.beginDataAccess();
+ img2.beginDataAccess();
+ QVERIFY(img1.constBits() == img2.constBits());
+ img2.endDataAccess();
+ img1.endDataAccess();
+ img1.imageRef(); // non-const call, should detach
+ img1.beginDataAccess();
+ img2.beginDataAccess();
+ QVERIFY(img1.constBits() != img2.constBits());
+ img2.endDataAccess();
+ img1.endDataAccess();
+
+ // toImage() should return a copy of the internal QImage.
+ // imageRef() is a reference to the internal QImage.
+ QVERIFY(img1.imageRef().constBits() != img1.toImage().constBits());
+
+#ifdef Q_OS_SYMBIAN
+ CFbsBitmap *bmp = new CFbsBitmap;
+ QVERIFY(bmp->Create(TSize(100, 50), EColor16MAP) == KErrNone);
+ QVolatileImage bmpimg(bmp);
+ QVolatileImage bmpimg2;
+ bmpimg2 = bmpimg;
+ QCOMPARE(bmpimg.constBits(), (const uchar *) bmp->DataAddress());
+ QCOMPARE(bmpimg2.constBits(), (const uchar *) bmp->DataAddress());
+ // Now force a detach, which should copy the pixel data under-the-hood.
+ bmpimg.imageRef();
+ QVERIFY(bmpimg.constBits() != (const uchar *) bmp->DataAddress());
+ QCOMPARE(bmpimg2.constBits(), (const uchar *) bmp->DataAddress());
+ delete bmp;
+#endif
+}
+
+bool fuzzyCompareImages(const QImage &image1, const QImage &image2, int tolerance)
+{
+ if (image1.bytesPerLine() != image2.bytesPerLine()
+ || image1.width() != image2.width()
+ || image1.height() != image2.height()) {
+ return false;
+ }
+ for (int i = 0; i < image1.height(); i++) {
+ const uchar *line1 = image1.scanLine(i);
+ const uchar *line2 = image2.scanLine(i);
+ int bytes = image1.bytesPerLine();
+ for (int j = 0; j < bytes; j++) {
+ int delta = line1[j] - line2[j];
+ if (qAbs(delta) > tolerance)
+ return false;
+ }
+ }
+ return true;
+}
+
+void tst_QVolatileImage::paint()
+{
+#ifdef Q_OS_SYMBIAN
+ QVolatileImage img(100, 100, QImage::Format_ARGB32);
+ img.beginDataAccess();
+ img.imageRef().fill(QColor(Qt::green).rgba());
+ QPainter p(&img.imageRef());
+ p.drawRect(10, 10, 50, 50);
+ p.end();
+ img.endDataAccess();
+ QImage imgA = img.toImage();
+
+ // The following assumes that on openvg the pixmapdata is backed by QVolatileImage)
+ // (and that openvg is in use)
+ // It should pass with any engine nonetheless.
+ // See if painting into the underlying QImage succeeds.
+ QPixmap pm(100, 100);
+ if (pm.paintEngine()->type() == QPaintEngine::Raster) {
+ pm.fill(Qt::green);
+ QPainter pmp(&pm);
+ pmp.drawRect(10, 10, 50, 50);
+ pmp.end();
+ QImage imgB = pm.toImage();
+ QVERIFY(fuzzyCompareImages(imgA, imgB, 0));
+ // Exercise the accelerated QVolatileImagePaintEngine::drawPixmap() a bit.
+ QPixmap targetPm(pm.size());
+ targetPm.fill(Qt::black);
+ pmp.begin(&targetPm);
+ pmp.drawPixmap(QPointF(0, 0), pm);
+ pmp.end();
+ imgB = targetPm.toImage();
+ QVERIFY(fuzzyCompareImages(imgA, imgB, 0));
+ // Now the overload taking rects.
+ targetPm.fill(Qt::black);
+ pmp.begin(&targetPm);
+ QRectF rect(QPointF(0, 0), pm.size());
+ pmp.drawPixmap(rect, pm, rect);
+ pmp.end();
+ imgB = targetPm.toImage();
+ QVERIFY(fuzzyCompareImages(imgA, imgB, 0));
+ } else {
+ QSKIP("Pixmaps not painted via raster, skipping paint test", SkipSingle);
+ }
+#endif
+}
+
+void tst_QVolatileImage::fill()
+{
+ QVolatileImage img(100, 100, QImage::Format_ARGB32_Premultiplied);
+ QColor col = QColor(10, 20, 30);
+ img.fill(col.rgba());
+ QVERIFY(img.imageRef().pixel(1, 1) == col.rgba());
+ QVERIFY(img.toImage().pixel(1, 1) == col.rgba());
+
+#ifdef Q_OS_SYMBIAN
+ CFbsBitmap *bmp = static_cast<CFbsBitmap *>(img.duplicateNativeImage());
+ QVERIFY(bmp);
+ TRgb pix;
+ bmp->GetPixel(pix, TPoint(1, 1));
+ QCOMPARE(pix.Red(), col.red());
+ QCOMPARE(pix.Green(), col.green());
+ QCOMPARE(pix.Blue(), col.blue());
+ delete bmp;
+#endif
+}
+
+void tst_QVolatileImage::copy()
+{
+ QVolatileImage img(100, 100, QImage::Format_RGB32);
+ img.beginDataAccess();
+ img.imageRef().fill(QColor(Qt::green).rgba());
+ QPainter p(&img.imageRef());
+ p.drawRect(10, 10, 50, 50);
+ p.end();
+ img.endDataAccess();
+
+ QVolatileImage img2(100, 100, QImage::Format_RGB32);
+ img2.copyFrom(&img, QRect());
+ QImage imgA = img.toImage();
+ QImage imgB = img2.toImage();
+ QCOMPARE(imgA.size(), imgB.size());
+ QVERIFY(fuzzyCompareImages(imgA, imgB, 0));
+
+ img2 = QVolatileImage(20, 20, QImage::Format_RGB32);
+ img2.copyFrom(&img, QRect(5, 5, 20, 20));
+ imgA = img.toImage().copy(5, 5, 20, 20);
+ imgB = img2.toImage();
+ QCOMPARE(imgA.size(), imgB.size());
+ QVERIFY(fuzzyCompareImages(imgA, imgB, 0));
+}
+
+void tst_QVolatileImage::bitmap()
+{
+#ifdef Q_OS_SYMBIAN
+ CFbsBitmap *bmp = new CFbsBitmap;
+ QVERIFY(bmp->Create(TSize(100, 50), EColor64K) == KErrNone);
+ QVolatileImage bmpimg(bmp);
+ CFbsBitmap *dupbmp = static_cast<CFbsBitmap *>(bmpimg.duplicateNativeImage());
+ QVERIFY(dupbmp);
+ QVERIFY(dupbmp != bmp);
+ QCOMPARE(dupbmp->DataAddress(), bmp->DataAddress());
+ delete dupbmp;
+ delete bmp;
+ bmpimg.beginDataAccess();
+ qMemSet(bmpimg.bits(), 0, bmpimg.byteCount());
+ qMemSet(bmpimg.bits(), 1, bmpimg.bytesPerLine() * bmpimg.height());
+ bmpimg.endDataAccess();
+
+ // Test bgr->rgb conversion in case of EColor16M.
+ bmp = new CFbsBitmap;
+ QVERIFY(bmp->Create(TSize(101, 89), EColor16M) == KErrNone);
+ bmp->BeginDataAccess();
+ TUint32 *addr = bmp->DataAddress();
+ uint rgb = QColor(10, 20, 30).rgb();
+ qMemCopy(bmp->DataAddress(), &rgb, 3);
+ bmp->EndDataAccess();
+ TRgb symrgb;
+ bmp->GetPixel(symrgb, TPoint(0, 0));
+ QVERIFY(symrgb.Red() == 10 && symrgb.Green() == 20 && symrgb.Blue() == 30);
+ bmpimg = QVolatileImage(bmp);
+ QVERIFY(bmpimg.toImage().pixel(0, 0) == rgb);
+ // check if there really was a conversion
+ bmp->BeginDataAccess();
+ bmpimg.beginDataAccess();
+ qMemCopy(&rgb, bmpimg.constBits(), 3);
+ uint rgb2 = rgb;
+ qMemCopy(&rgb2, bmp->DataAddress(), 3);
+ QVERIFY(rgb != rgb2);
+ bmpimg.endDataAccess(true);
+ bmp->EndDataAccess(true);
+ delete bmp;
+
+ bmp = new CFbsBitmap;
+ QVERIFY(bmp->Create(TSize(101, 89), EGray2) == KErrNone);
+ bmpimg = QVolatileImage(bmp); // inverts pixels, but should do it in place
+ QCOMPARE(bmpimg.constBits(), (const uchar *) bmp->DataAddress());
+ QCOMPARE(bmpimg.format(), QImage::Format_MonoLSB);
+ bmpimg.ensureFormat(QImage::Format_ARGB32_Premultiplied);
+ QVERIFY(bmpimg.constBits() != (const uchar *) bmp->DataAddress());
+ QCOMPARE(bmpimg.format(), QImage::Format_ARGB32_Premultiplied);
+ delete bmp;
+
+ // The following two formats must be optimal always.
+ bmp = new CFbsBitmap;
+ QVERIFY(bmp->Create(TSize(101, 89), EColor16MAP) == KErrNone);
+ bmpimg = QVolatileImage(bmp);
+ QCOMPARE(bmpimg.format(), QImage::Format_ARGB32_Premultiplied);
+ QCOMPARE(bmpimg.constBits(), (const uchar *) bmp->DataAddress());
+ bmpimg.ensureFormat(QImage::Format_ARGB32_Premultiplied);
+ QCOMPARE(bmpimg.constBits(), (const uchar *) bmp->DataAddress());
+ delete bmp;
+ bmp = new CFbsBitmap;
+ QVERIFY(bmp->Create(TSize(101, 89), EColor16MU) == KErrNone);
+ bmpimg = QVolatileImage(bmp);
+ QCOMPARE(bmpimg.format(), QImage::Format_RGB32);
+ QCOMPARE(bmpimg.constBits(), (const uchar *) bmp->DataAddress());
+ bmpimg.ensureFormat(QImage::Format_RGB32);
+ QCOMPARE(bmpimg.constBits(), (const uchar *) bmp->DataAddress());
+ delete bmp;
+
+#else
+ QSKIP("CFbsBitmap is only available on Symbian, skipping bitmap test", SkipSingle);
+#endif
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication::setGraphicsSystem("openvg");
+ QApplication app(argc, argv);
+ tst_QVolatileImage tc;
+ return QTest::qExec(&tc, argc, argv);
+}
+
+#include "tst_qvolatileimage.moc"
diff --git a/tests/benchmarks/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/benchmarks/network/ssl/qsslsocket/tst_qsslsocket.cpp
index 6cb62d0..041b61a 100644
--- a/tests/benchmarks/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/benchmarks/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -46,7 +46,7 @@
#include <qsslsocket.h>
-// #include "../../../../auto/network-settings.h"
+#include "../../../../auto/network-settings.h"
//TESTED_CLASS=
//TESTED_FILES=
@@ -65,6 +65,7 @@ public slots:
void init();
void cleanup();
private slots:
+ void rootCertLoading();
void systemCaCertificates();
};
@@ -89,6 +90,16 @@ void tst_QSslSocket::cleanup()
}
//----------------------------------------------------------------------------------
+
+void tst_QSslSocket::rootCertLoading()
+{
+ QBENCHMARK_ONCE {
+ QSslSocket socket;
+ socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
+ socket.waitForEncrypted();
+ }
+}
+
void tst_QSslSocket::systemCaCertificates()
{
// The results of this test change if the benchmarking system changes too much.
diff --git a/tests/benchmarks/script/script.pro b/tests/benchmarks/script/script.pro
index d4fc822..80278d0 100644
--- a/tests/benchmarks/script/script.pro
+++ b/tests/benchmarks/script/script.pro
@@ -13,6 +13,8 @@ SUBDIRS = \
TRUSTED_BENCHMARKS += \
qscriptclass \
qscriptvalue \
- qscriptengine
+ qscriptengine \
+ qscriptobject \
+ context2d
include(../trusted-benchmarks.pri)
diff --git a/tests/benchmarks/script/sunspider/tst_sunspider.cpp b/tests/benchmarks/script/sunspider/tst_sunspider.cpp
index 0df19b6..9e2bb6f 100644
--- a/tests/benchmarks/script/sunspider/tst_sunspider.cpp
+++ b/tests/benchmarks/script/sunspider/tst_sunspider.cpp
@@ -110,7 +110,7 @@ void tst_SunSpider::benchmark_data()
void tst_SunSpider::benchmark()
{
QFETCH(QString, testName);
- QString testContents = readFile(testsDir.absoluteFilePath(testName + ".js"));
+ QString testContents = readFile(testsDir.filePath(testName + ".js"));
QVERIFY(!testContents.isEmpty());
QScriptEngine engine;
diff --git a/tests/benchmarks/script/v8/tst_v8.cpp b/tests/benchmarks/script/v8/tst_v8.cpp
index 841e2f3..b9cb859 100644
--- a/tests/benchmarks/script/v8/tst_v8.cpp
+++ b/tests/benchmarks/script/v8/tst_v8.cpp
@@ -115,10 +115,10 @@ void tst_V8::benchmark()
{
QFETCH(QString, testName);
- QString baseDotJsContents = readFile(testsDir.absoluteFilePath("base.js"));
+ QString baseDotJsContents = readFile(testsDir.filePath("base.js"));
QVERIFY(!baseDotJsContents.isEmpty());
- QString testContents = readFile(testsDir.absoluteFilePath(testName + ".js"));
+ QString testContents = readFile(testsDir.filePath(testName + ".js"));
QVERIFY(!testContents.isEmpty());
QScriptEngine engine;
diff --git a/tools/designer/src/components/formeditor/qdesigner_resource.cpp b/tools/designer/src/components/formeditor/qdesigner_resource.cpp
index 0426b8c..714a556 100644
--- a/tools/designer/src/components/formeditor/qdesigner_resource.cpp
+++ b/tools/designer/src/components/formeditor/qdesigner_resource.cpp
@@ -2278,6 +2278,7 @@ void QDesignerResource::createResources(DomResources *resources)
path = core()->dialogGui()->getOpenFileName(dialogParent, fileDialogTitle, fi.absolutePath(), fileDialogPattern);
if (path.isEmpty())
break;
+ m_formWindow->setProperty("_q_resourcepathchanged", QVariant(true));
} else {
break;
}
diff --git a/tools/designer/src/designer/qdesigner_formwindow.cpp b/tools/designer/src/designer/qdesigner_formwindow.cpp
index 1fbdcec..4770d2a 100644
--- a/tools/designer/src/designer/qdesigner_formwindow.cpp
+++ b/tools/designer/src/designer/qdesigner_formwindow.cpp
@@ -159,6 +159,7 @@ void QDesignerFormWindow::firstShow()
if (m_editor) {
connect(m_editor, SIGNAL(fileNameChanged(QString)), this, SLOT(updateWindowTitle(QString)));
updateWindowTitle(m_editor->fileName());
+ updateChanged();
}
}
show();
diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp
index 836feb7..840667a 100644
--- a/tools/designer/src/designer/qdesigner_workbench.cpp
+++ b/tools/designer/src/designer/qdesigner_workbench.cpp
@@ -966,7 +966,9 @@ QDesignerFormWindow * QDesignerWorkbench::loadForm(const QString &fileName,
return 0;
}
*uic3Converted = editor->fileName().isEmpty();
- editor->setDirty(false);
+ // Did user specify another (missing) resource path -> set dirty.
+ const bool dirty = editor->property("_q_resourcepathchanged").toBool();
+ editor->setDirty(dirty);
resizeForm(formWindow, editor->mainContainer());
formWindowManager->setActiveFormWindow(editor);
return formWindow;
diff --git a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp
index e1c0460..ac32995 100644
--- a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp
+++ b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp
@@ -111,6 +111,8 @@ void QMeeGoGraphicsSystemHelper::switchToRaster()
QApplication *app = static_cast<QApplication *>(QCoreApplication::instance());
app->setGraphicsSystem(QLatin1String("raster"));
+ QMeeGoRuntime::invalidateLiveSurfaces();
+
QMeeGoSwitchEvent didSwitchEvent(QLatin1String("raster"), QMeeGoSwitchEvent::DidSwitch);
foreach (QWidget *widget, QApplication::topLevelWidgets())
QCoreApplication::sendEvent(widget, &didSwitchEvent);
diff --git a/tools/qmeegographicssystemhelper/qmeegoruntime.cpp b/tools/qmeegographicssystemhelper/qmeegoruntime.cpp
index c32b654..7c81d51 100644
--- a/tools/qmeegographicssystemhelper/qmeegoruntime.cpp
+++ b/tools/qmeegographicssystemhelper/qmeegoruntime.cpp
@@ -65,6 +65,7 @@ typedef bool (*QMeeGoLiveTextureReleaseFunc) (QPixmap*, QImage *i);
typedef Qt::HANDLE (*QMeeGoLiveTextureGetHandleFunc) (QPixmap*);
typedef void* (*QMeeGoCreateFenceSyncFunc) (void);
typedef void (*QMeeGoDestroyFenceSyncFunc) (void *fs);
+typedef void (*QMeeGoInvalidateLiveSurfacesFunc) (void);
static QMeeGoImageToEglSharedImageFunc qt_meego_image_to_egl_shared_image = NULL;
static QMeeGoPixmapDataFromEglSharedImageFunc qt_meego_pixmapdata_from_egl_shared_image = NULL;
@@ -81,6 +82,7 @@ static QMeeGoLiveTextureReleaseFunc qt_meego_live_texture_release = NULL;
static QMeeGoLiveTextureGetHandleFunc qt_meego_live_texture_get_handle = NULL;
static QMeeGoCreateFenceSyncFunc qt_meego_create_fence_sync = NULL;
static QMeeGoDestroyFenceSyncFunc qt_meego_destroy_fence_sync = NULL;
+static QMeeGoInvalidateLiveSurfacesFunc qt_meego_invalidate_live_surfaces = NULL;
void QMeeGoRuntime::initialize()
{
@@ -109,13 +111,14 @@ void QMeeGoRuntime::initialize()
qt_meego_live_texture_get_handle = (QMeeGoLiveTextureGetHandleFunc) library.resolve("qt_meego_live_texture_get_handle");
qt_meego_create_fence_sync = (QMeeGoCreateFenceSyncFunc) library.resolve("qt_meego_create_fence_sync");
qt_meego_destroy_fence_sync = (QMeeGoDestroyFenceSyncFunc) library.resolve("qt_meego_destroy_fence_sync");
+ qt_meego_invalidate_live_surfaces = (QMeeGoInvalidateLiveSurfacesFunc) library.resolve("qt_meego_invalidate_live_surfaces");
if (qt_meego_image_to_egl_shared_image && qt_meego_pixmapdata_from_egl_shared_image &&
qt_meego_pixmapdata_with_gl_texture && qt_meego_destroy_egl_shared_image && qt_meego_update_egl_shared_image_pixmap &&
qt_meego_set_surface_fixed_size && qt_meego_set_surface_scaling && qt_meego_set_translucent &&
qt_meego_pixmapdata_with_new_live_texture && qt_meego_pixmapdata_from_live_texture_handle &&
qt_meego_live_texture_lock && qt_meego_live_texture_release && qt_meego_live_texture_get_handle &&
- qt_meego_create_fence_sync && qt_meego_destroy_fence_sync)
+ qt_meego_create_fence_sync && qt_meego_destroy_fence_sync && qt_meego_invalidate_live_surfaces)
{
qDebug("Successfully resolved MeeGo graphics system: %s %s\n", qPrintable(libraryPrivate->fileName), qPrintable(libraryPrivate->fullVersion));
} else {
@@ -232,3 +235,10 @@ void QMeeGoRuntime::destroyFenceSync(void *fs)
Q_ASSERT(qt_meego_destroy_fence_sync);
qt_meego_destroy_fence_sync(fs);
}
+
+void QMeeGoRuntime::invalidateLiveSurfaces()
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_invalidate_live_surfaces);
+ qt_meego_invalidate_live_surfaces();
+}
diff --git a/tools/qmeegographicssystemhelper/qmeegoruntime.h b/tools/qmeegographicssystemhelper/qmeegoruntime.h
index bdc4eef..b91efae 100644
--- a/tools/qmeegographicssystemhelper/qmeegoruntime.h
+++ b/tools/qmeegographicssystemhelper/qmeegoruntime.h
@@ -62,6 +62,7 @@ public:
static Qt::HANDLE getLiveTextureHandle(QPixmap *pixmap);
static void* createFenceSync();
static void destroyFenceSync(void *fs);
+ static void invalidateLiveSurfaces();
private:
static bool initialized;
diff --git a/tools/qmeegographicssystemhelper/qmeegoswitchevent.cpp b/tools/qmeegographicssystemhelper/qmeegoswitchevent.cpp
index 0ab272f..b833e31 100644
--- a/tools/qmeegographicssystemhelper/qmeegoswitchevent.cpp
+++ b/tools/qmeegographicssystemhelper/qmeegoswitchevent.cpp
@@ -65,4 +65,4 @@ QEvent::Type QMeeGoSwitchEvent::eventNumber()
switchEventNumber = QEvent::registerEventType();
return (QEvent::Type) switchEventNumber;
-} \ No newline at end of file
+}
diff --git a/tools/qml/qml.pri b/tools/qml/qml.pri
index 2010cc1..cfc74af 100644
--- a/tools/qml/qml.pri
+++ b/tools/qml/qml.pri
@@ -26,6 +26,8 @@ symbian {
!contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) {
LIBS += -lsensrvclient -lsensrvutil
SOURCES += $$PWD/deviceorientation_symbian.cpp
+ } else {
+ SOURCES += $$PWD/deviceorientation.cpp
}
FORMS = $$PWD/recopts.ui \
$$PWD/proxysettings.ui