summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfig.tests/unix/compile.test8
-rw-r--r--config.tests/unix/icu/icu.pro5
-rwxr-xr-xconfig.tests/unix/objcopy.test29
-rw-r--r--config.tests/unix/objcopy/objcopy.cpp45
-rw-r--r--config.tests/unix/objcopy/objcopy.pro4
-rwxr-xr-xconfigure43
-rw-r--r--doc/src/snippets/qx11embedcontainer/main.cpp67
-rw-r--r--doc/src/snippets/qx11embedwidget/main.cpp61
-rw-r--r--examples/widgets/tutorials/addressbook/part5/addressbook.cpp2
-rw-r--r--examples/widgets/tutorials/addressbook/part6/addressbook.cpp2
-rw-r--r--examples/widgets/tutorials/addressbook/part7/addressbook.cpp2
-rw-r--r--mkspecs/android-g++/qmake.conf1
-rw-r--r--mkspecs/common/qcc-base-qnx.conf1
-rw-r--r--mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in2
-rw-r--r--mkspecs/features/default_post.prf4
-rw-r--r--mkspecs/features/incredibuild_xge.prf2
-rw-r--r--mkspecs/features/java.prf2
-rw-r--r--mkspecs/features/qml_plugin.prf9
-rw-r--r--mkspecs/features/qt_common.prf18
-rw-r--r--mkspecs/features/qt_functions.prf2
-rw-r--r--mkspecs/features/qt_module.prf52
-rw-r--r--mkspecs/features/qt_module_pris.prf3
-rw-r--r--mkspecs/features/qt_plugin.prf11
-rw-r--r--mkspecs/features/simd.prf2
-rw-r--r--mkspecs/features/testcase.prf2
-rw-r--r--mkspecs/features/win32/windeployqt.prf6
-rw-r--r--mkspecs/features/win32/windows.prf2
-rw-r--r--mkspecs/features/winrt/font_deployment.prf6
-rw-r--r--mkspecs/features/winrt/package_manifest.prf15
-rw-r--r--mkspecs/macx-ios-clang/features/default_post.prf6
-rw-r--r--mkspecs/qnx-armle-v7-qcc/qplatformdefs.h2
-rw-r--r--mkspecs/qnx-x86-qcc/qplatformdefs.h2
-rw-r--r--mkspecs/win32-g++/qmake.conf1
-rw-r--r--qmake/doc/src/qmake-manual.qdoc7
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp2
-rw-r--r--qmake/generators/makefile.cpp28
-rw-r--r--qmake/generators/projectgenerator.cpp27
-rw-r--r--qmake/library/qmakebuiltins.cpp18
-rw-r--r--qmake/qmake.pri3
-rw-r--r--qtbase.pro2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp2
-rw-r--r--src/angle/patches/0017-ANGLE-D3D11-Don-t-use-mipmaps-in-level-9-textures.patch31
-rw-r--r--src/corelib/animation/qabstractanimation.cpp7
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qregexp.cpp2
-rw-r--r--src/corelib/global/qglobal.h4
-rw-r--r--src/corelib/global/qlogging.cpp36
-rw-r--r--src/corelib/io/qfiledevice.cpp7
-rw-r--r--src/corelib/io/qfileinfo.cpp11
-rw-r--r--src/corelib/io/qfileselector.cpp5
-rw-r--r--src/corelib/io/qfilesystemengine.cpp4
-rw-r--r--src/corelib/io/qfilesystemiterator_p.h4
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp15
-rw-r--r--src/corelib/io/qfilesystemwatcher_polling.cpp10
-rw-r--r--src/corelib/io/qtemporarydir.cpp14
-rw-r--r--src/corelib/io/qtextstream.cpp4
-rw-r--r--src/corelib/io/qwindowspipereader.cpp1
-rw-r--r--src/corelib/io/qwindowspipewriter.cpp1
-rw-r--r--src/corelib/kernel/qcoreevent.h1
-rw-r--r--src/corelib/kernel/qmath.cpp84
-rw-r--r--src/corelib/kernel/qmath.qdoc95
-rw-r--r--src/corelib/kernel/qobject.cpp4
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp8
-rw-r--r--src/corelib/tools/qcollator.cpp5
-rw-r--r--src/corelib/tools/qdatetime.cpp21
-rw-r--r--src/corelib/tools/qregexp.cpp4
-rw-r--r--src/corelib/tools/qsize.cpp2
-rw-r--r--src/corelib/tools/tools.pri4
-rw-r--r--src/dbus/Qt5DBusMacros.cmake1
-rw-r--r--src/gui/image/qpixmap_blitter.cpp4
-rw-r--r--src/gui/kernel/qguiapplication.cpp18
-rw-r--r--src/gui/kernel/qopenglcontext.cpp3
-rw-r--r--src/gui/kernel/qopenglcontext_p.h7
-rw-r--r--src/gui/kernel/qplatformmenu.h5
-rw-r--r--src/gui/kernel/qwindow.cpp4
-rw-r--r--src/gui/opengl/qopengl.h10
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp3
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp48
-rw-r--r--src/gui/opengl/qopengltexture.cpp4
-rw-r--r--src/gui/painting/qblittable_p.h2
-rw-r--r--src/gui/painting/qdrawhelper.cpp157
-rw-r--r--src/gui/painting/qpaintengine_blitter.cpp2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp33
-rw-r--r--src/gui/painting/qpainter.cpp18
-rw-r--r--src/gui/painting/qvectorpath_p.h28
-rw-r--r--src/gui/text/qfontdatabase.cpp6
-rw-r--r--src/gui/text/qfontengine.cpp9
-rw-r--r--src/gui/text/qfontengine_ft.cpp36
-rw-r--r--src/gui/text/qfontengine_p.h2
-rw-r--r--src/gui/text/qtextlayout.cpp1
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp6
-rw-r--r--src/network/socket/qabstractsocket.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp2
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp10
-rw-r--r--src/opengl/qgl.cpp14
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience.cpp50
-rw-r--r--src/plugins/accessible/widgets/complexwidgets.cpp6
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp4
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerservice.h4
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp10
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp1
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp55
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm41
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm15
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm41
-rw-r--r--src/plugins/platforms/direct2d/direct2d.pro2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp48
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h12
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp4
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h4
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp137
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp982
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h36
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp38
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h5
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp97
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h7
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h2
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm7
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm36
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.cpp5
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.cpp23
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.h4
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterwindow.cpp5
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp10
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp25
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp89
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp23
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h5
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp22
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp106
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h4
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp31
-rw-r--r--src/sql/kernel/qsqlquery.cpp25
-rw-r--r--src/testlib/doc/src/qttestlib-manual.qdoc19
-rw-r--r--src/testlib/qtest.h10
-rw-r--r--src/testlib/qtestaccessible.h8
-rw-r--r--src/testlib/qtestcase.cpp31
-rw-r--r--src/testlib/qtestresult.cpp8
-rw-r--r--src/tools/moc/generator.cpp9
-rw-r--r--src/tools/moc/token.cpp171
-rw-r--r--src/tools/moc/token.h410
-rw-r--r--src/widgets/Qt5WidgetsConfigExtras.cmake.in2
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp77
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp4
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp2
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp2
-rw-r--r--src/widgets/itemviews/qtreeview.cpp13
-rw-r--r--src/widgets/kernel/qapplication.cpp2
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp13
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp2
-rw-r--r--src/widgets/kernel/qtooltip.cpp4
-rw-r--r--src/widgets/kernel/qwidget.cpp2
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp10
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp11
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp2
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm34
-rw-r--r--src/widgets/widgets/qfontcombobox.cpp7
-rw-r--r--src/widgets/widgets/qmacnativewidget_mac.mm1
-rw-r--r--src/widgets/widgets/qmdiarea.cpp3
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp7
-rw-r--r--src/widgets/widgets/qmenu.cpp42
-rw-r--r--src/widgets/widgets/qmenu.h1
-rw-r--r--src/widgets/widgets/qmenu_mac.mm19
-rw-r--r--src/widgets/widgets/qmenu_p.h4
-rw-r--r--src/widgets/widgets/qmenubar.cpp7
-rw-r--r--src/xml/sax/qxml.cpp2
-rw-r--r--tests/auto/corelib/codecs/utf8/tst_utf8.cpp36
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp31
-rw-r--r--tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp7
-rw-r--r--tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp2
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp8
-rw-r--r--tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp20
-rw-r--r--tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.pro2
-rw-r--r--tests/auto/dbus/qdbusmarshall/qpong/qpong.pro2
-rw-r--r--tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp36
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp113
-rw-r--r--tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp8
-rw-r--r--tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp71
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp2
-rw-r--r--tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp4
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp6
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp64
-rw-r--r--tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp6
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp152
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp28
-rw-r--r--tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp5
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp7
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp2
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp33
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp36
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp148
-rw-r--r--tests/auto/widgets/styles/styles.pro2
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp14
-rw-r--r--tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp5
-rw-r--r--tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp2
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp4
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp9
-rw-r--r--tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp14
-rw-r--r--tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp34
-rw-r--r--tools/configure/configureapp.cpp28
220 files changed, 3569 insertions, 1709 deletions
diff --git a/config.tests/unix/compile.test b/config.tests/unix/compile.test
index 22064b85e9..f99237cb50 100755
--- a/config.tests/unix/compile.test
+++ b/config.tests/unix/compile.test
@@ -69,15 +69,11 @@ rm -f "$EXE" "${EXE}.exe"
set -- "$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "CONFIG+=android_app" "CONFIG-=debug_and_release app_bundle lib_bundle" "LIBS*=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" "QT_BUILD_TREE=$OUTDIR" "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile"
if [ "$VERBOSE" = "yes" ]; then
- OUTDIR=$OUTDIR "$@"
- $MAKE
+ OUTDIR=$OUTDIR "$@" && $MAKE && SUCCESS=yes
else
- OUTDIR=$OUTDIR "$@" >/dev/null 2>&1
- $MAKE >/dev/null 2>&1
+ OUTDIR=$OUTDIR "$@" >/dev/null 2>&1 && $MAKE >/dev/null 2>&1 && SUCCESS=yes
fi
-( [ -f "$EXE" ] || [ -f "${EXE}.exe" ] ) && SUCCESS=yes
-
# done
if [ "$SUCCESS" != "yes" ]; then
[ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION disabled."
diff --git a/config.tests/unix/icu/icu.pro b/config.tests/unix/icu/icu.pro
index 2c1b431f92..16267ff827 100644
--- a/config.tests/unix/icu/icu.pro
+++ b/config.tests/unix/icu/icu.pro
@@ -1,6 +1,7 @@
SOURCES = icu.cpp
CONFIG += console
CONFIG -= qt dylib
+
win32 {
CONFIG(static, static|shared) {
CONFIG(debug, debug|release) {
@@ -9,8 +10,8 @@ win32 {
LIBS += -lsicuin -lsicuuc -lsicudt
}
} else {
- LIBS += -licuin -licuuc
+ LIBS += -licuin -licuuc -licudt
}
} else {
- LIBS += -licui18n -licuuc
+ LIBS += -licui18n -licuuc -licudata
}
diff --git a/config.tests/unix/objcopy.test b/config.tests/unix/objcopy.test
deleted file mode 100755
index 9eb6e22ab0..0000000000
--- a/config.tests/unix/objcopy.test
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-
-TEST_PATH=`dirname "$0"`
-SEP_DEBUG_SUPPORT=no
-COMPILER=$1
-QMAKE_OBJCOPY=$2
-VERBOSE=$3
-
-if [ -n "$QMAKE_OBJCOPY" ]; then
- echo "int main() { return 0; }" > objcopy_test.cpp
- if $TEST_PATH/which.test "$QMAKE_OBJCOPY" >/dev/null 2>&1 && $COMPILER $SYSROOT_FLAG -g -o objcopy_test objcopy_test.cpp >/dev/null 2>&1; then
- "$QMAKE_OBJCOPY" --only-keep-debug objcopy_test objcopy_test.debug >/dev/null 2>&1 \
- && "$QMAKE_OBJCOPY" --strip-debug objcopy_test >/dev/null 2>&1 \
- && "$QMAKE_OBJCOPY" --add-gnu-debuglink=objcopy_test.debug objcopy_test >/dev/null 2>&1 \
- && SEP_DEBUG_SUPPORT=yes
- fi
- rm -f objcopy_test objcopy_test.debug objcopy_test.cpp
-else
- [ "$VERBOSE" = "yes" ] && echo "Separate debug info check skipped, QMAKE_OBJCOPY is unset.";
-fi
-
-# done
-if [ "$SEP_DEBUG_SUPPORT" != "yes" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Separate debug info support disabled."
- exit 0
-else
- [ "$VERBOSE" = "yes" ] && echo "Separate debug info support enabled."
- exit 1
-fi
diff --git a/config.tests/unix/objcopy/objcopy.cpp b/config.tests/unix/objcopy/objcopy.cpp
new file mode 100644
index 0000000000..66b261bd6d
--- /dev/null
+++ b/config.tests/unix/objcopy/objcopy.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+int main()
+{
+ return 0;
+}
diff --git a/config.tests/unix/objcopy/objcopy.pro b/config.tests/unix/objcopy/objcopy.pro
new file mode 100644
index 0000000000..3c28b89ef3
--- /dev/null
+++ b/config.tests/unix/objcopy/objcopy.pro
@@ -0,0 +1,4 @@
+SOURCES = objcopy.cpp
+CONFIG -= qt
+
+QMAKE_POST_LINK += $$QMAKE_OBJCOPY --only-keep-debug objcopy objcopy.debug && $$QMAKE_OBJCOPY --strip-debug objcopy && $$QMAKE_OBJCOPY --add-gnu-debuglink=objcopy.debug objcopy
diff --git a/configure b/configure
index 601d84ab93..e7e4f4f59b 100755
--- a/configure
+++ b/configure
@@ -1803,6 +1803,20 @@ while [ "$#" -gt 0 ]; do
UNKNOWN_OPT=yes
fi
;;
+ pulseaudio)
+ if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
+ CFG_PULSEAUDIO="$VAL"
+ else
+ UNKNOWN_OPT=yes
+ fi
+ ;;
+ alsa)
+ if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
+ CFG_ALSA="$VAL"
+ else
+ UNKNOWN_OPT=yes
+ fi
+ ;;
gtkstyle)
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
CFG_QGTKSTYLE="$VAL"
@@ -2367,6 +2381,15 @@ Third Party Libraries:
-no-glib ........... Do not compile Glib support.
+ -glib .............. Compile Glib support.
+ -no-pulseaudio ..... Do not compile PulseAudio support.
+ + -pulseaudio ........ Compile PulseAudio support.
+
+ -no-alsa ........... Do not compile ALSA support.
+ + -alsa .............. Compile ALSA support.
+
+ -no-gtkstyle ....... Do not compile GTK theme support.
+ + -gtkstyle .......... Compile GTK theme support.
+
Additional options:
-make <part> ....... Add part to the list of parts to be built at make time.
@@ -3176,7 +3199,7 @@ if [ "$CFG_PRECOMPILE" = "auto" ]; then
fi
fi
-# auto-detect support for separate debug info in objcopy
+# sanity-check for separate debug info
if [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then
if [ "$CFG_SHARED" = "no" ]; then
echo "ERROR: -separate-debug-info is incompatible with -static"
@@ -3186,13 +3209,6 @@ if [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then
echo "ERROR: -separate-debug-info needs -debug, -debug-and-release, or -force-debug-info"
exit 1
fi
- TEST_OBJCOPY=`getXQMakeConf QMAKE_OBJCOPY`
- COMPILER_WITH_FLAGS="$TEST_COMPILER $TEST_COMPILER_CXXFLAGS"
- if "$unixtests/objcopy.test" "$COMPILER_WITH_FLAGS" "$TEST_OBJCOPY" "$OPT_VERBOSE"; then
- echo "ERROR: -separate-debug-info was requested but this binutils does not support it."
- echo "Re-run configure with -v for more information"
- exit 1
- fi
fi
# auto-detect -fvisibility support
@@ -3934,6 +3950,15 @@ fi
# functionality tests
#-------------------------------------------------------------------------------
+# Detect objcopy support
+if [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then
+ if ! compileTest unix/objcopy "objcopy"; then
+ echo "ERROR: -separate-debug-info was requested but this binutils does not support it."
+ echo "Re-run configure with -v for more information"
+ exit 1
+ fi
+fi
+
# Detect C++11 support
if [ "$CFG_CXX11" != "no" ]; then
# Configure detects compiler features based on cross compiler, so we need
@@ -4615,7 +4640,7 @@ if [ "$CFG_GLIB" = "yes" -a "$CFG_QGTKSTYLE" != "no" ]; then
QMakeVar set QT_LIBS_QGTK2 "$QT_LIBS_QGTK2"
else
if [ "$CFG_QGTKSTYLE" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then
- echo "Gtk theme support cannot be enabled due to functionality tests!"
+ echo "GTK theme support cannot be enabled due to functionality tests!"
echo " Turn on verbose messaging (-v) to $0 to see the fin al report."
echo " If you believe this message is in error you may use the continue"
echo " switch (-continue) to $0 to continue."
diff --git a/doc/src/snippets/qx11embedcontainer/main.cpp b/doc/src/snippets/qx11embedcontainer/main.cpp
deleted file mode 100644
index 97d6f11385..0000000000
--- a/doc/src/snippets/qx11embedcontainer/main.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui>
-#include <QX11EmbedContainer>
-
-//! [0]
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
-
- if (app.arguments().count() != 2) {
- qFatal("Error - expected executable path as argument");
- return 1;
- }
-
- QX11EmbedContainer container;
- container.show();
-
- QProcess process(&container);
- QString executable(app.arguments()[1]);
- QStringList arguments;
- arguments << QString::number(container.winId());
- process.start(executable, arguments);
-
- int status = app.exec();
- process.close();
- return status;
-}
-//! [0]
diff --git a/doc/src/snippets/qx11embedwidget/main.cpp b/doc/src/snippets/qx11embedwidget/main.cpp
deleted file mode 100644
index 77b45c1da3..0000000000
--- a/doc/src/snippets/qx11embedwidget/main.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QApplication>
-#include "embedwidget.h"
-
-//! [0]
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
-
- if (app.arguments().count() != 2) {
- qFatal("Error - expected window id as argument");
- return 1;
- }
-
- QString windowId(app.arguments()[1]);
- EmbedWidget window;
- window.embedInto(windowId.toULong());
- window.show();
-
- return app.exec();
-}
-//! [0]
diff --git a/examples/widgets/tutorials/addressbook/part5/addressbook.cpp b/examples/widgets/tutorials/addressbook/part5/addressbook.cpp
index ca2f72e9e1..a1005d6912 100644
--- a/examples/widgets/tutorials/addressbook/part5/addressbook.cpp
+++ b/examples/widgets/tutorials/addressbook/part5/addressbook.cpp
@@ -73,7 +73,7 @@ AddressBook::AddressBook(QWidget *parent)
previousButton->setEnabled(false);
//! [instantiating FindDialog]
- dialog = new FindDialog;
+ dialog = new FindDialog(this);
//! [instantiating FindDialog]
connect(addButton, SIGNAL(clicked()), this, SLOT(addContact()));
diff --git a/examples/widgets/tutorials/addressbook/part6/addressbook.cpp b/examples/widgets/tutorials/addressbook/part6/addressbook.cpp
index 2ced8e2404..536853590b 100644
--- a/examples/widgets/tutorials/addressbook/part6/addressbook.cpp
+++ b/examples/widgets/tutorials/addressbook/part6/addressbook.cpp
@@ -80,7 +80,7 @@ AddressBook::AddressBook(QWidget *parent)
//! [tooltip 2]
saveButton->setEnabled(false);
- dialog = new FindDialog;
+ dialog = new FindDialog(this);
connect(addButton, SIGNAL(clicked()), this, SLOT(addContact()));
connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact()));
diff --git a/examples/widgets/tutorials/addressbook/part7/addressbook.cpp b/examples/widgets/tutorials/addressbook/part7/addressbook.cpp
index 2060d97d2f..ba42cd4c93 100644
--- a/examples/widgets/tutorials/addressbook/part7/addressbook.cpp
+++ b/examples/widgets/tutorials/addressbook/part7/addressbook.cpp
@@ -80,7 +80,7 @@ AddressBook::AddressBook(QWidget *parent)
exportButton->setToolTip(tr("Export as vCard"));
exportButton->setEnabled(false);
- dialog = new FindDialog;
+ dialog = new FindDialog(this);
connect(addButton, SIGNAL(clicked()), this, SLOT(addContact()));
connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact()));
diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf
index c9497edfad..78b484fdb5 100644
--- a/mkspecs/android-g++/qmake.conf
+++ b/mkspecs/android-g++/qmake.conf
@@ -26,6 +26,7 @@ contains(QMAKE_HOST.os,Windows) {
} else {
MINGW_IN_SHELL = 1
QMAKE_DIR_SEP = /
+ QMAKE_DIRLIST_SEP = :
# Because install's ability to set permissions is not relevant on Windows,
# and git's msys does not provide it to start with.
QMAKE_INSTALL_FILE = cp -f
diff --git a/mkspecs/common/qcc-base-qnx.conf b/mkspecs/common/qcc-base-qnx.conf
index 0954cfd1ee..a0a88b9605 100644
--- a/mkspecs/common/qcc-base-qnx.conf
+++ b/mkspecs/common/qcc-base-qnx.conf
@@ -57,4 +57,5 @@ QMAKE_STRIPFLAGS_LIB += --strip-unneeded
equals(QMAKE_HOST.os, Windows) {
isEmpty(QMAKE_SH): error("This mkspec requires an MSYS environment.")
QMAKE_DIR_SEP = /
+ QMAKE_DIRLIST_SEP = :
}
diff --git a/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in
index 5efb9c7b06..18d37cf7fc 100644
--- a/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in
+++ b/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in
@@ -1,6 +1,6 @@
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<Deployment xmlns=\"http://schemas.microsoft.com/windowsphone/2012/deployment\" AppPlatformVersion=\"8.0\">
- <DefaultLanguage xmlns=\"\" code=\"en-US\" />
+ <DefaultLanguage xmlns=\"\" code=\"$${WINRT_MANIFEST.default_language}\" />$${WINRT_MANIFEST.languages}
<App xmlns=\"\"
ProductID=\"$${WINRT_MANIFEST.identity}\"
Title=\"$${WINRT_MANIFEST.name}\"
diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf
index 938670b2a8..6fb140b252 100644
--- a/mkspecs/features/default_post.prf
+++ b/mkspecs/features/default_post.prf
@@ -83,8 +83,8 @@ silent {
breakpad {
load(resolve_target)
- DEBUGFILENAME = $$shell_quote($$shell_path($$QMAKE_RESOLVED_TARGET))
- PROJECTPATH = $$shell_quote($$shell_path($$OUT_PWD))
+ DEBUGFILENAME = $$shell_quote($$system_path($$QMAKE_RESOLVED_TARGET))
+ PROJECTPATH = $$shell_quote($$system_path($$OUT_PWD))
!isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)
QMAKE_POST_LINK = $$QMAKE_POST_LINK$$quote($${QT_BREAKPAD_ROOT_PATH}$${QMAKE_DIR_SEP}qtbreakpadsymbols $$DEBUGFILENAME $$PROJECTPATH)
diff --git a/mkspecs/features/incredibuild_xge.prf b/mkspecs/features/incredibuild_xge.prf
index b43ecf2809..75c7a9a75b 100644
--- a/mkspecs/features/incredibuild_xge.prf
+++ b/mkspecs/features/incredibuild_xge.prf
@@ -3,6 +3,6 @@ contains(TEMPLATE, "vc.*") {
EOC = $$escape_expand(\\r\\h)
for(xge, INCREDIBUILD_XGE) {
- $${xge}.commands = Rem IncrediBuild_AllowRemote $$EOC Rem IncrediBuild_OutputFile $$shell_path($${xge}.output) $$EOC $$eval($${xge}.commands)
+ $${xge}.commands = Rem IncrediBuild_AllowRemote $$EOC Rem IncrediBuild_OutputFile $$system_path($${xge}.output) $$EOC $$eval($${xge}.commands)
}
}
diff --git a/mkspecs/features/java.prf b/mkspecs/features/java.prf
index eeaafcc883..790724cec9 100644
--- a/mkspecs/features/java.prf
+++ b/mkspecs/features/java.prf
@@ -44,7 +44,7 @@ CONFIG += plugin no_plugin_name_prefix
javac.input = JAVASOURCES
javac.output = $$CLASS_DIR
javac.CONFIG += combine
-javac.commands = javac -source 6 -target 6 -Xlint:unchecked -bootclasspath $$ANDROID_JAR_FILE -cp $$shell_quote($$shell_path($$join(JAVACLASSPATH, $$QMAKE_DIRLIST_SEP))) -d $$shell_quote($$CLASS_DIR) ${QMAKE_FILE_IN}
+javac.commands = javac -source 6 -target 6 -Xlint:unchecked -bootclasspath $$ANDROID_JAR_FILE -cp $$shell_quote($$system_path($$join(JAVACLASSPATH, $$DIRLIST_SEP))) -d $$shell_quote($$CLASS_DIR) ${QMAKE_FILE_IN}
# Force rebuild every time, because we don't know the paths of the destination files
# as they depend on the code.
javac.depends = FORCE
diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf
index f3739572c7..f161a71ef9 100644
--- a/mkspecs/features/qml_plugin.prf
+++ b/mkspecs/features/qml_plugin.prf
@@ -100,12 +100,3 @@ load(qt_common)
}
load(qml_module)
-
-unix|mingw {
- !isEmpty(_QMAKE_SUPER_CACHE_): \
- lib_replace.match = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]*/lib
- else: \
- lib_replace.match = $$MODULE_BASE_OUTDIR
- lib_replace.replace = $$[QT_INSTALL_LIBS/raw]
- QMAKE_PRL_INSTALL_REPLACE += lib_replace
-}
diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf
index 6cd848b405..4dcabe9237 100644
--- a/mkspecs/features/qt_common.prf
+++ b/mkspecs/features/qt_common.prf
@@ -19,6 +19,24 @@ contains(TEMPLATE, .*lib) {
unix:contains(QT_CONFIG, reduce_relocations): CONFIG += bsymbolic_functions
contains(QT_CONFIG, largefile): CONFIG += largefile
contains(QT_CONFIG, separate_debug_info): CONFIG += separate_debug_info
+
+ !isEmpty(_QMAKE_SUPER_CACHE_): \
+ rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]*
+ else: \
+ rplbase = $$MODULE_BASE_OUTDIR
+ host_build: \
+ qt_libdir = $$[QT_HOST_LIBS]
+ else: \
+ qt_libdir = $$[QT_INSTALL_LIBS/raw]
+ contains(QMAKE_DEFAULT_LIBDIRS, $$qt_libdir) {
+ lib_replace.match = "[^ ']*$$rplbase/lib"
+ lib_replace.replace =
+ } else {
+ lib_replace.match = $$rplbase/lib
+ lib_replace.replace = $$qt_libdir
+ }
+ lib_replace.CONFIG = path
+ QMAKE_PRL_INSTALL_REPLACE += lib_replace
}
warnings_are_errors:warning_clean {
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 1dacfedd02..64b9fee361 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -210,7 +210,7 @@ defineTest(qtPrepareTool) {
$$1$$3 = $$system_path($$eval($$1))
qtAddTargetEnv($$1$$3, QT_TOOL.$${2}.depends, system)
}
- $$1 = $$shell_path($$eval($$1))
+ $$1 = $$system_path($$eval($$1))
qtAddTargetEnv($$1, QT_TOOL.$${2}.depends, )
}
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
index 2134077ed3..5dac0250ea 100644
--- a/mkspecs/features/qt_module.prf
+++ b/mkspecs/features/qt_module.prf
@@ -127,6 +127,8 @@ win32 {
# keeps the code clean and helps in writing code that is
# safe across all platforms.
DEFINES *= _CRT_SECURE_NO_WARNINGS
+
+ DEFINES += _USE_MATH_DEFINES
}
aix-g++* {
@@ -166,43 +168,29 @@ android: CONFIG += qt_android_deps
#install directives
load(qt_installs)
-!isEmpty(_QMAKE_SUPER_CACHE_): \
- rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]*
-else: \
- rplbase = $$MODULE_BASE_OUTDIR
-include_replace.match = $$rplbase/include
-include_replace.replace = $$[QT_INSTALL_HEADERS/raw]
-include_replace.CONFIG = path
-lib_replace.match = $$rplbase/lib
-host_build: \
- lib_replace.replace = $$[QT_HOST_LIBS]
-else: \
- lib_replace.replace = $$[QT_INSTALL_LIBS/raw]
-lib_replace.CONFIG = path
-QMAKE_PRL_INSTALL_REPLACE += include_replace lib_replace
-
-unix|mingw {
- CONFIG += create_pc
- QMAKE_PKGCONFIG_LIBDIR = $$lib_replace.replace
- QMAKE_PKGCONFIG_INCDIR = $$include_replace.replace
- QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME
- QMAKE_PKGCONFIG_DESTDIR = pkgconfig
- QMAKE_PKGCONFIG_INSTALL_REPLACE += include_replace lib_replace
-}
-
-unix {
- CONFIG += create_libtool explicitlib
- QMAKE_LIBTOOL_LIBDIR = $$lib_replace.replace
- QMAKE_LIBTOOL_INSTALL_REPLACE += include_replace lib_replace
-}
+load(qt_targets)
+load(qt_common)
+# this builds on top of qt_common
unix|mingw {
+ CONFIG += create_pc
+ QMAKE_PKGCONFIG_DESTDIR = pkgconfig
+ QMAKE_PKGCONFIG_LIBDIR = $$qt_libdir
+ QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw]
+ QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME
QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$section(VERSION, ., 0, 0) ")
QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$section(VERSION, ., 0, 0))
for(i, MODULE_DEPENDS): \
QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$eval(QT.$${i}.MAJOR_VERSION))
isEmpty(QMAKE_PKGCONFIG_DESCRIPTION): \
QMAKE_PKGCONFIG_DESCRIPTION = $$replace(TARGET, ^Qt, "Qt ") module
+ QMAKE_PKGCONFIG_INSTALL_REPLACE += lib_replace
+
+ unix {
+ CONFIG += create_libtool explicitlib
+ QMAKE_LIBTOOL_LIBDIR = $$qt_libdir
+ QMAKE_LIBTOOL_INSTALL_REPLACE += lib_replace
+ }
}
contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE
@@ -221,9 +209,3 @@ win32 {
}
TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #do this towards the end
-
-load(qt_targets)
-load(qt_common)
-
-win32:DEFINES+=_USE_MATH_DEFINES
-
diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf
index f31bc38c75..aba720238f 100644
--- a/mkspecs/features/qt_module_pris.prf
+++ b/mkspecs/features/qt_module_pris.prf
@@ -177,9 +177,8 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
include($$mod_work_pfx/qt_lib_$${pri}.pri)
for(mod, mods_to_load) {
for(var, $$list(VERSION MAJOR_VERSION MINOR_VERSION PATCH_VERSION \
- name depends module_config CONFIG DEFINES sources \
+ name depends run_depends plugin_types module_config CONFIG DEFINES \
includes bins libs libexecs plugins imports qml \
- rpath_link \
)):defined(QT.$${mod}.$$var, var):cache(QT.$${mod}.$$var, transient)
}
cache(QT_MODULES, transient)
diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf
index c020bd2767..b012278bde 100644
--- a/mkspecs/features/qt_plugin.prf
+++ b/mkspecs/features/qt_plugin.prf
@@ -38,7 +38,7 @@ CONFIG(static, static|shared) {
!build_pass {
MODULE_PRI_CONT = \
"QT_PLUGIN.$${MODULE}.TYPE = $$PLUGIN_TYPE" \
- "QT_PLUGIN.$${MODULE}.EXTENDS = $$PLUGIN_EXTENDS" \
+ "QT_PLUGIN.$${MODULE}.EXTENDS =$$join(PLUGIN_EXTENDS, " ", " ")" \
"QT_PLUGIN.$${MODULE}.CLASS_NAME = $$PLUGIN_CLASS_NAME" \
"QT_PLUGINS += $$MODULE"
write_file($$MODULE_PRI, MODULE_PRI_CONT)|error("Aborting.")
@@ -83,12 +83,3 @@ load(qt_common)
wince*:LIBS += $$QMAKE_LIBS_GUI
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
-
-!isEmpty(_QMAKE_SUPER_CACHE_): \
- rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]*
-else: \
- rplbase = $$MODULE_BASE_OUTDIR
-lib_replace.match = $$rplbase/lib
-lib_replace.replace = $$[QT_INSTALL_LIBS/raw]
-lib_replace.CONFIG = path
-QMAKE_PRL_INSTALL_REPLACE += lib_replace
diff --git a/mkspecs/features/simd.prf b/mkspecs/features/simd.prf
index 4f86f60700..62a63f90ca 100644
--- a/mkspecs/features/simd.prf
+++ b/mkspecs/features/simd.prf
@@ -18,7 +18,7 @@ QT_CPU_FEATURES = $$eval(QT_CPU_FEATURES.$$QT_ARCH)
#
# Set up compilers for SIMD (SSE/AVX, NEON etc)
#
-*-g++*|intel_icc|*-clang*|*-qcc* {
+gcc { # includes intel_icc and clang variants
sse2 {
HEADERS += $$SSE2_HEADERS
diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf
index 40ec7cff30..6656d1b898 100644
--- a/mkspecs/features/testcase.prf
+++ b/mkspecs/features/testcase.prf
@@ -22,7 +22,7 @@ debug_and_release:debug_and_release_target {
}
!isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD,^\\./?): \
- check.commands = cd $$system_path($$TESTRUN_CWD) &&
+ check.commands = cd $$shell_path($$TESTRUN_CWD) &&
# Allow for a custom test runner script
check.commands += $(TESTRUNNER)
diff --git a/mkspecs/features/win32/windeployqt.prf b/mkspecs/features/win32/windeployqt.prf
index f49df47ffe..22253f6299 100644
--- a/mkspecs/features/win32/windeployqt.prf
+++ b/mkspecs/features/win32/windeployqt.prf
@@ -3,9 +3,9 @@ qtPrepareTool(QMAKE_WINDEPLOYQT, windeployqt)
build_pass {
load(resolve_target)
- isEmpty(WINDEPLOYQT_OPTIONS): WINDEPLOYQT_OPTIONS = -qmldir $$shell_quote($$shell_path($$_PRO_FILE_PWD_))
- WINDEPLOYQT_TARGET = $$shell_quote($$shell_path($$QMAKE_RESOLVED_TARGET))
- WINDEPLOYQT_OUTPUT = $$shell_quote($$shell_path($$dirname(QMAKE_RESOLVED_TARGET)/$$basename(TARGET).windeployqt))
+ isEmpty(WINDEPLOYQT_OPTIONS): WINDEPLOYQT_OPTIONS = -qmldir $$shell_quote($$system_path($$_PRO_FILE_PWD_))
+ WINDEPLOYQT_TARGET = $$shell_quote($$system_path($$QMAKE_RESOLVED_TARGET))
+ WINDEPLOYQT_OUTPUT = $$shell_quote($$system_path($$dirname(QMAKE_RESOLVED_TARGET)/$$basename(TARGET).windeployqt))
windeployqt.target = windeployqt
windeployqt.commands = $$QMAKE_WINDEPLOYQT $$WINDEPLOYQT_OPTIONS -list target $$WINDEPLOYQT_TARGET > $$WINDEPLOYQT_OUTPUT
diff --git a/mkspecs/features/win32/windows.prf b/mkspecs/features/win32/windows.prf
index 6d8289d949..f19a42b7e2 100644
--- a/mkspecs/features/win32/windows.prf
+++ b/mkspecs/features/win32/windows.prf
@@ -7,6 +7,8 @@ contains(TEMPLATE, ".*app"){
qt:for(entryLib, $$list($$unique(QMAKE_LIBS_QT_ENTRY))) {
isEqual(entryLib, -lqtmain): {
+ !contains(QMAKE_DEFAULT_LIBDIRS, $$QT.core.libs): \
+ QMAKE_LIBS += -L$$QT.core.libs
CONFIG(debug, debug|release): QMAKE_LIBS += $${entryLib}$${QT_LIBINFIX}d
else: QMAKE_LIBS += $${entryLib}$${QT_LIBINFIX}
} else {
diff --git a/mkspecs/features/winrt/font_deployment.prf b/mkspecs/features/winrt/font_deployment.prf
index 36db5b7cac..c767d5bc1a 100644
--- a/mkspecs/features/winrt/font_deployment.prf
+++ b/mkspecs/features/winrt/font_deployment.prf
@@ -43,7 +43,7 @@ if(!build_pass:equals(TEMPLATE, "vcapp")) {
!isEmpty(FONTS):equals(TEMPLATE, "app") {
fonts.files = $$BUILD_DIR/fonts/*
- isEmpty($$target.path) {
+ isEmpty(target.path) {
fonts.path = $$OUT_PWD/fonts
} else {
fonts.path = $$target.path/fonts
@@ -54,7 +54,9 @@ if(!build_pass:equals(TEMPLATE, "vcapp")) {
}
!isEmpty(FONTS):winphone:equals(TEMPLATE, "vcapp"):build_pass {
- fonts.files = $$OUT_PWD/fonts/*
+ for (FONT, FONTS) {
+ fonts.files += $$OUT_PWD/fonts/$$basename(FONT)
+ }
fonts.path = fonts
DEPLOYMENT += fonts
}
diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf
index fda4fb5e8f..444b8b873e 100644
--- a/mkspecs/features/winrt/package_manifest.prf
+++ b/mkspecs/features/winrt/package_manifest.prf
@@ -27,6 +27,8 @@
# WINRT_MANIFEST.splash_screen: Splash screen image file. Default provided by the mkspec.
# WINRT_MANIFEST.iconic_tile_icon: Image file for the "iconic" tile template icon. Default provided by the mkspec.
# WINRT_MANIFEST.iconic_tile_small: Image file for the small "iconic" tile template logo. Default provided by the mkspec.
+# WINRT_MANIFEST.default_language: Specifies the default language of the application
+# WINRT_MANIFEST.languages: Specifies the languages the application supports
# WINRT_MANIFEST.capabilities: Specifies capabilities to add to the capability list.
# WINRT_MANIFEST.capabilities_device: Specifies device capabilities to add to the capability list. (location, webcam...)
# WINRT_MANIFEST.dependencies: Specifies dependencies required by the package.
@@ -90,10 +92,23 @@
isEmpty(WINRT_MANIFEST.genre): WINRT_MANIFEST.genre = apps.normal
isEmpty(WINRT_MANIFEST.background): WINRT_MANIFEST.background = green
isEmpty(WINRT_MANIFEST.foreground): WINRT_MANIFEST.foreground = light
+ isEmpty(WINRT_MANIFEST.default_language): WINRT_MANIFEST.default_language = en
winphone: INDENT = "$$escape_expand(\\r\\n) "
else: INDENT = "$$escape_expand(\\r\\n) "
+ # Languages are given as a string list
+ WINRT_MANIFEST.languages = $$unique(WINRT_MANIFEST.languages)
+ winphone:equals(WINSDK_VER, 8.0):!isEmpty(WINRT_MANIFEST.languages) {
+ for(LANGUAGE, WINRT_MANIFEST.languages): \
+ MANIFEST_LANGUAGES += "<Language code=\"$$LANGUAGE\" />"
+
+ WINRT_MANIFEST.languages = \
+ $$join(MANIFEST_LANGUAGES, $$INDENT, \
+ "$$escape_expand(\\r\\n) <Languages xmlns=\"\">$$INDENT", \
+ "$$escape_expand(\\r\\n) </Languages>")
+ }
+
# Capabilities are given as a string list and may change with the configuration (network, sensors, etc.)
WINRT_MANIFEST.capabilities = $$unique(WINRT_MANIFEST.capabilities)
WINRT_MANIFEST.capabilities_device = $$unique(WINRT_MANIFEST.capabilities_device)
diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf
index 496553f8c0..79024c588c 100644
--- a/mkspecs/macx-ios-clang/features/default_post.prf
+++ b/mkspecs/macx-ios-clang/features/default_post.prf
@@ -77,6 +77,9 @@ equals(TEMPLATE, app) {
args += $$system_quote($$arg)
system("cd $$system_quote($$OUT_PWD) && $$QMAKE_QMAKE $$args $$system_quote($$_PRO_FILE_) -spec macx-xcode")
+ check.commands = "$(MAKE) -f $(MAKEFILE).ReleaseSimulator xcode_build_check"
+ QMAKE_EXTRA_TARGETS += check
+
} else {
load(resolve_config)
@@ -113,6 +116,9 @@ equals(TEMPLATE, app) {
QMAKE_EXTRA_TARGETS += xcode_build_dir_distclean
distclean.depends = xcode_build_dir_distclean
QMAKE_EXTRA_TARGETS += distclean
+
+ xcode_build_check.commands = "$(TESTRUNNER) $$title($$cfg)-$${sdk}/$(TARGET).app $(TESTARGS)"
+ QMAKE_EXTRA_TARGETS += xcode_build_check
}
CONFIG =
diff --git a/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h b/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h
index 2f95f0d392..27e4a3aa41 100644
--- a/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h
+++ b/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h
@@ -83,7 +83,7 @@
#include <arpa/inet.h>
#define QT_USE_XOPEN_LFS_EXTENSIONS
-#if !defined(__EXT_QNX__READDIR64_R)
+#if defined(__EXT_QNX__READDIR_R) && !defined(__EXT_QNX__READDIR64_R)
#define QT_NO_READDIR64
#endif
#include "../common/posix/qplatformdefs.h"
diff --git a/mkspecs/qnx-x86-qcc/qplatformdefs.h b/mkspecs/qnx-x86-qcc/qplatformdefs.h
index b47aecde0d..246f82e27f 100644
--- a/mkspecs/qnx-x86-qcc/qplatformdefs.h
+++ b/mkspecs/qnx-x86-qcc/qplatformdefs.h
@@ -83,7 +83,7 @@
#include <arpa/inet.h>
#define QT_USE_XOPEN_LFS_EXTENSIONS
-#if !defined(__EXT_QNX__READDIR64_R)
+#if defined(__EXT_QNX__READDIR_R) && !defined(__EXT_QNX__READDIR64_R)
#define QT_NO_READDIR64
#endif
#include "../common/posix/qplatformdefs.h"
diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf
index 1ac35611f5..830dde97e9 100644
--- a/mkspecs/win32-g++/qmake.conf
+++ b/mkspecs/win32-g++/qmake.conf
@@ -93,6 +93,7 @@ QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
!isEmpty(QMAKE_SH) {
MINGW_IN_SHELL = 1
QMAKE_DIR_SEP = /
+ QMAKE_DIRLIST_SEP = :
include(../common/shell-unix.conf)
# Because install's ability to set permissions is not relevant on Windows,
# and git's msys does not provide it to start with.
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index 94fe02dc70..2f43c8ad1f 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -2422,6 +2422,9 @@
\li Specifies device capabilities to add to the capability list
(location, webcam, and so on). This option is not available on Windows Phone.
\row
+ \li default_language
+ \li The default language code of the application. Defaults to "en".
+ \row
\li dependencies
\li Specifies dependencies required by the package.
\row
@@ -2448,6 +2451,10 @@
\li The unique ID of the app. Defaults to reusing the existing generated
manifest's UUID, or generates a new UUID if none is present.
\row
+ \li languages
+ \li A list of additional language codes supported by the application. This list
+ is empty by default.
+ \row
\li logo_large
\li Large logo image file. Default provided by the mkspec.
\row
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index da64c33cf2..d44c2ca73f 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -1116,7 +1116,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
//all files
const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files"));
for(int file = 0; file < files.count(); file++) {
- QString fn = files[file].toQString();
+ QString fn = fileFixify(files[file].toQString(), Option::output_dir, input_dir);
QString file_ref_key = keyFor("QMAKE_PBX_BUNDLE_DATA_FILE_REF." + bundle_data[i] + "-" + fn);
bundle_file_refs += file_ref_key;
t << "\t\t" << file_ref_key << " = {\n"
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index bad4eb5456..0e3e058c7b 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -370,7 +370,8 @@ MakefileGenerator::findFilesInVPATH(ProStringList l, uchar flags, const QString
regex.remove(0, dir.length());
}
if(real_dir.isEmpty() || exists(real_dir)) {
- QStringList files = QDir(real_dir).entryList(QStringList(regex));
+ QStringList files = QDir(real_dir).entryList(QStringList(regex),
+ QDir::NoDotAndDotDot | QDir::AllEntries);
if(files.isEmpty()) {
debug_msg(1, "%s:%d Failure to find %s in vpath (%s)",
__FILE__, __LINE__,
@@ -383,8 +384,6 @@ MakefileGenerator::findFilesInVPATH(ProStringList l, uchar flags, const QString
l.removeAt(val_it);
QString a;
for(int i = (int)files.count()-1; i >= 0; i--) {
- if(files[i] == "." || files[i] == "..")
- continue;
a = real_dir + files[i];
if(!(flags & VPATH_NoFixify))
a = fileFixify(a);
@@ -1324,7 +1323,8 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild)
continue;
}
QString local_dirstr = Option::fixPathToLocalOS(dirstr, true);
- QStringList files = QDir(local_dirstr).entryList(QStringList(filestr));
+ QStringList files = QDir(local_dirstr).entryList(QStringList(filestr),
+ QDir::NoDotAndDotDot | QDir::AllEntries);
if (installConfigValues.contains("no_check_exist") && files.isEmpty()) {
QString dst_file = filePrefixRoot(root, dst_dir);
QString cmd;
@@ -1346,8 +1346,6 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild)
}
for(int x = 0; x < files.count(); x++) {
QString file = files[x];
- if(file == "." || file == "..") //blah
- continue;
uninst.append(rm_dir_contents + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + file, FileFixifyAbsolute, false))));
QFileInfo fi(fileInfo(dirstr + file));
QString dst_file = filePrefixRoot(root, fileFixify(dst_dir, FileFixifyAbsolute, false));
@@ -3217,7 +3215,7 @@ MakefileGenerator::writePkgConfigFile()
QString prefix = pkgConfigPrefix();
QString libDir = project->first("QMAKE_PKGCONFIG_LIBDIR").toQString();
if(libDir.isEmpty())
- libDir = prefix + Option::dir_sep + "lib" + Option::dir_sep;
+ libDir = prefix + "/lib";
QString includeDir = project->first("QMAKE_PKGCONFIG_INCDIR").toQString();
if(includeDir.isEmpty())
includeDir = prefix + "/include";
@@ -3284,10 +3282,12 @@ MakefileGenerator::writePkgConfigFile()
// libs
t << "Libs: ";
- QString pkgConfiglibDir;
QString pkgConfiglibName;
if (target_mode == TARG_MAC_MODE && project->isActiveConfig("lib_bundle")) {
- pkgConfiglibDir = "-F${libdir}";
+ if (libDir != QLatin1String("/System/Library/Frameworks")
+ && libDir != QLatin1String("/Library/Frameworks")) {
+ t << "-F${libdir} ";
+ }
ProString bundle;
if (!project->isEmpty("QMAKE_FRAMEWORK_BUNDLE_NAME"))
bundle = unescapeFilePath(project->first("QMAKE_FRAMEWORK_BUNDLE_NAME"));
@@ -3298,12 +3298,13 @@ MakefileGenerator::writePkgConfigFile()
bundle = bundle.left(suffix);
pkgConfiglibName = "-framework " + bundle + " ";
} else {
- pkgConfiglibDir = "-L${libdir}";
+ if (!project->values("QMAKE_DEFAULT_LIBDIRS").contains(libDir))
+ t << "-L${libdir} ";
pkgConfiglibName = "-l" + unescapeFilePath(project->first("QMAKE_ORIG_TARGET"));
if (project->isActiveConfig("shared"))
pkgConfiglibName += project->first("TARGET_VERSION_EXT").toQString();
}
- t << pkgConfiglibDir << " " << pkgConfiglibName << " \n";
+ t << pkgConfiglibName << " \n";
ProStringList libs;
if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) {
@@ -3327,7 +3328,10 @@ MakefileGenerator::writePkgConfigFile()
<< varGlue("PRL_EXPORT_CXXFLAGS", "", " ", " ")
<< varGlue("QMAKE_PKGCONFIG_CFLAGS", "", " ", " ")
// << varGlue("DEFINES","-D"," -D"," ")
- << "-I${includedir}\n";
+ ;
+ if (!project->values("QMAKE_DEFAULT_INCDIRS").contains(includeDir))
+ t << "-I${includedir}";
+ t << endl;
// requires
const QString requires = project->values("QMAKE_PKGCONFIG_REQUIRES").join(' ');
diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp
index 3cd5a22a33..05fdcb320d 100644
--- a/qmake/generators/projectgenerator.cpp
+++ b/qmake/generators/projectgenerator.cpp
@@ -111,10 +111,8 @@ ProjectGenerator::init()
dir += Option::dir_sep;
if (Option::recursive) {
QStringList files = QDir(dir).entryList(QDir::Files);
- for(int i = 0; i < (int)files.count(); i++) {
- if(files[i] != "." && files[i] != "..")
- dirs.append(dir + files[i] + QDir::separator() + builtin_regex);
- }
+ for (int i = 0; i < files.count(); i++)
+ dirs.append(dir + files[i] + QDir::separator() + builtin_regex);
}
regex = builtin_regex;
} else {
@@ -137,12 +135,9 @@ ProjectGenerator::init()
regex = regex.right(regex.length() - (s+1));
}
if (Option::recursive) {
- QStringList entries = QDir(dir).entryList(QDir::Dirs);
- for(int i = 0; i < (int)entries.count(); i++) {
- if(entries[i] != "." && entries[i] != "..") {
- dirs.append(dir + entries[i] + QDir::separator() + regex);
- }
- }
+ QStringList entries = QDir(dir).entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+ for (int i = 0; i < entries.count(); i++)
+ dirs.append(dir + entries[i] + QDir::separator() + regex);
}
QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regex));
for(int i = 0; i < (int)files.count(); i++) {
@@ -186,16 +181,15 @@ ProjectGenerator::init()
nd += QDir::separator();
nd += profiles[i];
fileFixify(nd);
- if(profiles[i] != "." && profiles[i] != ".." &&
- !subdirs.contains(nd, Qt::CaseInsensitive) && !out_file.endsWith(nd))
+ if (!subdirs.contains(nd, Qt::CaseInsensitive) && !out_file.endsWith(nd))
subdirs.append(nd);
}
}
if (Option::recursive) {
- QStringList dirs = QDir(newdir).entryList(QDir::Dirs);
+ QStringList dirs = QDir(newdir).entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for(int i = 0; i < (int)dirs.count(); i++) {
QString nd = fileFixify(newdir + QDir::separator() + dirs[i]);
- if(dirs[i] != "." && dirs[i] != ".." && !knownDirs.contains(nd, Qt::CaseInsensitive))
+ if (!knownDirs.contains(nd, Qt::CaseInsensitive))
knownDirs.append(nd);
}
}
@@ -207,12 +201,13 @@ ProjectGenerator::init()
dir = regx.left(s+1);
regx = regx.right(regx.length() - (s+1));
}
- QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regx), QDir::Dirs);
+ QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regx),
+ QDir::Dirs | QDir::NoDotAndDotDot);
ProStringList &subdirs = v["SUBDIRS"];
for(int i = 0; i < (int)files.count(); i++) {
QString newdir(dir + files[i]);
QFileInfo fi(fileInfo(newdir));
- if(fi.fileName() != "." && fi.fileName() != "..") {
+ {
newdir = fileFixify(newdir);
if(exists(fi.filePath() + QDir::separator() + fi.fileName() + Option::pro_ext) &&
!subdirs.contains(newdir)) {
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 5ae99bab92..46934c83e9 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -1064,10 +1064,18 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
evalError(fL1S("shell_path(path) requires one argument."));
} else {
QString rstr = args.at(0).toQString(m_tmp1);
- if (m_dirSep.startsWith(QLatin1Char('\\')))
+ if (m_dirSep.startsWith(QLatin1Char('\\'))) {
rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
- else
+ } else {
rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
+#ifdef Q_OS_WIN
+ // Convert d:/foo/bar to msys-style /d/foo/bar.
+ if (rstr.length() > 2 && rstr.at(1) == QLatin1Char(':') && rstr.at(2) == QLatin1Char('/')) {
+ rstr[1] = rstr.at(0);
+ rstr[0] = QLatin1Char('/');
+ }
+#endif
+ }
ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
}
break;
@@ -1737,14 +1745,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
if (target == TargetSuper) {
if (m_superfile.isEmpty()) {
m_superfile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.super"));
- printf("Info: creating super cache file %s\n", qPrintable(m_superfile));
+ printf("Info: creating super cache file %s\n", qPrintable(QDir::toNativeSeparators(m_superfile)));
valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
}
fn = m_superfile;
} else if (target == TargetCache) {
if (m_cachefile.isEmpty()) {
m_cachefile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.cache"));
- printf("Info: creating cache file %s\n", qPrintable(m_cachefile));
+ printf("Info: creating cache file %s\n", qPrintable(QDir::toNativeSeparators(m_cachefile)));
valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
// We could update m_{source,build}Root and m_featureRoots here, or even
// "re-home" our rootEnv, but this doesn't sound too useful - if somebody
@@ -1758,7 +1766,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
if (fn.isEmpty())
fn = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.stash"));
if (!m_vfs->exists(fn)) {
- printf("Info: creating stash file %s\n", qPrintable(fn));
+ printf("Info: creating stash file %s\n", qPrintable(QDir::toNativeSeparators(fn)));
valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn);
}
}
diff --git a/qmake/qmake.pri b/qmake/qmake.pri
index 73757ee086..4457b2643b 100644
--- a/qmake/qmake.pri
+++ b/qmake/qmake.pri
@@ -137,7 +137,8 @@ bootstrap { #Qt code
unix {
SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp
mac {
- SOURCES += qcore_mac.cpp qsettings_mac.cpp qlocale_mac.mm
+ SOURCES += qcore_mac.cpp qsettings_mac.cpp
+ OBJECTIVE_SOURCES += qlocale_mac.mm
LIBS += -framework ApplicationServices
} else {
SOURCES += qlocale_unix.cpp
diff --git a/qtbase.pro b/qtbase.pro
index ed6fc394cb..d6861cf09f 100644
--- a/qtbase.pro
+++ b/qtbase.pro
@@ -87,7 +87,7 @@ INSTALLS += syncqt
# qtPrepareTool() to find the non-installed syncqt.
prefix_build|!equals(PWD, $$OUT_PWD) {
- cmd = perl -w $$shell_path($$PWD/bin/syncqt.pl)
+ cmd = perl -w $$system_path($$PWD/bin/syncqt.pl)
TOOL_PRI = $$OUT_PWD/mkspecs/modules/qt_tool_syncqt.pri
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
index fdfbe526ec..0c981ac503 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
@@ -257,7 +257,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum
D3D11_TEXTURE2D_DESC desc;
desc.Width = width; // Compressed texture size constraints?
desc.Height = height;
- desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0;
+ desc.MipLevels = mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 ? ((levels > 0) ? levels + mLodOffset : 0) : 1;
desc.ArraySize = 1;
desc.Format = mTextureFormat;
desc.SampleDesc.Count = 1;
diff --git a/src/angle/patches/0017-ANGLE-D3D11-Don-t-use-mipmaps-in-level-9-textures.patch b/src/angle/patches/0017-ANGLE-D3D11-Don-t-use-mipmaps-in-level-9-textures.patch
new file mode 100644
index 0000000000..200a8105de
--- /dev/null
+++ b/src/angle/patches/0017-ANGLE-D3D11-Don-t-use-mipmaps-in-level-9-textures.patch
@@ -0,0 +1,31 @@
+From 9632c57033b514bfb10a0dfa7ba51ec27a944616 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Tue, 6 May 2014 13:35:14 +0300
+Subject: [PATCH] ANGLE D3D11: Don't use mipmaps in level 9 textures
+
+As the mipmaps levels aren't being generated on level 9, they shouldn't
+be used. Fall back to multisampled textures instead (which is the
+behavior for non-power-of-two textures anyway). This fixes an issue in
+which textured polygons (e.g. QML Images) turn black when scaled down.
+
+Change-Id: I648b8be473dc38f4e1b26724cbaff610e586fdbd
+---
+ src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
+index fdfbe52..0c981ac 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
+@@ -257,7 +257,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width; // Compressed texture size constraints?
+ desc.Height = height;
+- desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0;
++ desc.MipLevels = mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 ? ((levels > 0) ? levels + mLodOffset : 0) : 1;
+ desc.ArraySize = 1;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+--
+1.9.0.msysgit.0
+
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index f7bb1e91bd..95d7713cfe 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -253,8 +253,9 @@ QUnifiedTimer *QUnifiedTimer::instance()
void QUnifiedTimer::maybeUpdateAnimationsToCurrentTime()
{
- if (time.elapsed() - lastTick > 50)
- updateAnimationTimers(driver->elapsed());
+ qint64 elapsed = driver->elapsed();
+ if (elapsed - lastTick > 50)
+ updateAnimationTimers(elapsed);
}
void QUnifiedTimer::updateAnimationTimers(qint64 currentTick)
@@ -263,7 +264,7 @@ void QUnifiedTimer::updateAnimationTimers(qint64 currentTick)
if(insideTick)
return;
- qint64 totalElapsed = currentTick >= 0 ? currentTick : time.elapsed();
+ qint64 totalElapsed = currentTick >= 0 ? currentTick : driver->elapsed();
// ignore consistentTiming in case the pause timer is active
qint64 delta = (consistentTiming && !pauseTimer.isActive()) ?
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qregexp.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qregexp.cpp
index 779fbaa723..530819a173 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qregexp.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qregexp.cpp
@@ -77,7 +77,7 @@ QRegExp mark("\\b" // word boundary
QRegExp rx("^\\d\\d?$"); // match integers 0 to 99
rx.indexIn("123"); // returns -1 (no match)
rx.indexIn("-6"); // returns -1 (no match)
-rx.indexIn("6"); // returns 0 (matched as position 0)
+rx.indexIn("6"); // returns 0 (matched at position 0)
//! [4]
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 391466448f..707e46dd40 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -45,11 +45,11 @@
#include <stddef.h>
-#define QT_VERSION_STR "5.3.0"
+#define QT_VERSION_STR "5.3.1"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x050300
+#define QT_VERSION 0x050301
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index da26490d18..4a602e4b2b 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1207,6 +1207,23 @@ static void android_default_message_handler(QtMsgType type,
static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context,
const QString &buf)
{
+ // to determine logging destination and marking logging environment variable as deprecated
+ // ### remove when deprecated
+ struct LogDestination {
+ LogDestination(const char *deprecated, bool forceConsole) {
+ const char* replacement = "QT_LOGGING_TO_CONSOLE";
+ bool newEnv = qEnvironmentVariableIsSet(replacement);
+ bool oldEnv = qEnvironmentVariableIsSet(deprecated);
+ if (oldEnv && !newEnv && !forceConsole) {
+ fprintf(stderr, "Warning: Environment variable %s is deprecated, "
+ "use %s instead.\n", deprecated, replacement);
+ fflush(stderr);
+ }
+ toConsole = newEnv || oldEnv || forceConsole;
+ }
+ bool toConsole;
+ };
+
QString logMessage = qMessageFormatString(type, context, buf);
#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
@@ -1217,12 +1234,19 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
#endif // Q_OS_WIN
#if defined(QT_USE_SLOG2)
- slog2_default_handler(type, logMessage.toLocal8Bit().constData());
+ static const bool logToConsole = qEnvironmentVariableIsSet("QT_LOGGING_TO_CONSOLE");
+ if (!logToConsole) {
+ slog2_default_handler(type, logMessage.toLocal8Bit().constData());
+ } else {
+ fprintf(stderr, "%s", logMessage.toLocal8Bit().constData());
+ fflush(stderr);
+ }
#elif defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
// We use isatty to catch the obvious case of someone running something interactively.
- // We also support an environment variable for Qt Creator use, or more complicated cases like subprocesses.
- static bool logToConsole = isatty(fileno(stdin)) || !qEnvironmentVariableIsEmpty("QT_NO_JOURNALD_LOG");
- if (Q_LIKELY(!logToConsole)) {
+ // We also support environment variables for Qt Creator use, or more complicated cases
+ // like subprocesses.
+ static const LogDestination logdest("QT_NO_JOURNALD_LOG", isatty(fileno(stdin)));
+ if (Q_LIKELY(!logdest.toConsole)) {
// remove trailing \n, systemd appears to want them newline-less
logMessage.chop(1);
systemd_default_message_handler(type, context, logMessage);
@@ -1231,8 +1255,8 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
fflush(stderr);
}
#elif defined(Q_OS_ANDROID)
- static bool logToAndroid = qEnvironmentVariableIsEmpty("QT_ANDROID_PLAIN_LOG");
- if (logToAndroid) {
+ static const LogDestination logdest("QT_ANDROID_PLAIN_LOG", false);
+ if (!logdest.toConsole) {
android_default_message_handler(type, context, logMessage);
} else {
fprintf(stderr, "%s", logMessage.toLocal8Bit().constData());
diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp
index d2c8d37d4a..f7e58a7bed 100644
--- a/src/corelib/io/qfiledevice.cpp
+++ b/src/corelib/io/qfiledevice.cpp
@@ -139,10 +139,9 @@ void QFileDevicePrivate::setError(QFileDevice::FileError err, int errNum)
are returned and on Windows the rights of the current user are
returned. This behavior might change in a future Qt version.
- Note that Qt does not by default check for permissions on NTFS
- file systems, as this may decrease the performance of file
- handling considerably. It is possible to force permission checking
- on NTFS by including the following code in your source:
+ \note On NTFS file systems, ownership and permissions checking is
+ disabled by default for performance reasons. To enable it,
+ include the following line:
\snippet ntfsp.cpp 0
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 2cf97ef94e..60f7e47e62 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -271,6 +271,17 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request)
groupId(). You can examine a file's permissions and ownership in a
single statement using the permission() function.
+ \note On NTFS file systems, ownership and permissions checking is
+ disabled by default for performance reasons. To enable it,
+ include the following line:
+
+ \snippet ntfsp.cpp 0
+
+ Permission checking is then turned on and off by incrementing and
+ decrementing \c qt_ntfs_permission_lookup by 1.
+
+ \snippet ntfsp.cpp 1
+
\section1 Performance Issues
Some of QFileInfo's functions query the file system, but for
diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp
index b4021c060f..0fa1f02f5c 100644
--- a/src/corelib/io/qfileselector.cpp
+++ b/src/corelib/io/qfileselector.cpp
@@ -365,6 +365,11 @@ QStringList QFileSelectorPrivate::platformSelectors()
ret << QStringLiteral("windows");
# if defined(Q_OS_WINCE)
ret << QStringLiteral("wince");
+# elif defined(Q_OS_WINRT)
+ ret << QStringLiteral("winrt");
+# if defined(Q_OS_WINPHONE)
+ ret << QStringLiteral("winphone");
+# endif
# endif
#elif defined(Q_OS_UNIX)
ret << QStringLiteral("unix");
diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp
index 53cf6158ad..8b6ceebc62 100644
--- a/src/corelib/io/qfilesystemengine.cpp
+++ b/src/corelib/io/qfilesystemengine.cpp
@@ -224,7 +224,7 @@ bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data)
return false;
}
-#if defined(Q_OS_QNX)
+#if defined(QT_EXT_QNX_READDIR_R)
static void fillStat64fromStat32(struct stat64 *statBuf64, const struct stat &statBuf32)
{
statBuf64->st_mode = statBuf32.st_mode;
@@ -289,7 +289,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer)
void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry)
{
-#if defined(Q_OS_QNX)
+#if defined(QT_EXT_QNX_READDIR_R)
knownFlagsMask = 0;
entryFlags = 0;
for (dirent_extra *extra = _DEXTRA_FIRST(&entry); _DEXTRA_VALID(extra, &entry);
diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h
index 4164020359..18a9c2dbda 100644
--- a/src/corelib/io/qfilesystemiterator_p.h
+++ b/src/corelib/io/qfilesystemiterator_p.h
@@ -95,10 +95,10 @@ private:
#else
QT_DIR *dir;
QT_DIRENT *dirEntry;
-#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN)
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) || defined(QT_EXT_QNX_READDIR_R)
// for readdir_r
QScopedPointer<QT_DIRENT, QScopedPointerPodDeleter> mt_file;
-#if defined(Q_OS_QNX) && defined(__EXT_QNX__READDIR_R)
+#if defined(QT_EXT_QNX_READDIR_R)
// for _readdir_r
size_t direntSize;
#endif
diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp
index 0b59aa169a..0f9bbd8a29 100644
--- a/src/corelib/io/qfilesystemiterator_unix.cpp
+++ b/src/corelib/io/qfilesystemiterator_unix.cpp
@@ -70,7 +70,7 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi
if (!nativePath.endsWith('/'))
nativePath.append('/');
-#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN)
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) || defined(QT_EXT_QNX_READDIR_R)
// ### Race condition; we should use fpathconf and dirfd().
size_t maxPathName = ::pathconf(nativePath.constData(), _PC_NAME_MAX);
if (maxPathName == size_t(-1))
@@ -81,13 +81,14 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi
Q_CHECK_PTR(p);
mt_file.reset(p);
-#if defined(Q_OS_QNX) && defined(__EXT_QNX__READDIR_R)
+#if defined(QT_EXT_QNX_READDIR_R)
direntSize = maxPathName;
- // Include extra stat information in the readdir() call (d_stat member of dirent_extra_stat).
- // This is used in QFileSystemMetaData::fillFromDirEnt() to avoid extra stat() calls when iterating
- // over directories
- if (dircntl(dir, D_SETFLAG, D_FLAG_STAT) == -1)
+ // Include extra stat information in the readdir() call (d_stat member of
+ // dirent_extra_stat). This is used in QFileSystemMetaData::fillFromDirEnt() to
+ // avoid extra stat() calls when iterating over directories
+ int flags = dircntl(dir, D_GETFLAG) | D_FLAG_STAT | D_FLAG_FILTER;
+ if (dircntl(dir, D_SETFLAG, flags) == -1)
lastError = errno;
#endif
#endif
@@ -105,7 +106,7 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa
if (!dir)
return false;
-#if defined(Q_OS_QNX) && defined(QT_EXT_QNX_READDIR_R)
+#if defined(QT_EXT_QNX_READDIR_R)
lastError = QT_EXT_QNX_READDIR_R(dir, mt_file.data(), &dirEntry, direntSize);
if (lastError)
return false;
diff --git a/src/corelib/io/qfilesystemwatcher_polling.cpp b/src/corelib/io/qfilesystemwatcher_polling.cpp
index 689f05bb1b..401f95ae82 100644
--- a/src/corelib/io/qfilesystemwatcher_polling.cpp
+++ b/src/corelib/io/qfilesystemwatcher_polling.cpp
@@ -65,14 +65,16 @@ QStringList QPollingFileSystemWatcherEngine::addPaths(const QStringList &paths,
if (!fi.exists())
continue;
if (fi.isDir()) {
- if (!directories->contains(path))
- directories->append(path);
+ if (directories->contains(path))
+ continue;
+ directories->append(path);
if (!path.endsWith(QLatin1Char('/')))
fi = QFileInfo(path + QLatin1Char('/'));
this->directories.insert(path, fi);
} else {
- if (!files->contains(path))
- files->append(path);
+ if (files->contains(path))
+ continue;
+ files->append(path);
this->files.insert(path, fi);
}
it.remove();
diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp
index 2c526847b4..1e615956d7 100644
--- a/src/corelib/io/qtemporarydir.cpp
+++ b/src/corelib/io/qtemporarydir.cpp
@@ -218,25 +218,25 @@ QTemporaryDir::QTemporaryDir()
}
/*!
- Constructs a QTemporaryFile with a template name of \a templateName.
+ Constructs a QTemporaryDir with a template of \a templatePath.
- If \a templateName is a relative path, the path will be relative to the
+ If \a templatePath is a relative path, the path will be relative to the
current working directory. You can use QDir::tempPath() to construct \a
- templateName if you want use the system's temporary directory.
+ templatePath if you want use the system's temporary directory.
- If the \a templateName ends with XXXXXX it will be used as the dynamic portion
+ If the \a templatePath ends with XXXXXX it will be used as the dynamic portion
of the directory name, otherwise it will be appended.
Unlike QTemporaryFile, XXXXXX in the middle of the template string is not supported.
\sa QDir::tempPath()
*/
-QTemporaryDir::QTemporaryDir(const QString &templateName)
+QTemporaryDir::QTemporaryDir(const QString &templatePath)
: d_ptr(new QTemporaryDirPrivate)
{
- if (templateName.isEmpty())
+ if (templatePath.isEmpty())
d_ptr->create(defaultTemplateName());
else
- d_ptr->create(templateName);
+ d_ptr->create(templatePath);
}
/*!
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index 163b087436..288a939ab2 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -569,7 +569,9 @@ void QTextStreamPrivate::flushWriteBuffer()
#endif
// convert from unicode to raw data
- QByteArray data = codec->fromUnicode(writeBuffer.data(), writeBuffer.size(), &writeConverterState);
+ // codec might be null if we're already inside global destructors (QTestCodec::codecForLocale returned null)
+ QByteArray data = Q_LIKELY(codec) ? codec->fromUnicode(writeBuffer.data(), writeBuffer.size(), &writeConverterState)
+ : writeBuffer.toLatin1();
#else
QByteArray data = writeBuffer.toLocal8Bit();
#endif
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index df65aebcff..7dd2125e70 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -318,6 +318,7 @@ bool QWindowsPipeReader::waitForPipeClosed(int msecs)
QElapsedTimer stopWatch;
stopWatch.start();
forever {
+ waitForReadyRead(0);
checkPipeState();
if (pipeBroken)
return true;
diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp
index daa8068734..daad542705 100644
--- a/src/corelib/io/qwindowspipewriter.cpp
+++ b/src/corelib/io/qwindowspipewriter.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qwindowspipewriter_p.h"
-#include <string.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index 3ee0eaaa61..8b58fdf55f 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -323,6 +323,7 @@ private:
friend class QGraphicsViewPrivate;
friend class QGraphicsScene;
friend class QGraphicsScenePrivate;
+ friend class QWidgetWindow;
#ifndef QT_NO_GESTURES
friend class QGestureManager;
#endif
diff --git a/src/corelib/kernel/qmath.cpp b/src/corelib/kernel/qmath.cpp
index b1860fa24a..9f276b4ca9 100644
--- a/src/corelib/kernel/qmath.cpp
+++ b/src/corelib/kernel/qmath.cpp
@@ -303,88 +303,4 @@ const qreal qt_sine_table[QT_SINE_TABLE_SIZE] = {
qreal(-0.024541228522912448)
};
-/*!
- \headerfile <QtMath>
- \title Generic Math Declarations
- \ingroup funclists
-
- \brief The <QtMath> header file includes generic math declarations.
-
- These functions are partly convenience definitions for basic
- operations, for instance not available in the Standard Template Library et
- al.
-*/
-
-/*!
- \fn float qDegreesToRadians(float degrees)
- \relates <QtMath>
- \since 5.1
-
- \brief The function converts the \a degrees in float to radians.
-
- The purpose of the function is to aid the conversion as such a convenient
- function is not part of the Standard Template Library, i.e. in <cmath> or
- elsewhere.
-
- Example:
-
- \snippet code/src_corelib_kernel_qmath.cpp 0
-
- \sa qRadiansToDegrees()
-*/
-
-/*!
- \fn double qDegreesToRadians(double degrees)
- \relates <QtMath>
- \since 5.1
-
- \brief The function converts the \a degrees in double to radians.
-
- The purpose of the function is to aid the conversion as such a convenient
- function is not part of the Standard Template Library, i.e. in <cmath> or
- elsewhere.
-
- Example:
-
- \snippet code/src_corelib_kernel_qmath.cpp 1
-
- \sa qRadiansToDegrees()
-*/
-
-/*!
- \fn float qRadiansToDegrees(float radians)
- \relates <QtMath>
- \since 5.1
-
- \brief The function converts the \a radians in float to degrees.
-
- The purpose of the function is to aid the conversion as such a convenient
- function is not part of the Standard Template Library, i.e. in <cmath> or
- elsewhere.
-
- Example:
-
- \snippet code/src_corelib_kernel_qmath.cpp 2
-
- \sa qDegreesToRadians()
-*/
-
-/*!
- \fn double qRadiansToDegrees(double radians)
- \relates <QtMath>
- \since 5.1
-
- \brief The function converts the \a radians in double to degrees.
-
- The purpose of the function is to aid the conversion as such a convenient
- function is not part of the Standard Template Library, i.e. in <cmath> or
- elsewhere.
-
- Example:
-
- \snippet code/src_corelib_kernel_qmath.cpp 3
-
- \sa qDegreesToRadians()
-*/
-
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qmath.qdoc b/src/corelib/kernel/qmath.qdoc
index 06d8db9277..04dbbb0a3b 100644
--- a/src/corelib/kernel/qmath.qdoc
+++ b/src/corelib/kernel/qmath.qdoc
@@ -26,10 +26,15 @@
****************************************************************************/
/*!
- \headerfile <QtCore/qmath.h>
- \title Math Functions
+ \headerfile <QtMath>
+ \title Generic Math Functions
\ingroup funclists
- \brief The <QtCore/qmath.h> header provides various math functions.
+
+ \brief The <QtMath> header file provides various math functions.
+
+ These functions are partly convenience definitions for basic math operations
+ not available in the C or Standard Template Libraries.
+
\pagekeywords math trigonometry qmath floor ceiling absolute sine cosine tangent inverse tan exponent power natural logarithm
*/
@@ -40,7 +45,7 @@
The ceiling is the smallest integer that is not less than \a v.
For example, if \a v is 41.2, then the ceiling is 42.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qFloor()
*/
@@ -51,7 +56,7 @@
The floor is the largest integer that is not greater than \a v.
For example, if \a v is 41.2, then the floor is 41.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qCeil()
*/
@@ -59,14 +64,14 @@
\fn qreal qFabs(qreal v)
Returns the absolute value of \a v as a qreal.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
*/
/*!
\fn qreal qSin(qreal v)
Returns the sine of the angle \a v in radians.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qCos(), qTan()
*/
@@ -74,7 +79,7 @@
\fn qreal qCos(qreal v)
Returns the cosine of an angle \a v in radians.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qSin(), qTan()
*/
@@ -82,7 +87,7 @@
\fn qreal qTan(qreal v)
Returns the tangent of an angle \a v in radians.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qSin(), qCos()
*/
@@ -91,7 +96,7 @@
Returns the arccosine of \a v as an angle in radians.
Arccosine is the inverse operation of cosine.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qAtan(), qAsin(), qCos()
*/
@@ -100,7 +105,7 @@
Returns the arcsine of \a v as an angle in radians.
Arcsine is the inverse operation of sine.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qSin(), qAtan(), qAcos()
*/
@@ -109,7 +114,7 @@
Returns the arctangent of \a v as an angle in radians.
Arctangent is the inverse operation of tangent.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qTan(), qAcos(), qAsin()
*/
@@ -118,7 +123,7 @@
Returns the arctangent of a point specified by the coordinates \a y and \a x.
This function will return the angle (argument) of that point.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qAtan()
*/
@@ -127,7 +132,7 @@
Returns the square root of \a v.
This function returns a NaN if \a v is a negative number.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qPow()
*/
@@ -135,7 +140,7 @@
\fn qreal qLn(qreal v)
Returns the natural logarithm of \a v. Natural logarithm uses base e.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qExp()
*/
@@ -143,7 +148,7 @@
\fn qreal qExp(qreal v)
Returns the exponential function of \c e to the power of \a v.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qLn()
*/
@@ -152,6 +157,62 @@
Returns the value of \a x raised to the power of \a y.
That is, \a x is the base and \a y is the exponent.
- \relates <QtCore/qmath.h>
+ \relates <QtMath>
\sa qSqrt()
*/
+
+/*!
+ \fn float qDegreesToRadians(float degrees)
+ \relates <QtMath>
+ \since 5.1
+
+ This function converts the \a degrees in float to radians.
+
+ Example:
+
+ \snippet code/src_corelib_kernel_qmath.cpp 0
+
+ \sa qRadiansToDegrees()
+*/
+
+/*!
+ \fn double qDegreesToRadians(double degrees)
+ \relates <QtMath>
+ \since 5.1
+
+ This function converts the \a degrees in double to radians.
+
+ Example:
+
+ \snippet code/src_corelib_kernel_qmath.cpp 1
+
+ \sa qRadiansToDegrees()
+*/
+
+/*!
+ \fn float qRadiansToDegrees(float radians)
+ \relates <QtMath>
+ \since 5.1
+
+ This function converts the \a radians in float to degrees.
+
+ Example:
+
+ \snippet code/src_corelib_kernel_qmath.cpp 2
+
+ \sa qDegreesToRadians()
+*/
+
+/*!
+ \fn double qRadiansToDegrees(double radians)
+ \relates <QtMath>
+ \since 5.1
+
+ This function converts the \a radians in double to degrees.
+
+ Example:
+
+ \snippet code/src_corelib_kernel_qmath.cpp 3
+
+ \sa qDegreesToRadians()
+*/
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 0a504657a3..0e9cbfe1c9 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4436,6 +4436,8 @@ void qDeleteInEventHandler(QObject *o)
\snippet code/src_corelib_kernel_qobject.cpp 46
The connection will automatically disconnect if the sender is destroyed.
+ However, you should take care that any objects used within the functor
+ are still alive when the signal is emitted.
\note If the compiler does not support C++11 variadic templates, the number
of arguments in the signal or slot are limited to 6, and the functor object
@@ -4473,6 +4475,8 @@ void qDeleteInEventHandler(QObject *o)
The connection will automatically disconnect if the sender or the context
is destroyed.
+ However, you should take care that any objects used within the functor
+ are still alive when the signal is emitted.
\note If the compiler does not support C++11 variadic templates, the number
of arguments in the signal or slot are limited to 6, and the functor object
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index 407a6a4e02..cde42c4f6e 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -125,11 +125,9 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
or writing to the shared memory, and remember to release the lock
with unlock() after you are done.
- Unlike QtSharedMemory, QSharedMemory automatically destroys the
- shared memory segment when the last instance of QSharedMemory is
- detached from the segment, and no references to the segment
- remain. Do not mix using QtSharedMemory and QSharedMemory. Port
- everything to QSharedMemory.
+ QSharedMemory automatically destroys the shared memory segment when
+ the last instance of QSharedMemory is detached from the segment, and
+ no references to the segment remain.
\warning QSharedMemory changes the key in a Qt-specific way, unless otherwise
specified. Interoperation with non-Qt applications is achieved by first creating
diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp
index 9c97d6b158..f7dfaa7d33 100644
--- a/src/corelib/tools/qcollator.cpp
+++ b/src/corelib/tools/qcollator.cpp
@@ -205,6 +205,11 @@ QLocale QCollator::locale() const
By default this mode is off.
+ \note On Windows, this functionality makes use of the \l{ICU} library. If Qt was
+ compiled without ICU support, it falls back to code using native Windows API,
+ which only works from Windows 7 onwards. On older versions of Windows, it will not work
+ and a warning will be emitted at runtime.
+
\sa numericMode()
*/
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index e38a5f569a..801876629c 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -253,7 +253,7 @@ static QString toOffsetString(Qt::DateFormat format, int offset)
return result.arg(offset >= 0 ? QLatin1Char('+') : QLatin1Char('-'))
.arg(qAbs(offset) / SECS_PER_HOUR, 2, 10, QLatin1Char('0'))
- .arg((offset / 60) % 60, 2, 10, QLatin1Char('0'));
+ .arg((qAbs(offset) / 60) % 60, 2, 10, QLatin1Char('0'));
}
// Parse offset in [+-]HH[:]MM format
@@ -265,17 +265,24 @@ static int fromOffsetString(const QString &offsetString, bool *valid)
if (size < 2 || size > 6)
return 0;
+ // sign will be +1 for a positive and -1 for a negative offset
+ int sign;
+
// First char must be + or -
- const QChar sign = offsetString.at(0);
- if (sign != QLatin1Char('+') && sign != QLatin1Char('-'))
+ const QChar signChar = offsetString.at(0);
+ if (signChar == QLatin1Char('+'))
+ sign = 1;
+ else if (signChar == QLatin1Char('-'))
+ sign = -1;
+ else
return 0;
// Split the hour and minute parts
- QStringList parts = offsetString.split(QLatin1Char(':'));
+ QStringList parts = offsetString.mid(1).split(QLatin1Char(':'));
if (parts.count() == 1) {
// [+-]HHMM format
- parts.append(parts.at(0).mid(3));
- parts[0] = parts.at(0).left(3);
+ parts.append(parts.at(0).mid(2));
+ parts[0] = parts.at(0).left(2);
}
bool ok = false;
@@ -288,7 +295,7 @@ static int fromOffsetString(const QString &offsetString, bool *valid)
return 0;
*valid = true;
- return ((hour * 60) + minute) * 60;
+ return sign * ((hour * 60) + minute) * 60;
}
/*****************************************************************************
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index cadf2da019..fbcd271f1d 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -388,7 +388,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Note: Quantifiers are normally "greedy". They always match as much
text as they can. For example, \b{0+} matches the first zero it
finds and all the consecutive zeros after the first zero. Applied
- to '20005', it matches'2\underline{000}5'. Quantifiers can be made
+ to '20005', it matches '2\underline{000}5'. Quantifiers can be made
non-greedy, see setMinimal().
\target capturing parentheses
@@ -678,7 +678,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
QRegExp can match case insensitively using setCaseSensitivity(),
and can use non-greedy matching, see setMinimal(). By
default QRegExp uses full regexps but this can be changed with
- setWildcard(). Searching can be forward with indexIn() or backward
+ setPatternSyntax(). Searching can be done forward with indexIn() or backward
with lastIndexIn(). Captured text can be accessed using
capturedTexts() which returns a string list of all captured
strings, or using cap() which returns the captured string for the
diff --git a/src/corelib/tools/qsize.cpp b/src/corelib/tools/qsize.cpp
index b53eced298..c9a6ffa03a 100644
--- a/src/corelib/tools/qsize.cpp
+++ b/src/corelib/tools/qsize.cpp
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
width and height can be swapped using the transpose() function.
The isValid() function determines if a size is valid (a valid size
- has both width and height greater than zero). The isEmpty()
+ has both width and height greater than or equal to zero). The isEmpty()
function returns \c true if either of the width and height is less
than, or equal to, zero, while the isNull() function returns \c true
only if both the width and the height is zero.
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 863cf03439..57a9591060 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -163,10 +163,10 @@ contains(QT_CONFIG,icu) {
LIBS_PRIVATE += -lsicuin -lsicuuc -lsicudt
}
} else {
- LIBS_PRIVATE += -licuin -licuuc
+ LIBS_PRIVATE += -licuin -licuuc -licudt
}
} else {
- LIBS_PRIVATE += -licui18n -licuuc
+ LIBS_PRIVATE += -licui18n -licuuc -licudata
}
} else: win32 {
SOURCES += tools/qcollator_win.cpp
diff --git a/src/dbus/Qt5DBusMacros.cmake b/src/dbus/Qt5DBusMacros.cmake
index ff497e8ebc..2364c6710c 100644
--- a/src/dbus/Qt5DBusMacros.cmake
+++ b/src/dbus/Qt5DBusMacros.cmake
@@ -32,6 +32,7 @@
include(MacroAddFileDependencies)
+include(CMakeParseArguments)
function(QT5_ADD_DBUS_INTERFACE _sources _interface _basename)
get_filename_component(_infile ${_interface} ABSOLUTE)
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index 839a7a709f..2915cdda2d 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -59,6 +59,7 @@ static int global_ser_no = 0;
QBlittablePlatformPixmap::QBlittablePlatformPixmap()
: QPlatformPixmap(QPlatformPixmap::PixmapType,BlitterClass)
, m_alpha(false)
+ , m_devicePixelRatio(1.0)
#ifdef QT_BLITTER_RASTEROVERLAY
,m_rasterOverlay(0), m_unmergedCopy(0)
#endif //QT_BLITTER_RASTEROVERLAY
@@ -121,7 +122,7 @@ int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) con
case QPaintDevice::PdmPhysicalDpiY:
return qt_defaultDpiY();
case QPaintDevice::PdmDevicePixelRatio:
- return 1;
+ return devicePixelRatio();
default:
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
break;
@@ -178,6 +179,7 @@ void QBlittablePlatformPixmap::fromImage(const QImage &image,
Qt::ImageConversionFlags flags)
{
m_alpha = image.hasAlphaChannel();
+ m_devicePixelRatio = image.devicePixelRatio();
resize(image.width(),image.height());
markRasterOverlay(QRect(0,0,w,h));
QImage *thisImg = buffer();
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index ab71fe9081..8ccff4321d 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -466,7 +466,14 @@ static QWindowGeometrySpecification windowGeometrySpecification;
\section1 Supported Command Line Options
- All Qt programs automatically support the following command line options:
+ All Qt programs automatically support a set of command-line options that
+ allow modifying the way Qt will interact with the windowing system. Some of
+ the options are also accessible via environment variables, which are the
+ preferred form if the application can launch GUI sub-processes or other
+ applications (environment variables will be inherited by child processes).
+ When in doubt, use the environment variables.
+
+ The options currently supported are the following:
\list
\li \c{-platform} \e {platformName[:options]}, specifies the
@@ -489,18 +496,21 @@ static QWindowGeometrySpecification windowGeometrySpecification;
\li \c {-qwindowgeometry} \e geometry, specifies window geometry for
the main window using the X11-syntax. For example:
\c {-qwindowgeometry 100x100+50+50}
+ \li \c {-qwindowtitle}, sets the title of the first window
\li \c{-reverse}, sets the application's layout direction to
- Qt::RightToLeft
+ Qt::RightToLeft. This option is intended to aid debugging and should
+ not be used in production. The default value is automatically detected
+ from the user's locale (see also QLocale::textDirection()).
\li \c{-session} \e session, restores the application from an earlier
\l{Session Management}{session}.
- \li -qwindowgeometry, sets the geometry of the first window
- \li -qwindowtitle, sets the title of the first window
\endlist
The following standard command line options are available for X11:
\list
\li \c {-display} \e {hostname:screen_number}, switches displays on X11.
+
+ Overrides the \c DISPLAY environment variable.
\li \c {-geometry} \e geometry, same as \c {-qwindowgeometry}.
\endlist
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 1af5c09fd2..be592153d2 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -1345,7 +1345,8 @@ void QOpenGLSharedResourceGuard::freeResource(QOpenGLContext *context)
QOpenGLMultiGroupSharedResource instance.
*/
QOpenGLMultiGroupSharedResource::QOpenGLMultiGroupSharedResource()
- : active(0)
+ : active(0),
+ m_mutex(QMutex::Recursive)
{
#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
qDebug("Creating context group resource object %p.", this);
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
index b21ff67068..711a3b1b2f 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -127,7 +127,7 @@ private:
class Q_GUI_EXPORT QOpenGLContextGroupPrivate : public QObjectPrivate
{
- Q_DECLARE_PUBLIC(QOpenGLContextGroup);
+ Q_DECLARE_PUBLIC(QOpenGLContextGroup)
public:
QOpenGLContextGroupPrivate()
: m_context(0)
@@ -171,7 +171,9 @@ public:
template <typename T>
T *value(QOpenGLContext *context) {
QOpenGLContextGroup *group = context->shareGroup();
- QMutexLocker locker(&group->d_func()->m_mutex);
+ // Have to use our own mutex here, not the group's, since
+ // m_groups has to be protected too against any concurrent access.
+ QMutexLocker locker(&m_mutex);
T *resource = static_cast<T *>(group->d_func()->m_resources.value(this, 0));
if (!resource) {
resource = new T(context);
@@ -183,6 +185,7 @@ public:
private:
QAtomicInt active;
QList<QOpenGLContextGroup *> m_groups;
+ QMutex m_mutex;
};
class QPaintEngineEx;
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index 19e2d9bccf..b88f2a7e84 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -86,6 +86,9 @@ public:
virtual void setChecked(bool isChecked) = 0;
virtual void setShortcut(const QKeySequence& shortcut) = 0;
virtual void setEnabled(bool enabled) = 0;
+
+ virtual void setNativeContents(WId item) { Q_UNUSED(item); }
+
Q_SIGNALS:
void activated();
void hovered();
@@ -118,6 +121,8 @@ public:
setVisible(true);
}
+ virtual void dismiss() { } // Closes this and all its related menu popups
+
virtual QPlatformMenuItem *menuItemAt(int position) const = 0;
virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const = 0;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 6dcc3df166..40e9b9723a 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -455,7 +455,7 @@ void QWindow::setVisible(bool visible)
}
#ifndef QT_NO_CURSOR
- if (visible && d->hasCursor)
+ if (visible && (d->hasCursor || QGuiApplication::overrideCursor()))
d->applyCursor();
#endif
d->platformWindow->setVisible(visible);
@@ -743,7 +743,7 @@ void QWindow::setTitle(const QString &title)
d->windowTitle = title;
changed = true;
}
- if (d->platformWindow)
+ if (d->platformWindow && type() != Qt::Desktop)
d->platformWindow->setWindowTitle(title);
if (changed)
emit windowTitleChanged(title);
diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h
index 190c05ba26..ef5ab9aa65 100644
--- a/src/gui/opengl/qopengl.h
+++ b/src/gui/opengl/qopengl.h
@@ -112,17 +112,19 @@ typedef GLfloat GLdouble;
# endif // Q_OS_MAC
#endif // QT_OPENGL_ES_2
-// Desktops, apart from Mac OS X prior to 10.7 can support OpenGL 3
-// and desktops apart from Mac can support OpenGL 4
+// Desktops, apart from Mac OS X prior to 10.7 can support OpenGL 3.
+// Desktops, apart from Mac OS X prior to 10.9 can support OpenGL 4.
#if !defined(QT_OPENGL_ES_2)
# if !defined(Q_OS_MAC) || (defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
# define QT_OPENGL_3
# define QT_OPENGL_3_2
# endif
-#if !defined(Q_OS_MAC)
+# if !defined(Q_OS_MAC) || (defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9)
# define QT_OPENGL_4
+# endif
+# if !defined(Q_OS_MAC)
# define QT_OPENGL_4_3
-#endif
+# endif
#endif
QT_BEGIN_NAMESPACE
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index cc829df950..7fb6815120 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -1112,6 +1112,9 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format,
\fn QImage QOpenGLFramebufferObject::toImage() const
Returns the contents of this framebuffer object as a QImage.
+
+ Will try to return a premultiplied ARBG32 or RGB32 image. Since 5.2 it will fall back to
+ a premultiplied RGBA8888 or RGBx8888 image when reading to ARGB32 is not supported.
*/
QImage QOpenGLFramebufferObject::toImage() const
{
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index c4862945bb..6e85e5eb4b 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -2236,6 +2236,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& v
Sets the uniform variable at \a location in the current context
to a 2x3 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat2x3, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec3.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
@@ -2251,6 +2255,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value
Sets the uniform variable called \a name in the current context
to a 2x3 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat2x3, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec3.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value)
@@ -2262,6 +2270,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& v
Sets the uniform variable at \a location in the current context
to a 2x4 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat2x4, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec4.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
@@ -2277,6 +2289,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value
Sets the uniform variable called \a name in the current context
to a 2x4 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat2x4, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec4.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value)
@@ -2288,6 +2304,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& v
Sets the uniform variable at \a location in the current context
to a 3x2 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat3x2, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec2.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
@@ -2303,6 +2323,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value
Sets the uniform variable called \a name in the current context
to a 3x2 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat3x2, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec2.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value)
@@ -2340,6 +2364,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& v
Sets the uniform variable at \a location in the current context
to a 3x4 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat3x4, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec4.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
@@ -2355,6 +2383,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value
Sets the uniform variable called \a name in the current context
to a 3x4 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat3x4, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec4.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value)
@@ -2366,6 +2398,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& v
Sets the uniform variable at \a location in the current context
to a 4x2 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat4x2, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec2.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
@@ -2381,6 +2417,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value
Sets the uniform variable called \a name in the current context
to a 4x2 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat4x2, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec2.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value)
@@ -2392,6 +2432,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& v
Sets the uniform variable at \a location in the current context
to a 4x3 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat4x3, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec3.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
@@ -2407,6 +2451,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value
Sets the uniform variable called \a name in the current context
to a 4x3 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat4x3, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec3.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value)
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index 445e3ed64e..e3444332a0 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -180,6 +180,10 @@ bool QOpenGLTexturePrivate::create()
void QOpenGLTexturePrivate::destroy()
{
+ if (!context) {
+ // not created or already destroyed
+ return;
+ }
if (QOpenGLContext::currentContext() != context) {
qWarning("Requires a valid current OpenGL context.\n"
"Texture has not been destroyed");
diff --git a/src/gui/painting/qblittable_p.h b/src/gui/painting/qblittable_p.h
index 159e60079f..f65549d63c 100644
--- a/src/gui/painting/qblittable_p.h
+++ b/src/gui/painting/qblittable_p.h
@@ -68,7 +68,7 @@ public:
// Internal ones
OutlineCapability = 0x0001000
};
- Q_DECLARE_FLAGS (Capabilities, Capability);
+ Q_DECLARE_FLAGS (Capabilities, Capability)
QBlittable(const QSize &size, Capabilities caps);
virtual ~QBlittable();
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 7a5c5dc660..b5ccafdf9a 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -1709,6 +1709,163 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
}
} else {
//we are zooming less than 8x, use 4bit precision
+
+ if (blendType != BlendTransformedBilinearTiled) {
+#define BILINEAR_ROTATE_BOUNDS_PROLOG \
+ while (b < end) { \
+ int x1 = (fx >> 16); \
+ int x2; \
+ int y1 = (fy >> 16); \
+ int y2; \
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); \
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); \
+ if (x1 != x2 && y1 != y2) \
+ break; \
+ const uint *s1 = (const uint *)data->texture.scanLine(y1); \
+ const uint *s2 = (const uint *)data->texture.scanLine(y2); \
+ uint tl = s1[x1]; \
+ uint tr = s1[x2]; \
+ uint bl = s2[x1]; \
+ uint br = s2[x2]; \
+ int distx = (fx & 0x0000ffff) >> 12; \
+ int disty = (fy & 0x0000ffff) >> 12; \
+ *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); \
+ fx += fdx; \
+ fy += fdy; \
+ ++b; \
+ } \
+ uint *boundedEnd = end - 3; \
+ boundedEnd -= 3;
+
+#if defined(__SSE2__)
+ BILINEAR_ROTATE_BOUNDS_PROLOG
+
+ const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+ const __m128i v_256 = _mm_set1_epi16(256);
+ __m128i v_fdx = _mm_set1_epi32(fdx*4);
+ __m128i v_fdy = _mm_set1_epi32(fdy*4);
+
+ const uchar *textureData = data->texture.imageData;
+ const int bytesPerLine = data->texture.bytesPerLine;
+
+ union Vect_buffer { __m128i vect; qint32 i[4]; };
+ Vect_buffer v_fx, v_fy;
+
+ for (int i = 0; i < 4; i++) {
+ v_fx.i[i] = fx;
+ v_fy.i[i] = fy;
+ fx += fdx;
+ fy += fdy;
+ }
+
+ while (b < boundedEnd) {
+ if (fdx > 0 && (v_fx.i[3] >> 16) >= image_x2)
+ break;
+ if (fdx < 0 && (v_fx.i[3] >> 16) < image_x1)
+ break;
+ if (fdy > 0 && (v_fy.i[3] >> 16) >= image_y2)
+ break;
+ if (fdy < 0 && (v_fy.i[3] >> 16) < image_y1)
+ break;
+
+ Vect_buffer tl, tr, bl, br;
+ Vect_buffer v_fx_shifted, v_fy_shifted;
+ v_fx_shifted.vect = _mm_srli_epi32(v_fx.vect, 16);
+ v_fy_shifted.vect = _mm_srli_epi32(v_fy.vect, 16);
+
+ for (int i = 0; i < 4; i++) {
+ const int x1 = v_fx_shifted.i[i];
+ const int y1 = v_fy_shifted.i[i];
+ const uchar *sl = textureData + bytesPerLine * y1;
+ const uint *s1 = (const uint *)sl;
+ const uint *s2 = (const uint *)(sl + bytesPerLine);
+ tl.i[i] = s1[x1];
+ tr.i[i] = s1[x1+1];
+ bl.i[i] = s2[x1];
+ br.i[i] = s2[x1+1];
+ }
+ __m128i v_distx = _mm_srli_epi16(v_fx.vect, 12);
+ __m128i v_disty = _mm_srli_epi16(v_fy.vect, 12);
+ v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
+ v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
+ v_disty = _mm_shufflehi_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
+ v_disty = _mm_shufflelo_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
+
+ interpolate_4_pixels_16_sse2(tl.vect, tr.vect, bl.vect, br.vect, v_distx, v_disty, colorMask, v_256, b);
+ b+=4;
+ v_fx.vect = _mm_add_epi32(v_fx.vect, v_fdx);
+ v_fy.vect = _mm_add_epi32(v_fy.vect, v_fdy);
+ }
+ fx = v_fx.i[0];
+ fy = v_fy.i[0];
+#elif defined(__ARM_NEON__)
+ BILINEAR_ROTATE_BOUNDS_PROLOG
+
+ const int16x8_t colorMask = vdupq_n_s16(0x00ff);
+ const int16x8_t invColorMask = vmvnq_s16(colorMask);
+ const int16x8_t v_256 = vdupq_n_s16(256);
+ int32x4_t v_fdx = vdupq_n_s32(fdx*4);
+ int32x4_t v_fdy = vdupq_n_s32(fdy*4);
+
+ const uchar *textureData = data->texture.imageData;
+ const int bytesPerLine = data->texture.bytesPerLine;
+
+ union Vect_buffer { int32x4_t vect; quint32 i[4]; };
+ Vect_buffer v_fx, v_fy;
+
+ for (int i = 0; i < 4; i++) {
+ v_fx.i[i] = fx;
+ v_fy.i[i] = fy;
+ fx += fdx;
+ fy += fdy;
+ }
+
+ const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
+
+ while (b < boundedEnd) {
+ if (fdx > 0 && (v_fx.i[3] >> 16) >= image_x2)
+ break;
+ if (fdx < 0 && (v_fx.i[3] >> 16) < image_x1)
+ break;
+ if (fdy > 0 && (v_fy.i[3] >> 16) >= image_y2)
+ break;
+ if (fdy < 0 && (v_fy.i[3] >> 16) < image_y1)
+ break;
+
+ Vect_buffer tl, tr, bl, br;
+
+ Vect_buffer v_fx_shifted, v_fy_shifted;
+ v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16);
+ v_fy_shifted.vect = vshrq_n_s32(v_fy.vect, 16);
+
+ for (int i = 0; i < 4; i++) {
+ const int x1 = v_fx_shifted.i[i];
+ const int y1 = v_fy_shifted.i[i];
+ const uchar *sl = textureData + bytesPerLine * y1;
+ const uint *s1 = (const uint *)sl;
+ const uint *s2 = (const uint *)(sl + bytesPerLine);
+ tl.i[i] = s1[x1];
+ tr.i[i] = s1[x1+1];
+ bl.i[i] = s2[x1];
+ br.i[i] = s2[x1+1];
+ }
+
+ int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12);
+ int32x4_t v_disty = vshrq_n_s32(vandq_s32(v_fy.vect, v_ffff_mask), 12);
+ v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
+ v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16));
+ int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4);
+
+ interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b);
+ b+=4;
+ v_fx.vect = vaddq_s32(v_fx.vect, v_fdx);
+ v_fy.vect = vaddq_s32(v_fy.vect, v_fdy);
+ }
+ fx = v_fx.i[0];
+ fy = v_fy.i[0];
+#endif
+ }
+
while (b < end) {
int x1 = (fx >> 16);
int x2;
diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp
index 26eacacd49..67a692e2db 100644
--- a/src/gui/painting/qpaintengine_blitter.cpp
+++ b/src/gui/painting/qpaintengine_blitter.cpp
@@ -238,7 +238,7 @@ private:
class QBlitterPaintEnginePrivate : public QRasterPaintEnginePrivate
{
- Q_DECLARE_PUBLIC(QBlitterPaintEngine);
+ Q_DECLARE_PUBLIC(QBlitterPaintEngine)
public:
QBlitterPaintEnginePrivate(QBlittablePlatformPixmap *p)
: QRasterPaintEnginePrivate()
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index bfcb24ae3a..ce8c1d1ca7 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -235,21 +235,6 @@ static const QRectF boundingRect(const QPointF *points, int pointCount)
}
#endif
-template <typename T> static inline bool isRect(const T *pts, int elementCount) {
- return (elementCount == 5 // 5-point polygon, check for closed rect
- && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point
- && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
- && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
- && pts[0] < pts[4] && pts[1] < pts[5]
- ) ||
- (elementCount == 4 // 4-point polygon, check for unclosed rect
- && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
- && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
- && pts[0] < pts[4] && pts[1] < pts[5]
- );
-}
-
-
static void qt_ft_outline_move_to(qfixed x, qfixed y, void *data)
{
((QOutlineMapper *) data)->moveTo(QPointF(qt_fixed_to_real(x), qt_fixed_to_real(y)));
@@ -1193,22 +1178,14 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
- const qreal *points = path.points();
- const QPainterPath::ElementType *types = path.elements();
-
// There are some cases that are not supported by clip(QRect)
if (op != Qt::IntersectClip || !s->clip || s->clip->hasRectClip || s->clip->hasRegionClip) {
if (s->matrix.type() <= QTransform::TxScale
- && ((path.shape() == QVectorPath::RectangleHint)
- || (isRect(points, path.elementCount())
- && (!types || (types[0] == QPainterPath::MoveToElement
- && types[1] == QPainterPath::LineToElement
- && types[2] == QPainterPath::LineToElement
- && types[3] == QPainterPath::LineToElement))))) {
+ && path.isRect()) {
#ifdef QT_DEBUG_DRAW
qDebug() << " --- optimizing vector clip to rect clip...";
#endif
-
+ const qreal *points = path.points();
QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]);
if (setClipRectInDeviceCoords(s->matrix.mapRect(r).toRect(), op))
return;
@@ -1939,7 +1916,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly
#endif
Q_ASSERT(pointCount >= 2);
- if (mode != PolylineMode && isRect((qreal *) points, pointCount)) {
+ if (mode != PolylineMode && QVectorPath::isRect((qreal *) points, pointCount)) {
QRectF r(points[0], points[2]);
drawRects(&r, 1);
return;
@@ -1980,7 +1957,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
qDebug() << " - " << points[i];
#endif
Q_ASSERT(pointCount >= 2);
- if (mode != PolylineMode && isRect((int *) points, pointCount)) {
+ if (mode != PolylineMode && QVectorPath::isRect((int *) points, pointCount)) {
QRect r(points[0].x(),
points[0].y(),
points[2].x() - points[0].x(),
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index fe5fc051df..3f387d575b 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -147,8 +147,9 @@ static inline uint line_emulation(uint emulation)
}
#ifndef QT_NO_DEBUG
-static bool qt_painter_thread_test(int devType, const char *what)
+static bool qt_painter_thread_test(int devType, int engineType, const char *what)
{
+ const QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
switch (devType) {
case QInternal::Image:
case QInternal::Printer:
@@ -157,8 +158,13 @@ static bool qt_painter_thread_test(int devType, const char *what)
break;
default:
if (QThread::currentThread() != qApp->thread()
- && (devType!=QInternal::Pixmap || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps))
- && (devType!=QInternal::OpenGL || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL))) {
+ // pixmaps cannot be targets unless threaded pixmaps are supported
+ && (devType != QInternal::Pixmap || !platformIntegration->hasCapability(QPlatformIntegration::ThreadedPixmaps))
+ // framebuffer objects and such cannot be targets unless threaded GL is supported
+ && (devType != QInternal::OpenGL || !platformIntegration->hasCapability(QPlatformIntegration::ThreadedOpenGL))
+ // widgets cannot be targets except for QGLWidget
+ && (devType != QInternal::Widget || !platformIntegration->hasCapability(QPlatformIntegration::ThreadedOpenGL)
+ || (engineType != QPaintEngine::OpenGL && engineType != QPaintEngine::OpenGL2))) {
qWarning("QPainter: It is not safe to use %s outside the GUI thread", what);
return false;
}
@@ -5054,7 +5060,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
return;
#ifndef QT_NO_DEBUG
- qt_painter_thread_test(d->device->devType(), "drawPixmap()");
+ qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawPixmap()");
#endif
if (d->extended) {
@@ -5125,7 +5131,7 @@ void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
if (!d->engine || pm.isNull())
return;
#ifndef QT_NO_DEBUG
- qt_painter_thread_test(d->device->devType(), "drawPixmap()");
+ qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawPixmap()");
#endif
qreal x = r.x();
@@ -6610,7 +6616,7 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo
return;
#ifndef QT_NO_DEBUG
- qt_painter_thread_test(d->device->devType(), "drawTiledPixmap()");
+ qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawTiledPixmap()");
#endif
qreal sw = pixmap.width();
diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h
index e97d6e1dce..ca95c32597 100644
--- a/src/gui/painting/qvectorpath_p.h
+++ b/src/gui/painting/qvectorpath_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -167,6 +167,32 @@ public:
return 0;
}
+ template <typename T> static inline bool isRect(const T *pts, int elementCount) {
+ return (elementCount == 5 // 5-point polygon, check for closed rect
+ && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point
+ && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
+ && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
+ && pts[0] < pts[4] && pts[1] < pts[5]
+ ) ||
+ (elementCount == 4 // 4-point polygon, check for unclosed rect
+ && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
+ && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
+ && pts[0] < pts[4] && pts[1] < pts[5]
+ );
+ }
+
+ inline bool isRect() const
+ {
+ const QPainterPath::ElementType * const types = elements();
+
+ return (shape() == QVectorPath::RectangleHint)
+ || (isRect(points(), elementCount())
+ && (!types || (types[0] == QPainterPath::MoveToElement
+ && types[1] == QPainterPath::LineToElement
+ && types[2] == QPainterPath::LineToElement
+ && types[3] == QPainterPath::LineToElement)));
+ }
+
private:
Q_DISABLE_COPY(QVectorPath)
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 558258c30e..06438103ad 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -2501,10 +2501,14 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp,
if (!engine) {
if (!request.family.isEmpty()) {
+ QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
+ if (styleHint == QFont::AnyStyle && request.fixedPitch)
+ styleHint = QFont::TypeWriter;
+
QStringList fallbacks = request.fallBackFamilies
+ fallbackFamilies(request.family,
QFont::Style(request.style),
- QFont::StyleHint(request.styleHint),
+ styleHint,
QChar::Script(script));
if (script > QChar::Script_Common)
fallbacks += QString(); // Find the first font matching the specified script.
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index b2254c4826..078e16574f 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1335,6 +1335,15 @@ QByteArray QFontEngine::convertToPostscriptFontFamilyName(const QByteArray &fami
return f;
}
+/**
+ * Some font engines like the windows font engine
+ * can not reliable create outline paths
+ */
+bool QFontEngine::hasUnreliableGlyphOutline() const
+{
+ return false;
+}
+
QFixed QFontEngine::lastRightBearing(const QGlyphLayout &glyphs, bool round)
{
if (glyphs.numGlyphs >= 1) {
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index fe38755ffd..f5ca559d62 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -450,6 +450,7 @@ static void scaleOutline(FT_Face face, FT_GlyphSlot g, FT_Fixed x_scale, FT_Fixe
}
}
+#define GLYPH2PATH_DEBUG QT_NO_QDEBUG_MACRO // qDebug
void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoint &point, QPainterPath *path, FT_Fixed x_scale, FT_Fixed y_scale)
{
const qreal factor = 1/64.;
@@ -461,22 +462,32 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
int i = 0;
for (int j = 0; j < g->outline.n_contours; ++j) {
int last_point = g->outline.contours[j];
- QPointF start = cp + QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
- if(!(g->outline.tags[i] & 1)) {
- start += cp + QPointF(g->outline.points[last_point].x*factor, -g->outline.points[last_point].y*factor);
- start /= 2;
+ GLYPH2PATH_DEBUG() << "contour:" << i << "to" << last_point;
+ QPointF start = QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
+ if (!(g->outline.tags[i] & 1)) { // start point is not on curve:
+ if (!(g->outline.tags[last_point] & 1)) { // end point is not on curve:
+ GLYPH2PATH_DEBUG() << " start and end point are not on curve";
+ start = (QPointF(g->outline.points[last_point].x*factor,
+ -g->outline.points[last_point].y*factor) + start) / 2.0;
+ } else {
+ GLYPH2PATH_DEBUG() << " end point is on curve, start is not";
+ start = QPointF(g->outline.points[last_point].x*factor,
+ -g->outline.points[last_point].y*factor);
+ }
+ --i; // to use original start point as control point below
}
-// qDebug("contour: %d -- %d", i, g->outline.contours[j]);
-// qDebug("first point at %f %f", start.x(), start.y());
- path->moveTo(start);
+ start += cp;
+ GLYPH2PATH_DEBUG() << " start at" << start;
+ path->moveTo(start);
QPointF c[4];
c[0] = start;
int n = 1;
while (i < last_point) {
++i;
c[n] = cp + QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
-// qDebug() << " i=" << i << " flag=" << (int)g->outline.tags[i] << "point=" << c[n];
+ GLYPH2PATH_DEBUG() << " " << i << c[n] << "tag =" << (int)g->outline.tags[i]
+ << ": on curve =" << (bool)(g->outline.tags[i] & 1);
++n;
switch (g->outline.tags[i] & 3) {
case 2:
@@ -498,7 +509,7 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
case 1:
case 3:
if (n == 2) {
-// qDebug() << "lineTo" << c[1];
+ GLYPH2PATH_DEBUG() << " lineTo" << c[1];
path->lineTo(c[1]);
c[0] = c[1];
n = 1;
@@ -510,13 +521,14 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
}
break;
}
-// qDebug() << "cubicTo" << c[1] << c[2] << c[3];
+ GLYPH2PATH_DEBUG() << " cubicTo" << c[1] << c[2] << c[3];
path->cubicTo(c[1], c[2], c[3]);
c[0] = c[3];
n = 1;
}
+
if (n == 1) {
-// qDebug() << "closeSubpath";
+ GLYPH2PATH_DEBUG() << " closeSubpath";
path->closeSubpath();
} else {
c[3] = start;
@@ -524,7 +536,7 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
c[2] = (2*c[1] + c[3])/3;
c[1] = (2*c[1] + c[0])/3;
}
-// qDebug() << "cubicTo" << c[1] << c[2] << c[3];
+ GLYPH2PATH_DEBUG() << " close cubicTo" << c[1] << c[2] << c[3];
path->cubicTo(c[1], c[2], c[3]);
}
++i;
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 5e40abbda6..fc849d788f 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -251,6 +251,8 @@ public:
static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);
+ virtual bool hasUnreliableGlyphOutline() const;
+
enum HintStyle {
HintNone,
HintLight,
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index c3cf2e56bb..84ad9038d5 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -2810,7 +2810,6 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
break;
glyph_pos = gs;
edge = pos;
- break;
}
pos -= glyphs.effectiveAdvance(gs);
++gs;
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index e03dcb8ead..76107d3110 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -352,8 +352,10 @@ void QHttpThreadDelegate::startRequest()
connect(httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
this, SLOT(synchronousAuthenticationRequiredSlot(QHttpNetworkRequest,QAuthenticator*)));
+#ifndef QT_NO_NETWORKPROXY
connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
this, SLOT(synchronousProxyAuthenticationRequiredSlot(QNetworkProxy,QAuthenticator*)));
+#endif
// Don't care about ignored SSL errors for now in the synchronous HTTP case.
} else if (!synchronous) {
@@ -373,8 +375,10 @@ void QHttpThreadDelegate::startRequest()
// Connect the reply signals that we can directly forward
connect(httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
this, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)));
+#ifndef QT_NO_NETWORKPROXY
connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
+#endif
}
connect(httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)),
@@ -706,9 +710,11 @@ void QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot(const QNet
a->setPassword(credential.password);
}
+#ifndef QT_NO_NETWORKPROXY
// Disconnect this connection now since we only want to ask the authentication cache once.
QObject::disconnect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
this, SLOT(synchronousProxyAuthenticationRequiredSlot(QNetworkProxy,QAuthenticator*)));
+#endif
}
#endif
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index b8f76f8d4f..bead45ab83 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -509,7 +509,7 @@ static QByteArray qt_prettyDebug(const char *data, int len, int maxLength)
{
if (!data) return "(null)";
QByteArray out;
- for (int i = 0; i < len; ++i) {
+ for (int i = 0; i < qMin(len, maxLength); ++i) {
char c = data[i];
if (isprint(int(uchar(c)))) {
out += c;
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 45e2fabfe9..2ee69d35da 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -1438,8 +1438,10 @@ void QSslSocketBackendPrivate::continueHandshake()
if (readBufferMaxSize)
plainSocket->setReadBufferSize(readBufferMaxSize);
+#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
if (q_SSL_ctrl((ssl), SSL_CTRL_GET_SESSION_REUSED, 0, NULL))
configuration.peerSessionShared = true;
+#endif
#ifdef QT_DECRYPT_SSL_TRAFFIC
if (ssl->session && ssl->s3) {
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 78c4b23665..5d4ca42dc2 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -223,11 +223,19 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size)
currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
+ GLuint wrapMode = GL_REPEAT;
+ if (ctx->contextHandle()->isOpenGLES()) {
+ // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
+ // we emulate GL_REPEAT by only taking the fractional part of the texture coords
+ // in the qopenglslTextureBrushSrcFragmentShader program.
+ wrapMode = GL_CLAMP_TO_EDGE;
+ }
+
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA,
QGLContext::InternalBindOption |
QGLContext::CanFlipNativePixmapBindOption);
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
textureInvertedY = tex->options & QGLContext::InvertedYBindOption ? -1 : 1;
}
brushTextureDirty = false;
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index ae70072c4d..02ea6e45e3 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2497,7 +2497,19 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
}
if (!texture) {
- QImage image = pixmap.toImage();
+ QImage image;
+ QPaintEngine* paintEngine = pixmap.paintEngine();
+ if (!paintEngine || paintEngine->type() != QPaintEngine::Raster)
+ image = pixmap.toImage();
+ else {
+ // QRasterPixmapData::toImage() will deep-copy the backing QImage if there's an active QPainter on it.
+ // For performance reasons, we don't want that here, so we temporarily redirect the paint engine.
+ QPaintDevice* currentPaintDevice = paintEngine->paintDevice();
+ paintEngine->setPaintDevice(0);
+ image = pixmap.toImage();
+ paintEngine->setPaintDevice(currentPaintDevice);
+ }
+
// If the system depth is 16 and the pixmap doesn't have an alpha channel
// then we convert it to RGB16 in the hope that it gets uploaded as a 16
// bit texture which is much faster to access than a 32-bit one.
diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp
index 75789db153..5eed47050f 100644
--- a/src/platformsupport/eglconvenience/qeglconvenience.cpp
+++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp
@@ -66,26 +66,30 @@ QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format)
int stencilSize = format.stencilBufferSize();
int sampleCount = format.samples();
- // We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide
- // the best performance. The EGL config selection algorithm is a bit stange in this regard:
- // The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard
- // 32-bit configs completely from the selection. So it then comes to the sorting algorithm.
- // The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort
- // order is special and described as "by larger _total_ number of color bits.". So EGL will
- // put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on
- // to say "If the requested number of bits in attrib_list for a particular component is 0,
- // then the number of bits for that component is not considered". This part of the spec also
- // seems to imply that setting the red/green/blue bits to zero means none of the components
- // are considered and EGL disregards the entire sorting rule. It then looks to the next
- // highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being
- // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are
- // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit,
- // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that
- // if the application sets the red/green/blue size to 5/6/5 on the QSurfaceFormat,
- // they might still get a 32-bit config, even when there's an RGB565 config available.
-
QVector<EGLint> configAttributes;
+ // Map default, unspecified values (-1) to 0. This is important due to sorting rule #3
+ // in section 3.4.1 of the spec and allows picking a potentially faster 16-bit config
+ // over 32-bit ones when there is no explicit request for the color channel sizes:
+ //
+ // The red/green/blue sizes have a sort priority of 3, so they are sorted by
+ // first. (unless a caveat like SLOW or NON_CONFORMANT is present) The sort order is
+ // Special and described as "by larger _total_ number of color bits.". So EGL will put
+ // 32-bit configs in the list before the 16-bit configs. However, the spec also goes
+ // on to say "If the requested number of bits in attrib_list for a particular
+ // component is 0, then the number of bits for that component is not considered". This
+ // part of the spec also seems to imply that setting the red/green/blue bits to zero
+ // means none of the components are considered and EGL disregards the entire sorting
+ // rule. It then looks to the next highest priority rule, which is
+ // EGL_BUFFER_SIZE. Despite the selection criteria being "AtLeast" for
+ // EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are put in the
+ // list before 32-bit configs.
+ //
+ // This also means that explicitly specifying a size like 565 will still result in
+ // having larger (888) configs first in the returned list. We need to handle this
+ // ourselves later by manually filtering the list, instead of just blindly taking the
+ // first config from it.
+
configAttributes.append(EGL_RED_SIZE);
configAttributes.append(redSize > 0 ? redSize : 0);
@@ -293,6 +297,13 @@ EGLConfig QEglConfigChooser::chooseConfig()
if (!cfg && matching > 0)
cfg = configs.first();
+ // Filter the list. Due to the EGL sorting rules configs with higher depth are
+ // placed first when the minimum color channel sizes have been specified (i.e. the
+ // QSurfaceFormat contains color sizes > 0). To prevent returning a 888 config
+ // when the QSurfaceFormat explicitly asked for 565, go through the returned
+ // configs and look for one that exactly matches the requested sizes. When no
+ // sizes have been given, take the first, which will be a config with the smaller
+ // (e.g. 16-bit) depth.
for (int i = 0; i < configs.size(); ++i) {
if (filterConfig(configs[i]))
return configs.at(i);
@@ -306,6 +317,8 @@ EGLConfig QEglConfigChooser::chooseConfig()
bool QEglConfigChooser::filterConfig(EGLConfig config) const
{
+ // If we are fine with the highest depth (e.g. RGB888 configs) even when something
+ // smaller (565) was explicitly requested, do nothing.
if (m_ignore)
return true;
@@ -314,6 +327,7 @@ bool QEglConfigChooser::filterConfig(EGLConfig config) const
EGLint blue = 0;
EGLint alpha = 0;
+ // Compare only if a size was given. Otherwise just accept.
if (m_confAttrRed)
eglGetConfigAttrib(display(), config, EGL_RED_SIZE, &red);
if (m_confAttrGreen)
diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp
index b1df6d816a..5f3b6b4bd6 100644
--- a/src/plugins/accessible/widgets/complexwidgets.cpp
+++ b/src/plugins/accessible/widgets/complexwidgets.cpp
@@ -315,19 +315,19 @@ QString QAccessibleComboBox::text(QAccessible::Text t) const
QStringList QAccessibleComboBox::actionNames() const
{
- return QStringList(showMenuAction());
+ return QStringList() << showMenuAction() << pressAction();
}
QString QAccessibleComboBox::localizedActionDescription(const QString &actionName) const
{
- if (actionName == showMenuAction())
+ if (actionName == showMenuAction() || actionName == pressAction())
return QComboBox::tr("Open the combo box selection popup");
return QString();
}
void QAccessibleComboBox::doAction(const QString &actionName)
{
- if (actionName == showMenuAction()) {
+ if (actionName == showMenuAction() || actionName == pressAction()) {
if (comboBox()->view()->isVisible()) {
comboBox()->hidePopup();
} else {
diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp
index 646eeb06a1..a5365b2598 100644
--- a/src/plugins/accessible/widgets/simplewidgets.cpp
+++ b/src/plugins/accessible/widgets/simplewidgets.cpp
@@ -647,10 +647,6 @@ QAccessible::State QAccessibleLineEdit::state() const
if (l->hasSelectedText())
state.selected = true;
- if (l->contextMenuPolicy() != Qt::NoContextMenu
- && l->contextMenuPolicy() != Qt::PreventContextMenu)
- state.hasPopup = true;
-
return state;
}
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
index 74a25c1370..9493218024 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
@@ -197,7 +197,7 @@ public:
Privacy = 0x1
};
- Q_DECLARE_FLAGS(ApFlags, ApFlag);
+ Q_DECLARE_FLAGS(ApFlags, ApFlag)
enum ApSecurityFlag {
ApSecurityNone = 0x0,
@@ -213,7 +213,7 @@ public:
Key8021x = 0x200
};
- Q_DECLARE_FLAGS(ApSecurityFlags, ApSecurityFlag);
+ Q_DECLARE_FLAGS(ApSecurityFlags, ApSecurityFlag)
explicit QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent = 0);
~QNetworkManagerInterfaceAccessPoint();
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index b987c49c9c..a38741cc91 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -50,7 +50,7 @@
#include "qdebug.h"
-static const char m_qtTag[] = "QtA11y";
+static const char m_qtTag[] = "Qt A11Y";
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
@@ -184,8 +184,6 @@ if (!clazz) { \
desc = iface->text(QAccessible::Name);
if (desc.isEmpty())
desc = iface->text(QAccessible::Description);
-
- desc += QChar(' ') + QString::fromUtf8(qAccessibleRoleString(iface->role()));
}
jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size());
@@ -216,12 +214,6 @@ if (!clazz) { \
}
}
- if ((iface->role() != QAccessible::NoRole) &&
- (iface->role() != QAccessible::Client) &&
- (iface->role() != QAccessible::Pane)) {
- desc += QChar(' ') + QString::fromUtf8(qAccessibleRoleString(iface->role()));
- }
-
CALL_METHOD(node, "setEnabled", "(Z)V", !state.disabled)
//CALL_METHOD(node, "setFocusable", "(Z)V", state.focusable)
CALL_METHOD(node, "setFocusable", "(Z)V", true)
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index ff1a40bfc5..2998762cc3 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -769,7 +769,6 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
|| !QtAndroidInput::registerNatives(env)
|| !QtAndroidClipboard::registerNatives(env)
|| !QtAndroidMenu::registerNatives(env)
- || !QtAndroidAccessibility::registerNatives(env)
|| !QtAndroidDialogHelpers::registerNatives(env)) {
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
return -1;
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index e255a49ac7..c2e5f83639 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -591,19 +591,37 @@ jboolean QAndroidInputContext::endBatchEdit()
return JNI_TRUE;
}
-jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/)
+/*
+ Android docs say: If composing, replace compose text with \a text.
+ Otherwise insert \a text at current cursor position.
+
+ The cursor should then be moved to newCursorPosition. If > 0, this is
+ relative to the end of the text - 1; if <= 0, this is relative to the start
+ of the text. updateSelection() needs to be called.
+*/
+jboolean QAndroidInputContext::commitText(const QString &text, jint newCursorPosition)
{
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
- if (query.isNull())
- return JNI_FALSE;
+ QInputMethodEvent event;
+ event.setCommitString(text);
+ sendInputMethodEvent(&event);
+ clear();
+ // Qt has now put the cursor at the end of the text, corresponding to newCursorPosition == 1
+ if (newCursorPosition != 1) {
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (!query.isNull()) {
+ QList<QInputMethodEvent::Attribute> attributes;
+ const int localPos = query->value(Qt::ImCursorPosition).toInt();
+ const int newLocalPos = newCursorPosition > 0
+ ? localPos + newCursorPosition - 1
+ : localPos - text.length() + newCursorPosition;
+ //move the cursor
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection,
+ newLocalPos, 0, QVariant()));
+ }
+ }
- const int cursorPos = getAbsoluteCursorPosition(query);
- m_composingText = text;
- m_composingTextStart = cursorPos;
- m_composingCursor = cursorPos + text.length();
- finishComposingText();
- //### move cursor to newCursorPosition and call updateCursorPosition()
+ updateCursorPosition();
return JNI_TRUE;
}
@@ -624,9 +642,24 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right
return JNI_TRUE;
}
+// Android docs say the cursor must not move
jboolean QAndroidInputContext::finishComposingText()
{
- QInputMethodEvent event;
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (query.isNull())
+ return JNI_FALSE;
+
+ if (m_composingText.isEmpty())
+ return JNI_TRUE; // not composing
+
+ const int blockPos = getBlockPosition(query);
+ const int localCursorPos = m_composingCursor - blockPos;
+
+ // Moving Qt's cursor to where the preedit cursor used to be
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, localCursorPos, 0, QVariant()));
+
+ QInputMethodEvent event(QString(), attributes);
event.setCommitString(m_composingText);
sendInputMethodEvent(&event);
clear();
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 1df4230385..dd3b9f53db 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -168,6 +168,14 @@
// TODO: multi-selection: NSAccessibilitySelectedTextRangesAttribute,
}
+ if (iface->valueInterface()) {
+ [attributes addObjectsFromArray: [[NSArray alloc] initWithObjects:
+ NSAccessibilityMinValueAttribute,
+ NSAccessibilityMaxValueAttribute,
+ nil
+ ]];
+ }
+
return [attributes autorelease];
}
@@ -191,6 +199,19 @@
return [QCocoaAccessibleElement elementWithId: parentId];
}
+
+- (id) minValueAttribute:(QAccessibleInterface*)iface {
+ if (QAccessibleValueInterface *val = iface->valueInterface())
+ return [NSNumber numberWithDouble: val->minimumValue().toDouble()];
+ return nil;
+}
+
+- (id) maxValueAttribute:(QAccessibleInterface*)iface {
+ if (QAccessibleValueInterface *val = iface->valueInterface())
+ return [NSNumber numberWithDouble: val->maximumValue().toDouble()];
+ return nil;
+}
+
- (id)accessibilityAttributeValue:(NSString *)attribute {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) {
@@ -272,6 +293,10 @@
return [NSNumber numberWithInt: textBeforeCursor.count(QLatin1Char('\n'))];
}
return nil;
+ } else if ([attribute isEqualToString:NSAccessibilityMinValueAttribute]) {
+ return [self minValueAttribute:iface];
+ } else if ([attribute isEqualToString:NSAccessibilityMaxValueAttribute]) {
+ return [self maxValueAttribute:iface];
}
return nil;
@@ -332,7 +357,7 @@
startOffset = text.indexOf(QLatin1Char('\n'), startOffset) + 1;
if (startOffset < 0) // invalid line number, return the first line
startOffset = 0;
- int endOffset = text.indexOf(QLatin1Char('\n'), startOffset + 1);
+ int endOffset = text.indexOf(QLatin1Char('\n'), startOffset);
if (endOffset == -1)
endOffset = text.length();
return [NSValue valueWithRange:NSMakeRange(quint32(startOffset), quint32(endOffset - startOffset))];
@@ -359,6 +384,12 @@
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
return iface->state().focusable ? YES : NO;
+ } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
+ if (iface->textInterface() && iface->state().editable)
+ return YES;
+ if (iface->valueInterface())
+ return YES;
+ return NO;
} else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
return iface->textInterface() ? YES : NO;
}
@@ -372,6 +403,14 @@
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
if (QAccessibleActionInterface *action = iface->actionInterface())
action->doAction(QAccessibleActionInterface::setFocusAction());
+ } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
+ if (iface->textInterface()) {
+ QString text = QString::fromNSString((NSString *)value);
+ iface->setText(QAccessible::Value, text);
+ } else if (QAccessibleValueInterface *valueIface = iface->valueInterface()) {
+ double val = [value doubleValue];
+ valueIface->setCurrentValue(val);
+ }
} else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
if (QAccessibleTextInterface *text = iface->textInterface()) {
NSRange range = [value rangeValue];
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h
index 59fda96dff..3ee1dab84d 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.h
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -68,6 +68,7 @@ public:
void setEnabled(bool enabled);
void setVisible(bool visible);
void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item);
+ void dismiss();
void syncSeparatorsCollapsible(bool enable);
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 9b5753035a..a89979a8ea 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -494,6 +494,11 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatf
[(QNSView *)view resetMouseButtons];
}
+void QCocoaMenu::dismiss()
+{
+ [m_nativeMenu cancelTracking];
+}
+
QPlatformMenuItem *QCocoaMenu::menuItemAt(int position) const
{
if (0 <= position && position < m_menuItems.count())
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index ffc0fabdce..aceb9b619b 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -124,6 +124,8 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
m_menus.insert(beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size(), menu);
if (!menu->menuBar())
insertNativeMenu(menu, beforeMenu);
+ if (m_window && m_window->window()->isActive())
+ updateMenuBarImmediately();
}
void QCocoaMenuBar::removeNativeMenu(QCocoaMenu *menu)
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h
index 61706c19bc..1efc9f9bfd 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h
@@ -57,6 +57,7 @@
QT_FORWARD_DECLARE_OBJC_CLASS(NSMenuItem);
QT_FORWARD_DECLARE_OBJC_CLASS(NSMenu);
QT_FORWARD_DECLARE_OBJC_CLASS(NSObject);
+QT_FORWARD_DECLARE_OBJC_CLASS(NSView);
QT_BEGIN_NAMESPACE
@@ -86,6 +87,8 @@ public:
void setChecked(bool isChecked);
void setEnabled(bool isEnabled);
+ void setNativeContents(WId item);
+
inline QString text() const { return m_text; }
inline NSMenuItem * nsItem() { return m_native; }
NSMenuItem *sync();
@@ -105,6 +108,7 @@ private:
QKeySequence mergeAccel();
NSMenuItem *m_native;
+ NSView *m_itemView;
QString m_text;
bool m_textSynced;
QIcon m_icon;
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index da5475496a..9e748bff72 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -91,6 +91,7 @@ NSUInteger keySequenceModifierMask(const QKeySequence &accel)
QCocoaMenuItem::QCocoaMenuItem() :
m_native(NULL),
+ m_itemView(nil),
m_textSynced(false),
m_menu(NULL),
m_isVisible(true),
@@ -112,6 +113,8 @@ QCocoaMenuItem::~QCocoaMenuItem()
} else {
[m_native release];
}
+
+ [m_itemView release];
}
void QCocoaMenuItem::setText(const QString &text)
@@ -180,6 +183,17 @@ void QCocoaMenuItem::setEnabled(bool enabled)
m_enabled = enabled;
}
+void QCocoaMenuItem::setNativeContents(WId item)
+{
+ NSView *itemView = (NSView *)item;
+ [m_itemView release];
+ m_itemView = [itemView retain];
+ [m_itemView setAutoresizesSubviews:YES];
+ [m_itemView setAutoresizingMask:NSViewWidthSizable];
+ [m_itemView setHidden:NO];
+ [m_itemView setNeedsDisplay:YES];
+}
+
NSMenuItem *QCocoaMenuItem::sync()
{
if (m_isSeparator != [m_native isSeparatorItem]) {
@@ -283,6 +297,7 @@ NSMenuItem *QCocoaMenuItem::sync()
[m_native setHidden: !m_isVisible];
[m_native setEnabled: m_enabled];
+ [m_native setView:m_itemView];
QString text = mergeText();
QKeySequence accel = mergeAccel();
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 4065b57e46..24a9f6fff0 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -42,6 +42,7 @@
#include <QtCore/qglobal.h>
#include <Carbon/Carbon.h>
+#include <dlfcn.h>
#include "qnsview.h"
#include "qcocoawindow.h"
@@ -65,6 +66,9 @@
static QTouchDevice *touchDevice = 0;
+// ### HACK Remove once 10.8 is unsupported
+static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
+
@interface NSEvent (Qt_Compile_Leopard_DeviceDelta)
- (CGFloat)deviceDeltaX;
- (CGFloat)deviceDeltaY;
@@ -73,6 +77,13 @@ static QTouchDevice *touchDevice = 0;
@implementation QNSView
++ (void)initialize
+{
+ NSString **notificationNameVar = (NSString **)dlsym(RTLD_NEXT, "NSWindowDidChangeOcclusionStateNotification");
+ if (notificationNameVar)
+ _q_NSWindowDidChangeOcclusionStateNotification = *notificationNameVar;
+}
+
- (id) init
{
self = [super initWithFrame : NSMakeRect(0,0, 300,300)];
@@ -192,6 +203,19 @@ static QTouchDevice *touchDevice = 0;
}
}
+- (void)viewDidMoveToWindow
+{
+ if (self.window) {
+ // This is the case of QWidgetAction's generated QWidget inserted in an NSMenu.
+ // 10.9 and newer get the NSWindowDidChangeOcclusionStateNotification
+ if (!_q_NSWindowDidChangeOcclusionStateNotification
+ && [self.window.className isEqualToString:@"NSCarbonMenuWindow"])
+ m_platformWindow->exposeWindow();
+ } else {
+ m_platformWindow->obscureWindow();
+ }
+}
+
- (void)viewWillMoveToWindow:(NSWindow *)newWindow
{
// ### Merge "normal" window code path with this one for 5.1.
@@ -325,6 +349,23 @@ static QTouchDevice *touchDevice = 0;
m_platformWindow->obscureWindow();
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
m_platformWindow->exposeWindow();
+ } else if (_q_NSWindowDidChangeOcclusionStateNotification
+ && [notificationName isEqualToString:_q_NSWindowDidChangeOcclusionStateNotification]) {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
+// ### HACK Remove the enum declaration, the warning disabling and the cast further down once 10.8 is unsupported
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wobjc-method-access"
+ enum { NSWindowOcclusionStateVisible = 1UL << 1 };
+#endif
+ // Older versions managed in -[QNSView viewDidMoveToWindow].
+ // Support QWidgetAction in NSMenu. Mavericks only sends this notification.
+ // Ideally we should support this in Qt as well, in order to disable animations
+ // when the window is occluded.
+ if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible)
+ m_platformWindow->exposeWindow();
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
+#pragma clang diagnostic pop
+#endif
} else if (notificationName == NSWindowDidChangeScreenNotification) {
if (m_window) {
NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen];
diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro
index 439d31fb56..03997f2737 100644
--- a/src/plugins/platforms/direct2d/direct2d.pro
+++ b/src/plugins/platforms/direct2d/direct2d.pro
@@ -9,7 +9,7 @@ QT *= core-private
QT *= gui-private
QT *= platformsupport-private
-LIBS *= -ld2d1 -ld3d11 -ldwrite
+LIBS *= -ld2d1 -ld3d11 -ldwrite -lVersion
include(../windows/windows.pri)
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
index 079ad6f127..be013f027b 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -66,6 +66,16 @@ static inline QWindowsDirect2DPlatformPixmap *platformPixmap(QPixmap *p)
return static_cast<QWindowsDirect2DPlatformPixmap *>(p->handle());
}
+static inline QWindowsDirect2DBitmap *bitmap(QPixmap *p)
+{
+ return platformPixmap(p)->bitmap();
+}
+
+static inline QWindowsDirect2DWindow *nativeWindow(QWindow *window)
+{
+ return static_cast<QWindowsDirect2DWindow *>(window->handle());
+}
+
QWindowsDirect2DBackingStore::QWindowsDirect2DBackingStore(QWindow *window)
: QPlatformBackingStore(window)
{
@@ -75,28 +85,42 @@ QWindowsDirect2DBackingStore::~QWindowsDirect2DBackingStore()
{
}
+void QWindowsDirect2DBackingStore::beginPaint(const QRegion &)
+{
+ bitmap(nativeWindow(window())->pixmap())->deviceContext()->begin();
+}
+
+void QWindowsDirect2DBackingStore::endPaint()
+{
+ bitmap(nativeWindow(window())->pixmap())->deviceContext()->end();
+}
+
QPaintDevice *QWindowsDirect2DBackingStore::paintDevice()
{
- return m_pixmap.data();
+ return nativeWindow(window())->pixmap();
}
-void QWindowsDirect2DBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+void QWindowsDirect2DBackingStore::flush(QWindow *targetWindow, const QRegion &region, const QPoint &offset)
{
- QPlatformWindow *pw = window->handle();
- if (pw && m_pixmap)
- static_cast<QWindowsDirect2DWindow *>(pw)->flush(platformPixmap(m_pixmap.data())->bitmap(), region, offset);
+ if (targetWindow != window()) {
+ QSharedPointer<QWindowsDirect2DBitmap> copy(nativeWindow(window())->copyBackBuffer());
+ nativeWindow(targetWindow)->flush(copy.data(), region, offset);
+ }
+
+ nativeWindow(targetWindow)->present();
}
void QWindowsDirect2DBackingStore::resize(const QSize &size, const QRegion &region)
{
- Q_UNUSED(region);
+ QPixmap old = nativeWindow(window())->pixmap()->copy();
- QScopedPointer<QPixmap> oldPixmap(m_pixmap.take());
- m_pixmap.reset(new QPixmap(size.width(), size.height()));
+ nativeWindow(window())->resizeSwapChain(size);
+ QPixmap *newPixmap = nativeWindow(window())->pixmap();
- if (oldPixmap) {
- foreach (const QRect &rect, region.rects())
- platformPixmap(m_pixmap.data())->copy(oldPixmap->handle(), rect);
+ if (!old.isNull()) {
+ foreach (const QRect &rect, region.rects()) {
+ platformPixmap(newPixmap)->copy(old.handle(), rect);
+ }
}
}
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
index 9776d234e8..71e9437274 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -50,6 +50,8 @@
QT_BEGIN_NAMESPACE
+class QWindowsDirect2DWindow;
+
class QWindowsDirect2DBackingStore : public QPlatformBackingStore
{
Q_DISABLE_COPY(QWindowsDirect2DBackingStore)
@@ -58,12 +60,12 @@ public:
QWindowsDirect2DBackingStore(QWindow *window);
~QWindowsDirect2DBackingStore();
+ void beginPaint(const QRegion &);
+ void endPaint();
+
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
- void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+ void flush(QWindow *targetWindow, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
-
-private:
- QScopedPointer<QPixmap> m_pixmap;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
index 85c56bc73e..8bfeac0b2a 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
index d7015ef342..de63bc77f7 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
index 58002fb0dd..1ea90c4f91 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -99,7 +99,7 @@ public:
return false;
}
- hr = dxgiDevice->GetParent(IID_PPV_ARGS(&dxgiAdapter));
+ hr = dxgiDevice->GetAdapter(&dxgiAdapter);
if (FAILED(hr)) {
qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#x", __FUNCTION__, hr);
return false;
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
index 0025463dd5..f9ccab5783 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
index 27e94e4be4..fb47851a06 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
index 4986efb967..c563f6a8f0 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
index 98248515e6..c1b7fc97a8 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -84,8 +84,6 @@ Q_DECL_CONSTEXPR inline D2D1::ColorF to_d2d_color_f(const QColor &c)
Q_DECL_CONSTEXPR inline D2D1_MATRIX_3X2_F to_d2d_matrix_3x2_f(const QTransform &transform)
{
- Q_ASSERT(transform.isAffine());
-
return D2D1::Matrix3x2F(transform.m11(), transform.m12(),
transform.m21(), transform.m22(),
transform.m31(), transform.m32());
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
index 1a26d7029e..9833d50e6c 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -48,7 +48,8 @@
#include "qwindowscontext.h"
-#include <QtCore/QDebug>
+#include <qplatformdefs.h>
+#include <QtCore/QCoreApplication>
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/qpa/qwindowsysteminterface.h>
@@ -61,8 +62,140 @@ public:
QWindowsDirect2DContext m_d2dContext;
};
+class Direct2DVersion
+{
+private:
+ Direct2DVersion()
+ : partOne(0)
+ , partTwo(0)
+ , partThree(0)
+ , partFour(0)
+ {}
+
+ Direct2DVersion(int one, int two, int three, int four)
+ : partOne(one)
+ , partTwo(two)
+ , partThree(three)
+ , partFour(four)
+ {}
+
+public:
+ // 6.2.9200.16765 corresponds to Direct2D 1.1 on Windows 7 SP1 with Platform Update
+ enum {
+ D2DMinVersionPart1 = 6,
+ D2DMinVersionPart2 = 2,
+ D2DMinVersionPart3 = 9200,
+ D2DMinVersionPart4 = 16765
+ };
+
+ static Direct2DVersion systemVersion() {
+ static const int bufSize = 512;
+ TCHAR filename[bufSize];
+
+ UINT i = GetSystemDirectory(filename, bufSize);
+ if (i > 0 && i < MAX_PATH) {
+ if (_tcscat_s(filename, MAX_PATH, __TEXT("\\d2d1.dll")) == 0) {
+ DWORD versionInfoSize = GetFileVersionInfoSize(filename, NULL);
+ if (versionInfoSize) {
+ QVector<BYTE> info(versionInfoSize);
+ if (GetFileVersionInfo(filename, NULL, versionInfoSize, info.data())) {
+ UINT size;
+ DWORD *fi;
+
+ if (VerQueryValue(info.constData(), __TEXT("\\"), (LPVOID *) &fi, &size) && size) {
+ VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *) fi;
+ return Direct2DVersion(HIWORD(verInfo->dwFileVersionMS),
+ LOWORD(verInfo->dwFileVersionMS),
+ HIWORD(verInfo->dwFileVersionLS),
+ LOWORD(verInfo->dwFileVersionLS));
+ }
+ }
+ }
+ }
+ }
+
+ return Direct2DVersion();
+ }
+
+ static Direct2DVersion minimumVersion() {
+ return Direct2DVersion(D2DMinVersionPart1,
+ D2DMinVersionPart2,
+ D2DMinVersionPart3,
+ D2DMinVersionPart4);
+ }
+
+ bool isValid() const {
+ return partOne || partTwo || partThree || partFour;
+ }
+
+ bool operator<(const Direct2DVersion &other) {
+ int c = cmp(partOne, other.partOne);
+ if (c > 0)
+ return false;
+ if (c < 0)
+ return true;
+
+ c = cmp(partTwo, other.partTwo);
+ if (c > 0)
+ return false;
+ if (c < 0)
+ return true;
+
+ c = cmp(partThree, other.partThree);
+ if (c > 0)
+ return false;
+ if (c < 0)
+ return true;
+
+ c = cmp(partFour, other.partFour);
+ if (c > 0)
+ return false;
+ if (c < 0)
+ return true;
+
+ return false;
+ }
+
+ static Q_DECL_CONSTEXPR int cmp(int a, int b) {
+ return a - b;
+ }
+
+ int partOne, partTwo, partThree, partFour;
+};
+
QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList &paramList)
{
+ Direct2DVersion systemVersion = Direct2DVersion::systemVersion();
+
+ if (systemVersion.isValid() && systemVersion < Direct2DVersion::minimumVersion()) {
+ QString msg = QCoreApplication::translate("QWindowsDirect2DIntegration",
+ "Qt cannot load the direct2d platform plugin because " \
+ "the Direct2D version on this system is too old. The " \
+ "minimum system requirement for this platform plugin " \
+ "is Windows 7 SP1 with Platform Update.\n\n" \
+ "The minimum Direct2D version required is %1.%2.%3.%4. " \
+ "The Direct2D version on this system is %5.%6.%7.%8.");
+
+ msg = msg.arg(Direct2DVersion::D2DMinVersionPart1)
+ .arg(Direct2DVersion::D2DMinVersionPart2)
+ .arg(Direct2DVersion::D2DMinVersionPart3)
+ .arg(Direct2DVersion::D2DMinVersionPart4)
+ .arg(systemVersion.partOne)
+ .arg(systemVersion.partTwo)
+ .arg(systemVersion.partThree)
+ .arg(systemVersion.partFour);
+
+ QString caption = QCoreApplication::translate("QWindowsDirect2DIntegration",
+ "Cannot load direct2d platform plugin");
+
+ MessageBoxW(NULL,
+ msg.toStdWString().c_str(),
+ caption.toStdWString().c_str(),
+ MB_OK | MB_ICONERROR);
+
+ return Q_NULLPTR;
+ }
+
QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList);
if (!integration->init()) {
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
index a46d5c0126..0a5a7ff58a 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
index 6792d92de5..0020a95a4d 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h
index ee3f7f6eed..ee1e3db3d2 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
index 85dbaab2ce..f5f4923b2f 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
index c799083d84..c9d8607497 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index d8f34fc3ed..6e8d9b0baf 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -52,12 +52,12 @@
#include "qwindowsfontdatabase.h"
#include "qwindowsintegration.h"
+#include <QtCore/QStack>
#include <QtGui/private/qpaintengine_p.h>
#include <QtGui/private/qtextengine_p.h>
#include <QtGui/private/qfontengine_p.h>
#include <QtGui/private/qstatictext_p.h>
-#include <wrl.h>
using Microsoft::WRL::ComPtr;
QT_BEGIN_NAMESPACE
@@ -71,8 +71,15 @@ QT_BEGIN_NAMESPACE
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd370979(v=vs.85).aspx
enum {
D2DDebugDrawInitialStateTag = -1,
- D2DDebugDrawImageTag = 1,
- D2DDebugFillTag,
+ D2DDebugFillTag = 1,
+ D2DDebugFillRectTag,
+ D2DDebugDrawRectsTag,
+ D2DDebugDrawRectFsTag,
+ D2DDebugDrawLinesTag,
+ D2DDebugDrawLineFsTag,
+ D2DDebugDrawEllipseTag,
+ D2DDebugDrawEllipseFTag,
+ D2DDebugDrawImageTag,
D2DDebugDrawPixmapTag,
D2DDebugDrawStaticTextItemTag,
D2DDebugDrawTextItemTag
@@ -80,9 +87,19 @@ enum {
//Clipping flags
enum {
- UserClip = 0x1,
- SimpleSystemClip = 0x2
+ SimpleSystemClip = 0x1
};
+
+enum ClipType {
+ AxisAlignedClip,
+ LayerClip
+};
+
+// Since d2d is a float-based system we need to be able to snap our drawing to whole pixels.
+// Applying the magical aliasing offset to coordinates will do so, just make sure that
+// aliased painting is turned on on the d2d device context.
+static const qreal MAGICAL_ALIASING_OFFSET = 0.5;
+
#define D2D_TAG(tag) d->dc()->SetTags(tag, tag)
Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);
@@ -92,51 +109,127 @@ static inline ID2D1Factory1 *factory()
return QWindowsDirect2DContext::instance()->d2dFactory();
}
-// XXX reduce code duplication between painterPathToPathGeometry and
-// vectorPathToID2D1PathGeometry, the two are quite similar
-
-static ComPtr<ID2D1PathGeometry1> painterPathToPathGeometry(const QPainterPath &path)
+class Direct2DPathGeometryWriter
{
- ComPtr<ID2D1PathGeometry1> geometry;
- ComPtr<ID2D1GeometrySink> sink;
+public:
+ Direct2DPathGeometryWriter()
+ : m_inFigure(false)
+ , m_roundCoordinates(false)
+ {
- HRESULT hr = factory()->CreatePathGeometry(&geometry);
- if (FAILED(hr)) {
- qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr);
- return NULL;
}
- hr = geometry->Open(&sink);
- if (FAILED(hr)) {
- qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr);
- return NULL;
+ bool begin()
+ {
+ HRESULT hr = factory()->CreatePathGeometry(&m_geometry);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = m_geometry->Open(&m_sink);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ return true;
}
- switch (path.fillRule()) {
- case Qt::WindingFill:
- sink->SetFillMode(D2D1_FILL_MODE_WINDING);
- break;
- case Qt::OddEvenFill:
- sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE);
- break;
+ void setWindingFillEnabled(bool enable)
+ {
+ if (enable)
+ m_sink->SetFillMode(D2D1_FILL_MODE_WINDING);
+ else
+ m_sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE);
+ }
+
+ void setAliasingEnabled(bool enable)
+ {
+ m_roundCoordinates = enable;
+ }
+
+ bool isInFigure() const
+ {
+ return m_inFigure;
+ }
+
+ void moveTo(const QPointF &point)
+ {
+ if (m_inFigure)
+ m_sink->EndFigure(D2D1_FIGURE_END_OPEN);
+
+ m_sink->BeginFigure(adjusted(point), D2D1_FIGURE_BEGIN_FILLED);
+ m_inFigure = true;
+ }
+
+ void lineTo(const QPointF &point)
+ {
+ m_sink->AddLine(adjusted(point));
+ }
+
+ void curveTo(const QPointF &p1, const QPointF &p2, const QPointF &p3)
+ {
+ D2D1_BEZIER_SEGMENT segment = {
+ adjusted(p1),
+ adjusted(p2),
+ adjusted(p3)
+ };
+
+ m_sink->AddBezier(segment);
+ }
+
+ void close()
+ {
+ if (m_inFigure)
+ m_sink->EndFigure(D2D1_FIGURE_END_OPEN);
+
+ m_sink->Close();
+ }
+
+ ComPtr<ID2D1PathGeometry1> geometry() const
+ {
+ return m_geometry;
+ }
+
+private:
+ D2D1_POINT_2F adjusted(const QPointF &point)
+ {
+ static const QPointF adjustment(MAGICAL_ALIASING_OFFSET,
+ MAGICAL_ALIASING_OFFSET);
+
+ if (m_roundCoordinates)
+ return to_d2d_point_2f(point + adjustment);
+ else
+ return to_d2d_point_2f(point);
}
- bool inFigure = false;
+ ComPtr<ID2D1PathGeometry1> m_geometry;
+ ComPtr<ID2D1GeometrySink> m_sink;
+
+ bool m_inFigure;
+ bool m_roundCoordinates;
+};
+
+static ComPtr<ID2D1PathGeometry1> painterPathToID2D1PathGeometry(const QPainterPath &path, bool alias)
+{
+ Direct2DPathGeometryWriter writer;
+ if (!writer.begin())
+ return NULL;
+
+ writer.setWindingFillEnabled(path.fillRule() == Qt::WindingFill);
+ writer.setAliasingEnabled(alias);
for (int i = 0; i < path.elementCount(); i++) {
const QPainterPath::Element element = path.elementAt(i);
switch (element.type) {
case QPainterPath::MoveToElement:
- if (inFigure)
- sink->EndFigure(D2D1_FIGURE_END_OPEN);
-
- sink->BeginFigure(to_d2d_point_2f(element), D2D1_FIGURE_BEGIN_FILLED);
- inFigure = true;
+ writer.moveTo(element);
break;
case QPainterPath::LineToElement:
- sink->AddLine(to_d2d_point_2f(element));
+ writer.lineTo(element);
break;
case QPainterPath::CurveToElement:
@@ -149,13 +242,7 @@ static ComPtr<ID2D1PathGeometry1> painterPathToPathGeometry(const QPainterPath &
Q_ASSERT(data1.type == QPainterPath::CurveToDataElement);
Q_ASSERT(data2.type == QPainterPath::CurveToDataElement);
- D2D1_BEZIER_SEGMENT segment;
-
- segment.point1 = to_d2d_point_2f(element);
- segment.point2 = to_d2d_point_2f(data1);
- segment.point3 = to_d2d_point_2f(data2);
-
- sink->AddBezier(segment);
+ writer.curveTo(element, data1, data2);
}
break;
@@ -165,55 +252,22 @@ static ComPtr<ID2D1PathGeometry1> painterPathToPathGeometry(const QPainterPath &
}
}
- if (inFigure)
- sink->EndFigure(D2D1_FIGURE_END_OPEN);
-
- sink->Close();
-
- return geometry;
+ writer.close();
+ return writer.geometry();
}
static ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias)
{
- ComPtr<ID2D1PathGeometry1> pathGeometry;
- HRESULT hr = factory()->CreatePathGeometry(pathGeometry.GetAddressOf());
- if (FAILED(hr)) {
- qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr);
+ Direct2DPathGeometryWriter writer;
+ if (!writer.begin())
return NULL;
- }
-
- if (path.isEmpty())
- return pathGeometry;
- ComPtr<ID2D1GeometrySink> sink;
- hr = pathGeometry->Open(sink.GetAddressOf());
- if (FAILED(hr)) {
- qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr);
- return NULL;
- }
-
- sink->SetFillMode(path.hasWindingFill() ? D2D1_FILL_MODE_WINDING
- : D2D1_FILL_MODE_ALTERNATE);
-
- bool inFigure = false;
+ writer.setWindingFillEnabled(path.hasWindingFill());
+ writer.setAliasingEnabled(alias);
const QPainterPath::ElementType *types = path.elements();
const int count = path.elementCount();
- const qreal *points = 0;
-
- QScopedArrayPointer<qreal> rounded_points;
-
- if (alias) {
- // Aliased painting, round to whole numbers
- rounded_points.reset(new qreal[count * 2]);
- points = rounded_points.data();
-
- for (int i = 0; i < (count * 2); i++)
- rounded_points[i] = qRound(path.points()[i]);
- } else {
- // Antialiased painting, keep original numbers
- points = path.points();
- }
+ const qreal *points = path.points();
Q_ASSERT(points);
@@ -226,15 +280,11 @@ static ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPat
switch (types[i]) {
case QPainterPath::MoveToElement:
- if (inFigure)
- sink->EndFigure(D2D1_FIGURE_END_OPEN);
-
- sink->BeginFigure(D2D1::Point2F(x, y), D2D1_FIGURE_BEGIN_FILLED);
- inFigure = true;
+ writer.moveTo(QPointF(x, y));
break;
case QPainterPath::LineToElement:
- sink->AddLine(D2D1::Point2F(x, y));
+ writer.lineTo(QPointF(x, y));
break;
case QPainterPath::CurveToElement:
@@ -251,13 +301,7 @@ static ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPat
const qreal x3 = points[i * 2];
const qreal y3 = points[i * 2 + 1];
- D2D1_BEZIER_SEGMENT segment = {
- D2D1::Point2F(x, y),
- D2D1::Point2F(x2, y2),
- D2D1::Point2F(x3, y3)
- };
-
- sink->AddBezier(segment);
+ writer.curveTo(QPointF(x, y), QPointF(x2, y2), QPointF(x3, y3));
}
break;
@@ -267,23 +311,17 @@ static ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPat
}
}
} else {
- sink->BeginFigure(D2D1::Point2F(points[0], points[1]), D2D1_FIGURE_BEGIN_FILLED);
- inFigure = true;
-
+ writer.moveTo(QPointF(points[0], points[1]));
for (int i = 1; i < count; i++)
- sink->AddLine(D2D1::Point2F(points[i * 2], points[i * 2 + 1]));
+ writer.lineTo(QPointF(points[i * 2], points[i * 2 + 1]));
}
- if (inFigure) {
+ if (writer.isInFigure())
if (path.hasImplicitClose())
- sink->AddLine(D2D1::Point2F(points[0], points[1]));
+ writer.lineTo(QPointF(points[0], points[1]));
- sink->EndFigure(D2D1_FIGURE_END_OPEN);
- }
-
- sink->Close();
-
- return pathGeometry;
+ writer.close();
+ return writer.geometry();
}
class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate
@@ -302,11 +340,13 @@ public:
QWindowsDirect2DBitmap *bitmap;
- QPainterPath clipPath;
unsigned int clipFlags;
+ QStack<ClipType> pushedClips;
QPointF currentBrushOrigin;
+ QHash< QFont, ComPtr<IDWriteFontFace> > fontCache;
+
struct {
bool emulate;
QPen qpen;
@@ -354,81 +394,97 @@ public:
: D2D1_ANTIALIAS_MODE_ALIASED;
}
- void updateTransform()
+ void updateTransform(const QTransform &transform)
{
- Q_Q(const QWindowsDirect2DPaintEngine);
- // Note the loss of info going from 3x3 to 3x2 matrix here
- dc()->SetTransform(to_d2d_matrix_3x2_f(q->state()->transform()));
+ dc()->SetTransform(to_d2d_matrix_3x2_f(transform));
}
- void updateOpacity()
+ void updateOpacity(qreal opacity)
{
- Q_Q(const QWindowsDirect2DPaintEngine);
- qreal opacity = q->state()->opacity;
if (brush.brush)
brush.brush->SetOpacity(opacity);
if (pen.brush)
pen.brush->SetOpacity(opacity);
}
- void pushClip()
+ void pushClip(const QVectorPath &path)
{
- popClip();
+ Q_Q(QWindowsDirect2DPaintEngine);
+
+ if (path.isEmpty()) {
+ D2D_RECT_F rect = {0, 0, 0, 0};
+ dc()->PushAxisAlignedClip(rect, antialiasMode());
+ pushedClips.push(AxisAlignedClip);
+ } else if (path.isRect() && (q->state()->matrix.type() <= QTransform::TxScale)) {
+ const qreal * const points = path.points();
+ D2D_RECT_F rect = {
+ points[0], // left
+ points[1], // top
+ points[2], // right,
+ points[5] // bottom
+ };
- ComPtr<ID2D1PathGeometry1> geometry = painterPathToPathGeometry(clipPath);
- if (!geometry)
- return;
+ dc()->PushAxisAlignedClip(rect, antialiasMode());
+ pushedClips.push(AxisAlignedClip);
+ } else {
+ ComPtr<ID2D1PathGeometry1> geometry = vectorPathToID2D1PathGeometry(path, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ if (!geometry) {
+ qWarning("%s: Could not convert vector path to painter path!", __FUNCTION__);
+ return;
+ }
- dc()->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(),
- geometry.Get(),
- antialiasMode(),
- D2D1::IdentityMatrix(),
- 1.0,
- NULL,
- D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND),
- NULL);
- clipFlags |= UserClip;
+ dc()->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(),
+ geometry.Get(),
+ antialiasMode(),
+ D2D1::IdentityMatrix(),
+ 1.0,
+ NULL,
+ D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND),
+ NULL);
+ pushedClips.push(LayerClip);
+ }
}
- void popClip()
+ void clearClips()
{
- if (clipFlags & UserClip) {
- dc()->PopLayer();
- clipFlags &= ~UserClip;
+ while (!pushedClips.isEmpty()) {
+ switch (pushedClips.pop()) {
+ case AxisAlignedClip:
+ dc()->PopAxisAlignedClip();
+ break;
+ case LayerClip:
+ dc()->PopLayer();
+ break;
+ }
}
}
- void updateClipEnabled()
+ void updateClipEnabled(bool enabled)
{
- Q_Q(const QWindowsDirect2DPaintEngine);
- if (!q->state()->clipEnabled)
- popClip();
- else if (!(clipFlags & UserClip))
- pushClip();
+ if (!enabled)
+ clearClips();
+ else if (pushedClips.isEmpty())
+ replayClipOperations();
}
- void updateClipPath(const QPainterPath &path, Qt::ClipOperation operation)
+ void clip(const QVectorPath &path, Qt::ClipOperation operation)
{
switch (operation) {
case Qt::NoClip:
- popClip();
+ clearClips();
break;
case Qt::ReplaceClip:
- clipPath = path;
- pushClip();
+ clearClips();
+ pushClip(path);
break;
case Qt::IntersectClip:
- clipPath &= path;
- pushClip();
+ pushClip(path);
break;
}
}
- void updateCompositionMode()
+ void updateCompositionMode(QPainter::CompositionMode mode)
{
- Q_Q(const QWindowsDirect2DPaintEngine);
- QPainter::CompositionMode mode = q->state()->compositionMode();
-
switch (mode) {
case QPainter::CompositionMode_Source:
dc()->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_COPY);
@@ -447,7 +503,7 @@ public:
{
Q_Q(const QWindowsDirect2DPaintEngine);
- if (qbrush_fast_equals(brush.qbrush, newBrush))
+ if (qbrush_fast_equals(brush.qbrush, newBrush) && (brush.brush || brush.emulate))
return;
brush.brush = to_d2d_brush(newBrush, &brush.emulate);
@@ -459,12 +515,10 @@ public:
}
}
- void updateBrushOrigin()
+ void updateBrushOrigin(const QPointF &brushOrigin)
{
- Q_Q(const QWindowsDirect2DPaintEngine);
-
negateCurrentBrushOrigin();
- applyBrushOrigin(q->state()->brushOrigin);
+ applyBrushOrigin(brushOrigin);
}
void negateCurrentBrushOrigin()
@@ -492,12 +546,10 @@ public:
currentBrushOrigin = origin;
}
- void updatePen()
+ void updatePen(const QPen &newPen)
{
Q_Q(const QWindowsDirect2DPaintEngine);
- const QPen &newPen = q->state()->pen;
-
- if (qpen_fast_equals(newPen, pen.qpen))
+ if (qpen_fast_equals(newPen, pen.qpen) && (pen.brush || pen.emulate))
return;
pen.reset();
@@ -658,7 +710,91 @@ public:
break;
case Qt::LinearGradientPattern:
+ if (newBrush.gradient()->spread() != QGradient::PadSpread) {
+ *needsEmulation = true;
+ } else {
+ ComPtr<ID2D1LinearGradientBrush> linear;
+ const QLinearGradient *qlinear = static_cast<const QLinearGradient *>(newBrush.gradient());
+
+ D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties;
+ ComPtr<ID2D1GradientStopCollection> gradientStopCollection;
+
+ const QGradientStops &qstops = qlinear->stops();
+ QVector<D2D1_GRADIENT_STOP> stops(qstops.count());
+
+ linearGradientBrushProperties.startPoint = to_d2d_point_2f(qlinear->start());
+ linearGradientBrushProperties.endPoint = to_d2d_point_2f(qlinear->finalStop());
+
+ for (int i = 0; i < stops.size(); i++) {
+ stops[i].position = qstops[i].first;
+ stops[i].color = to_d2d_color_f(qstops[i].second);
+ }
+
+ hr = dc()->CreateGradientStopCollection(stops.constData(), stops.size(), &gradientStopCollection);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create gradient stop collection for linear gradient: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = dc()->CreateLinearGradientBrush(linearGradientBrushProperties, gradientStopCollection.Get(),
+ &linear);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D linear gradient brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = linear.As(&result);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not convert Direct2D linear gradient brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+ }
+ break;
+
case Qt::RadialGradientPattern:
+ if (newBrush.gradient()->spread() != QGradient::PadSpread) {
+ *needsEmulation = true;
+ } else {
+ ComPtr<ID2D1RadialGradientBrush> radial;
+ const QRadialGradient *qradial = static_cast<const QRadialGradient *>(newBrush.gradient());
+
+ D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties;
+ ComPtr<ID2D1GradientStopCollection> gradientStopCollection;
+
+ const QGradientStops &qstops = qradial->stops();
+ QVector<D2D1_GRADIENT_STOP> stops(qstops.count());
+
+ radialGradientBrushProperties.center = to_d2d_point_2f(qradial->center());
+ radialGradientBrushProperties.gradientOriginOffset = to_d2d_point_2f(qradial->focalPoint() - qradial->center());
+ radialGradientBrushProperties.radiusX = qradial->radius();
+ radialGradientBrushProperties.radiusY = qradial->radius();
+
+ for (int i = 0; i < stops.size(); i++) {
+ stops[i].position = qstops[i].first;
+ stops[i].color = to_d2d_color_f(qstops[i].second);
+ }
+
+ hr = dc()->CreateGradientStopCollection(stops.constData(), stops.size(), &gradientStopCollection);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create gradient stop collection for radial gradient: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = dc()->CreateRadialGradientBrush(radialGradientBrushProperties, gradientStopCollection.Get(),
+ &radial);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D radial gradient brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ radial.As(&result);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not convert Direct2D radial gradient brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+ }
+ break;
+
case Qt::ConicalGradientPattern:
*needsEmulation = true;
break;
@@ -706,16 +842,9 @@ QWindowsDirect2DPaintEngine::QWindowsDirect2DPaintEngine(QWindowsDirect2DBitmap
: QPaintEngineEx(*(new QWindowsDirect2DPaintEnginePrivate(bitmap)))
{
QPaintEngine::PaintEngineFeatures unsupported =
- // As of 1.1 Direct2D gradient support is deficient for linear and radial gradients
- QPaintEngine::LinearGradientFill
- | QPaintEngine::RadialGradientFill
-
- // As of 1.1 Direct2D does not support conical gradients at all
- | QPaintEngine::ConicalGradientFill
-
// As of 1.1 Direct2D does not natively support complex composition modes
// However, using Direct2D effects that implement them should be possible
- | QPaintEngine::PorterDuff
+ QPaintEngine::PorterDuff
| QPaintEngine::BlendModes
| QPaintEngine::RasterOpModes
@@ -739,7 +868,7 @@ bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev)
QPainterPath p;
p.addRegion(systemClip());
- ComPtr<ID2D1PathGeometry1> geometry = painterPathToPathGeometry(p);
+ ComPtr<ID2D1PathGeometry1> geometry = painterPathToID2D1PathGeometry(p, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
if (!geometry)
return false;
@@ -761,6 +890,7 @@ bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev)
D2D_TAG(D2DDebugDrawInitialStateTag);
+ setActive(true);
return true;
}
@@ -768,7 +898,7 @@ bool QWindowsDirect2DPaintEngine::end()
{
Q_D(QWindowsDirect2DPaintEngine);
// First pop any user-applied clipping
- d->popClip();
+ d->clearClips();
// Now the system clip from begin() above
if (d->clipFlags & SimpleSystemClip) {
d->dc()->PopAxisAlignedClip();
@@ -784,6 +914,23 @@ QPaintEngine::Type QWindowsDirect2DPaintEngine::type() const
return QPaintEngine::Direct2D;
}
+void QWindowsDirect2DPaintEngine::setState(QPainterState *s)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+
+ QPaintEngineEx::setState(s);
+ d->clearClips();
+
+ clipEnabledChanged();
+ penChanged();
+ brushChanged();
+ brushOriginChanged();
+ opacityChanged();
+ compositionModeChanged();
+ renderHintsChanged();
+ transformChanged();
+}
+
void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
{
Q_D(QWindowsDirect2DPaintEngine);
@@ -792,28 +939,10 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br
if (path.isEmpty())
return;
- d->updateBrush(brush);
-
- if (d->brush.emulate) {
- // We mostly (only?) get here when gradients are required.
- // We could probably natively support linear and radial gradients that have pad reflect
-
- QImage img(d->bitmap->size(), QImage::Format_ARGB32);
- img.fill(Qt::transparent);
-
- QPainter p;
- QPaintEngine *engine = img.paintEngine();
- if (engine->isExtended() && p.begin(&img)) {
- QPaintEngineEx *extended = static_cast<QPaintEngineEx *>(engine);
- extended->fill(path, brush);
- if (!p.end())
- qWarning("%s: Paint Engine end returned false", __FUNCTION__);
-
- drawImage(img.rect(), img, img.rect());
- } else {
- qWarning("%s: Could not fall back to QImage", __FUNCTION__);
- }
+ ensureBrush(brush);
+ if (emulationRequired(BrushEmulation)) {
+ rasterFill(path, brush);
return;
}
@@ -829,46 +958,22 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br
d->dc()->FillGeometry(geometry.Get(), d->brush.brush.Get());
}
-// For clipping we convert everything to painter paths since it allows
-// calculating intersections easily. It might be faster to convert to
-// ID2D1Geometry and use its operations, although that needs to measured.
-// The implementation would be more complex in any case.
-
void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
{
- clip(path.convertToPainterPath(), op);
-}
-
-void QWindowsDirect2DPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
-{
- QPainterPath p;
- p.addRect(rect);
- clip(p, op);
-}
-
-void QWindowsDirect2DPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
-{
- QPainterPath p;
- p.addRegion(region);
- clip(p, op);
-}
-
-void QWindowsDirect2DPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op)
-{
Q_D(QWindowsDirect2DPaintEngine);
- d->updateClipPath(path, op);
+ d->clip(path, op);
}
void QWindowsDirect2DPaintEngine::clipEnabledChanged()
{
Q_D(QWindowsDirect2DPaintEngine);
- d->updateClipEnabled();
+ d->updateClipEnabled(state()->clipEnabled);
}
void QWindowsDirect2DPaintEngine::penChanged()
{
Q_D(QWindowsDirect2DPaintEngine);
- d->updatePen();
+ d->updatePen(state()->pen);
}
void QWindowsDirect2DPaintEngine::brushChanged()
@@ -880,19 +985,19 @@ void QWindowsDirect2DPaintEngine::brushChanged()
void QWindowsDirect2DPaintEngine::brushOriginChanged()
{
Q_D(QWindowsDirect2DPaintEngine);
- d->updateBrushOrigin();
+ d->updateBrushOrigin(state()->brushOrigin);
}
void QWindowsDirect2DPaintEngine::opacityChanged()
{
Q_D(QWindowsDirect2DPaintEngine);
- d->updateOpacity();
+ d->updateOpacity(state()->opacity);
}
void QWindowsDirect2DPaintEngine::compositionModeChanged()
{
Q_D(QWindowsDirect2DPaintEngine);
- d->updateCompositionMode();
+ d->updateCompositionMode(state()->compositionMode());
}
void QWindowsDirect2DPaintEngine::renderHintsChanged()
@@ -904,7 +1009,199 @@ void QWindowsDirect2DPaintEngine::renderHintsChanged()
void QWindowsDirect2DPaintEngine::transformChanged()
{
Q_D(QWindowsDirect2DPaintEngine);
- d->updateTransform();
+ d->updateTransform(state()->transform());
+}
+
+void QWindowsDirect2DPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugFillRectTag);
+
+ ensureBrush(brush);
+
+ if (emulationRequired(BrushEmulation)) {
+ QPaintEngineEx::fillRect(rect, brush);
+ } else {
+ QRectF r = rect.normalized();
+ adjustForAliasing(&r);
+
+ if (d->brush.brush)
+ d->dc()->FillRectangle(to_d2d_rect_f(rect), d->brush.brush.Get());
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawRects(const QRect *rects, int rectCount)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawRectsTag);
+
+ ensureBrush();
+ ensurePen();
+
+ if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) {
+ QPaintEngineEx::drawRects(rects, rectCount);
+ } else {
+ QRectF rect;
+ for (int i = 0; i < rectCount; i++) {
+ rect = rects[i].normalized();
+ adjustForAliasing(&rect);
+
+ D2D1_RECT_F d2d_rect = to_d2d_rect_f(rect);
+
+ if (d->brush.brush)
+ d->dc()->FillRectangle(d2d_rect, d->brush.brush.Get());
+
+ if (d->pen.brush)
+ d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ }
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawRects(const QRectF *rects, int rectCount)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawRectFsTag);
+
+ ensureBrush();
+ ensurePen();
+
+ if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) {
+ QPaintEngineEx::drawRects(rects, rectCount);
+ } else {
+ QRectF rect;
+ for (int i = 0; i < rectCount; i++) {
+ rect = rects[i].normalized();
+ adjustForAliasing(&rect);
+
+ D2D1_RECT_F d2d_rect = to_d2d_rect_f(rect);
+
+ if (d->brush.brush)
+ d->dc()->FillRectangle(d2d_rect, d->brush.brush.Get());
+
+ if (d->pen.brush)
+ d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ }
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawLines(const QLine *lines, int lineCount)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawLinesTag);
+
+ ensurePen();
+
+ if (emulationRequired(PenEmulation)) {
+ QPaintEngineEx::drawLines(lines, lineCount);
+ } else if (d->pen.brush) {
+ for (int i = 0; i < lineCount; i++) {
+ QPointF p1 = lines[i].p1();
+ QPointF p2 = lines[i].p2();
+
+ // Match raster engine output
+ if (p1 == p2 && d->pen.qpen.widthF() <= 1.0) {
+ fillRect(QRectF(p1, QSizeF(d->pen.qpen.widthF(), d->pen.qpen.widthF())),
+ d->pen.qpen.brush());
+ continue;
+ }
+
+ adjustForAliasing(&p1);
+ adjustForAliasing(&p2);
+
+ D2D1_POINT_2F d2d_p1 = to_d2d_point_2f(p1);
+ D2D1_POINT_2F d2d_p2 = to_d2d_point_2f(p2);
+
+ d->dc()->DrawLine(d2d_p1, d2d_p2, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ }
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawLines(const QLineF *lines, int lineCount)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawLineFsTag);
+
+ ensurePen();
+
+ if (emulationRequired(PenEmulation)) {
+ QPaintEngineEx::drawLines(lines, lineCount);
+ } else if (d->pen.brush) {
+ for (int i = 0; i < lineCount; i++) {
+ QPointF p1 = lines[i].p1();
+ QPointF p2 = lines[i].p2();
+
+ // Match raster engine output
+ if (p1 == p2 && d->pen.qpen.widthF() <= 1.0) {
+ fillRect(QRectF(p1, QSizeF(d->pen.qpen.widthF(), d->pen.qpen.widthF())),
+ d->pen.qpen.brush());
+ continue;
+ }
+
+ adjustForAliasing(&p1);
+ adjustForAliasing(&p2);
+
+ D2D1_POINT_2F d2d_p1 = to_d2d_point_2f(p1);
+ D2D1_POINT_2F d2d_p2 = to_d2d_point_2f(p2);
+
+ d->dc()->DrawLine(d2d_p1, d2d_p2, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ }
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawEllipse(const QRectF &r)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawEllipseFTag);
+
+ ensureBrush();
+ ensurePen();
+
+ if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) {
+ QPaintEngineEx::drawEllipse(r);
+ } else {
+ QPointF p = r.center();
+ adjustForAliasing(&p);
+
+ D2D1_ELLIPSE ellipse = {
+ to_d2d_point_2f(p),
+ r.width() / 2.0,
+ r.height() / 2.0
+ };
+
+ if (d->brush.brush)
+ d->dc()->FillEllipse(ellipse, d->brush.brush.Get());
+
+ if (d->pen.brush)
+ d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawEllipse(const QRect &r)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawEllipseTag);
+
+ ensureBrush();
+ ensurePen();
+
+ if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) {
+ QPaintEngineEx::drawEllipse(r);
+ } else {
+ QPointF p = r.center();
+ adjustForAliasing(&p);
+
+ D2D1_ELLIPSE ellipse = {
+ to_d2d_point_2f(p),
+ r.width() / 2.0,
+ r.height() / 2.0
+ };
+
+ if (d->brush.brush)
+ d->dc()->FillEllipse(ellipse, d->brush.brush.Get());
+
+ if (d->pen.brush)
+ d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ }
}
void QWindowsDirect2DPaintEngine::drawImage(const QRectF &rectangle, const QImage &image,
@@ -938,6 +1235,8 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
QWindowsDirect2DPlatformPixmap *pp = static_cast<QWindowsDirect2DPlatformPixmap *>(pm.handle());
QWindowsDirect2DBitmap *bitmap = pp->bitmap();
+ ensurePen();
+
if (bitmap->bitmap() != d->bitmap->bitmap()) {
// Good, src bitmap != dst bitmap
if (sr.isValid())
@@ -993,74 +1292,33 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
}
}
-static ComPtr<IDWriteFontFace> fontFaceFromFontEngine(QFontEngine *fe)
-{
- ComPtr<IDWriteFontFace> fontFace;
-
- switch (fe->type()) {
- case QFontEngine::Win:
- {
- QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(fe);
- QSharedPointer<QWindowsFontEngineData> wfed = wfe->fontEngineData();
-
- HGDIOBJ oldfont = wfe->selectDesignFont();
- HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFaceFromHdc(wfed->hdc, &fontFace);
- DeleteObject(SelectObject(wfed->hdc, oldfont));
- if (FAILED(hr))
- qWarning("%s: Could not create DirectWrite fontface from HDC: %#x", __FUNCTION__, hr);
-
- }
- break;
-
-#ifndef QT_NO_DIRECTWRITE
-
- case QFontEngine::DirectWrite:
- {
- QWindowsFontEngineDirectWrite *wfedw = static_cast<QWindowsFontEngineDirectWrite *>(fe);
- fontFace = wfedw->directWriteFontFace();
- }
- break;
-
-#endif // QT_NO_DIRECTWRITE
-
- default:
- qWarning("%s: Unknown font engine!", __FUNCTION__);
- break;
- }
-
- return fontFace;
-}
-
void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticTextItem)
{
Q_D(QWindowsDirect2DPaintEngine);
D2D_TAG(D2DDebugDrawStaticTextItemTag);
- if (qpen_style(d->pen.qpen) == Qt::NoPen)
- return;
-
if (staticTextItem->numGlyphs == 0)
return;
+ ensurePen();
+
// If we can't support the current configuration with Direct2D, fall back to slow path
- // Most common cases are perspective transform and gradient brush as pen
- if ((state()->transform().isAffine() == false) || d->pen.emulate) {
+ if (emulationRequired(PenEmulation)) {
QPaintEngineEx::drawStaticTextItem(staticTextItem);
return;
}
- ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(staticTextItem->fontEngine());
+ ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(staticTextItem->font, staticTextItem->fontEngine());
if (!fontFace) {
qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
QPaintEngineEx::drawStaticTextItem(staticTextItem);
return;
}
- QVector<UINT16> glyphIndices(staticTextItem->numGlyphs);
- QVector<FLOAT> glyphAdvances(staticTextItem->numGlyphs);
- QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs);
+ QVarLengthArray<UINT16> glyphIndices(staticTextItem->numGlyphs);
+ QVarLengthArray<FLOAT> glyphAdvances(staticTextItem->numGlyphs);
+ QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs);
- // XXX Are we generating a lot of cache misses here?
for (int i = 0; i < staticTextItem->numGlyphs; i++) {
glyphIndices[i] = UINT16(staticTextItem->glyphs[i]); // Imperfect conversion here
@@ -1086,32 +1344,29 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem
Q_D(QWindowsDirect2DPaintEngine);
D2D_TAG(D2DDebugDrawTextItemTag);
- if (qpen_style(d->pen.qpen) == Qt::NoPen)
- return;
-
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
if (ti.glyphs.numGlyphs == 0)
return;
+ ensurePen();
+
// If we can't support the current configuration with Direct2D, fall back to slow path
- // Most common cases are perspective transform and gradient brush as pen
- if ((state()->transform().isAffine() == false) || d->pen.emulate) {
+ if (emulationRequired(PenEmulation)) {
QPaintEngine::drawTextItem(p, textItem);
return;
}
- ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(ti.fontEngine);
+ ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(*ti.f, ti.fontEngine);
if (!fontFace) {
qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
QPaintEngine::drawTextItem(p, textItem);
return;
}
- QVector<UINT16> glyphIndices(ti.glyphs.numGlyphs);
- QVector<FLOAT> glyphAdvances(ti.glyphs.numGlyphs);
- QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs);
+ QVarLengthArray<UINT16> glyphIndices(ti.glyphs.numGlyphs);
+ QVarLengthArray<FLOAT> glyphAdvances(ti.glyphs.numGlyphs);
+ QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs);
- // XXX Are we generating a lot of cache misses here?
for (int i = 0; i < ti.glyphs.numGlyphs; i++) {
glyphIndices[i] = UINT16(ti.glyphs.glyphs[i]); // Imperfect conversion here
glyphAdvances[i] = ti.glyphs.effectiveAdvance(i).toReal();
@@ -1194,4 +1449,177 @@ void QWindowsDirect2DPaintEngine::drawGlyphRun(const D2D1_POINT_2F &pos,
DWRITE_MEASURING_MODE_GDI_CLASSIC);
}
+void QWindowsDirect2DPaintEngine::ensureBrush()
+{
+ ensureBrush(state()->brush);
+}
+
+void QWindowsDirect2DPaintEngine::ensureBrush(const QBrush &brush)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateBrush(brush);
+}
+
+void QWindowsDirect2DPaintEngine::ensurePen()
+{
+ ensurePen(state()->pen);
+}
+
+void QWindowsDirect2DPaintEngine::ensurePen(const QPen &pen)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updatePen(pen);
+}
+
+void QWindowsDirect2DPaintEngine::rasterFill(const QVectorPath &path, const QBrush &brush)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+
+ QImage img(d->bitmap->size(), QImage::Format_ARGB32);
+ img.fill(Qt::transparent);
+
+ QPainter p;
+ QPaintEngine *engine = img.paintEngine();
+
+ if (engine->isExtended() && p.begin(&img)) {
+ p.setRenderHints(state()->renderHints);
+ p.setCompositionMode(state()->compositionMode());
+ p.setOpacity(state()->opacity);
+ p.setBrushOrigin(state()->brushOrigin);
+ p.setBrush(state()->brush);
+ p.setPen(state()->pen);
+
+ QPaintEngineEx *extended = static_cast<QPaintEngineEx *>(engine);
+ foreach (const QPainterClipInfo &info, state()->clipInfo) {
+ extended->state()->matrix = info.matrix;
+ extended->transformChanged();
+
+ switch (info.clipType) {
+ case QPainterClipInfo::RegionClip:
+ extended->clip(info.region, info.operation);
+ break;
+ case QPainterClipInfo::PathClip:
+ extended->clip(info.path, info.operation);
+ break;
+ case QPainterClipInfo::RectClip:
+ extended->clip(info.rect, info.operation);
+ break;
+ case QPainterClipInfo::RectFClip:
+ qreal right = info.rectf.x() + info.rectf.width();
+ qreal bottom = info.rectf.y() + info.rectf.height();
+ qreal pts[] = { info.rectf.x(), info.rectf.y(),
+ right, info.rectf.y(),
+ right, bottom,
+ info.rectf.x(), bottom };
+ QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint);
+ extended->clip(vp, info.operation);
+ break;
+ }
+ }
+
+ extended->state()->matrix = state()->matrix;
+ extended->transformChanged();
+
+ extended->fill(path, brush);
+ if (!p.end())
+ qWarning("%s: Paint Engine end returned false", __FUNCTION__);
+
+ d->updateClipEnabled(false);
+ d->updateTransform(QTransform());
+ drawImage(img.rect(), img, img.rect());
+ transformChanged();
+ clipEnabledChanged();
+ } else {
+ qWarning("%s: Could not fall back to QImage", __FUNCTION__);
+ }
+}
+
+bool QWindowsDirect2DPaintEngine::emulationRequired(EmulationType type) const
+{
+ Q_D(const QWindowsDirect2DPaintEngine);
+
+ if (!state()->matrix.isAffine())
+ return true;
+
+ switch (type) {
+ case PenEmulation:
+ return d->pen.emulate;
+ break;
+ case BrushEmulation:
+ return d->brush.emulate;
+ break;
+ }
+
+ return false;
+}
+
+bool QWindowsDirect2DPaintEngine::antiAliasingEnabled() const
+{
+ return state()->renderHints & QPainter::Antialiasing;
+}
+
+void QWindowsDirect2DPaintEngine::adjustForAliasing(QRectF *rect)
+{
+ if (!antiAliasingEnabled()) {
+ rect->adjust(MAGICAL_ALIASING_OFFSET,
+ MAGICAL_ALIASING_OFFSET,
+ MAGICAL_ALIASING_OFFSET,
+ MAGICAL_ALIASING_OFFSET);
+ }
+}
+
+void QWindowsDirect2DPaintEngine::adjustForAliasing(QPointF *point)
+{
+ static const QPointF adjustment(MAGICAL_ALIASING_OFFSET,
+ MAGICAL_ALIASING_OFFSET);
+
+ if (!antiAliasingEnabled())
+ (*point) += adjustment;
+}
+
+Microsoft::WRL::ComPtr<IDWriteFontFace> QWindowsDirect2DPaintEngine::fontFaceFromFontEngine(const QFont &font, QFontEngine *fe)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+
+ ComPtr<IDWriteFontFace> fontFace = d->fontCache.value(font);
+ if (fontFace)
+ return fontFace;
+
+ switch (fe->type()) {
+ case QFontEngine::Win:
+ {
+ QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(fe);
+ QSharedPointer<QWindowsFontEngineData> wfed = wfe->fontEngineData();
+
+ HGDIOBJ oldfont = wfe->selectDesignFont();
+ HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFaceFromHdc(wfed->hdc, &fontFace);
+ DeleteObject(SelectObject(wfed->hdc, oldfont));
+ if (FAILED(hr))
+ qWarning("%s: Could not create DirectWrite fontface from HDC: %#x", __FUNCTION__, hr);
+
+ }
+ break;
+
+#ifndef QT_NO_DIRECTWRITE
+
+ case QFontEngine::DirectWrite:
+ {
+ QWindowsFontEngineDirectWrite *wfedw = static_cast<QWindowsFontEngineDirectWrite *>(fe);
+ fontFace = wfedw->directWriteFontFace();
+ }
+ break;
+
+#endif // QT_NO_DIRECTWRITE
+
+ default:
+ qWarning("%s: Unknown font engine!", __FUNCTION__);
+ break;
+ }
+
+ if (fontFace)
+ d->fontCache.insert(font, fontFace);
+
+ return fontFace;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
index 6c74a07e88..fb9b7acec3 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -47,6 +47,7 @@
#include <d2d1_1.h>
#include <dwrite_1.h>
+#include <wrl.h>
QT_BEGIN_NAMESPACE
@@ -65,12 +66,10 @@ public:
Type type() const Q_DECL_OVERRIDE;
- void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE;
+ void setState(QPainterState *s) Q_DECL_OVERRIDE;
+ void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE;
void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
- void clip(const QRect &rect, Qt::ClipOperation op) Q_DECL_OVERRIDE;
- void clip(const QRegion &region, Qt::ClipOperation op) Q_DECL_OVERRIDE;
- void clip(const QPainterPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
void clipEnabledChanged() Q_DECL_OVERRIDE;
void penChanged() Q_DECL_OVERRIDE;
@@ -81,6 +80,17 @@ public:
void renderHintsChanged() Q_DECL_OVERRIDE;
void transformChanged() Q_DECL_OVERRIDE;
+ void fillRect(const QRectF &rect, const QBrush &brush) Q_DECL_OVERRIDE;
+
+ void drawRects(const QRect *rects, int rectCount) Q_DECL_OVERRIDE;
+ void drawRects(const QRectF *rects, int rectCount) Q_DECL_OVERRIDE;
+
+ void drawLines(const QLine *lines, int lineCount) Q_DECL_OVERRIDE;
+ void drawLines(const QLineF *lines, int lineCount) Q_DECL_OVERRIDE;
+
+ void drawEllipse(const QRectF &r) Q_DECL_OVERRIDE;
+ void drawEllipse(const QRect &r) Q_DECL_OVERRIDE;
+
void drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE;
@@ -91,6 +101,22 @@ private:
void drawGlyphRun(const D2D1_POINT_2F &pos, IDWriteFontFace *fontFace, const QFont &font,
int numGlyphs, const UINT16 *glyphIndices, const FLOAT *glyphAdvances,
const DWRITE_GLYPH_OFFSET *glyphOffsets, bool rtl);
+
+ void ensureBrush();
+ void ensureBrush(const QBrush &brush);
+ void ensurePen();
+ void ensurePen(const QPen &pen);
+
+ void rasterFill(const QVectorPath &path, const QBrush &brush);
+
+ enum EmulationType { PenEmulation, BrushEmulation };
+ bool emulationRequired(EmulationType type) const;
+
+ bool antiAliasingEnabled() const;
+ void adjustForAliasing(QRectF *rect);
+ void adjustForAliasing(QPointF *point);
+
+ Microsoft::WRL::ComPtr<IDWriteFontFace> fontFaceFromFontEngine(const QFont &font, QFontEngine *fe);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
index 072c4b3c0e..d9f7c595ca 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -56,12 +56,27 @@ class QWindowsDirect2DPlatformPixmapPrivate
{
public:
QWindowsDirect2DPlatformPixmapPrivate()
- : bitmap(new QWindowsDirect2DBitmap)
- , device(new QWindowsDirect2DPaintDevice(bitmap.data(), QInternal::Pixmap))
+ : owns_bitmap(true)
+ , bitmap(new QWindowsDirect2DBitmap)
+ , device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap))
, devicePixelRatio(1.0)
{}
- QScopedPointer<QWindowsDirect2DBitmap> bitmap;
+ QWindowsDirect2DPlatformPixmapPrivate(QWindowsDirect2DBitmap *bitmap)
+ : owns_bitmap(false)
+ , bitmap(bitmap)
+ , device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap))
+ , devicePixelRatio(1.0)
+ {}
+
+ ~QWindowsDirect2DPlatformPixmapPrivate()
+ {
+ if (owns_bitmap)
+ delete bitmap;
+ }
+
+ bool owns_bitmap;
+ QWindowsDirect2DBitmap *bitmap;
QScopedPointer<QWindowsDirect2DPaintDevice> device;
qreal devicePixelRatio;
};
@@ -75,6 +90,19 @@ QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(PixelType pixelTy
setSerialNumber(qt_d2dpixmap_serno++);
}
+QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixelType pixelType,
+ QWindowsDirect2DBitmap *bitmap)
+ : QPlatformPixmap(pixelType, Direct2DClass)
+ , d_ptr(new QWindowsDirect2DPlatformPixmapPrivate(bitmap))
+{
+ setSerialNumber(qt_d2dpixmap_serno++);
+
+ is_null = false;
+ w = bitmap->size().width();
+ h = bitmap->size().height();
+ this->d = 32;
+}
+
QWindowsDirect2DPlatformPixmap::~QWindowsDirect2DPlatformPixmap()
{
@@ -173,7 +201,7 @@ void QWindowsDirect2DPlatformPixmap::setDevicePixelRatio(qreal scaleFactor)
QWindowsDirect2DBitmap *QWindowsDirect2DPlatformPixmap::bitmap() const
{
Q_D(const QWindowsDirect2DPlatformPixmap);
- return d->bitmap.data();
+ return d->bitmap;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
index e6684ea423..1936ef0622 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -55,6 +55,9 @@ class QWindowsDirect2DPlatformPixmap : public QPlatformPixmap
Q_DECLARE_PRIVATE(QWindowsDirect2DPlatformPixmap)
public:
QWindowsDirect2DPlatformPixmap(PixelType pixelType);
+
+ // We do NOT take ownership of the bitmap through this constructor!
+ QWindowsDirect2DPlatformPixmap(PixelType pixelType, QWindowsDirect2DBitmap *bitmap);
~QWindowsDirect2DPlatformPixmap();
virtual void resize(int width, int height);
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
index f75bb49fd9..85fbeb7d6f 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
index bf860f982e..15ec0c3526 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
@@ -43,6 +43,7 @@
#include "qwindowsdirect2dwindow.h"
#include "qwindowsdirect2ddevicecontext.h"
#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dplatformpixmap.h"
#include <d3d11.h>
#include <d2d1_1.h>
@@ -54,6 +55,9 @@ QWindowsDirect2DWindow::QWindowsDirect2DWindow(QWindow *window, const QWindowsWi
: QWindowsWindow(window, data)
, m_needsFullFlush(true)
{
+ if (window->type() == Qt::Desktop)
+ return; // No further handling for Qt::Desktop
+
DXGI_SWAP_CHAIN_DESC1 desc = {};
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
@@ -84,6 +88,13 @@ QWindowsDirect2DWindow::~QWindowsDirect2DWindow()
{
}
+QPixmap *QWindowsDirect2DWindow::pixmap()
+{
+ setupBitmap();
+
+ return m_pixmap.data();
+}
+
void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion &region, const QPoint &offset)
{
DXGI_SWAP_CHAIN_DESC1 desc;
@@ -99,33 +110,39 @@ void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion
if (!m_bitmap)
return;
- m_bitmap->deviceContext()->begin();
-
- ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get();
- if (!m_needsFullFlush) {
- QRegion clipped = region;
- clipped &= QRect(0, 0, desc.Width, desc.Height);
-
- foreach (const QRect &rect, clipped.rects()) {
- QRectF rectF(rect);
+ if (bitmap != m_bitmap.data()) {
+ m_bitmap->deviceContext()->begin();
+
+ ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get();
+ if (!m_needsFullFlush) {
+ QRegion clipped = region;
+ clipped &= QRect(0, 0, desc.Width, desc.Height);
+
+ foreach (const QRect &rect, clipped.rects()) {
+ QRectF rectF(rect);
+ dc->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(rectF),
+ 1.0,
+ D2D1_INTERPOLATION_MODE_LINEAR,
+ to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
+ }
+ } else {
+ QRectF rectF(0, 0, desc.Width, desc.Height);
dc->DrawBitmap(bitmap->bitmap(),
to_d2d_rect_f(rectF),
1.0,
D2D1_INTERPOLATION_MODE_LINEAR,
to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
+ m_needsFullFlush = false;
}
- } else {
- QRectF rectF(0, 0, desc.Width, desc.Height);
- dc->DrawBitmap(bitmap->bitmap(),
- to_d2d_rect_f(rectF),
- 1.0,
- D2D1_INTERPOLATION_MODE_LINEAR,
- to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
- m_needsFullFlush = false;
+
+ m_bitmap->deviceContext()->end();
}
+}
- m_bitmap->deviceContext()->end();
- m_swapChain->Present(1, 0);
+void QWindowsDirect2DWindow::present()
+{
+ m_swapChain->Present(0, 0);
}
void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
@@ -133,6 +150,7 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
if (!m_swapChain)
return;
+ m_pixmap.reset();
m_bitmap.reset();
m_deviceContext->SetTarget(Q_NULLPTR);
@@ -146,6 +164,43 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
m_needsFullFlush = true;
}
+QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer() const
+{
+ const QSharedPointer<QWindowsDirect2DBitmap> null_result;
+
+ if (!m_bitmap)
+ return null_result;
+
+ D2D1_PIXEL_FORMAT format = m_bitmap->bitmap()->GetPixelFormat();
+ D2D1_SIZE_U size = m_bitmap->bitmap()->GetPixelSize();
+
+ FLOAT dpiX, dpiY;
+ m_bitmap->bitmap()->GetDpi(&dpiX, &dpiY);
+
+ D2D1_BITMAP_PROPERTIES1 properties = {
+ format, // D2D1_PIXEL_FORMAT pixelFormat;
+ dpiX, // FLOAT dpiX;
+ dpiY, // FLOAT dpiY;
+ D2D1_BITMAP_OPTIONS_TARGET, // D2D1_BITMAP_OPTIONS bitmapOptions;
+ Q_NULLPTR // _Field_size_opt_(1) ID2D1ColorContext *colorContext;
+ };
+ ComPtr<ID2D1Bitmap1> copy;
+ HRESULT hr = m_deviceContext.Get()->CreateBitmap(size, NULL, 0, properties, &copy);
+
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create staging bitmap: %#x", __FUNCTION__, hr);
+ return null_result;
+ }
+
+ hr = copy.Get()->CopyFromBitmap(NULL, m_bitmap->bitmap(), NULL);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy from bitmap! %#x", __FUNCTION__, hr);
+ return null_result;
+ }
+
+ return QSharedPointer<QWindowsDirect2DBitmap>(new QWindowsDirect2DBitmap(copy.Get(), Q_NULLPTR));
+}
+
void QWindowsDirect2DWindow::setupBitmap()
{
if (m_bitmap)
@@ -172,6 +227,10 @@ void QWindowsDirect2DWindow::setupBitmap()
}
m_bitmap.reset(new QWindowsDirect2DBitmap(backBufferBitmap.Get(), m_deviceContext.Get()));
+
+ QWindowsDirect2DPlatformPixmap *pp = new QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixmapType,
+ m_bitmap.data());
+ m_pixmap.reset(new QPixmap(pp));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
index 7996904639..47c790da5d 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
@@ -56,16 +56,21 @@ public:
QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data);
~QWindowsDirect2DWindow();
+ QPixmap *pixmap();
void flush(QWindowsDirect2DBitmap *bitmap, const QRegion &region, const QPoint &offset);
+ void present();
+ void resizeSwapChain(const QSize &size);
+
+ QSharedPointer<QWindowsDirect2DBitmap> copyBackBuffer() const;
private:
- void resizeSwapChain(const QSize &size);
void setupBitmap();
private:
Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain;
Microsoft::WRL::ComPtr<ID2D1DeviceContext> m_deviceContext;
QScopedPointer<QWindowsDirect2DBitmap> m_bitmap;
+ QScopedPointer<QPixmap> m_pixmap;
bool m_needsFullFlush;
};
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index c8c31816a0..f3fd06037e 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -91,7 +91,7 @@ private:
Created = 0x01,
HasNativeWindow = 0x02
};
- Q_DECLARE_FLAGS(Flags, Flag);
+ Q_DECLARE_FLAGS(Flags, Flag)
Flags m_flags;
};
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 9a2c55f7f2..8be3846e06 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -229,6 +229,13 @@
[super touchesEnded:touches withEvent:event];
}
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ m_touchPressWhileKeyboardVisible = NO;
+ [self performSelectorOnMainThread:@selector(touchesEndedPostDelivery) withObject:nil waitUntilDone:NO];
+ [super touchesCancelled:touches withEvent:event];
+}
+
- (void)touchesEndedPostDelivery
{
// Do some clean-up _after_ touchEnd has been delivered to QUIView
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index ebff2c25a1..6f5c96cfc1 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -292,19 +292,33 @@
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
- if (!touches && m_activeTouches.isEmpty())
+ if (m_activeTouches.isEmpty())
return;
- if (!touches) {
- m_activeTouches.clear();
- } else {
- for (UITouch *touch in touches)
- m_activeTouches.remove(touch);
-
- Q_ASSERT_X(m_activeTouches.isEmpty(), Q_FUNC_INFO,
- "Subset of active touches cancelled by UIKit");
- }
-
+ // When four-finger swiping, we get a touchesCancelled callback
+ // which includes all four touch points. The swipe gesture is
+ // then active until all four touches have been released, and
+ // we start getting touchesBegan events again.
+
+ // When five-finger pinching, we also get a touchesCancelled
+ // callback with all five touch points, but the pinch gesture
+ // ends when the second to last finger is released from the
+ // screen. The last finger will not emit any more touch
+ // events, _but_, will contribute to starting another pinch
+ // gesture. That second pinch gesture will _not_ trigger a
+ // touchesCancelled event when starting, but as each finger
+ // is released, and we may get touchesMoved events for the
+ // remaining fingers. [event allTouches] also contains one
+ // less touch point than it should, so this behavior is
+ // likely a bug in the iOS system gesture recognizer, but we
+ // have to take it into account when maintaining the Qt state.
+ // We do this by assuming that there are no cases where a
+ // sub-set of the active touch events are intentionally cancelled.
+
+ if (touches && (static_cast<NSInteger>([touches count]) != m_activeTouches.count()))
+ qWarning("Subset of active touches cancelled by UIKit");
+
+ m_activeTouches.clear();
m_nextTouchId = 0;
NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime];
diff --git a/src/plugins/platforms/kms/qkmsdevice.cpp b/src/plugins/platforms/kms/qkmsdevice.cpp
index 1e08c6f301..8e669fe7d5 100644
--- a/src/plugins/platforms/kms/qkmsdevice.cpp
+++ b/src/plugins/platforms/kms/qkmsdevice.cpp
@@ -85,8 +85,7 @@ QKmsDevice::~QKmsDevice()
void QKmsDevice::createScreens()
{
- drmModeRes *resources = 0;
- resources = drmModeGetResources(m_fd);
+ drmModeRes *resources = drmModeGetResources(m_fd);
if (!resources)
qFatal("drmModeGetResources failed");
@@ -95,7 +94,7 @@ void QKmsDevice::createScreens()
drmModeConnector *connector = 0;
connector = drmModeGetConnector(m_fd, resources->connectors[i]);
if (connector && connector->connection == DRM_MODE_CONNECTED) {
- m_integration->addScreen(new QKmsScreen(this, connector->connector_id));
+ m_integration->addScreen(new QKmsScreen(this, resources, connector));
}
drmModeFreeConnector(connector);
}
diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp
index ad1a45b459..a930aa6545 100644
--- a/src/plugins/platforms/kms/qkmsscreen.cpp
+++ b/src/plugins/platforms/kms/qkmsscreen.cpp
@@ -63,18 +63,18 @@ static drmModeModeInfo builtin_1024x768 = {
"1024x768"
};
-QKmsScreen::QKmsScreen(QKmsDevice *device, int connectorId)
+QKmsScreen::QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector)
: m_device(device),
m_current_bo(0),
m_next_bo(0),
- m_connectorId(connectorId),
+ m_connectorId(connector->connector_id),
m_depth(32),
m_format(QImage::Format_Invalid),
m_eglWindowSurface(EGL_NO_SURFACE),
m_modeSet(false)
{
m_cursor = new QKmsCursor(this);
- initializeScreenMode();
+ initializeScreenMode(resources, connector);
}
QKmsScreen::~QKmsScreen()
@@ -114,14 +114,9 @@ QPlatformCursor *QKmsScreen::cursor() const
return m_cursor;
}
-void QKmsScreen::initializeScreenMode()
+void QKmsScreen::initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector)
{
//Determine optimal mode for screen
- drmModeRes *resources = drmModeGetResources(m_device->fd());
- if (!resources)
- qFatal("drmModeGetResources failed");
-
- drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId);
drmModeModeInfo *mode = 0;
for (int i = 0; i < connector->count_modes; ++i) {
if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) {
@@ -129,8 +124,12 @@ void QKmsScreen::initializeScreenMode()
break;
}
}
- if (!mode)
- mode = &builtin_1024x768;
+ if (!mode) {
+ if (connector->count_modes > 0)
+ mode = &connector->modes[0];
+ else
+ mode = &builtin_1024x768;
+ }
drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]);
if (encoder == 0)
@@ -162,8 +161,6 @@ void QKmsScreen::initializeScreenMode()
qDebug() << "created gbm surface" << m_gbmSurface << m_mode.hdisplay << m_mode.vdisplay;
//Cleanup
drmModeFreeEncoder(encoder);
- drmModeFreeConnector(connector);
- drmModeFreeResources(resources);
}
QSurfaceFormat QKmsScreen::tweakFormat(const QSurfaceFormat &format)
diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h
index 5ae5a1062b..1fa8dbb763 100644
--- a/src/plugins/platforms/kms/qkmsscreen.h
+++ b/src/plugins/platforms/kms/qkmsscreen.h
@@ -68,7 +68,7 @@ class QKmsContext;
class QKmsScreen : public QPlatformScreen
{
public:
- QKmsScreen(QKmsDevice *device, int connectorId);
+ QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector);
~QKmsScreen();
QRect geometry() const;
@@ -94,7 +94,7 @@ public:
private:
void performPageFlip();
- void initializeScreenMode();
+ void initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector);
QKmsDevice *m_device;
gbm_bo *m_current_bo;
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
index e83fc445d6..83af966a00 100644
--- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
@@ -88,7 +88,9 @@ Q_SIGNALS:
void dialogClosed();
private Q_SLOTS:
+#if !defined(Q_OS_BLACKBERRY_TABLET)
void emitSignals();
+#endif
private:
void setNameFilter(const QString &filter);
diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
index eb9fac540f..ead6e73a87 100644
--- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
@@ -64,10 +64,13 @@ QQnxRasterWindow::QQnxRasterWindow(QWindow *window, screen_context_t context, bo
initWindow();
// Set window usage
+ if (window->type() == Qt::Desktop)
+ return;
+
const int val = SCREEN_USAGE_NATIVE | SCREEN_USAGE_READ | SCREEN_USAGE_WRITE;
const int result = screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_USAGE, &val);
if (result != 0)
- qFatal("QQnxEglWindow: failed to set window alpha usage, errno=%d", errno);
+ qFatal("QQnxRasterWindow: failed to set window alpha usage, errno=%d", errno);
}
void QQnxRasterWindow::post(const QRegion &dirty)
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index 2707f14db2..9ba0f5cd2e 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -97,9 +97,9 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
const int envHeight = envPhySizeStrList.size() == 2 ? envPhySizeStrList[1].toInt() : -1;
if (envWidth <= 0 || envHeight <= 0) {
- qFatal("QQnxScreen: The value of QQNX_PHYSICAL_SCREEN_SIZE must be in the format "
- "\"width,height\" in mm, with width, height > 0. "
- "Example: QQNX_PHYSICAL_SCREEN_SIZE=150,90");
+ qWarning("QQnxScreen: The value of QQNX_PHYSICAL_SCREEN_SIZE must be in the format "
+ "\"width,height\" in mm, with width, height > 0. Defaulting to 150x90. "
+ "Example: QQNX_PHYSICAL_SCREEN_SIZE=150,90");
return QSize(150, 90);
}
@@ -114,8 +114,8 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
return defSize;
#else
if (primaryScreen)
- qFatal("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. "
- "Could not determine physical screen size.");
+ qWarning("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. "
+ "Could not determine physical screen size. Defaulting to 150x90.");
return QSize(150, 90);
#endif
}
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 2e0febff20..5a405f9577 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -174,7 +174,7 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
// indication that we want to create a child window and join that window group.
const QVariant windowGroup = window->property("qnxInitialWindowGroup");
- if (window->type() == Qt::CoverWindow || window->type() == Qt::Desktop) {
+ if (window->type() == Qt::CoverWindow) {
// Cover windows have to be top level to be accessible to window delegate (i.e. navigator)
// Desktop windows also need to be toplevel because they are not
// supposed to be part of the window hierarchy tree
@@ -189,10 +189,13 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
m_isTopLevel = !needRootWindow || !platformScreen->rootWindow();
}
+ if (window->type() == Qt::Desktop) // A desktop widget does not need a libscreen window
+ return;
+
if (m_isTopLevel) {
Q_SCREEN_CRITICALERROR(screen_create_window(&m_window, m_screenContext),
"Could not create top level window"); // Creates an application window
- if (window->type() != Qt::CoverWindow && window->type() != Qt::Desktop) {
+ if (window->type() != Qt::CoverWindow) {
if (needRootWindow)
platformScreen->setRootWindow(this);
}
@@ -245,9 +248,9 @@ void QQnxWindow::setGeometry(const QRect &rect)
if (shouldMakeFullScreen())
newGeometry = screen()->geometry();
- setGeometryHelper(newGeometry);
+ if (window()->type() != Qt::Desktop)
+ setGeometryHelper(newGeometry);
- QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
if (isExposed())
QWindowSystemInterface::handleExposeEvent(window(), newGeometry);
}
@@ -278,13 +281,15 @@ void QQnxWindow::setGeometryHelper(const QRect &rect)
"Failed to set window source size");
screen_flush_context(m_screenContext, 0);
+
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
}
void QQnxWindow::setVisible(bool visible)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "visible =" << visible;
- if (m_visible == visible)
+ if (m_visible == visible || window()->type() == Qt::Desktop)
return;
// The first time through we join a window group if appropriate.
@@ -667,6 +672,9 @@ void QQnxWindow::setRotation(int rotation)
void QQnxWindow::initWindow()
{
+ if (window()->type() == Qt::Desktop)
+ return;
+
// Alpha channel is always pre-multiplied if present
int val = SCREEN_PRE_MULTIPLIED_ALPHA;
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val),
@@ -711,12 +719,7 @@ void QQnxWindow::initWindow()
if (window()->parent() && window()->parent()->handle())
setParent(window()->parent()->handle());
- if (shouldMakeFullScreen())
- setGeometryHelper(screen()->geometry());
- else
- setGeometryHelper(window()->geometry());
-
- QWindowSystemInterface::handleGeometryChange(window(), screen()->geometry());
+ setGeometryHelper(shouldMakeFullScreen() ? screen()->geometry() : window()->geometry());
}
void QQnxWindow::createWindowGroup()
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index 9a2006396f..94df903336 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -75,7 +75,7 @@ public:
bool isExposed() const;
- WId winId() const { return (WId)m_window; }
+ WId winId() const { return window()->type() == Qt::Desktop ? -1 : (WId)m_window; }
screen_window_t nativeHandle() const { return m_window; }
void setBufferSize(const QSize &size);
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 1abf447709..34a9c1df5f 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -145,9 +145,8 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
<< " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
}
#endif
- QImage::Format format = QWindowsNativeImage::systemFormat();
- if (format == QImage::Format_RGB32 && window()->format().hasAlpha())
- format = QImage::Format_ARGB32_Premultiplied;
+ const QImage::Format format = window()->format().hasAlpha() ?
+ QImage::Format_ARGB32_Premultiplied : QWindowsNativeImage::systemFormat();
QWindowsNativeImage *oldwni = m_image.data();
QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format);
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 6462cb8d3e..ead29556b7 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -49,11 +49,11 @@
#include "qwindowsmime.h"
#include "qwindowsinputcontext.h"
#include "qwindowstabletsupport.h"
+#include <private/qguiapplication_p.h>
#ifndef QT_NO_ACCESSIBILITY
# include "accessible/qwindowsaccessibility.h"
#endif
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
-# include <private/qguiapplication_p.h>
# include <private/qsessionmanager_p.h>
# include "qwindowssessionmanager.h"
#endif
@@ -76,6 +76,9 @@
#include <stdlib.h>
#include <stdio.h>
#include <windowsx.h>
+#ifndef Q_OS_WINCE
+# include <comdef.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -213,7 +216,7 @@ bool QWindowsUser32DLL::initTouch()
unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow"));
getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo"));
closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle"));
- return registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && getTouchInputInfo;
+ return registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle;
}
/*!
@@ -309,6 +312,10 @@ QWindowsContextPrivate::QWindowsContextPrivate()
m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
m_keyMapper.setUseRTLExtensions(true);
}
+ if (FAILED(m_oleInitializeResult)) {
+ qWarning() << "QWindowsContext: OleInitialize() failed: "
+ << QWindowsContext::comErrorString(m_oleInitializeResult);
+ }
}
QWindowsContext::QWindowsContext() :
@@ -691,45 +698,70 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn,
QByteArray QWindowsContext::comErrorString(HRESULT hr)
{
+ QByteArray result = QByteArrayLiteral("COM error 0x")
+ + QByteArray::number(quintptr(hr), 16) + ' ';
switch (hr) {
case S_OK:
- return QByteArrayLiteral("S_OK");
+ result += QByteArrayLiteral("S_OK");
+ break;
case S_FALSE:
- return QByteArrayLiteral("S_FALSE");
+ result += QByteArrayLiteral("S_FALSE");
+ break;
case E_UNEXPECTED:
- return QByteArrayLiteral("E_UNEXPECTED");
+ result += QByteArrayLiteral("E_UNEXPECTED");
+ break;
case CO_E_ALREADYINITIALIZED:
- return QByteArrayLiteral("CO_E_ALREADYINITIALIZED");
+ result += QByteArrayLiteral("CO_E_ALREADYINITIALIZED");
+ break;
case CO_E_NOTINITIALIZED:
- return QByteArrayLiteral("CO_E_NOTINITIALIZED");
+ result += QByteArrayLiteral("CO_E_NOTINITIALIZED");
+ break;
case RPC_E_CHANGED_MODE:
- return QByteArrayLiteral("RPC_E_CHANGED_MODE");
+ result += QByteArrayLiteral("RPC_E_CHANGED_MODE");
+ break;
case OLE_E_WRONGCOMPOBJ:
- return QByteArrayLiteral("OLE_E_WRONGCOMPOBJ");
+ result += QByteArrayLiteral("OLE_E_WRONGCOMPOBJ");
+ break;
case CO_E_NOT_SUPPORTED:
- return QByteArrayLiteral("CO_E_NOT_SUPPORTED");
+ result += QByteArrayLiteral("CO_E_NOT_SUPPORTED");
+ break;
case E_NOTIMPL:
- return QByteArrayLiteral("E_NOTIMPL");
+ result += QByteArrayLiteral("E_NOTIMPL");
+ break;
case E_INVALIDARG:
- return QByteArrayLiteral("E_INVALIDARG");
+ result += QByteArrayLiteral("E_INVALIDARG");
+ break;
case E_NOINTERFACE:
- return QByteArrayLiteral("E_NOINTERFACE");
+ result += QByteArrayLiteral("E_NOINTERFACE");
+ break;
case E_POINTER:
- return QByteArrayLiteral("E_POINTER");
+ result += QByteArrayLiteral("E_POINTER");
+ break;
case E_HANDLE:
- return QByteArrayLiteral("E_HANDLE");
+ result += QByteArrayLiteral("E_HANDLE");
+ break;
case E_ABORT:
- return QByteArrayLiteral("E_ABORT");
+ result += QByteArrayLiteral("E_ABORT");
+ break;
case E_FAIL:
- return QByteArrayLiteral("E_FAIL");
+ result += QByteArrayLiteral("E_FAIL");
+ break;
case RPC_E_WRONG_THREAD:
- return QByteArrayLiteral("RPC_E_WRONG_THREAD");
+ result += QByteArrayLiteral("RPC_E_WRONG_THREAD");
+ break;
case RPC_E_THREAD_NOT_INIT:
- return QByteArrayLiteral("RPC_E_THREAD_NOT_INIT");
+ result += QByteArrayLiteral("RPC_E_THREAD_NOT_INIT");
+ break;
default:
break;
}
- return "Unknown error 0x" + QByteArray::number(quint64(hr), 16);
+#ifndef Q_OS_WINCE
+ _com_error error(hr);
+ result += QByteArrayLiteral(" (");
+ result += QString::fromWCharArray(error.ErrorMessage()).toLocal8Bit();
+ result += ')';
+#endif // !Q_OS_WINCE
+ return result;
}
/*!
@@ -1025,6 +1057,21 @@ void QWindowsContext::handleFocusEvent(QtWindows::WindowsEventType et,
{
QWindow *nextActiveWindow = 0;
if (et == QtWindows::FocusInEvent) {
+ QWindow *topWindow = QWindowsWindow::topLevelOf(platformWindow->window());
+ QWindow *modalWindow = 0;
+ if (QGuiApplicationPrivate::instance()->isWindowBlocked(topWindow, &modalWindow) && topWindow != modalWindow) {
+ modalWindow->requestActivate();
+ return;
+ }
+ // QTBUG-32867: Invoking WinAPI SetParent() can cause focus-in for the
+ // window which is not desired for native child widgets.
+ if (platformWindow->testFlag(QWindowsWindow::WithinSetParent)) {
+ QWindow *currentFocusWindow = QGuiApplication::focusWindow();
+ if (currentFocusWindow && currentFocusWindow != platformWindow->window()) {
+ currentFocusWindow->requestActivate();
+ return;
+ }
+ }
nextActiveWindow = platformWindow->window();
} else {
// Focus out: Is the next window known and different
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 4f3a007bd7..6f97c8584b 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -169,6 +169,20 @@ bool QWindowsFontEngine::hasCMapTable() const
return GetFontData(hdc, MAKE_TAG('c', 'm', 'a', 'p'), 0, 0, 0) != GDI_ERROR;
}
+bool QWindowsFontEngine::hasGlyfTable() const
+{
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ return GetFontData(hdc, MAKE_TAG('g', 'l', 'y', 'f'), 0, 0, 0) != GDI_ERROR;
+}
+
+bool QWindowsFontEngine::hasEbdtTable() const
+{
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ return GetFontData(hdc, MAKE_TAG('E', 'B', 'D', 'T'), 0, 0, 0) != GDI_ERROR;
+}
+
void QWindowsFontEngine::getCMap()
{
ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE) || hasCMapTable();
@@ -308,6 +322,8 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name,
userData.insert(QStringLiteral("hFont"), QVariant::fromValue(hfont));
userData.insert(QStringLiteral("trueType"), QVariant(bool(ttf)));
setUserData(userData);
+
+ hasUnreliableOutline = hasGlyfTable() && hasEbdtTable();
}
QWindowsFontEngine::~QWindowsFontEngine()
@@ -662,6 +678,11 @@ void QWindowsFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qre
}
#endif // Q_CC_MINGW
+bool QWindowsFontEngine::hasUnreliableGlyphOutline() const
+{
+ return hasUnreliableOutline;
+}
+
qreal QWindowsFontEngine::minLeftBearing() const
{
if (lbearing == SHRT_MIN)
@@ -1032,7 +1053,7 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph,
int iw = gm.width.toInt();
int ih = gm.height.toInt();
- if (iw <= 0 || iw <= 0)
+ if (iw <= 0 || ih <= 0)
return 0;
bool has_transformation = t.type() > QTransform::TxTranslate;
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
index 7a0803830c..0ddf778fa0 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -122,6 +122,8 @@ public:
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
#endif
+ bool hasUnreliableGlyphOutline() const Q_DECL_OVERRIDE;
+
int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs) const;
void getCMap();
@@ -136,6 +138,8 @@ private:
QImage::Format mask_format);
bool hasCFFTable() const;
bool hasCMapTable() const;
+ bool hasGlyfTable() const;
+ bool hasEbdtTable() const;
const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
@@ -146,6 +150,7 @@ private:
uint stockFont : 1;
uint ttf : 1;
uint hasOutline : 1;
+ uint hasUnreliableOutline : 1;
uint cffTable : 1;
TEXTMETRIC tm;
int lw;
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 6349c1e355..6a3930dc78 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -230,12 +230,16 @@ static inline QPalette toolTipPalette(const QPalette &systemPalette)
result.setColor(QPalette::All, QPalette::Text, tipTextColor);
result.setColor(QPalette::All, QPalette::WindowText, tipTextColor);
result.setColor(QPalette::All, QPalette::ButtonText, tipTextColor);
+ result.setColor(QPalette::All, QPalette::ToolTipBase, tipBgColor);
+ result.setColor(QPalette::All, QPalette::ToolTipText, tipTextColor);
const QColor disabled =
mixColors(result.foreground().color(), result.button().color());
result.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
result.setColor(QPalette::Disabled, QPalette::Text, disabled);
+ result.setColor(QPalette::Disabled, QPalette::ToolTipText, disabled);
result.setColor(QPalette::Disabled, QPalette::Base, Qt::white);
result.setColor(QPalette::Disabled, QPalette::BrightText, Qt::white);
+ result.setColor(QPalette::Disabled, QPalette::ToolTipBase, Qt::white);
return result;
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index a6b7d19432..c8eaded38d 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1016,17 +1016,17 @@ QWindow *QWindowsWindow::topLevelOf(QWindow *w)
while (QWindow *parent = w->parent())
w = parent;
- const QWindowsWindow *ww = static_cast<const QWindowsWindow *>(w->handle());
-
- // In case the topmost parent is embedded, find next ancestor using native methods
- if (ww->isEmbedded(0)) {
- HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT);
- const HWND desktopHwnd = GetDesktopWindow();
- const QWindowsContext *ctx = QWindowsContext::instance();
- while (parentHWND && parentHWND != desktopHwnd) {
- if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND))
- return topLevelOf(ancestor->window());
- parentHWND = GetAncestor(parentHWND, GA_PARENT);
+ if (const QPlatformWindow *handle = w->handle()) {
+ const QWindowsWindow *ww = static_cast<const QWindowsWindow *>(handle);
+ if (ww->isEmbedded(0)) {
+ HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT);
+ const HWND desktopHwnd = GetDesktopWindow();
+ const QWindowsContext *ctx = QWindowsContext::instance();
+ while (parentHWND && parentHWND != desktopHwnd) {
+ if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND))
+ return topLevelOf(ancestor->window());
+ parentHWND = GetAncestor(parentHWND, GA_PARENT);
+ }
}
}
return w;
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index b7bfce5931..e2ff7197aa 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -487,6 +487,7 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window)
// Set initial orientation
onOrientationChanged(0);
+ setOrientationUpdateMask(m_nativeOrientation);
m_displayProperties->add_OrientationChanged(Callback<IDisplayPropertiesEventHandler>(this, &QWinRTScreen::onOrientationChanged).Get(),
&m_tokens[QEvent::OrientationChange]);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 386bf16c16..3645b6469a 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -485,7 +485,7 @@ QXcbWindow::~QXcbWindow()
void QXcbWindow::destroy()
{
if (connection()->focusWindow() == this)
- connection()->setFocusWindow(0);
+ doFocusOut();
if (m_syncCounter && m_usingSyncProtocol)
Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
@@ -554,7 +554,7 @@ QMargins QXcbWindow::frameMargins() const
xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, NULL);
if (reply) {
- if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1) {
+ if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1 || reply->parent == XCB_WINDOW_NONE) {
foundRoot = true;
} else {
window = parent;
@@ -671,6 +671,9 @@ void QXcbWindow::show()
Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
+ if (QGuiApplication::modalWindow() == window())
+ requestActivateWindow();
+
m_screen->windowShown(this);
connection()->sync();
@@ -694,6 +697,68 @@ void QXcbWindow::hide()
m_mapped = false;
}
+static QWindow *tlWindow(QWindow *window)
+{
+ if (window && window->parent())
+ return tlWindow(window->parent());
+ return window;
+}
+
+bool QXcbWindow::relayFocusToModalWindow() const
+{
+ QWindow *w = tlWindow(static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver());
+ QWindow *modal_window = 0;
+ if (QGuiApplicationPrivate::instance()->isWindowBlocked(w,&modal_window) && modal_window != w) {
+ modal_window->requestActivate();
+ connection()->flush();
+ return true;
+ }
+
+ return false;
+}
+
+void QXcbWindow::doFocusIn()
+{
+ if (relayFocusToModalWindow())
+ return;
+ QWindow *w = static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver();
+ connection()->setFocusWindow(static_cast<QXcbWindow *>(w->handle()));
+ QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason);
+}
+
+static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event)
+{
+ if (!event) {
+ // FocusIn event is not in the queue, proceed with FocusOut normally.
+ QWindowSystemInterface::handleWindowActivated(0, Qt::ActiveWindowFocusReason);
+ return true;
+ }
+ uint response_type = event->response_type & ~0x80;
+ if (response_type == XCB_FOCUS_IN)
+ return true;
+
+ /* We are also interested in XEMBED_FOCUS_IN events */
+ if (response_type == XCB_CLIENT_MESSAGE) {
+ xcb_client_message_event_t *cme = (xcb_client_message_event_t *)event;
+ if (cme->type == connection->atom(QXcbAtom::_XEMBED)
+ && cme->data.data32[1] == XEMBED_FOCUS_IN)
+ return true;
+ }
+
+ return false;
+}
+
+void QXcbWindow::doFocusOut()
+{
+ if (relayFocusToModalWindow())
+ return;
+ connection()->setFocusWindow(0);
+ // Do not set the active window to 0 if there is a FocusIn coming.
+ // There is however no equivalent for XPutBackEvent so register a
+ // callback for QXcbConnection instead.
+ connection()->addPeekFunc(focusInPeeker);
+}
+
struct QtMotifWmHints {
quint32 flags, functions, decorations;
qint32 input_mode;
@@ -1514,6 +1579,8 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
QWindowSystemInterface::handleCloseEvent(window());
} else if (event->data.data32[0] == atom(QXcbAtom::WM_TAKE_FOCUS)) {
connection()->setTime(event->data.data32[1]);
+ relayFocusToModalWindow();
+ return;
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) {
if (event->window == m_screen->root())
return;
@@ -1549,8 +1616,7 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
} else if (event->type == atom(QXcbAtom::_XEMBED)) {
handleXEmbedMessage(event);
} else if (event->type == atom(QXcbAtom::_NET_ACTIVE_WINDOW)) {
- connection()->setFocusWindow(this);
- QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason);
+ doFocusIn();
} else if (event->type == atom(QXcbAtom::MANAGER)
|| event->type == atom(QXcbAtom::_NET_WM_STATE)
|| event->type == atom(QXcbAtom::WM_CHANGE_STATE)) {
@@ -1868,41 +1934,13 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *)
{
- QWindow *w = window();
- w = static_cast<QWindowPrivate *>(QObjectPrivate::get(w))->eventReceiver();
- connection()->setFocusWindow(static_cast<QXcbWindow *>(w->handle()));
- QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason);
+ doFocusIn();
}
-static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event)
-{
- if (!event) {
- // FocusIn event is not in the queue, proceed with FocusOut normally.
- QWindowSystemInterface::handleWindowActivated(0, Qt::ActiveWindowFocusReason);
- return true;
- }
- uint response_type = event->response_type & ~0x80;
- if (response_type == XCB_FOCUS_IN)
- return true;
-
- /* We are also interested in XEMBED_FOCUS_IN events */
- if (response_type == XCB_CLIENT_MESSAGE) {
- xcb_client_message_event_t *cme = (xcb_client_message_event_t *)event;
- if (cme->type == connection->atom(QXcbAtom::_XEMBED)
- && cme->data.data32[1] == XEMBED_FOCUS_IN)
- return true;
- }
-
- return false;
-}
void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
{
- connection()->setFocusWindow(0);
- // Do not set the active window to 0 if there is a FocusIn coming.
- // There is however no equivalent for XPutBackEvent so register a
- // callback for QXcbConnection instead.
- connection()->addPeekFunc(focusInPeeker);
+ doFocusOut();
}
void QXcbWindow::updateSyncRequestCounter()
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index a90ad7b5ed..12d17023fb 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -176,6 +176,10 @@ private:
void show();
void hide();
+ bool relayFocusToModalWindow() const;
+ void doFocusIn();
+ void doFocusOut();
+
QXcbScreen *m_screen;
xcb_window_t m_window;
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index c052e4c2e7..722595ad52 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -104,6 +104,11 @@
#define QXIDOID 28
#define QCIDOID 29
+#define QBITOID 1560
+#define QVARBITOID 1562
+
+#define VARHDRSZ 4
+
/* This is a compile time switch - if PQfreemem is declared, the compiler will use that one,
otherwise it'll run in this template */
template <typename T>
@@ -533,17 +538,33 @@ QSqlRecord QPSQLResult::record() const
f.setName(QString::fromUtf8(PQfname(d->result, i)));
else
f.setName(QString::fromLocal8Bit(PQfname(d->result, i)));
- f.setType(qDecodePSQLType(PQftype(d->result, i)));
+ int ptype = PQftype(d->result, i);
+ f.setType(qDecodePSQLType(ptype));
int len = PQfsize(d->result, i);
int precision = PQfmod(d->result, i);
- // swap length and precision if length == -1
- if (len == -1 && precision > -1) {
- len = precision - 4;
+
+ switch (ptype) {
+ case QNUMERICOID:
+ if (precision != -1) {
+ len = (precision >> 16);
+ precision = ((precision - VARHDRSZ) & 0xffff);
+ }
+ break;
+ case QBITOID:
+ case QVARBITOID:
+ len = precision;
precision = -1;
+ break;
+ default:
+ if (len == -1 && precision >= VARHDRSZ) {
+ len = precision - VARHDRSZ;
+ precision = -1;
+ }
}
+
f.setLength(len);
f.setPrecision(precision);
- f.setSqlType(PQftype(d->result, i));
+ f.setSqlType(ptype);
info.append(f);
}
return info;
diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp
index b08f6bc8ef..6b13eb02ed 100644
--- a/src/sql/kernel/qsqlquery.cpp
+++ b/src/sql/kernel/qsqlquery.cpp
@@ -511,12 +511,23 @@ const QSqlResult* QSqlQuery::result() const
\list
- \li If the result is currently positioned before the first record or
- on the first record, and \a index is negative, there is no change,
- and false is returned.
+ \li If the result is currently positioned before the first record and:
+ \list
+ \li \a index is negative or zero, there is no change, and false is
+ returned.
+ \li \a index is positive, an attempt is made to position the result
+ at absolute position \a index - 1, following the sames rule for non
+ relative seek, above.
+ \endlist
- \li If the result is currently located after the last record, and \a
- index is positive, there is no change, and false is returned.
+ \li If the result is currently positioned after the last record and:
+ \list
+ \li \a index is positive or zero, there is no change, and false is
+ returned.
+ \li \a index is negative, an attempt is made to position the result
+ at \a index + 1 relative position from last record, following the
+ rule below.
+ \endlist
\li If the result is currently located somewhere in the middle, and
the relative offset \a index moves the result below zero, the result
@@ -549,7 +560,7 @@ bool QSqlQuery::seek(int index, bool relative)
switch (at()) { // relative seek
case QSql::BeforeFirstRow:
if (index > 0)
- actualIdx = index;
+ actualIdx = index - 1;
else {
return false;
}
@@ -557,7 +568,7 @@ bool QSqlQuery::seek(int index, bool relative)
case QSql::AfterLastRow:
if (index < 0) {
d->sqlResult->fetchLast();
- actualIdx = at() + index;
+ actualIdx = at() + index + 1;
} else {
return false;
}
diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc
index 13654972ec..4125e63ddc 100644
--- a/src/testlib/doc/src/qttestlib-manual.qdoc
+++ b/src/testlib/doc/src/qttestlib-manual.qdoc
@@ -315,12 +315,15 @@
\row \li CPU tick counter
\li -tickcounter
\li Windows, Mac OS X, Linux, many UNIX-like systems.
- \row \li Valgrind Callgrind
- \li -callgrind
- \li Linux (if installed)
\row \li Event Counter
\li -eventcounter
\li All platforms
+ \row \li Valgrind Callgrind
+ \li -callgrind
+ \li Linux (if installed)
+ \row \li Linux Perf
+ \li -perf
+ \li Linux
\endtable
In short, walltime is always available but requires many repetitions to
@@ -335,6 +338,16 @@
that were received by the event loop before they are sent to their corresponding
targets (this might include non-Qt events).
+ The Linux Performance Monitoring solution is available only on Linux and
+ provides many different counters, which can be selected by passing an
+ additional option \c {-perfcounter countername}, such as \c {-perfcounter
+ cache-misses}, \c {-perfcounter branch-misses}, or \c {-perfcounter
+ l1d-load-misses}. The default counter is \c {cpu-cycles}. The full list of
+ counters can be obtained by running any benchmark executable with the
+ option \c -perfcounterlist.
+
+ Note that using the performance counter may require enabling access to non-privileged applications.
+
\note Depending on the device configuration, tick counters on the
Windows CE platform may not be as fine-grained, compared to other platforms.
Devices that do not support high-resolution timers default to
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h
index 7c9a7b2b3f..7d2f3cea72 100644
--- a/src/testlib/qtest.h
+++ b/src/testlib/qtest.h
@@ -201,11 +201,17 @@ inline bool qCompare(QList<T> const &t1, QList<T> const &t2, const char *actual,
}
for (int i = 0; isOk && i < actualSize; ++i) {
if (!(t1.at(i) == t2.at(i))) {
+ char *val1 = toString(t1.at(i));
+ char *val2 = toString(t2.at(i));
+
qsnprintf(msg, sizeof(msg), "Compared lists differ at index %d.\n"
" Actual (%s): %s\n"
- " Expected (%s): %s", i, actual, toString(t1.at(i)),
- expected, toString(t2.at(i)));
+ " Expected (%s): %s", i, actual, val1 ? val1 : "<null>",
+ expected, val2 ? val2 : "<null>");
isOk = false;
+
+ delete [] val1;
+ delete [] val2;
}
}
return compare_helper(isOk, msg, 0, 0, actual, expected, file, line);
diff --git a/src/testlib/qtestaccessible.h b/src/testlib/qtestaccessible.h
index f27651c3ad..ef6f61bd82 100644
--- a/src/testlib/qtestaccessible.h
+++ b/src/testlib/qtestaccessible.h
@@ -253,12 +253,10 @@ private:
{
QString rc;
QDebug str = QDebug(&rc).nospace();
- str << "Event " << needle->object() << ", type: "
- << needle->type() << ", child: " << needle->child()
- << " not found at head of event list of size " << haystack.size() << " :";
+ str << "Event " << *needle
+ << " not found at head of event list of size " << haystack.size() << " :";
Q_FOREACH (const QAccessibleEvent *e, haystack)
- str << ' ' << e->object() << ", type: "
- << e->type() << ", child: " << e->child();
+ str << ' ' << *e;
return rc;
}
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index cbf479f1d2..ffcc7abbfe 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -2143,18 +2143,26 @@ char *toHexRepresentation(const char *ba, int length)
char *toPrettyUnicode(const ushort *p, int length)
{
// keep it simple for the vast majority of cases
- QScopedArrayPointer<char> buffer(new char[length * 6 + 3]);
+ bool trimmed = false;
+ QScopedArrayPointer<char> buffer(new char[256]);
const ushort *end = p + length;
char *dst = buffer.data();
*dst++ = '"';
for ( ; p != end; ++p) {
+ if (dst - buffer.data() > 245) {
+ // plus the the quote, the three dots and NUL, it's 250, 251 or 255
+ trimmed = true;
+ break;
+ }
+
if (*p < 0x7f && *p >= 0x20 && *p != '\\') {
*dst++ = *p;
continue;
}
// write as an escape sequence
+ // this means we may advance dst to buffer.data() + 246 or 250
*dst++ = '\\';
switch (*p) {
case 0x22:
@@ -2186,6 +2194,11 @@ char *toPrettyUnicode(const ushort *p, int length)
}
*dst++ = '"';
+ if (trimmed) {
+ *dst++ = '.';
+ *dst++ = '.';
+ *dst++ = '.';
+ }
*dst++ = '\0';
return buffer.take();
}
@@ -2863,8 +2876,6 @@ bool QTest::currentTestFailed()
void QTest::qSleep(int ms)
{
QTEST_ASSERT(ms > 0);
- QElapsedTimer timer;
- timer.start();
#if defined(Q_OS_WINRT)
WaitForSingleObjectEx(GetCurrentThread(), ms, true);
@@ -2874,20 +2885,6 @@ void QTest::qSleep(int ms)
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
nanosleep(&ts, NULL);
#endif
- // Warn if the elapsed time was more than 50% longer or more than 10% shorter than the
- // requested time.
- qint64 requested = 1000000 * (qint64)ms;
- qint64 diff = timer.nsecsElapsed() - requested;
-#ifndef Q_OS_WIN
- const qint64 factor = 2; // more than 50% longer
-#else
- const qint64 factor = 1; // Windows: 50% is quite common, warn about 100%
-#endif
- if (diff * factor > requested || diff * 10 < -requested) {
- QTestLog::warn(qPrintable(
- QString::fromLatin1("QTest::qSleep() should have taken %1ns, but actually took %2ns!")
- .arg(requested).arg(diff + requested)), __FILE__, __LINE__);
- }
}
/*! \internal
diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp
index a9abca0ef8..859f6743cd 100644
--- a/src/testlib/qtestresult.cpp
+++ b/src/testlib/qtestresult.cpp
@@ -51,6 +51,8 @@
#include <string.h>
#include <wchar.h>
+static const char *currentAppName = 0;
+
QT_BEGIN_NAMESPACE
namespace QTest
@@ -64,8 +66,6 @@ namespace QTest
static const char *expectFailComment = 0;
static int expectFailMode = 0;
-
- static const char *currentAppName = 0;
}
void QTestResult::reset()
@@ -322,12 +322,12 @@ bool QTestResult::skipCurrentTest()
void QTestResult::setCurrentAppName(const char *appName)
{
- QTest::currentAppName = appName;
+ ::currentAppName = appName;
}
const char *QTestResult::currentAppName()
{
- return QTest::currentAppName;
+ return ::currentAppName;
}
QT_END_NAMESPACE
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index d831edfef0..a67ea05956 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -983,6 +983,7 @@ void Generator::generateMetacall()
fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s; break;\n",
propindex, p.type.constData(), prefix.constData(), p.member.constData());
}
+ fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
@@ -1031,6 +1032,7 @@ void Generator::generateMetacall()
fprintf(out, " break;\n");
}
}
+ fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
@@ -1054,6 +1056,7 @@ void Generator::generateMetacall()
fprintf(out, " case %d: %s%s; break;\n",
propindex, prefix.constData(), p.reset.constData());
}
+ fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
@@ -1072,6 +1075,7 @@ void Generator::generateMetacall()
fprintf(out, " case %d: *_b = %s; break;\n",
propindex, p.designable.constData());
}
+ fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
@@ -1090,6 +1094,7 @@ void Generator::generateMetacall()
fprintf(out, " case %d: *_b = %s; break;\n",
propindex, p.scriptable.constData());
}
+ fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
@@ -1108,6 +1113,7 @@ void Generator::generateMetacall()
fprintf(out, " case %d: *_b = %s; break;\n",
propindex, p.stored.constData());
}
+ fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
@@ -1126,6 +1132,7 @@ void Generator::generateMetacall()
fprintf(out, " case %d: *_b = %s; break;\n",
propindex, p.editable.constData());
}
+ fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
@@ -1145,6 +1152,7 @@ void Generator::generateMetacall()
fprintf(out, " case %d: *_b = %s; break;\n",
propindex, p.user.constData());
}
+ fprintf(out, " default: break;\n");
fprintf(out, " }\n");
}
fprintf(out,
@@ -1226,6 +1234,7 @@ void Generator::generateStaticMetacall()
fprintf(out, ");\n");
fprintf(out, " if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;\n");
}
+ fprintf(out, " default: break;\n");
fprintf(out, " }\n");
fprintf(out, " }");
needElse = true;
diff --git a/src/tools/moc/token.cpp b/src/tools/moc/token.cpp
index a936555980..36b413ca84 100644
--- a/src/tools/moc/token.cpp
+++ b/src/tools/moc/token.cpp
@@ -47,174 +47,9 @@ QT_BEGIN_NAMESPACE
const char *tokenTypeName(Token t)
{
switch (t) {
- case NOTOKEN: return "NOTOKEN";
- case IDENTIFIER: return "IDENTIFIER";
- case INTEGER_LITERAL: return "INTEGER_LITERAL";
- case CHARACTER_LITERAL: return "CHARACTER_LITERAL";
- case STRING_LITERAL: return "STRING_LITERAL";
- case BOOLEAN_LITERAL: return "BOOLEAN_LITERAL";
- case HEADER_NAME: return "HEADER_NAME";
- case LANGLE: return "LANGLE";
- case RANGLE: return "RANGLE";
- case LPAREN: return "LPAREN";
- case RPAREN: return "RPAREN";
- case ELIPSIS: return "ELIPSIS";
- case LBRACK: return "LBRACK";
- case RBRACK: return "RBRACK";
- case LBRACE: return "LBRACE";
- case RBRACE: return "RBRACE";
- case EQ: return "EQ";
- case SCOPE: return "SCOPE";
- case SEMIC: return "SEMIC";
- case COLON: return "COLON";
- case DOTSTAR: return "DOTSTAR";
- case QUESTION: return "QUESTION";
- case DOT: return "DOT";
- case DYNAMIC_CAST: return "DYNAMIC_CAST";
- case STATIC_CAST: return "STATIC_CAST";
- case REINTERPRET_CAST: return "REINTERPRET_CAST";
- case CONST_CAST: return "CONST_CAST";
- case TYPEID: return "TYPEID";
- case THIS: return "THIS";
- case TEMPLATE: return "TEMPLATE";
- case THROW: return "THROW";
- case TRY: return "TRY";
- case CATCH: return "CATCH";
- case TYPEDEF: return "TYPEDEF";
- case FRIEND: return "FRIEND";
- case CLASS: return "CLASS";
- case NAMESPACE: return "NAMESPACE";
- case ENUM: return "ENUM";
- case STRUCT: return "STRUCT";
- case UNION: return "UNION";
- case VIRTUAL: return "VIRTUAL";
- case PRIVATE: return "PRIVATE";
- case PROTECTED: return "PROTECTED";
- case PUBLIC: return "PUBLIC";
- case EXPORT: return "EXPORT";
- case AUTO: return "AUTO";
- case REGISTER: return "REGISTER";
- case EXTERN: return "EXTERN";
- case MUTABLE: return "MUTABLE";
- case ASM: return "ASM";
- case USING: return "USING";
- case INLINE: return "INLINE";
- case EXPLICIT: return "EXPLICIT";
- case STATIC: return "STATIC";
- case CONST: return "CONST";
- case VOLATILE: return "VOLATILE";
- case OPERATOR: return "OPERATOR";
- case SIZEOF: return "SIZEOF";
- case NEW: return "NEW";
- case DELETE: return "DELETE";
- case PLUS: return "PLUS";
- case MINUS: return "MINUS";
- case STAR: return "STAR";
- case SLASH: return "SLASH";
- case PERCENT: return "PERCENT";
- case HAT: return "HAT";
- case AND: return "AND";
- case OR: return "OR";
- case TILDE: return "TILDE";
- case NOT: return "NOT";
- case PLUS_EQ: return "PLUS_EQ";
- case MINUS_EQ: return "MINUS_EQ";
- case STAR_EQ: return "STAR_EQ";
- case SLASH_EQ: return "SLASH_EQ";
- case PERCENT_EQ: return "PERCENT_EQ";
- case HAT_EQ: return "HAT_EQ";
- case AND_EQ: return "AND_EQ";
- case OR_EQ: return "OR_EQ";
- case LTLT: return "LTLT";
- case GTGT: return "GTGT";
- case GTGT_EQ: return "GTGT_EQ";
- case LTLT_EQ: return "LTLT_EQ";
- case EQEQ: return "EQEQ";
- case NE: return "NE";
- case LE: return "LE";
- case GE: return "GE";
- case ANDAND: return "ANDAND";
- case OROR: return "OROR";
- case INCR: return "INCR";
- case DECR: return "DECR";
- case COMMA: return "COMMA";
- case ARROW_STAR: return "ARROW_STAR";
- case ARROW: return "ARROW";
- case CHAR: return "CHAR";
- case WCHAR: return "WCHAR";
- case BOOL: return "BOOL";
- case SHORT: return "SHORT";
- case INT: return "INT";
- case LONG: return "LONG";
- case SIGNED: return "SIGNED";
- case UNSIGNED: return "UNSIGNED";
- case FLOAT: return "FLOAT";
- case DOUBLE: return "DOUBLE";
- case VOID: return "VOID";
- case CASE: return "CASE";
- case DEFAULT: return "DEFAULT";
- case IF: return "IF";
- case ELSE: return "ELSE";
- case SWITCH: return "SWITCH";
- case WHILE: return "WHILE";
- case DO: return "DO";
- case FOR: return "FOR";
- case BREAK: return "BREAK";
- case CONTINUE: return "CONTINUE";
- case GOTO: return "GOTO";
- case SIGNALS: return "SIGNALS";
- case SLOTS: return "SLOTS";
- case RETURN: return "RETURN";
- case Q_OBJECT_TOKEN: return "Q_OBJECT_TOKEN";
- case Q_GADGET_TOKEN: return "Q_GADGET_TOKEN";
- case Q_PROPERTY_TOKEN: return "Q_PROPERTY_TOKEN";
- case Q_ENUMS_TOKEN: return "Q_ENUMS_TOKEN";
- case Q_FLAGS_TOKEN: return "Q_FLAGS_TOKEN";
- case Q_DECLARE_FLAGS_TOKEN: return "Q_DECLARE_FLAGS_TOKEN";
- case Q_DECLARE_INTERFACE_TOKEN: return "Q_DECLARE_INTERFACE_TOKEN";
- case Q_CLASSINFO_TOKEN: return "Q_CLASSINFO_TOKEN";
- case Q_INTERFACES_TOKEN: return "Q_INTERFACES_TOKEN";
- case Q_SIGNALS_TOKEN: return "Q_SIGNALS_TOKEN";
- case Q_SLOTS_TOKEN: return "Q_SLOTS_TOKEN";
- case Q_SIGNAL_TOKEN: return "Q_SIGNAL_TOKEN";
- case Q_SLOT_TOKEN: return "Q_SLOT_TOKEN";
- case Q_PRIVATE_SLOT_TOKEN: return "Q_PRIVATE_SLOT_TOKEN";
- case Q_PRIVATE_PROPERTY_TOKEN: return "Q_PRIVATE_PROPERTY_TOKEN";
- case Q_REVISION_TOKEN: return "Q_REVISION_TOKEN";
- case SPECIAL_TREATMENT_MARK: return "SPECIAL_TREATMENT_MARK";
- case MOC_INCLUDE_BEGIN: return "MOC_INCLUDE_BEGIN";
- case MOC_INCLUDE_END: return "MOC_INCLUDE_END";
- case CPP_COMMENT: return "CPP_COMMENT";
- case C_COMMENT: return "C_COMMENT";
- case FLOATING_LITERAL: return "FLOATING_LITERAL";
- case HASH: return "HASH";
- case QUOTE: return "QUOTE";
- case SINGLEQUOTE: return "SINGLEQUOTE";
- case DIGIT: return "DIGIT";
- case CHARACTER: return "CHARACTER";
- case NEWLINE: return "NEWLINE";
- case WHITESPACE: return "WHITESPACE";
- case BACKSLASH: return "BACKSLASH";
- case INCOMPLETE: return "INCOMPLETE";
- case PP_DEFINE: return "PP_DEFINE";
- case PP_UNDEF: return "PP_UNDEF";
- case PP_IF: return "PP_IF";
- case PP_IFDEF: return "PP_IFDEF";
- case PP_IFNDEF: return "PP_IFNDEF";
- case PP_ELIF: return "PP_ELIF";
- case PP_ELSE: return "PP_ELSE";
- case PP_ENDIF: return "PP_ENDIF";
- case PP_INCLUDE: return "PP_INCLUDE";
- case PP_HASHHASH: return "PP_HASHHASH";
- case PP_HASH: return "PP_HASH";
- case PP_DEFINED: return "PP_DEFINED";
- case PP_INCOMPLETE: return "PP_INCOMPLETE";
- case PP_MOC_TRUE: return "PP_MOC_TRUE";
- case PP_MOC_FALSE: return "PP_MOC_FALSE";
- case Q_DECLARE_METATYPE_TOKEN: return "Q_DECLARE_METATYPE_TOKEN";
- case Q_MOC_COMPAT_TOKEN: return "Q_MOC_COMPAT_TOKEN";
- case Q_INVOKABLE_TOKEN: return "Q_INVOKABLE_TOKEN";
- case Q_SCRIPTABLE_TOKEN: return "Q_SCRIPTABLE_TOKEN";
+#define CREATE_CASE(Name) case Name: return #Name;
+ FOR_ALL_TOKENS(CREATE_CASE)
+#undef CREATE_CASE
}
return "";
}
diff --git a/src/tools/moc/token.h b/src/tools/moc/token.h
index 378d4c63f7..2920fadbb9 100644
--- a/src/tools/moc/token.h
+++ b/src/tools/moc/token.h
@@ -46,222 +46,228 @@
QT_BEGIN_NAMESPACE
-enum Token {
- NOTOKEN,
- IDENTIFIER,
- INTEGER_LITERAL,
- CHARACTER_LITERAL,
- STRING_LITERAL,
- BOOLEAN_LITERAL,
- HEADER_NAME,
- LANGLE,
- RANGLE,
- LPAREN,
- RPAREN,
- ELIPSIS,
- LBRACK,
- RBRACK,
- LBRACE,
- RBRACE,
- EQ,
- SCOPE,
- SEMIC,
- COLON,
- DOTSTAR,
- QUESTION,
- DOT,
- DYNAMIC_CAST,
- STATIC_CAST,
- REINTERPRET_CAST,
- CONST_CAST,
- TYPEID,
- THIS,
- TEMPLATE,
- THROW,
- TRY,
- CATCH,
- TYPEDEF,
- FRIEND,
- CLASS,
- NAMESPACE,
- ENUM,
- STRUCT,
- UNION,
- VIRTUAL,
- PRIVATE,
- PROTECTED,
- PUBLIC,
- EXPORT,
- AUTO,
- REGISTER,
- EXTERN,
- MUTABLE,
- ASM,
- USING,
- INLINE,
- EXPLICIT,
- STATIC,
- CONST,
- VOLATILE,
- OPERATOR,
- SIZEOF,
- NEW,
- DELETE,
- PLUS,
- MINUS,
- STAR,
- SLASH,
- PERCENT,
- HAT,
- AND,
- OR,
- TILDE,
- NOT,
- PLUS_EQ,
- MINUS_EQ,
- STAR_EQ,
- SLASH_EQ,
- PERCENT_EQ,
- HAT_EQ,
- AND_EQ,
- OR_EQ,
- LTLT,
- GTGT,
- GTGT_EQ,
- LTLT_EQ,
- EQEQ,
- NE,
- LE,
- GE,
- ANDAND,
- OROR,
- INCR,
- DECR,
- COMMA,
- ARROW_STAR,
- ARROW,
- CHAR,
- WCHAR,
- BOOL,
- SHORT,
- INT,
- LONG,
- SIGNED,
- UNSIGNED,
- FLOAT,
- DOUBLE,
- VOID,
- CASE,
- DEFAULT,
- IF,
- ELSE,
- SWITCH,
- WHILE,
- DO,
- FOR,
- BREAK,
- CONTINUE,
- GOTO,
- SIGNALS,
- SLOTS,
- RETURN,
- Q_META_TOKEN_BEGIN,
- Q_OBJECT_TOKEN = Q_META_TOKEN_BEGIN,
- Q_GADGET_TOKEN,
- Q_PROPERTY_TOKEN,
- Q_PLUGIN_METADATA_TOKEN,
- Q_ENUMS_TOKEN,
- Q_FLAGS_TOKEN,
- Q_DECLARE_FLAGS_TOKEN,
- Q_DECLARE_INTERFACE_TOKEN,
- Q_DECLARE_METATYPE_TOKEN,
- Q_CLASSINFO_TOKEN,
- Q_INTERFACES_TOKEN,
- Q_SIGNALS_TOKEN,
- Q_SLOTS_TOKEN,
- Q_SIGNAL_TOKEN,
- Q_SLOT_TOKEN,
- Q_PRIVATE_SLOT_TOKEN,
- Q_MOC_COMPAT_TOKEN,
- Q_INVOKABLE_TOKEN,
- Q_SCRIPTABLE_TOKEN,
- Q_PRIVATE_PROPERTY_TOKEN,
- Q_REVISION_TOKEN,
- Q_META_TOKEN_END,
- SPECIAL_TREATMENT_MARK = Q_META_TOKEN_END,
- MOC_INCLUDE_BEGIN,
- MOC_INCLUDE_END,
- CPP_COMMENT,
- C_COMMENT,
- FLOATING_LITERAL,
- HASH,
- QUOTE,
- SINGLEQUOTE,
- LANGLE_SCOPE,
- DIGIT,
- CHARACTER,
- NEWLINE,
- WHITESPACE,
- BACKSLASH,
- INCOMPLETE,
+#define FOR_ALL_TOKENS(F) \
+ F(NOTOKEN) \
+ F(IDENTIFIER) \
+ F(INTEGER_LITERAL) \
+ F(CHARACTER_LITERAL) \
+ F(STRING_LITERAL) \
+ F(BOOLEAN_LITERAL) \
+ F(HEADER_NAME) \
+ F(LANGLE) \
+ F(RANGLE) \
+ F(LPAREN) \
+ F(RPAREN) \
+ F(ELIPSIS) \
+ F(LBRACK) \
+ F(RBRACK) \
+ F(LBRACE) \
+ F(RBRACE) \
+ F(EQ) \
+ F(SCOPE) \
+ F(SEMIC) \
+ F(COLON) \
+ F(DOTSTAR) \
+ F(QUESTION) \
+ F(DOT) \
+ F(DYNAMIC_CAST) \
+ F(STATIC_CAST) \
+ F(REINTERPRET_CAST) \
+ F(CONST_CAST) \
+ F(TYPEID) \
+ F(THIS) \
+ F(TEMPLATE) \
+ F(THROW) \
+ F(TRY) \
+ F(CATCH) \
+ F(TYPEDEF) \
+ F(FRIEND) \
+ F(CLASS) \
+ F(NAMESPACE) \
+ F(ENUM) \
+ F(STRUCT) \
+ F(UNION) \
+ F(VIRTUAL) \
+ F(PRIVATE) \
+ F(PROTECTED) \
+ F(PUBLIC) \
+ F(EXPORT) \
+ F(AUTO) \
+ F(REGISTER) \
+ F(EXTERN) \
+ F(MUTABLE) \
+ F(ASM) \
+ F(USING) \
+ F(INLINE) \
+ F(EXPLICIT) \
+ F(STATIC) \
+ F(CONST) \
+ F(VOLATILE) \
+ F(OPERATOR) \
+ F(SIZEOF) \
+ F(NEW) \
+ F(DELETE) \
+ F(PLUS) \
+ F(MINUS) \
+ F(STAR) \
+ F(SLASH) \
+ F(PERCENT) \
+ F(HAT) \
+ F(AND) \
+ F(OR) \
+ F(TILDE) \
+ F(NOT) \
+ F(PLUS_EQ) \
+ F(MINUS_EQ) \
+ F(STAR_EQ) \
+ F(SLASH_EQ) \
+ F(PERCENT_EQ) \
+ F(HAT_EQ) \
+ F(AND_EQ) \
+ F(OR_EQ) \
+ F(LTLT) \
+ F(GTGT) \
+ F(GTGT_EQ) \
+ F(LTLT_EQ) \
+ F(EQEQ) \
+ F(NE) \
+ F(LE) \
+ F(GE) \
+ F(ANDAND) \
+ F(OROR) \
+ F(INCR) \
+ F(DECR) \
+ F(COMMA) \
+ F(ARROW_STAR) \
+ F(ARROW) \
+ F(CHAR) \
+ F(WCHAR) \
+ F(BOOL) \
+ F(SHORT) \
+ F(INT) \
+ F(LONG) \
+ F(SIGNED) \
+ F(UNSIGNED) \
+ F(FLOAT) \
+ F(DOUBLE) \
+ F(VOID) \
+ F(CASE) \
+ F(DEFAULT) \
+ F(IF) \
+ F(ELSE) \
+ F(SWITCH) \
+ F(WHILE) \
+ F(DO) \
+ F(FOR) \
+ F(BREAK) \
+ F(CONTINUE) \
+ F(GOTO) \
+ F(SIGNALS) \
+ F(SLOTS) \
+ F(RETURN) \
+ F(Q_OBJECT_TOKEN) \
+ F(Q_GADGET_TOKEN) \
+ F(Q_PROPERTY_TOKEN) \
+ F(Q_PLUGIN_METADATA_TOKEN) \
+ F(Q_ENUMS_TOKEN) \
+ F(Q_FLAGS_TOKEN) \
+ F(Q_DECLARE_FLAGS_TOKEN) \
+ F(Q_DECLARE_INTERFACE_TOKEN) \
+ F(Q_DECLARE_METATYPE_TOKEN) \
+ F(Q_CLASSINFO_TOKEN) \
+ F(Q_INTERFACES_TOKEN) \
+ F(Q_SIGNALS_TOKEN) \
+ F(Q_SLOTS_TOKEN) \
+ F(Q_SIGNAL_TOKEN) \
+ F(Q_SLOT_TOKEN) \
+ F(Q_PRIVATE_SLOT_TOKEN) \
+ F(Q_MOC_COMPAT_TOKEN) \
+ F(Q_INVOKABLE_TOKEN) \
+ F(Q_SCRIPTABLE_TOKEN) \
+ F(Q_PRIVATE_PROPERTY_TOKEN) \
+ F(Q_REVISION_TOKEN) \
+ F(SPECIAL_TREATMENT_MARK) \
+ F(MOC_INCLUDE_BEGIN) \
+ F(MOC_INCLUDE_END) \
+ F(CPP_COMMENT) \
+ F(C_COMMENT) \
+ F(FLOATING_LITERAL) \
+ F(HASH) \
+ F(QUOTE) \
+ F(SINGLEQUOTE) \
+ F(LANGLE_SCOPE) \
+ F(DIGIT) \
+ F(CHARACTER) \
+ F(NEWLINE) \
+ F(WHITESPACE) \
+ F(BACKSLASH) \
+ F(INCOMPLETE) \
+ F(PP_DEFINE) \
+ F(PP_UNDEF) \
+ F(PP_IF) \
+ F(PP_IFDEF) \
+ F(PP_IFNDEF) \
+ F(PP_ELIF) \
+ F(PP_ELSE) \
+ F(PP_ENDIF) \
+ F(PP_INCLUDE) \
+ F(PP_HASHHASH) \
+ F(PP_HASH) \
+ F(PP_DEFINED) \
+ F(PP_INCOMPLETE) \
+ F(PP_MOC_TRUE) \
+ F(PP_MOC_FALSE)
+
- PP_DEFINE,
- PP_UNDEF,
- PP_IF,
- PP_IFDEF,
- PP_IFNDEF,
- PP_ELIF,
- PP_ELSE,
- PP_ENDIF,
- PP_INCLUDE,
- PP_HASHHASH,
- PP_HASH,
- PP_DEFINED,
- PP_INCOMPLETE,
+enum Token {
- PP_MOC_TRUE,
- PP_MOC_FALSE,
+#define CREATE_ENUM_VALUE(Name) Name,
+ FOR_ALL_TOKENS(CREATE_ENUM_VALUE)
+#undef CREATE_ENUM_VALUE
- PP_NOTOKEN = NOTOKEN,
+ // aliases
+ PP_AND = AND,
+ PP_ANDAND = ANDAND,
+ PP_BACKSLASH = BACKSLASH,
+ PP_CHARACTER = CHARACTER,
+ PP_CHARACTER_LITERAL = CHARACTER_LITERAL,
+ PP_COLON = COLON,
+ PP_COMMA = COMMA,
+ PP_CPP_COMMENT = CPP_COMMENT,
+ PP_C_COMMENT = C_COMMENT,
+ PP_DIGIT = DIGIT,
+ PP_EQEQ = EQEQ,
+ PP_FLOATING_LITERAL = FLOATING_LITERAL,
+ PP_GE = GE,
+ PP_GTGT = GTGT,
+ PP_HAT = HAT,
PP_IDENTIFIER = IDENTIFIER,
PP_INTEGER_LITERAL = INTEGER_LITERAL,
- PP_CHARACTER_LITERAL = CHARACTER_LITERAL,
- PP_STRING_LITERAL = STRING_LITERAL,
PP_LANGLE = LANGLE,
- PP_RANGLE = RANGLE,
+ PP_LE = LE,
PP_LPAREN = LPAREN,
- PP_RPAREN = RPAREN,
- PP_COMMA = COMMA,
- PP_PLUS = PLUS,
- PP_MINUS = MINUS,
- PP_STAR = STAR,
- PP_SLASH = SLASH,
- PP_PERCENT = PERCENT,
- PP_HAT = HAT,
- PP_AND = AND,
- PP_OR = OR,
- PP_TILDE = TILDE,
- PP_NOT = NOT,
PP_LTLT = LTLT,
- PP_GTGT = GTGT,
- PP_EQEQ = EQEQ,
+ PP_MINUS = MINUS,
PP_NE = NE,
- PP_LE = LE,
- PP_GE = GE,
- PP_ANDAND = ANDAND,
+ PP_NEWLINE = NEWLINE,
+ PP_NOTOKEN = NOTOKEN,
+ PP_NOT = NOT,
+ PP_OR = OR,
PP_OROR = OROR,
+ PP_PERCENT = PERCENT,
+ PP_PLUS = PLUS,
PP_QUESTION = QUESTION,
- PP_COLON = COLON,
- PP_FLOATING_LITERAL = FLOATING_LITERAL,
PP_QUOTE = QUOTE,
+ PP_RANGLE = RANGLE,
+ PP_RPAREN = RPAREN,
PP_SINGLEQUOTE = SINGLEQUOTE,
- PP_DIGIT = DIGIT,
- PP_CHARACTER = CHARACTER,
+ PP_SLASH = SLASH,
+ PP_STAR = STAR,
+ PP_STRING_LITERAL = STRING_LITERAL,
+ PP_TILDE = TILDE,
PP_WHITESPACE = WHITESPACE,
- PP_NEWLINE = NEWLINE,
- PP_CPP_COMMENT = CPP_COMMENT,
- PP_C_COMMENT = C_COMMENT,
- PP_BACKSLASH = BACKSLASH
+ Q_META_TOKEN_BEGIN = Q_OBJECT_TOKEN,
+ Q_META_TOKEN_END = SPECIAL_TREATMENT_MARK
};
// for debugging only
diff --git a/src/widgets/Qt5WidgetsConfigExtras.cmake.in b/src/widgets/Qt5WidgetsConfigExtras.cmake.in
index e5650ff362..99d87e2e46 100644
--- a/src/widgets/Qt5WidgetsConfigExtras.cmake.in
+++ b/src/widgets/Qt5WidgetsConfigExtras.cmake.in
@@ -14,4 +14,6 @@ if (NOT TARGET Qt5::uic)
)
endif()
+include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5Widgets_AccessibleFactory.cmake\" OPTIONAL)
+
set(Qt5Widgets_UIC_EXECUTABLE Qt5::uic)
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 80e8d152ff..6349bdc301 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -71,6 +71,7 @@ extern bool qt_priv_ptr_valid;
#endif
#if defined(Q_OS_UNIX)
#include <pwd.h>
+#include <unistd.h> // for pathconf() on OS X
#elif defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
#endif
@@ -1018,6 +1019,44 @@ QUrl QFileDialog::directoryUrl() const
return QUrl::fromLocalFile(directory().absolutePath());
}
+// FIXME Qt 5.4: Use upcoming QVolumeInfo class to determine this information?
+static inline bool isCaseSensitiveFileSystem(const QString &path)
+{
+ Q_UNUSED(path)
+#if defined(Q_OS_WIN)
+ // Return case insensitive unconditionally, even if someone has a case sensitive
+ // file system mounted, wrongly capitalized drive letters will cause mismatches.
+ return false;
+#elif defined(Q_OS_OSX)
+ return pathconf(QFile::encodeName(path).constData(), _PC_CASE_SENSITIVE);
+#else
+ return true;
+#endif
+}
+
+// Determine the file name to be set on the line edit from the path
+// passed to selectFile() in mode QFileDialog::AcceptSave.
+static inline QString fileFromPath(const QString &rootPath, QString path)
+{
+ if (!QFileInfo(path).isAbsolute())
+ return path;
+ if (path.startsWith(rootPath, isCaseSensitiveFileSystem(rootPath) ? Qt::CaseSensitive : Qt::CaseInsensitive))
+ path.remove(0, rootPath.size());
+
+ if (path.isEmpty())
+ return path;
+
+ if (path.at(0) == QDir::separator()
+#ifdef Q_OS_WIN
+ //On Windows both cases can happen
+ || path.at(0) == QLatin1Char('/')
+#endif
+ ) {
+ path.remove(0, 1);
+ }
+ return path;
+}
+
/*!
Selects the given \a filename in the file dialog.
@@ -1049,28 +1088,9 @@ void QFileDialog::selectFile(const QString &filename)
}
QModelIndex index = d->model->index(filename);
- QString file;
- if (!index.isValid()) {
- // save as dialog where we want to input a default value
- QString text = filename;
- if (QFileInfo(filename).isAbsolute()) {
- QString current = d->rootPath();
- text.remove(current);
- if (text.at(0) == QDir::separator()
-#ifdef Q_OS_WIN
- //On Windows both cases can happen
- || text.at(0) == QLatin1Char('/')
-#endif
- )
- text = text.remove(0,1);
- }
- file = text;
- } else {
- file = index.data().toString();
- }
d->qFileDialogUi->listView->selectionModel()->clear();
if (!isVisible() || !d->lineEdit()->hasFocus())
- d->lineEdit()->setText(file);
+ d->lineEdit()->setText(index.isValid() ? index.data().toString() : fileFromPath(d->rootPath(), filename));
}
/*!
@@ -1255,7 +1275,7 @@ QStringList QFileDialog::selectedFiles() const
QStringList files;
foreach (const QUrl &file, d->userSelectedFiles())
files.append(file.toLocalFile());
- if (files.isEmpty()) {
+ if (files.isEmpty() && d->usingWidgets()) {
const FileMode fm = fileMode();
if (fm != ExistingFile && fm != ExistingFiles)
files.append(d->rootIndex().data(QFileSystemModel::FilePathRole).toString());
@@ -1600,7 +1620,7 @@ QFileDialog::ViewMode QFileDialog::viewMode() const
{
Q_D(const QFileDialog);
if (!d->usingWidgets())
- return QFileDialog::List;
+ return static_cast<QFileDialog::ViewMode>(d->options->viewMode());
return (d->qFileDialogUi->stackedWidget->currentWidget() == d->qFileDialogUi->listView->parent() ? QFileDialog::List : QFileDialog::Detail);
}
@@ -2108,6 +2128,11 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
return QString();
}
+static inline QUrl dialogResultToUrl(const QString &file)
+{
+ return file.isEmpty() ? QUrl() : QUrl::fromLocalFile(file);
+}
+
/*!
This is a convenience static function that returns an existing file
selected by the user. If the user presses Cancel, it returns an
@@ -2146,7 +2171,7 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent,
Q_UNUSED(supportedSchemes);
// Falls back to local file
- return QUrl::fromLocalFile(getOpenFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
+ return dialogResultToUrl(getOpenFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
}
/*!
@@ -2404,7 +2429,7 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent,
Q_UNUSED(supportedSchemes);
// Falls back to local file
- return QUrl::fromLocalFile(getSaveFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
+ return dialogResultToUrl(getSaveFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
}
/*!
@@ -2512,7 +2537,7 @@ QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent,
Q_UNUSED(supportedSchemes);
// Falls back to local file
- return QUrl::fromLocalFile(getExistingDirectory(parent, caption, dir.toLocalFile(), options));
+ return dialogResultToUrl(getExistingDirectory(parent, caption, dir.toLocalFile(), options));
}
inline static QString _qt_get_directory(const QString &path)
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
index 68944817f6..f5db85b698 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -379,6 +379,10 @@ QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next)
void QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot()
{
Q_Q(QGraphicsProxyWidget);
+ if (!widget.isNull()) {
+ if (QWExtra *extra = widget->d_func()->extra)
+ extra->proxyWidget = 0;
+ }
widget = 0;
delete q;
}
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index 86648c4f26..5bcf52b6a3 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -1655,7 +1655,7 @@ void QGraphicsView::invalidateScene(const QRectF &rect, QGraphicsScene::SceneLay
/*!
\property QGraphicsView::interactive
- \brief whether the view allowed scene interaction.
+ \brief whether the view allows scene interaction.
If enabled, this view is set to allow scene interaction. Otherwise, this
view will not allow interaction, and any mouse or key events are ignored
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index 5040192f31..1f954d67dd 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -1631,7 +1631,7 @@ QWidget *QListWidget::itemWidget(QListWidgetItem *item) const
/*!
\since 4.1
- Sets the \a widget to be displayed in the give \a item.
+ Sets the \a widget to be displayed in the given \a item.
This function should only be used to display static content in the place of
a list widget item. If you want to display custom dynamic content or
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 781dd345bd..3f952ff768 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -1421,15 +1421,8 @@ void QTreeViewPrivate::adjustViewOptionsForIndex(QStyleOptionViewItem *option, c
const int right = (spanning ? header->visualIndex(0) : header->count() - 1 );
calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);
- int columnIndex = 0;
- for (int visualIndex = 0; visualIndex < current.column(); ++visualIndex) {
- int logicalIndex = header->logicalIndex(visualIndex);
- if (!header->isSectionHidden(logicalIndex)) {
- ++columnIndex;
- }
- }
-
- option->viewItemPosition = viewItemPosList.at(columnIndex);
+ const int visualIndex = logicalIndices.indexOf(current.column());
+ option->viewItemPosition = viewItemPosList.at(visualIndex);
}
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index d90e2f5163..b4c4ffe7c7 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -368,6 +368,7 @@ QApplicationPrivate::~QApplicationPrivate()
void qt_init(QApplicationPrivate *priv, int type
);
+void qt_init_tooltip_palette();
void qt_cleanup();
QStyle *QApplicationPrivate::app_style = 0; // default application style
@@ -4025,6 +4026,7 @@ void QApplicationPrivate::notifyThemeChanged()
QGuiApplicationPrivate::notifyThemeChanged();
clearSystemPalette();
initSystemPalette();
+ qt_init_tooltip_palette();
}
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
index c68bcc773f..5893c52e1b 100644
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -442,6 +442,14 @@ void QApplication::alert(QWidget *widget, int duration)
}
}
+void qt_init_tooltip_palette()
+{
+#ifndef QT_NO_TOOLTIP
+ if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette))
+ QToolTip::setPalette(*toolTipPalette);
+#endif
+}
+
void qt_init(QApplicationPrivate *priv, int type)
{
Q_UNUSED(priv);
@@ -449,10 +457,7 @@ void qt_init(QApplicationPrivate *priv, int type)
QColormap::initialize();
-#ifndef QT_NO_TOOLTIP
- if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette))
- QToolTip::setPalette(*toolTipPalette);
-#endif
+ qt_init_tooltip_palette();
QApplicationPrivate::initializeWidgetFontHash();
}
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 10be5aef16..cbefb8a6bf 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -147,7 +147,7 @@ void QOpenGLWidget::paintGL()
void QOpenGLWidget::updateGL()
{
Q_D(QOpenGLWidget);
- if (d->uninitialized)
+ if (d->uninitialized || !d->surface())
return;
makeCurrent();
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index 5aea55e196..2b43fd7f6d 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -512,9 +512,9 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
else if (QApplication::isEffectEnabled(Qt::UI_AnimateTooltip))
qScrollEffect(QTipLabel::instance);
else
- QTipLabel::instance->show();
+ QTipLabel::instance->showNormal();
#else
- QTipLabel::instance->show();
+ QTipLabel::instance->showNormal();
#endif
}
}
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index f79eaf197d..65e435fbdc 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -6002,10 +6002,8 @@ void QWidget::setFocus(Qt::FocusReason reason)
if (!(testAttribute(Qt::WA_WState_Created) && window()->windowType() != Qt::Popup && internalWinId()))
//setFocusWidget will already post a focus event for us (that the AT client receives) on Windows
# endif
-# ifdef Q_OS_UNIX
// menus update the focus manually and this would create bogus events
if (!(f->inherits("QMenuBar") || f->inherits("QMenu") || f->inherits("QMenuItem")))
-# endif
{
QAccessibleEvent event(f, QAccessible::Focus);
QAccessible::updateAccessibility(&event);
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 0031d8e965..fc328e7af0 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -440,11 +440,13 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
if (!win)
win = w->nativeParentWidget()->windowHandle();
if (win && win->geometry().contains(event->globalPos())) {
+ // Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec()
const QPoint localPos = win->mapFromGlobal(event->globalPos());
- QMouseEvent e(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
- QGuiApplicationPrivate::setMouseEventSource(&e, QGuiApplicationPrivate::mouseEventSource(event));
- e.setTimestamp(event->timestamp());
- QApplication::sendSpontaneousEvent(win, &e);
+ QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
+ e->spont = 1;
+ QGuiApplicationPrivate::setMouseEventSource(e, QGuiApplicationPrivate::mouseEventSource(event));
+ e->setTimestamp(event->timestamp());
+ QCoreApplication::postEvent(win, e);
}
}
}
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index 4618e1c91d..1770e60c2e 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -72,7 +72,14 @@ public:
void updateGeometry() {
Q_Q(QWindowContainer);
- if (usesNativeWidgets)
+ if (q->geometry().bottom() <= 0 || q->geometry().right() <= 0)
+ /* Qt (e.g. QSplitter) sometimes prefer to hide a widget by *not* calling
+ setVisible(false). This is often done by setting its coordinates to a sufficiently
+ negative value so that its clipped outside the parent. Since a QWindow is not clipped
+ to widgets in general, it needs to be dealt with as a special case.
+ */
+ window->setGeometry(q->geometry());
+ else if (usesNativeWidgets)
window->setGeometry(q->rect());
else
window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size()));
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
index 2bd978bcb8..2c64225c70 100644
--- a/src/widgets/styles/qgtkstyle_p.cpp
+++ b/src/widgets/styles/qgtkstyle_p.cpp
@@ -855,7 +855,7 @@ QFont QGtkStylePrivate::getThemeFont()
QIcon QGtkStylePrivate::getFilesystemIcon(const QFileInfo &info)
{
QIcon icon;
- if (gnome_vfs_init && gnome_icon_lookup_sync) {
+ if (isThemeAvailable() && gnome_vfs_init && gnome_icon_lookup_sync) {
gnome_vfs_init();
GtkIconTheme *theme = gtk_icon_theme_get_default();
QByteArray fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded();
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index d35dd16f85..e165b8aa68 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -1345,12 +1345,30 @@ void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThem
// an extra check here before using the mini and small buttons.
int h = combo->rect.size().height();
if (combo->editable){
- if (h < 21)
- bdi->kind = kThemeComboBoxMini;
- else if (h < 26)
- bdi->kind = kThemeComboBoxSmall;
- else
- bdi->kind = kThemeComboBox;
+ if (qobject_cast<const QDateTimeEdit *>(widget)) {
+ // Except when, you know, we get a QDateTimeEdit with calendarPopup
+ // enabled. And then things get weird, basically because it's a
+ // transvestite spinbox with editable combobox tendencies. Meaning
+ // that it wants to look a combobox, except that it isn't one, so it
+ // doesn't get all those extra free margins around. (Don't know whose
+ // idea those margins were, but now it looks like we're stuck with
+ // them forever). So anyway, the height threshold should be smaller
+ // in this case, or the style gets confused when it needs to render
+ // or return any subcontrol size of the poor thing.
+ if (h < 9)
+ bdi->kind = kThemeComboBoxMini;
+ else if (h < 22)
+ bdi->kind = kThemeComboBoxSmall;
+ else
+ bdi->kind = kThemeComboBox;
+ } else {
+ if (h < 21)
+ bdi->kind = kThemeComboBoxMini;
+ else if (h < 26)
+ bdi->kind = kThemeComboBoxSmall;
+ else
+ bdi->kind = kThemeComboBox;
+ }
} else {
// Even if we specify that we want the kThemePopupButton, Carbon
// will use the kThemePopupButtonSmall if the size matches. So we
@@ -1678,7 +1696,7 @@ QMacStylePrivate::QMacStylePrivate()
if (ptrHIShapeGetBounds == 0) {
QLibrary library(QLatin1String("/System/Library/Frameworks/Carbon.framework/Carbon"));
library.setLoadHints(QLibrary::ExportExternalSymbolsHint);
- ptrHIShapeGetBounds = reinterpret_cast<PtrHIShapeGetBounds>(library.resolve("HIShapeGetBounds"));
+ ptrHIShapeGetBounds = reinterpret_cast<PtrHIShapeGetBounds>(library.resolve("HIShapeGetBounds"));
}
}
@@ -5301,7 +5319,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
HIThemeButtonDrawInfo bdi;
d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
- if (!tds == kThemeStateInactive)
+ if (tds != kThemeStateInactive)
QMacStylePrivate::drawCombobox(qt_hirectForQRect(combo->rect), bdi, p);
else
d->drawColorlessButton(qt_hirectForQRect(combo->rect), &bdi, p, opt);
diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp
index 2bbf3730db..40ca73904c 100644
--- a/src/widgets/widgets/qfontcombobox.cpp
+++ b/src/widgets/widgets/qfontcombobox.cpp
@@ -50,6 +50,7 @@
#include <qevent.h>
#include <qapplication.h>
#include <private/qcombobox_p.h>
+#include <QDesktopWidget>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -546,8 +547,10 @@ bool QFontComboBox::event(QEvent *e)
{
if (e->type() == QEvent::Resize) {
QListView *lview = qobject_cast<QListView*>(view());
- if (lview)
- lview->window()->setFixedWidth(width() * 5 / 3);
+ if (lview) {
+ setFixedWidth(qMin(width() * 5 / 3,
+ QApplication::desktop()->availableGeometry(lview).width()));
+ }
}
return QComboBox::event(e);
}
diff --git a/src/widgets/widgets/qmacnativewidget_mac.mm b/src/widgets/widgets/qmacnativewidget_mac.mm
index 66a1ed7ce7..d3f3515b04 100644
--- a/src/widgets/widgets/qmacnativewidget_mac.mm
+++ b/src/widgets/widgets/qmacnativewidget_mac.mm
@@ -128,6 +128,7 @@ QMacNativeWidget::QMacNativeWidget(NSView *parentView)
setAttribute(Qt::WA_SetPalette, false);
setAttribute(Qt::WA_LayoutUsesWidgetRect);
setAttribute(Qt::WA_TranslucentBackground);
+ setAttribute(Qt::WA_NoSystemBackground, false);
}
/*!
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 600d9b536f..17f73b2809 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -2591,6 +2591,9 @@ bool QMdiArea::eventFilter(QObject *object, QEvent *event)
return QAbstractScrollArea::eventFilter(object, event);
}
+ if (subWindow->mdiArea() != this)
+ return QAbstractScrollArea::eventFilter(object, event);
+
// QMdiSubWindow events:
switch (event->type()) {
case QEvent::Move:
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index b1adb3f760..9104074122 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -1676,15 +1676,18 @@ void QMdiSubWindowPrivate::ensureWindowState(Qt::WindowState state)
switch (state) {
case Qt::WindowMinimized:
windowStates &= ~Qt::WindowMaximized;
+ windowStates &= ~Qt::WindowFullScreen;
windowStates &= ~Qt::WindowNoState;
break;
case Qt::WindowMaximized:
windowStates &= ~Qt::WindowMinimized;
+ windowStates &= ~Qt::WindowFullScreen;
windowStates &= ~Qt::WindowNoState;
break;
case Qt::WindowNoState:
windowStates &= ~Qt::WindowMinimized;
windowStates &= ~Qt::WindowMaximized;
+ windowStates &= ~Qt::WindowFullScreen;
break;
default:
break;
@@ -2732,7 +2735,7 @@ bool QMdiSubWindow::eventFilter(QObject *object, QEvent *event)
showMinimized();
else if (!(oldState & Qt::WindowMaximized) && (newState & Qt::WindowMaximized))
showMaximized();
- else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized)))
+ else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen)))
showNormal();
break;
}
@@ -3005,7 +3008,7 @@ void QMdiSubWindow::changeEvent(QEvent *changeEvent)
d->setMinimizeMode();
else if (!(oldState & Qt::WindowMaximized) && (newState & Qt::WindowMaximized))
d->setMaximizeMode();
- else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized)))
+ else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen)))
d->setNormalMode();
if (d->isActive)
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index eb93e461c0..7e48badea5 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -50,6 +50,9 @@
#include "qlayout.h"
#include "qpainter.h"
#include <qpa/qplatformtheme.h>
+#ifdef Q_OS_OSX
+#include "qmacnativewidget_mac.h"
+#endif
#include "qapplication.h"
#include "qdesktopwidget.h"
#ifndef QT_NO_ACCESSIBILITY
@@ -163,7 +166,7 @@ void QMenuPrivate::setPlatformMenu(QPlatformMenu *menu)
platformMenu = menu;
if (!platformMenu.isNull()) {
- QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SIGNAL(aboutToShow()));
+ QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SLOT(_q_platformMenuAboutToShow()));
QObject::connect(platformMenu, SIGNAL(aboutToHide()), q, SIGNAL(aboutToHide()));
}
}
@@ -1091,9 +1094,6 @@ void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e
QAccessibleEvent focusEvent(q, QAccessible::Focus);
focusEvent.setChild(actionIndex);
QAccessible::updateAccessibility(&focusEvent);
- QAccessibleEvent selectionEvent(q, QAccessible::Selection);
- focusEvent.setChild(actionIndex);
- QAccessible::updateAccessibility(&selectionEvent);
}
#endif
action->showStatusText(topCausedWidget());
@@ -1107,6 +1107,8 @@ void QMenuPrivate::_q_actionTriggered()
Q_Q(QMenu);
if (QAction *action = qobject_cast<QAction *>(q->sender())) {
QPointer<QAction> actionGuard = action;
+ if (platformMenu && widgetItems.value(action))
+ platformMenu->dismiss();
emit q->triggered(action);
if (!activationRecursionGuard && actionGuard) {
//in case the action has not been activated by the mouse
@@ -1137,6 +1139,24 @@ void QMenuPrivate::_q_actionHovered()
}
}
+void QMenuPrivate::_q_platformMenuAboutToShow()
+{
+ Q_Q(QMenu);
+
+#ifdef Q_OS_OSX
+ if (platformMenu)
+ Q_FOREACH (QAction *action, q->actions())
+ if (QWidget *widget = widgetItems.value(const_cast<QAction *>(action)))
+ if (widget->parent() == q) {
+ QPlatformMenuItem *menuItem = platformMenu->menuItemForTag(reinterpret_cast<quintptr>(action));
+ moveWidgetToPlatformItem(widget, menuItem);
+ platformMenu->syncMenuItem(menuItem);
+ }
+#endif
+
+ emit q->aboutToShow();
+}
+
bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)
{
//determines if the mouse has moved (ie its initial position has
@@ -2157,6 +2177,7 @@ QAction *QMenu::exec()
QAction *QMenu::exec(const QPoint &p, QAction *action)
{
Q_D(QMenu);
+ ensurePolished();
createWinId();
QEventLoop eventLoop;
d->eventLoop = &eventLoop;
@@ -2999,8 +3020,19 @@ void QMenu::actionEvent(QActionEvent *e)
if (e->action() == d->currentAction)
d->currentAction = 0;
if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
- if (QWidget *widget = d->widgetItems.value(wa))
+ if (QWidget *widget = d->widgetItems.value(wa)) {
+#ifdef Q_OS_OSX
+ QWidget *p = widget->parentWidget();
+ if (p != this && qobject_cast<QMacNativeWidget *>(p)) {
+ // This widget was reparented into a native Mac view
+ // (see QMenuPrivate::moveWidgetToPlatformItem).
+ // Reset the parent and delete the native widget.
+ widget->setParent(this);
+ p->deleteLater();
+ }
+#endif
wa->releaseWidget(widget);
+ }
}
d->widgetItems.remove(e->action());
}
diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h
index 8a8eaf3bae..fef7903278 100644
--- a/src/widgets/widgets/qmenu.h
+++ b/src/widgets/widgets/qmenu.h
@@ -195,6 +195,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
Q_PRIVATE_SLOT(d_func(), void _q_actionHovered())
Q_PRIVATE_SLOT(d_func(), void _q_overrideMenuActionDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void _q_platformMenuAboutToShow())
protected:
QMenu(QMenuPrivate &dd, QWidget* parent = 0);
diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm
index 41c4481b74..5e304d058b 100644
--- a/src/widgets/widgets/qmenu_mac.mm
+++ b/src/widgets/widgets/qmenu_mac.mm
@@ -44,6 +44,8 @@
#include "qmenu.h"
#include "qmenubar.h"
+#include "qmenubar_p.h"
+#include "qmacnativewidget_mac.h"
#include <QtCore/QDebug>
#include <QtGui/QGuiApplication>
@@ -115,6 +117,23 @@ void QMenu::setAsDockMenu()
\sa QMenu:setAsDockMenu()
*/
+void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* item)
+{
+ QMacNativeWidget *container = new QMacNativeWidget;
+ QObject::connect(platformMenu, SIGNAL(destroyed()), container, SLOT(deleteLater()));
+ container->resize(widget->sizeHint());
+ widget->setParent(container);
+
+ NSView *containerView = container->nativeView();
+ QWindow *containerWindow = container->windowHandle();
+ Qt::WindowFlags wf = containerWindow->flags();
+ containerWindow->setFlags(wf | Qt::SubWindow);
+ [(NSView *)widget->winId() setAutoresizingMask:NSViewWidthSizable];
+
+ item->setNativeContents((WId)containerView);
+ container->show();
+}
+
#endif //QT_NO_MENU
#ifndef QT_NO_MENUBAR
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index 9d9851af64..71bf33e1ce 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -110,6 +110,9 @@ public:
void init();
void setPlatformMenu(QPlatformMenu *menu);
void syncPlatformMenu();
+#ifdef Q_OS_OSX
+ void moveWidgetToPlatformItem(QWidget *w, QPlatformMenuItem* item);
+#endif
static QMenuPrivate *get(QMenu *m) { return m->d_func(); }
int scrollerHeight() const;
@@ -223,6 +226,7 @@ public:
void _q_actionTriggered();
void _q_actionHovered();
+ void _q_platformMenuAboutToShow();
bool hasMouseMoved(const QPoint &globalPos);
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index 03ab490823..f523ac2777 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -384,7 +384,7 @@ void QMenuBarPrivate::setCurrentAction(QAction *action, bool popup, bool activat
QAction *previousAction = currentAction;
#endif
currentAction = action;
- if (action) {
+ if (action && action->isEnabled()) {
activateAction(action, QAction::Hover);
if(popup)
popupAction(action, activateFirst);
@@ -531,9 +531,6 @@ void QMenuBarPrivate::_q_actionHovered()
QAccessibleEvent focusEvent(q, QAccessible::Focus);
focusEvent.setChild(actionIndex);
QAccessible::updateAccessibility(&focusEvent);
- QAccessibleEvent selectionEvent(q, QAccessible::Selection);
- selectionEvent.setChild(actionIndex);
- QAccessible::updateAccessibility(&selectionEvent);
}
#endif //QT_NO_ACCESSIBILITY
}
@@ -1041,7 +1038,7 @@ void QMenuBar::mousePressEvent(QMouseEvent *e)
d->mouseDown = true;
QAction *action = d->actionAt(e->pos());
- if (!action || !d->isVisible(action)) {
+ if (!action || !d->isVisible(action) || !action->isEnabled()) {
d->setCurrentAction(0);
#ifndef QT_NO_WHATSTHIS
if (QWhatsThis::inWhatsThisMode())
diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp
index 4b434822b8..9d91ce42a5 100644
--- a/src/xml/sax/qxml.cpp
+++ b/src/xml/sax/qxml.cpp
@@ -3247,7 +3247,7 @@ void QXmlSimpleReader::setFeature(const QString& name, bool enable)
|| name == QLatin1String("http://qt-project.org/xml/features/report-whitespace-only-CharData")) {
d->reportWhitespaceCharData = enable;
} else if (name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity") // For compat with Qt 4
- || name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) {
+ || name == QLatin1String("http://qt-project.org/xml/features/report-start-end-entity")) {
d->reportEntities = enable;
} else {
qWarning("Unknown feature %s", name.toLatin1().data());
diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
index b00fd0dfd4..d1aadab7d8 100644
--- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
+++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
@@ -53,11 +53,7 @@ public:
// test data:
QTextCodec *codec;
QString (*from8BitPtr)(const char *, int);
-#ifdef Q_COMPILER_REF_QUALIFIERS
- QByteArray (QString:: *to8Bit)() const &;
-#else
- QByteArray (QString:: *to8Bit)() const;
-#endif
+ static QByteArray to8Bit(const QString &);
inline QString from8Bit(const QByteArray &ba)
{ return from8BitPtr(ba.constData(), ba.length()); }
@@ -97,14 +93,21 @@ void tst_Utf8::init()
if (useLocale) {
codec = QTextCodec::codecForLocale();
from8BitPtr = &QString::fromLocal8Bit;
- to8Bit = &QString::toLocal8Bit;
} else {
codec = QTextCodec::codecForMib(106);
from8BitPtr = &QString::fromUtf8;
- to8Bit = &QString::toUtf8;
}
}
+QByteArray tst_Utf8::to8Bit(const QString &s)
+{
+ QFETCH_GLOBAL(bool, useLocale);
+ if (useLocale)
+ return s.toLocal8Bit();
+ else
+ return s.toUtf8();
+}
+
void tst_Utf8::roundTrip_data()
{
QTest::addColumn<QByteArray>("utf8");
@@ -114,10 +117,10 @@ void tst_Utf8::roundTrip_data()
QTest::newRow("nul") << QByteArray("", 1) << QString(QChar(QChar::Null));
static const char ascii[] = "This is a standard US-ASCII message";
- QTest::newRow("ascii") << QByteArray(ascii) << ascii;
+ QTest::newRow("ascii") << QByteArray(ascii) << QString::fromLatin1(ascii);
static const char ascii2[] = "\1This\2is\3an\4US-ASCII\020 message interspersed with control chars";
- QTest::newRow("ascii2") << QByteArray(ascii2) << ascii2;
+ QTest::newRow("ascii2") << QByteArray(ascii2) << QString::fromLatin1(ascii2);
static const char utf8_1[] = "\302\240"; // NBSP
QTest::newRow("utf8_1") << QByteArray(utf8_1) << QString(QChar(QChar::Nbsp));
@@ -161,11 +164,20 @@ void tst_Utf8::roundTrip()
QFETCH(QByteArray, utf8);
QFETCH(QString, utf16);
- QCOMPARE((utf16.*to8Bit)(), utf8);
+ QCOMPARE(to8Bit(utf16), utf8);
+ QCOMPARE(from8Bit(utf8), utf16);
+
+ QCOMPARE(to8Bit(from8Bit(utf8)), utf8);
+ QCOMPARE(from8Bit(to8Bit(utf16)), utf16);
+
+ // repeat with a longer message
+ utf8.prepend("12345678901234");
+ utf16.prepend(QLatin1String("12345678901234"));
+ QCOMPARE(to8Bit(utf16), utf8);
QCOMPARE(from8Bit(utf8), utf16);
- QCOMPARE((from8Bit(utf8).*to8Bit)(), utf8);
- QCOMPARE(from8Bit((utf16.*to8Bit)()), utf16);
+ QCOMPARE(to8Bit(from8Bit(utf8)), utf8);
+ QCOMPARE(from8Bit(to8Bit(utf16)), utf16);
}
void tst_Utf8::charByChar_data()
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
index a58c7dfb4b..4f7ddce9c3 100644
--- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
+++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
@@ -405,6 +405,13 @@ void tst_QFileSystemWatcher::removePaths()
watcher.removePaths(paths);
}
+static QByteArray msgFileOperationFailed(const char *what, const QFile &f)
+{
+ return what + QByteArrayLiteral(" failed on \"")
+ + QDir::toNativeSeparators(f.fileName()).toLocal8Bit()
+ + QByteArrayLiteral("\": ") + f.errorString().toLocal8Bit();
+}
+
void tst_QFileSystemWatcher::watchFileAndItsDirectory()
{
QFETCH(QString, backend);
@@ -420,14 +427,10 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
QString testFileName = testDir.filePath("testFile.txt");
QString secondFileName = testDir.filePath("testFile2.txt");
- QFile::remove(secondFileName);
QFile testFile(testFileName);
- testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
- testFile.remove();
-
- QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
- testFile.write(QByteArray("hello"));
+ QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate), msgFileOperationFailed("open", testFile));
+ QVERIFY2(testFile.write(QByteArrayLiteral("hello")) > 0, msgFileOperationFailed("write", testFile));
testFile.close();
QFileSystemWatcher watcher;
@@ -449,8 +452,8 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
// wait before modifying the directory...
QTest::qWait(2000);
- QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
- testFile.write(QByteArray("hello again"));
+ QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate), msgFileOperationFailed("open", testFile));
+ QVERIFY2(testFile.write(QByteArrayLiteral("hello again")), msgFileOperationFailed("write", testFile));
testFile.close();
#ifdef Q_OS_MAC
@@ -472,8 +475,8 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
fileChangedSpy.clear();
dirChangedSpy.clear();
QFile secondFile(secondFileName);
- secondFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
- secondFile.write("Foo");
+ QVERIFY2(secondFile.open(QIODevice::WriteOnly | QIODevice::Truncate), msgFileOperationFailed("open", secondFile));
+ QVERIFY2(secondFile.write(QByteArrayLiteral("Foo")) > 0, msgFileOperationFailed("write", secondFile));
secondFile.close();
timer.start(3000);
@@ -491,17 +494,17 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
dirChangedSpy.clear();
- QFile::remove(testFileName);
+ QVERIFY(QFile::remove(testFileName));
QTRY_VERIFY(fileChangedSpy.count() > 0);
- QCOMPARE(dirChangedSpy.count(), 1);
+ QTRY_COMPARE(dirChangedSpy.count(), 1);
fileChangedSpy.clear();
dirChangedSpy.clear();
// removing a deleted file should fail
QVERIFY(!watcher.removePath(testFileName));
- QFile::remove(secondFileName);
+ QVERIFY(QFile::remove(secondFileName));
timer.start(3000);
eventLoop.exec();
diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
index c19e80bff3..2ae085cb0b 100644
--- a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
@@ -247,6 +247,13 @@ private:
QString testFileName;
};
+void runOnExit()
+{
+ QByteArray buffer;
+ QTextStream(&buffer) << "This will try to use QTextCodec::codecForLocale" << endl;
+}
+Q_DESTRUCTOR_FUNCTION(runOnExit)
+
tst_QTextStream::tst_QTextStream()
: tempDir(QDir::tempPath() + "/tst_qtextstream.XXXXXX")
{
diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
index 6e183f3212..cdcbd19ae8 100644
--- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
+++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
@@ -1863,7 +1863,7 @@ void tst_QByteArray::reserve()
QCOMPARE(qba.capacity(), capacity);
QCOMPARE(copy.capacity(), capacity);
- copy = qba;
+ qba = copy;
qba.reserve(capacity * 2);
QCOMPARE(qba.size(), capacity);
QCOMPARE(qba.capacity(), capacity * 2);
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index bda5fc707a..8f9376f8b6 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -715,6 +715,10 @@ void tst_QDateTime::toString_isoDate_data()
QTest::newRow("negative OffsetFromUTC")
<< dt
<< QString("1978-11-09T13:28:34-02:00");
+ dt.setUtcOffset(-900);
+ QTest::newRow("negative non-integral OffsetFromUTC")
+ << dt
+ << QString("1978-11-09T13:28:34-00:15");
QTest::newRow("invalid")
<< QDateTime(QDate(-1, 11, 9), QTime(13, 28, 34), Qt::UTC)
<< QString();
@@ -1895,8 +1899,12 @@ void tst_QDateTime::fromStringDateFormat_data()
// Test Qt::ISODate format.
QTest::newRow("ISO +01:00") << QString::fromLatin1("1987-02-13T13:24:51+01:00")
<< Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
+ QTest::newRow("ISO +00:01") << QString::fromLatin1("1987-02-13T13:24:51+00:01")
+ << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(13, 23, 51), Qt::UTC);
QTest::newRow("ISO -01:00") << QString::fromLatin1("1987-02-13T13:24:51-01:00")
<< Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC);
+ QTest::newRow("ISO -00:01") << QString::fromLatin1("1987-02-13T13:24:51-00:01")
+ << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(13, 25, 51), Qt::UTC);
QTest::newRow("ISO +0000") << QString::fromLatin1("1970-01-01T00:12:34+0000")
<< Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
QTest::newRow("ISO +00:00") << QString::fromLatin1("1970-01-01T00:12:34+00:00")
diff --git a/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp b/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp
index e1ce12d7d5..57a4a19179 100644
--- a/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp
+++ b/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp
@@ -367,11 +367,11 @@ void emitSignalPeer(const QString &interface, const QString &name, const QVarian
QTest::qWait(1000);
}
-const char* slotSpyPeer()
+QString slotSpyPeer()
{
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "slotSpyServer");
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
- return reply.arguments().at(0).toString().toLatin1().data();
+ return reply.arguments().at(0).toString();
}
QString valueSpyPeer()
@@ -1108,7 +1108,7 @@ void tst_QDBusAbstractAdaptor::methodCallsPeer()
// simple call: one such method exists
QCOMPARE(if2.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ReplyMessage);
- QCOMPARE(slotSpyPeer(), "void Interface2::method()");
+ QCOMPARE(slotSpyPeer(), QStringLiteral("void Interface2::method()"));
if (!nInterfaces--)
return;
@@ -1121,24 +1121,24 @@ void tst_QDBusAbstractAdaptor::methodCallsPeer()
QCOMPARE(if2.call(QDBus::BlockWithGui, "methodString").type(), QDBusMessage::ErrorMessage);
QCOMPARE(if3.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ReplyMessage);
- QCOMPARE(slotSpyPeer(), "void Interface3::methodVoid()");
+ QCOMPARE(slotSpyPeer(), QStringLiteral("void Interface3::methodVoid()"));
QCOMPARE(if3.call(QDBus::BlockWithGui, "methodInt", 42).type(), QDBusMessage::ReplyMessage);
- QCOMPARE(slotSpyPeer(), "void Interface3::methodInt(int)");
+ QCOMPARE(slotSpyPeer(), QStringLiteral("void Interface3::methodInt(int)"));
QCOMPARE(if3.call(QDBus::BlockWithGui, "methodString", QString("")).type(), QDBusMessage::ReplyMessage);
- QCOMPARE(slotSpyPeer(), "void Interface3::methodString(QString)");
+ QCOMPARE(slotSpyPeer(), QStringLiteral("void Interface3::methodString(QString)"));
if (!nInterfaces--)
return;
// method overloading: different interfaces
QCOMPARE(if4.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ReplyMessage);
- QCOMPARE(slotSpyPeer(), "void Interface4::method()");
+ QCOMPARE(slotSpyPeer(), QStringLiteral("void Interface4::method()"));
// method overloading: different parameters
QCOMPARE(if4.call(QDBus::BlockWithGui, "method.i", 42).type(), QDBusMessage::ReplyMessage);
- QCOMPARE(slotSpyPeer(), "void Interface4::method(int)");
+ QCOMPARE(slotSpyPeer(), QStringLiteral("void Interface4::method(int)"));
QCOMPARE(if4.call(QDBus::BlockWithGui, "method.s", QString()).type(), QDBusMessage::ReplyMessage);
- QCOMPARE(slotSpyPeer(), "void Interface4::method(QString)");
+ QCOMPARE(slotSpyPeer(), QStringLiteral("void Interface4::method(QString)"));
}
void tst_QDBusAbstractAdaptor::methodCallScriptablePeer()
@@ -1152,7 +1152,7 @@ void tst_QDBusAbstractAdaptor::methodCallScriptablePeer()
QDBusInterface if2(QString(), "/", "local.Interface2", con);
QCOMPARE(if2.call(QDBus::BlockWithGui,"scriptableMethod").type(), QDBusMessage::ReplyMessage);
- QCOMPARE(slotSpyPeer(), "void Interface2::scriptableMethod()");
+ QCOMPARE(slotSpyPeer(), QStringLiteral("void Interface2::scriptableMethod()"));
}
void tst_QDBusAbstractAdaptor::signalEmissionsPeer_data()
diff --git a/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.pro b/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.pro
index b863135b68..5001ec2cd2 100644
--- a/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.pro
+++ b/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.pro
@@ -1,5 +1,7 @@
SOURCES = qpinger.cpp ../interface.cpp
HEADERS = ../interface.h
TARGET = qpinger
+CONFIG -= app_bundle
+CONFIG += console
QT = core dbus
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/dbus/qdbusmarshall/qpong/qpong.pro b/tests/auto/dbus/qdbusmarshall/qpong/qpong.pro
index d652036034..ffc538f2ab 100644
--- a/tests/auto/dbus/qdbusmarshall/qpong/qpong.pro
+++ b/tests/auto/dbus/qdbusmarshall/qpong/qpong.pro
@@ -1,5 +1,7 @@
SOURCES = qpong.cpp
TARGET = qpong
QT = core dbus
+CONFIG -= app_bundle
+CONFIG += console
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
index 6ef9957fa1..e551d99959 100644
--- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
+++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
@@ -48,6 +48,10 @@
#include <qpa/qwindowsysteminterface.h>
#include <qgenericplugin.h>
+#if defined(Q_OS_QNX)
+#include <QOpenGLContext>
+#endif
+
#include <QDebug>
#include "tst_qcoreapplication.h"
@@ -124,6 +128,9 @@ void tst_QGuiApplication::focusObject()
const QRect screenGeometry = QGuiApplication::primaryScreen()->availableVirtualGeometry();
DummyWindow window1;
+#if defined(Q_OS_QNX)
+ window1.setSurfaceType(QSurface::OpenGLSurface);
+#endif
window1.resize(windowSize, windowSize);
window1.setTitle(QStringLiteral("focusObject:window1"));
window1.setFramePosition(QPoint(screenGeometry.left() + spacing, screenGeometry.top() + spacing));
@@ -134,6 +141,15 @@ void tst_QGuiApplication::focusObject()
window1.show();
+#if defined(Q_OS_QNX) // We either need to create a eglSurface or a create a backing store
+ // and then post the window in order for screen to show the window
+ QOpenGLContext context;
+ context.create();
+ context.makeCurrent(&window1);
+ QTest::qWaitForWindowExposed(&window1); // Buffer swap only succeeds with exposed window
+ context.swapBuffers(&window1);
+#endif
+
QSignalSpy spy(&app, SIGNAL(focusObjectChanged(QObject*)));
@@ -279,15 +295,35 @@ void tst_QGuiApplication::changeFocusWindow()
// focus is changed between FocusAboutToChange and FocusChanged
FocusChangeWindow window1;
+#if defined(Q_OS_QNX)
+ window1.setSurfaceType(QSurface::OpenGLSurface);
+#endif
window1.resize(windowSize, windowSize);
window1.setFramePosition(QPoint(screenGeometry.left() + spacing, screenGeometry.top() + spacing));
window1.setTitle(QStringLiteral("changeFocusWindow:window1"));
window1.show();
+#if defined(Q_OS_QNX) // We either need to create a eglSurface or a create a backing store
+ // and then post the window in order for screen to show the window
+ QOpenGLContext context;
+ context.create();
+ context.makeCurrent(&window1);
+ QTest::qWaitForWindowExposed(&window1); // Buffer swap only succeeds with exposed window
+ context.swapBuffers(&window1);
+#endif
FocusChangeWindow window2;
+#if defined(Q_OS_QNX)
+ window2.setSurfaceType(QSurface::OpenGLSurface);
+#endif
window2.resize(windowSize, windowSize);
window2.setFramePosition(QPoint(screenGeometry.left() + 2 * spacing + windowSize, screenGeometry.top() + spacing));
window2.setTitle(QStringLiteral("changeFocusWindow:window2"));
window2.show();
+#if defined(Q_OS_QNX) // We either need to create a eglSurface or a create a backing store
+ // and then post the window in order for screen to show the window
+ context.makeCurrent(&window2);
+ QTest::qWaitForWindowExposed(&window2); // Buffer swap only succeeds with exposed window
+ context.swapBuffers(&window2);
+#endif
QVERIFY(QTest::qWaitForWindowExposed(&window1));
QVERIFY(QTest::qWaitForWindowExposed(&window2));
window1.requestActivate();
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index eefa85a745..589f3e66e1 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -88,6 +88,10 @@ private slots:
void visibility();
void mask();
void initialSize();
+ void modalDialog();
+ void modalDialogClosingOneOfTwoModal();
+ void modalWithChildWindow();
+ void modalWindowModallity();
void initTestCase()
{
@@ -1316,6 +1320,115 @@ void tst_QWindow::initialSize()
}
}
+void tst_QWindow::modalDialog()
+{
+ QWindow normalWindow;
+ normalWindow.resize(400, 400);
+ normalWindow.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&normalWindow));
+
+ QWindow dialog;
+ dialog.resize(200,200);
+ dialog.setModality(Qt::ApplicationModal);
+ dialog.setFlags(Qt::Dialog);
+ dialog.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&dialog));
+
+ normalWindow.requestActivate();
+
+ QGuiApplication::sync();
+ QGuiApplication::processEvents();
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &dialog);
+}
+
+void tst_QWindow::modalDialogClosingOneOfTwoModal()
+{
+ QWindow normalWindow;
+ normalWindow.resize(400, 400);
+ normalWindow.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&normalWindow));
+
+ QWindow first_dialog;
+ first_dialog.resize(200,200);
+ first_dialog.setModality(Qt::ApplicationModal);
+ first_dialog.setFlags(Qt::Dialog);
+ first_dialog.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&first_dialog));
+
+ {
+ QWindow second_dialog;
+ second_dialog.resize(200,200);
+ second_dialog.setModality(Qt::ApplicationModal);
+ second_dialog.setFlags(Qt::Dialog);
+ second_dialog.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&second_dialog));
+
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &second_dialog);
+
+ second_dialog.close();
+ }
+
+ QGuiApplication::sync();
+ QGuiApplication::processEvents();
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &first_dialog);
+}
+
+void tst_QWindow::modalWithChildWindow()
+{
+ QWindow normalWindow;
+ normalWindow.resize(400, 400);
+ normalWindow.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&normalWindow));
+
+ QWindow tlw_dialog;
+ tlw_dialog.resize(400,200);
+ tlw_dialog.setModality(Qt::ApplicationModal);
+ tlw_dialog.setFlags(Qt::Dialog);
+ tlw_dialog.create();
+
+ QWindow sub_window(&tlw_dialog);
+ sub_window.resize(200,300);
+ sub_window.show();
+
+ tlw_dialog.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tlw_dialog));
+ QVERIFY(QTest::qWaitForWindowExposed(&sub_window));
+
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &tlw_dialog);
+
+ sub_window.requestActivate();
+ QGuiApplication::sync();
+ QGuiApplication::processEvents();
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &sub_window);
+}
+
+void tst_QWindow::modalWindowModallity()
+{
+ QWindow normal_window;
+ normal_window.resize(400, 400);
+ normal_window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&normal_window));
+
+ QWindow parent_to_modal;
+ parent_to_modal.resize(400, 400);
+ parent_to_modal.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&parent_to_modal));
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &parent_to_modal);
+
+ QWindow modal_dialog;
+ modal_dialog.resize(400,200);
+ modal_dialog.setModality(Qt::WindowModal);
+ modal_dialog.setFlags(Qt::Dialog);
+ modal_dialog.setTransientParent(&parent_to_modal);
+ modal_dialog.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&modal_dialog));
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &modal_dialog);
+
+ normal_window.requestActivate();
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &normal_window);
+
+}
+
#include <tst_qwindow.moc>
QTEST_MAIN(tst_QWindow)
diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
index e589d520cb..122ac63034 100644
--- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
+++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
@@ -331,8 +331,8 @@ void tst_QTcpSocket::initTestCase_data()
qDebug() << QtNetworkSettings::serverName();
QTest::newRow("WithoutProxy") << false << 0 << false;
- QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy) << false;
- QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic) << false;
+ //QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy) << false; ### temporarily disabled, QTBUG-38385
+ //QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic) << false; ### temporarily disabled, QTBUG-38385
QTest::newRow("WithHttpProxy") << true << int(HttpProxy) << false;
QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic) << false;
@@ -340,8 +340,8 @@ void tst_QTcpSocket::initTestCase_data()
#ifndef QT_NO_SSL
QTest::newRow("WithoutProxy SSL") << false << 0 << true;
- QTest::newRow("WithSocks5Proxy SSL") << true << int(Socks5Proxy) << true;
- QTest::newRow("WithSocks5AuthProxy SSL") << true << int(Socks5Proxy | AuthBasic) << true;
+ //QTest::newRow("WithSocks5Proxy SSL") << true << int(Socks5Proxy) << true; ### temporarily disabled, QTBUG-38385
+ //QTest::newRow("WithSocks5AuthProxy SSL") << true << int(Socks5Proxy | AuthBasic) << true; ### temporarily disabled, QTBUG-38385
QTest::newRow("WithHttpProxy SSL") << true << int(HttpProxy) << true;
QTest::newRow("WithHttpProxyBasicAuth SSL") << true << int(HttpProxy | AuthBasic) << true;
diff --git a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp
index 74c3f7833b..4f62076870 100644
--- a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp
+++ b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp
@@ -81,6 +81,7 @@ private slots:
void emptyConstructor();
void constructor_data();
void constructor();
+ void constructor_device();
void constructingGarbage();
void copyAndAssign_data();
void copyAndAssign();
@@ -110,6 +111,8 @@ private slots:
void verify();
void extensions();
void threadSafeConstMethods();
+ void version_data();
+ void version();
// helper for verbose test failure messages
QString toString(const QList<QSslError>&);
@@ -225,6 +228,47 @@ void tst_QSslCertificate::constructor()
QVERIFY(!certificate.isNull());
}
+void tst_QSslCertificate::constructor_device()
+{
+ if (!QSslSocket::supportsSsl())
+ return;
+
+ QFile f(testDataDir + "/verify-certs/test-ocsp-good-cert.pem");
+ bool ok = f.open(QIODevice::ReadOnly);
+ QVERIFY(ok);
+
+ QSslCertificate cert(&f);
+ QVERIFY(!cert.isNull());
+ f.close();
+
+ // Check opening a DER as a PEM fails
+ QFile f2(testDataDir + "/certificates/cert.der");
+ ok = f2.open(QIODevice::ReadOnly);
+ QVERIFY(ok);
+
+ QSslCertificate cert2(&f2);
+ QVERIFY(cert2.isNull());
+ f2.close();
+
+ // Check opening a DER as a DER works
+ QFile f3(testDataDir + "/certificates/cert.der");
+ ok = f3.open(QIODevice::ReadOnly);
+ QVERIFY(ok);
+
+ QSslCertificate cert3(&f3, QSsl::Der);
+ QVERIFY(!cert3.isNull());
+ f3.close();
+
+ // Check opening a PEM as a DER fails
+ QFile f4(testDataDir + "/verify-certs/test-ocsp-good-cert.pem");
+ ok = f4.open(QIODevice::ReadOnly);
+ QVERIFY(ok);
+
+ QSslCertificate cert4(&f4, QSsl::Der);
+ QVERIFY(cert4.isNull());
+ f4.close();
+}
+
void tst_QSslCertificate::constructingGarbage()
{
if (!QSslSocket::supportsSsl())
@@ -1150,6 +1194,33 @@ void tst_QSslCertificate::threadSafeConstMethods()
}
+void tst_QSslCertificate::version_data()
+{
+ QTest::addColumn<QSslCertificate>("certificate");
+ QTest::addColumn<QByteArray>("result");
+
+ QTest::newRow("null certificate") << QSslCertificate() << QByteArray();
+
+ QList<QSslCertificate> certs;
+ certs << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-ocsp-good-cert.pem");
+
+ QTest::newRow("v3 certificate") << certs.first() << QByteArrayLiteral("3");
+
+ certs.clear();
+ certs << QSslCertificate::fromPath(testDataDir + "/certificates/cert.pem");
+ QTest::newRow("v1 certificate") << certs.first() << QByteArrayLiteral("1");
+}
+
+void tst_QSslCertificate::version()
+{
+ if (!QSslSocket::supportsSsl())
+ return;
+
+ QFETCH(QSslCertificate, certificate);
+ QFETCH(QByteArray, result);
+ QCOMPARE(certificate.version(), result);
+}
+
#endif // QT_NO_SSL
QTEST_MAIN(tst_QSslCertificate)
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index baaf21e6bb..30a9e19138 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -273,10 +273,12 @@ void tst_QSslSocket::initTestCase_data()
void tst_QSslSocket::initTestCase()
{
+#ifndef QT_NO_SSL
qDebug("Using SSL library %s (%ld)",
qPrintable(QSslSocket::sslLibraryVersionString()),
QSslSocket::sslLibraryVersionNumber());
QVERIFY(QtNetworkSettings::verifyTestNetworkSettings());
+#endif
}
void tst_QSslSocket::init()
diff --git a/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp b/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp
index 915f503b3f..a8a9deb25f 100644
--- a/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp
+++ b/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp
@@ -207,6 +207,10 @@ void tst_QGLBuffer::bufferSharing()
QSKIP("Unreproducible timeout on Windows (MSVC/MinGW) CI bots");
#endif
+#if defined(Q_OS_QNX)
+ QSKIP("Crashes on QNX when destroying the second QGLWidget (see QTBUG-38275)");
+#endif
+
QGLWidget *w1 = new QGLWidget();
w1->makeCurrent();
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index fcc5581bea..54c56eb18b 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -1928,7 +1928,7 @@ void tst_QAccessibility::lineEditTest()
QVERIFY(iface->state().movable);
QVERIFY(iface->state().focusable);
QVERIFY(iface->state().selectable);
- QVERIFY(iface->state().hasPopup);
+ QVERIFY(!iface->state().hasPopup);
QCOMPARE(bool(iface->state().focused), le->hasFocus());
QString secret(QLatin1String("secret"));
@@ -1956,7 +1956,7 @@ void tst_QAccessibility::lineEditTest()
QVERIFY(!(iface->state().movable));
QVERIFY(iface->state().focusable);
QVERIFY(iface->state().selectable);
- QVERIFY(iface->state().hasPopup);
+ QVERIFY(!iface->state().hasPopup);
QCOMPARE(bool(iface->state().focused), le->hasFocus());
QLineEdit *le2 = new QLineEdit(toplevel);
@@ -3283,7 +3283,7 @@ void tst_QAccessibility::comboBoxTest()
QVERIFY(!combo.view()->isVisible());
QVERIFY(iface->actionInterface());
- QCOMPARE(iface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction());
+ QCOMPARE(iface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction() << QAccessibleActionInterface::pressAction());
iface->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
QTRY_VERIFY(combo.view()->isVisible());
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index 55cb67eed9..824f042ffc 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -195,6 +195,9 @@ private slots:
void task_233829_data() { generic_data("QPSQL"); }
void task_233829();
+ void QTBUG_12477_data() { generic_data("QPSQL"); }
+ void QTBUG_12477();
+
void sqlServerReturn0_data() { generic_data(); }
void sqlServerReturn0();
@@ -1247,6 +1250,26 @@ void tst_QSqlQuery::seek()
QVERIFY( q.seek( 0 ) );
QCOMPARE( q.at(), 0 );
QCOMPARE( q.value( 0 ).toInt(), 1 );
+
+ QVERIFY(!q.seek(QSql::BeforeFirstRow));
+ QCOMPARE(q.at(), int(QSql::BeforeFirstRow));
+ QVERIFY(q.seek(1, true));
+ QCOMPARE(q.at(), 0);
+ QCOMPARE(q.value(0).toInt(), 1);
+
+ qint32 count = 1;
+ while (q.next()) ++count;
+
+ QCOMPARE(q.at(), int(QSql::AfterLastRow));
+
+ if (!q.isForwardOnly()) {
+ QVERIFY(q.seek(-1, true));
+ QCOMPARE(q.at(), count - 1);
+ QCOMPARE(q.value(0).toInt(), count);
+ } else {
+ QVERIFY(!q.seek(-1, true));
+ QCOMPARE(q.at(), int(QSql::AfterLastRow));
+ }
}
void tst_QSqlQuery::seekForwardOnlyQuery()
@@ -2992,6 +3015,47 @@ void tst_QSqlQuery::task_233829()
QVERIFY_SQL(q,exec());
}
+void tst_QSqlQuery::QTBUG_12477()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ if (!db.driverName().startsWith("QPSQL"))
+ QSKIP("PostgreSQL specific test");
+
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec("SELECT 1::bit, '10101010000111101101'::varbit, "
+ "'10101111011'::varbit(15), '22222.20'::numeric(16,2), "
+ "'333333'::numeric(18), '444444'::numeric"));
+ QVERIFY_SQL(q, next());
+ QSqlRecord r = q.record();
+ QSqlField f;
+
+ f = r.field(0);
+ QCOMPARE(f.length(), 1);
+ QCOMPARE(f.precision(), -1);
+
+ f = r.field(1);
+ QCOMPARE(f.length(), -1);
+ QCOMPARE(f.precision(), -1);
+
+ f = r.field(2);
+ QCOMPARE(f.length(), 15);
+ QCOMPARE(f.precision(), -1);
+
+ f = r.field(3);
+ QCOMPARE(f.length(), 16);
+ QCOMPARE(f.precision(), 2);
+
+ f = r.field(4);
+ QCOMPARE(f.length(), 18);
+ QCOMPARE(f.precision(), 0);
+
+ f = r.field(5);
+ QCOMPARE(f.length(), -1);
+ QCOMPARE(f.precision(), -1);
+}
+
void tst_QSqlQuery::sqlServerReturn0()
{
QFETCH( QString, dbName );
diff --git a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
index e85c64db8e..881f2b5c7c 100644
--- a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
+++ b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
@@ -50,7 +50,7 @@
#include "qdebug.h"
#ifdef Q_OS_LINUX
-#include <pthread.h>
+#include <sched.h>
#endif
const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase()));
@@ -159,7 +159,7 @@ public:
q.bindValue(2, 10);
QVERIFY_SQL(q, exec());
#ifdef Q_OS_LINUX
- pthread_yield();
+ sched_yield();
#endif
}
}
@@ -197,7 +197,7 @@ public:
q1.clear();
QVERIFY_SQL(q2, exec());
#ifdef Q_OS_LINUX
- pthread_yield();
+ sched_yield();
#endif
}
}
diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
index d360a646f1..096658ae02 100644
--- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
@@ -43,6 +43,7 @@
#include <QtTest/QtTest>
#include <qcoreapplication.h>
+#include <qfile.h>
#include <qdebug.h>
#include <qsharedpointer.h>
#include <qfiledialog.h>
@@ -72,6 +73,7 @@
#include <QFileSystemModel>
#if defined(Q_OS_UNIX)
+#include <unistd.h> // for pathconf() on OS X
#ifdef QT_BUILD_INTERNAL
QT_BEGIN_NAMESPACE
extern Q_GUI_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0);
@@ -79,6 +81,19 @@ QT_END_NAMESPACE
#endif
#endif
+static inline bool isCaseSensitiveFileSystem(const QString &path)
+{
+ Q_UNUSED(path)
+#if defined(Q_OS_MAC)
+ return pathconf(QFile::encodeName(path).constData(), _PC_CASE_SENSITIVE);
+#elif defined(Q_OS_WIN)
+ return false;
+#else
+ return true;
+#endif
+}
+
+
class QNonNativeFileDialog : public QFileDialog
{
Q_OBJECT
@@ -130,6 +145,7 @@ private slots:
void selectFile_data();
void selectFile();
void selectFiles();
+ void selectFileWrongCaseSaveAs();
void selectFilter();
void viewMode();
void proxymodel();
@@ -147,6 +163,7 @@ private slots:
void clearLineEdit();
void enableChooseButton();
void widgetlessNativeDialog();
+ void selectedFilesWithoutWidgets();
void trailingDotsAndSpaces();
#ifdef Q_OS_UNIX
#ifdef QT_BUILD_INTERNAL
@@ -154,6 +171,7 @@ private slots:
void tildeExpansion();
#endif // QT_BUILD_INTERNAL
#endif
+ void getFileUrl();
private:
QByteArray userSettings;
@@ -857,36 +875,59 @@ void tst_QFiledialog::selectFile()
{
QFETCH(QString, file);
QFETCH(int, count);
- QNonNativeFileDialog fd;
- QFileSystemModel *model = fd.findChild<QFileSystemModel*>("qt_filesystem_model");
+ QScopedPointer<QNonNativeFileDialog> fd(new QNonNativeFileDialog);
+ QFileSystemModel *model = fd->findChild<QFileSystemModel*>("qt_filesystem_model");
QVERIFY(model);
- fd.setDirectory(QDir::currentPath());
+ fd->setDirectory(QDir::currentPath());
// default value
- QCOMPARE(fd.selectedFiles().count(), 1);
+ QCOMPARE(fd->selectedFiles().count(), 1);
- QTemporaryFile tempFile(QDir::tempPath() + "/aXXXXXX");
- bool inTemp = (file == "temp");
- if (inTemp) {
- tempFile.open();
- file = tempFile.fileName();
+ QScopedPointer<QTemporaryFile> tempFile;
+ if (file == QLatin1String("temp")) {
+ tempFile.reset(new QTemporaryFile(QDir::tempPath() + QStringLiteral("/aXXXXXX")));
+ QVERIFY(tempFile->open());
+ file = tempFile->fileName();
}
- fd.selectFile(file);
- QCOMPARE(fd.selectedFiles().count(), count);
- if (inTemp) {
- QCOMPARE(model->index(fd.directory().path()), model->index(QDir::tempPath()));
+ fd->selectFile(file);
+ QCOMPARE(fd->selectedFiles().count(), count);
+ if (tempFile.isNull()) {
+ QCOMPARE(model->index(fd->directory().path()), model->index(QDir::currentPath()));
} else {
- QCOMPARE(model->index(fd.directory().path()), model->index(QDir::currentPath()));
+ QCOMPARE(model->index(fd->directory().path()), model->index(QDir::tempPath()));
}
+ fd.reset(); // Ensure the file dialog let's go of the temporary file for "temp".
+}
+
+void tst_QFiledialog::selectFileWrongCaseSaveAs()
+{
+ const QString home = QDir::homePath();
+ if (isCaseSensitiveFileSystem(home))
+ QSKIP("This test is intended for case-insensitive file systems only.");
+ // QTBUG-38162: when passing a wrongly capitalized path to selectFile()
+ // on a case-insensitive file system, the line edit should only
+ // contain the file name ("c:\PRogram files\foo.txt" -> "foo.txt").
+ const QString fileName = QStringLiteral("foo.txt");
+ const QString path = home + QLatin1Char('/') + fileName;
+ QString wrongCasePath = path;
+ for (int c = 0; c < wrongCasePath.size(); c += 2)
+ wrongCasePath[c] = wrongCasePath.at(c).isLower() ? wrongCasePath.at(c).toUpper() : wrongCasePath.at(c).toLower();
+ QNonNativeFileDialog fd(0, "QTBUG-38162", wrongCasePath);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.selectFile(wrongCasePath);
+ const QLineEdit *lineEdit = fd.findChild<QLineEdit*>("fileNameEdit");
+ QVERIFY(lineEdit);
+ QCOMPARE(lineEdit->text().compare(fileName, Qt::CaseInsensitive), 0);
}
void tst_QFiledialog::selectFiles()
{
- QNonNativeFileDialog fd;
- fd.setViewMode(QFileDialog::List);
QTemporaryDir tempDir;
QVERIFY(tempDir.isValid());
const QString tempPath = tempDir.path();
+ {
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
fd.setDirectory(tempPath);
QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(QString)));
QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(QString)));
@@ -931,17 +972,20 @@ void tst_QFiledialog::selectFiles()
QCOMPARE(spyFilesSelected.count(), 0);
QCOMPARE(spyFilterSelected.count(), 0);
- //If the selection is invalid then we fill the line edit but without the /
- QNonNativeFileDialog * dialog = new QNonNativeFileDialog( 0, "Save" );
- dialog->setFileMode( QFileDialog::AnyFile );
- dialog->setAcceptMode( QFileDialog::AcceptSave );
- dialog->selectFile(tempPath + QStringLiteral("/blah"));
- dialog->show();
- QVERIFY(QTest::qWaitForWindowExposed(dialog));
- QLineEdit *lineEdit = dialog->findChild<QLineEdit*>("fileNameEdit");
- QVERIFY(lineEdit);
- QCOMPARE(lineEdit->text(),QLatin1String("blah"));
- delete dialog;
+ }
+
+ {
+ //If the selection is invalid then we fill the line edit but without the /
+ QNonNativeFileDialog dialog( 0, "Save" );
+ dialog.setFileMode( QFileDialog::AnyFile );
+ dialog.setAcceptMode( QFileDialog::AcceptSave );
+ dialog.selectFile(tempPath + QStringLiteral("/blah"));
+ dialog.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&dialog));
+ QLineEdit *lineEdit = dialog.findChild<QLineEdit*>("fileNameEdit");
+ QVERIFY(lineEdit);
+ QCOMPARE(lineEdit->text(),QLatin1String("blah"));
+ }
}
void tst_QFiledialog::viewMode()
@@ -1321,6 +1365,14 @@ void tst_QFiledialog::widgetlessNativeDialog()
QVERIFY(!button);
}
+void tst_QFiledialog::selectedFilesWithoutWidgets()
+{
+ // Test for a crash when widgets are not instantiated yet.
+ QFileDialog fd;
+ fd.setAcceptMode(QFileDialog::AcceptOpen);
+ QVERIFY(fd.selectedFiles().size() >= 0);
+}
+
void tst_QFiledialog::trailingDotsAndSpaces()
{
#ifndef Q_OS_WIN
@@ -1378,5 +1430,49 @@ void tst_QFiledialog::tildeExpansion()
#endif // QT_BUILD_INTERNAL
#endif
+class DialogRejecter : public QObject
+{
+ Q_OBJECT
+public:
+ DialogRejecter()
+ {
+ QTimer *timer = new QTimer(this);
+ timer->setInterval(1000);
+ connect(timer, &QTimer::timeout, this, &DialogRejecter::rejectFileDialog);
+ timer->start();
+ }
+
+public slots:
+ void rejectFileDialog()
+ {
+ if (QWidget *w = QApplication::activeModalWidget())
+ if (QDialog *d = qobject_cast<QDialog *>(w))
+ d->reject();
+ }
+};
+
+void tst_QFiledialog::getFileUrl()
+{
+ // QTBUG-38672 , static functions should return empty Urls
+ const QFileDialog::Options options = QFileDialog::DontUseNativeDialog;
+ DialogRejecter dr;
+
+ QUrl url = QFileDialog::getOpenFileUrl(0, QStringLiteral("getOpenFileUrl"),
+ QUrl(), QString(), Q_NULLPTR, options);
+ QVERIFY(url.isEmpty());
+ QVERIFY(!url.isValid());
+
+ url = QFileDialog::getExistingDirectoryUrl(0, QStringLiteral("getExistingDirectoryUrl"),
+ QUrl(), options | QFileDialog::ShowDirsOnly);
+ QVERIFY(url.isEmpty());
+ QVERIFY(!url.isValid());
+
+ url = QFileDialog::getSaveFileUrl(0, QStringLiteral("getSaveFileUrl"),
+ QUrl(), QString(), Q_NULLPTR, options);
+ QVERIFY(url.isEmpty());
+ QVERIFY(!url.isValid());
+
+}
+
QTEST_MAIN(tst_QFiledialog)
#include "tst_qfiledialog.moc"
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
index 9e0446388e..3925090465 100644
--- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
@@ -476,13 +476,19 @@ void tst_QFileSystemModel::rowCount()
void tst_QFileSystemModel::rowsInserted_data()
{
QTest::addColumn<int>("count");
- QTest::addColumn<int>("assending");
+ QTest::addColumn<int>("ascending");
for (int i = 0; i < 4; ++i) {
QTest::newRow(QString("Qt::AscendingOrder %1").arg(i).toLocal8Bit().constData()) << i << (int)Qt::AscendingOrder;
QTest::newRow(QString("Qt::DescendingOrder %1").arg(i).toLocal8Bit().constData()) << i << (int)Qt::DescendingOrder;
}
}
+static inline QString lastEntry(const QModelIndex &root)
+{
+ const QAbstractItemModel *model = root.model();
+ return model->index(model->rowCount(root) - 1, 0, root).data().toString();
+}
+
void tst_QFileSystemModel::rowsInserted()
{
#if defined(Q_OS_WINCE)
@@ -492,9 +498,9 @@ void tst_QFileSystemModel::rowsInserted()
rowCount();
QModelIndex root = model->index(model->rootPath());
- QFETCH(int, assending);
+ QFETCH(int, ascending);
QFETCH(int, count);
- model->sort(0, (Qt::SortOrder)assending);
+ model->sort(0, (Qt::SortOrder)ascending);
QSignalSpy spy0(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
QSignalSpy spy1(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
@@ -505,7 +511,6 @@ void tst_QFileSystemModel::rowsInserted()
QVERIFY(createFiles(tmp, files, 5));
TRY_WAIT(model->rowCount(root) == oldCount + count);
QTRY_COMPARE(model->rowCount(root), oldCount + count);
- QTest::qWait(100); // Let the sort settle.
int totalRowsInserted = 0;
for (int i = 0; i < spy0.count(); ++i) {
int start = spy0[i].value(1).toInt();
@@ -513,12 +518,9 @@ void tst_QFileSystemModel::rowsInserted()
totalRowsInserted += end - start + 1;
}
QCOMPARE(totalRowsInserted, count);
- if (assending == (Qt::SortOrder)Qt::AscendingOrder) {
- QString letter = model->index(model->rowCount(root) - 1, 0, root).data().toString();
- QCOMPARE(letter, QString("j"));
- } else {
- QCOMPARE(model->index(model->rowCount(root) - 1, 0, root).data().toString(), QString("b"));
- }
+ const QString expected = ascending == Qt::AscendingOrder ? QStringLiteral("j") : QStringLiteral("b");
+ QTRY_COMPARE(lastEntry(root), expected);
+
if (spy0.count() > 0) {
if (count == 0)
QCOMPARE(spy0.count(), 0);
@@ -548,8 +550,8 @@ void tst_QFileSystemModel::rowsRemoved()
QModelIndex root = model->index(model->rootPath());
QFETCH(int, count);
- QFETCH(int, assending);
- model->sort(0, (Qt::SortOrder)assending);
+ QFETCH(int, ascending);
+ model->sort(0, (Qt::SortOrder)ascending);
QTest::qWait(WAITTIME);
QSignalSpy spy0(model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
index 4c07b48c00..a932a2e859 100644
--- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
+++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
@@ -2605,6 +2605,9 @@ void tst_QWizard::task161658_alignments()
void tst_QWizard::task177022_setFixedSize()
{
+#ifdef Q_OS_BLACKBERRY
+ QSKIP("Window is forced fullscreen");
+#endif
int width = 300;
int height = 200;
QWizard wiz;
@@ -2622,7 +2625,7 @@ void tst_QWizard::task177022_setFixedSize()
QCOMPARE(wiz.maximumWidth(), width);
QCOMPARE(wiz.maximumHeight(), height);
- wiz.show();
+ wiz.showNormal();
QVERIFY(QTest::qWaitForWindowExposed(&wiz));
QCOMPARE(wiz.size(), QSize(width, height));
diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
index 5b178903cf..8f57eca0a7 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
@@ -2502,9 +2502,6 @@ void tst_QGraphicsProxyWidget::popup_basic()
void tst_QGraphicsProxyWidget::popup_subwidget()
{
-#ifdef Q_OS_WIN
- QSKIP("This test crashes on Windows, QTBUG-33213");
-#endif
QGroupBox *groupBox = new QGroupBox;
groupBox->setTitle("GroupBox");
groupBox->setCheckable(true);
@@ -3183,10 +3180,6 @@ void tst_QGraphicsProxyWidget::actionsContextMenu()
void tst_QGraphicsProxyWidget::deleteProxyForChildWidget()
{
-#if defined(Q_OS_WIN)
- QSKIP("This test is crashing on windows, it needs to be fixed. QTBUG-29684");
-#endif
-
QDialog dialog;
dialog.resize(320, 120);
dialog.move(80, 40);
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
index 83c4582645..daca1d1516 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
@@ -1257,7 +1257,7 @@ void tst_QAbstractItemView::task250754_fontChange()
tree.setModel(m);
tree.setHeaderHidden(true); // The header is (in certain styles) dpi dependent
- w.resize(160, 300); // Minimum width for windows with frame on Windows 8
+ w.resize(160, 350); // Minimum width for windows with frame on Windows 8
centerOnScreen(&w);
moveCursorAway(&w);
w.showNormal();
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index 0579914940..d12fb06daa 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
@@ -261,6 +261,7 @@ private slots:
void taskQTBUG_18539_emitLayoutChanged();
void taskQTBUG_8176_emitOnExpandAll();
void taskQTBUG_34717_collapseAtBottom();
+ void taskQTBUG_37813_crash();
void testInitialFocus();
};
@@ -2488,7 +2489,7 @@ void tst_QTreeView::extendedSelection_data()
QTest::addColumn<int>("selectedCount");
QTest::newRow("select") << QPoint(10, 10) << 2;
- QTest::newRow("unselect") << QPoint(10, 150) << 0;
+ QTest::newRow("unselect") << QPoint(10, 300) << 0;
}
void tst_QTreeView::extendedSelection()
@@ -2499,7 +2500,7 @@ void tst_QTreeView::extendedSelection()
QStandardItemModel model(5, 2);
QWidget topLevel;
QTreeView view(&topLevel);
- view.resize(qMax(mousePressPos.x() * 2, 200), qMax(mousePressPos.y() * 2, 200));
+ view.resize(qMax(mousePressPos.x() * 2, 300), qMax(mousePressPos.y() * 2, 350));
view.setModel(&model);
view.setSelectionMode(QAbstractItemView::ExtendedSelection);
topLevel.show();
@@ -4327,5 +4328,31 @@ void tst_QTreeView::quickExpandCollapse()
}
#endif
+void tst_QTreeView::taskQTBUG_37813_crash()
+{
+ // QTBUG_37813: Crash in visual / logical index mapping in QTreeViewPrivate::adjustViewOptionsForIndex()
+ // when hiding/moving columns. It is reproduceable with a QTreeWidget only.
+#ifdef QT_BUILD_INTERNAL
+ QTreeWidget treeWidget;
+ treeWidget.setDragEnabled(true);
+ treeWidget.setColumnCount(2);
+ QList<QTreeWidgetItem *> items;
+ for (int r = 0; r < 2; ++r) {
+ QTreeWidgetItem *item = new QTreeWidgetItem();
+ for (int c = 0; c < treeWidget.columnCount(); ++c)
+ item->setText(c, QString::fromLatin1("Row %1 Column %2").arg(r).arg(c));
+ items.append(item);
+ }
+ treeWidget.addTopLevelItems(items);
+ treeWidget.setColumnHidden(0, true);
+ treeWidget.header()->moveSection(0, 1);
+ QItemSelection sel(treeWidget.model()->index(0, 0), treeWidget.model()->index(0, 1));
+ QRect rect;
+ QAbstractItemViewPrivate *av = static_cast<QAbstractItemViewPrivate*>(qt_widget_private(&treeWidget));
+ const QPixmap pixmap = av->renderToPixmap(sel.indexes(), &rect);
+ QVERIFY(pixmap.size().isValid());
+#endif // QT_BUILD_INTERNAL
+}
+
QTEST_MAIN(tst_QTreeView)
#include "tst_qtreeview.moc"
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index dd3d041f56..2a70431223 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -4631,32 +4631,28 @@ void tst_QWidget::windowMoveResize()
QTest::qWait(10);
QTRY_COMPARE(widget.pos(), rect.topLeft());
- if (m_platform == QStringLiteral("windows")) {
- QEXPECT_FAIL("130,100 0x200, flags 0", "QTBUG-26424", Continue);
- QEXPECT_FAIL("130,50 0x0, flags 0", "QTBUG-26424", Continue);
- }
- QTRY_COMPARE(widget.size(), rect.size());
+ // Windows: Minimum size of decorated windows.
+ const bool expectResizeFail = (!windowFlags && (rect.width() < 160 || rect.height() < 40))
+ && m_platform == QStringLiteral("windows");
+ if (!expectResizeFail)
+ QTRY_COMPARE(widget.size(), rect.size());
// move() while shown
foreach (const QRect &r, rects) {
- if (m_platform == QStringLiteral("xcb")
- && ((widget.width() == 0 || widget.height() == 0) && r.width() != 0 && r.height() != 0)) {
- QEXPECT_FAIL("130,100 0x200, flags 0",
- "First resize after show of zero-sized gets wrong win_gravity.",
- Continue);
- QEXPECT_FAIL("100,50 200x0, flags 0",
- "First resize after show of zero-sized gets wrong win_gravity.",
- Continue);
- QEXPECT_FAIL("130,50 0x0, flags 0",
- "First resize after show of zero-sized gets wrong win_gravity.",
- Continue);
- }
-
+ // XCB: First resize after show of zero-sized gets wrong win_gravity.
+ const bool expectMoveFail = !windowFlags
+ && ((widget.width() == 0 || widget.height() == 0) && r.width() != 0 && r.height() != 0)
+ && m_platform == QStringLiteral("xcb")
+ && (rect == QRect(QPoint(130, 100), QSize(0, 200))
+ || rect == QRect(QPoint(100, 50), QSize(200, 0))
+ || rect == QRect(QPoint(130, 50), QSize(0, 0)));
widget.move(r.topLeft());
widget.resize(r.size());
QApplication::processEvents();
- QTRY_COMPARE(widget.pos(), r.topLeft());
- QTRY_COMPARE(widget.size(), r.size());
+ if (!expectMoveFail) {
+ QTRY_COMPARE(widget.pos(), r.topLeft());
+ QTRY_COMPARE(widget.size(), r.size());
+ }
}
widget.move(rect.topLeft());
widget.resize(rect.size());
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
index 5a36ffc671..14d59d3630 100644
--- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
+++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
@@ -49,6 +49,12 @@
#include "../../../qtest-config.h"
+static inline void centerOnScreen(QWidget *w)
+{
+ const QPoint offset = QPoint(w->width() / 2, w->height() / 2);
+ w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset);
+}
+
class tst_QStyleSheetStyle : public QObject
{
Q_OBJECT
@@ -142,6 +148,8 @@ tst_QStyleSheetStyle::~tst_QStyleSheetStyle()
void tst_QStyleSheetStyle::numinstances()
{
QWidget w;
+ w.resize(200, 200);
+ centerOnScreen(&w);
QCommonStyle *style = new QCommonStyle;
style->setParent(&w);
QWidget c(&w);
@@ -531,7 +539,14 @@ void tst_QStyleSheetStyle::dynamicProperty()
qApp->setStyleSheet(QString());
QString appStyle = qApp->style()->metaObject()->className();
- QPushButton pb1, pb2;
+ QPushButton pb1(QStringLiteral("dynamicProperty_pb1"));
+ pb1.setMinimumWidth(160);
+ pb1.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(20, 100));
+
+ QPushButton pb2(QStringLiteral("dynamicProperty_pb2"));
+ pb2.setMinimumWidth(160);
+ pb2.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(20, 200));
+
pb1.setProperty("type", "critical");
qApp->setStyleSheet("*[class~=\"QPushButton\"] { color: red; } *[type=\"critical\"] { background: white; }");
QVERIFY(COLOR(pb1) == Qt::red);
@@ -675,6 +690,8 @@ void tst_QStyleSheetStyle::onWidgetDestroyed()
void tst_QStyleSheetStyle::fontPrecedence()
{
QLineEdit edit;
+ edit.setMinimumWidth(200);
+ centerOnScreen(&edit);
edit.show();
QFont font;
QVERIFY(FONTSIZE(edit) != 22); // Sanity check to make sure this test makes sense.
@@ -737,8 +754,9 @@ void tst_QStyleSheetStyle::focusColors()
// ten pixels of the right color requires quite a many characters, as the
// majority of the pixels will have slightly different colors due to the
// anti-aliasing effect.
-#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC) && !(defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(Q_CC_INTEL))
- QSKIP("This is a fragile test which fails on many esoteric platforms because of focus problems. "
+#if !defined(Q_OS_WIN32) && !(defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(Q_CC_INTEL))
+ QSKIP("This is a fragile test which fails on many esoteric platforms because of focus problems"
+ " (for example, QTBUG-33959)."
"That doesn't mean that the feature doesn't work in practice.");
#endif
QList<QWidget *> widgets;
@@ -768,6 +786,7 @@ void tst_QStyleSheetStyle::focusColors()
layout->addWidget(widget);
frame.setLayout(layout);
+ centerOnScreen(&frame);
frame.show();
QApplication::setActiveWindow(&frame);
QVERIFY(QTest::qWaitForWindowActive(&frame));
@@ -795,6 +814,9 @@ void tst_QStyleSheetStyle::focusColors()
#ifndef QTEST_NO_CURSOR
void tst_QStyleSheetStyle::hoverColors()
{
+#ifdef Q_OS_OSX
+ QSKIP("This test is fragile on Mac, most likely due to QTBUG-33959.");
+#endif
QList<QWidget *> widgets;
widgets << new QPushButton("TESTING TESTING");
widgets << new QLineEdit("TESTING TESTING");
@@ -822,31 +844,22 @@ void tst_QStyleSheetStyle::hoverColors()
layout->addWidget(widget);
frame.setLayout(layout);
+ centerOnScreen(&frame);
frame.show();
QApplication::setActiveWindow(&frame);
QVERIFY(QTest::qWaitForWindowActive(&frame));
//move the mouse inside the widget, it should be colored
QTest::mouseMove ( widget, QPoint(6,6));
- QTest::qWait(60);
-#ifdef Q_OS_MAC
- QEXPECT_FAIL("", "Numerous failures related to Qt::WA_UnderMouse, see QTBUGT-23685", Continue);
-#endif
- QVERIFY(widget->testAttribute(Qt::WA_UnderMouse));
+ QTRY_VERIFY(widget->testAttribute(Qt::WA_UnderMouse));
QImage image(frame.width(), frame.height(), QImage::Format_ARGB32);
frame.render(&image);
-#ifdef Q_OS_MAC
- QEXPECT_FAIL("", "Numerous failures related to Qt::WA_UnderMouse, see QTBUGT-23685", Continue);
-#endif
QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
(QString::fromLatin1(widget->metaObject()->className())
+ " did not contain background color #e8ff66").toLocal8Bit().constData());
-#ifdef Q_OS_MAC
- QEXPECT_FAIL("", "Numerous failures related to Qt::WA_UnderMouse, see QTBUGT-23685", Continue);
-#endif
QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
(QString::fromLatin1(widget->metaObject()->className())
+ " did not contain text color #ff0084").toLocal8Bit().constData());
@@ -866,9 +879,7 @@ void tst_QStyleSheetStyle::hoverColors()
//move the mouse again inside the widget, it should be colored
QTest::mouseMove (widget, QPoint(5,5));
- QTest::qWait(60);
-
- QVERIFY(widget->testAttribute(Qt::WA_UnderMouse));
+ QTRY_VERIFY(widget->testAttribute(Qt::WA_UnderMouse));
frame.render(&image);
@@ -904,35 +915,47 @@ public:
void tst_QStyleSheetStyle::background()
{
- const int number = 4;
- QWidget* widgets[number];
+ typedef QSharedPointer<QWidget> WidgetPtr;
+
+ const QString styleSheet = QStringLiteral("* { background-color: #e8ff66; }");
+ QVector<WidgetPtr> widgets;
+ const QPoint topLeft = QGuiApplication::primaryScreen()->availableGeometry().topLeft();
// Testing inheritance styling of QDialog.
- widgets[0] = new SingleInheritanceDialog;
- widgets[0]->setStyleSheet("* { background-color: #e8ff66; }");
- widgets[1] = new DoubleInheritanceDialog;
- widgets[1]->setStyleSheet("* { background-color: #e8ff66; }");
+ WidgetPtr toplevel(new SingleInheritanceDialog);
+ toplevel->resize(200, 200);
+ toplevel->move(topLeft + QPoint(20, 20));
+ toplevel->setStyleSheet(styleSheet);
+ widgets.append(toplevel);
+
+ toplevel = WidgetPtr(new DoubleInheritanceDialog);
+ toplevel->resize(200, 200);
+ toplevel->move(topLeft + QPoint(20, 320));
+ toplevel->setStyleSheet(styleSheet);
+ widgets.append(toplevel);
// Testing gradients in QComboBox.
- QLayout* layout;
- QComboBox* cb;
// First color
- widgets[2] = new QDialog;
- layout = new QGridLayout;
- cb = new QComboBox;
+ toplevel = WidgetPtr(new QDialog);
+ toplevel->move(topLeft + QPoint(320, 20));
+ QGridLayout *layout = new QGridLayout(toplevel.data());
+ QComboBox* cb = new QComboBox;
+ cb->setMinimumWidth(160);
cb->setStyleSheet("* { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop:0 #e8ff66, stop:1 #000000); }");
- layout->addWidget(cb);
- widgets[2]->setLayout(layout);
+ layout->addWidget(cb, 0, 0);
+ widgets.append(toplevel);
// Second color
- widgets[3] = new QDialog;
- layout = new QGridLayout;
+ toplevel = WidgetPtr(new QDialog);
+ toplevel->move(topLeft + QPoint(320, 320));
+ layout = new QGridLayout(toplevel.data());
cb = new QComboBox;
+ cb->setMinimumWidth(160);
cb->setStyleSheet("* { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop:0 #e8ff66, stop:1 #000000); }");
- layout->addWidget(cb);
- widgets[3]->setLayout(layout);
-
- for (int c = 0; c < number; ++c) {
- QWidget* widget = widgets[c];
+ layout->addWidget(cb, 0, 0);
+ widgets.append(toplevel);
+ for (int c = 0; c < widgets.size(); ++c) {
+ QWidget *widget = widgets.at(c).data();
+ widget->setWindowTitle(QStringLiteral("background ") + QString::number(c));
widget->show();
QVERIFY(QTest::qWaitForWindowExposed(widget));
@@ -941,12 +964,15 @@ void tst_QStyleSheetStyle::background()
if (image.depth() < 24)
QSKIP("Test doesn't support color depth < 24");
+ if (c == 2 && !QApplication::style()->objectName().compare(QLatin1String("fusion"), Qt::CaseInsensitive))
+ QEXPECT_FAIL("", "QTBUG-21468", Abort);
+
QVERIFY2(testForColors(image, QColor(0xe8, 0xff, 0x66)),
- (QString::fromLatin1(widget->metaObject()->className())
+ (QString::number(c) + QLatin1Char(' ') + QString::fromLatin1(widget->metaObject()->className())
+ " did not contain background image with color #e8ff66")
.toLocal8Bit().constData());
- delete widget;
+ widget->hide();
}
}
@@ -956,6 +982,7 @@ void tst_QStyleSheetStyle::tabAlignement()
QTabWidget tabWidget(&topLevel);
tabWidget.addTab(new QLabel("tab1"),"tab1");
tabWidget.resize(QSize(400,400));
+ centerOnScreen(&topLevel);
topLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
QTabBar *bar = tabWidget.findChild<QTabBar*>();
@@ -1023,6 +1050,7 @@ void tst_QStyleSheetStyle::minmaxSizes()
tabWidget.setStyleSheet("QTabBar::tab { min-width:100px; max-width:130px; }");
+ centerOnScreen(&tabWidget);
tabWidget.show();
QTest::qWait(50);
//i allow 4px additional border from the native style (hence the -2, <=2)
@@ -1050,6 +1078,7 @@ void tst_QStyleSheetStyle::task206238_twice()
tw->addTab(new QLabel("foo"), "test");
w.setCentralWidget(tw);
w.setStyleSheet("background: red;");
+ centerOnScreen(&w);
w.show();
QTest::qWait(20);
QCOMPARE(BACKGROUND(w) , QColor("red"));
@@ -1219,6 +1248,8 @@ void tst_QStyleSheetStyle::proxyStyle()
QString styleSheet("QPushButton {background-color: red; }");
QWidget *w = new QWidget;
+ w->setMinimumWidth(160);
+ centerOnScreen(w);
QVBoxLayout *layout = new QVBoxLayout(w);
QPushButton *pb1 = new QPushButton(qApp->style()->objectName(), w);
@@ -1294,6 +1325,7 @@ void tst_QStyleSheetStyle::emptyStyleSheet()
layout.addWidget(new QDateEdit(&w));
layout.addWidget(new QGroupBox("some text", &w));
+ centerOnScreen(&w);
w.show();
QVERIFY(QTest::qWaitForWindowExposed(&w));
//workaround the fact that the label sizehint is one pixel different the first time.
@@ -1315,13 +1347,30 @@ void tst_QStyleSheetStyle::emptyStyleSheet()
img2.save("emptyStyleSheet_img2.png");
}
+ QEXPECT_FAIL("", "QTBUG-21468", Abort);
QCOMPARE(img1,img2);
}
+class ApplicationStyleSetter
+{
+public:
+ explicit inline ApplicationStyleSetter(QStyle *s) : m_oldStyleName(QApplication::style()->objectName())
+ { QApplication::setStyle(s); }
+ inline ~ApplicationStyleSetter()
+ { QApplication::setStyle(QStyleFactory::create(m_oldStyleName)); }
+
+private:
+ const QString m_oldStyleName;
+};
+
void tst_QStyleSheetStyle::toolTip()
{
qApp->setStyleSheet(QString());
QWidget w;
+ // Use "Fusion" to prevent the Vista style from clobbering the tooltip palette in polish().
+ QStyle *fusionStyle = QStyleFactory::create(QLatin1String("Fusion"));
+ QVERIFY(fusionStyle);
+ ApplicationStyleSetter as(fusionStyle);
QHBoxLayout layout(&w);
w.setLayout(&layout);
@@ -1349,11 +1398,12 @@ void tst_QStyleSheetStyle::toolTip()
wid4->setToolTip("this is wid4");
wid4->setObjectName("wid4");
+ centerOnScreen(&w);
w.show();
qApp->setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
- QColor normalToolTip = qApp->palette().toolTipBase().color();
+ const QColor normalToolTip = QToolTip::palette().color(QPalette::Inactive, QPalette::ToolTipBase);
QList<QWidget *> widgets;
QList<QColor> colors;
@@ -1372,12 +1422,13 @@ void tst_QStyleSheetStyle::toolTip()
QWidget *tooltip = 0;
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
- if (widget->inherits("QTipLabel") && widget->isVisible()) {
+ if (widget->inherits("QTipLabel")) {
tooltip = widget;
break;
}
}
QVERIFY(tooltip);
+ QTRY_VERIFY(tooltip->isVisible()); // Wait until Roll-Effect is finished (Windows Vista)
QCOMPARE(tooltip->palette().color(tooltip->backgroundRole()), col);
}
@@ -1394,6 +1445,8 @@ void tst_QStyleSheetStyle::embeddedFonts()
{
//task 235622 and 210551
QSpinBox spin;
+ spin.setMinimumWidth(160);
+ spin.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(20, 20));
spin.show();
spin.setStyleSheet("QSpinBox { font-size: 32px; }");
QTest::qWait(20);
@@ -1411,6 +1464,8 @@ void tst_QStyleSheetStyle::embeddedFonts()
//task 242556
QComboBox box;
+ box.setMinimumWidth(160);
+ box.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(20, 120));
box.setEditable(true);
box.addItems(QStringList() << "First" << "Second" << "Third");
box.setStyleSheet("QComboBox { font-size: 32px; }");
@@ -1483,6 +1538,7 @@ void tst_QStyleSheetStyle::complexWidgetFocus()
layout->addWidget(widget);
frame.setLayout(layout);
+ centerOnScreen(&frame);
frame.show();
QApplication::setActiveWindow(&frame);
QVERIFY(QTest::qWaitForWindowActive(&frame));
@@ -1507,6 +1563,7 @@ void tst_QStyleSheetStyle::task188195_baseBackground()
{
QTreeView tree;
tree.setStyleSheet( "QTreeView:disabled { background-color:#ab1251; }" );
+ tree.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(20, 100));
tree.show();
QTest::qWait(20);
QImage image(tree.width(), tree.height(), QImage::Format_ARGB32);
@@ -1527,6 +1584,7 @@ void tst_QStyleSheetStyle::task188195_baseBackground()
QTableWidget table(12, 12);
table.setItem(0, 0, new QTableWidgetItem());
table.setStyleSheet( "QTableView {background-color: #ff0000}" );
+ table.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(300, 100));
table.show();
QTest::qWait(20);
image = QImage(table.width(), table.height(), QImage::Format_ARGB32);
@@ -1560,6 +1618,7 @@ void tst_QStyleSheetStyle::task232085_spinBoxLineEditBg()
layout->addWidget(spinbox);
frame.setLayout(layout);
+ centerOnScreen(&frame);
frame.show();
QApplication::setActiveWindow(&frame);
spinbox->setFocus();
@@ -1619,6 +1678,7 @@ void tst_QStyleSheetStyle::QTBUG11658_cachecrash()
Widget(QWidget *parent = 0)
: QWidget(parent)
{
+ setMinimumWidth(160);
QVBoxLayout* pLayout = new QVBoxLayout(this);
QCheckBox* pCheckBox = new QCheckBox(this);
pLayout->addWidget(pCheckBox);
@@ -1633,6 +1693,7 @@ void tst_QStyleSheetStyle::QTBUG11658_cachecrash()
Widget *w = new Widget();
delete w;
w = new Widget();
+ centerOnScreen(w);
w->show();
QVERIFY(QTest::qWaitForWindowExposed(w));
@@ -1653,6 +1714,8 @@ void tst_QStyleSheetStyle::QTBUG15910_crashNullWidget()
}
} w;
w.setStyleSheet("* { background-color: white; color:black; border 3px solid yellow }");
+ w.setMinimumWidth(160);
+ centerOnScreen(&w);
w.show();
QVERIFY(QTest::qWaitForWindowExposed(&w));
}
@@ -1675,6 +1738,7 @@ void tst_QStyleSheetStyle::QTBUG36933_brokenPseudoClassLookup()
// parsing of this stylesheet must not crash, and it must be correctly applied
widget.setStyleSheet(QStringLiteral("QHeaderView::section:vertical { background-color: #FF0000 }"));
+ centerOnScreen(&widget);
widget.show();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
@@ -1685,6 +1749,8 @@ void tst_QStyleSheetStyle::QTBUG36933_brokenPseudoClassLookup()
QHeaderView *verticalHeader = widget.verticalHeader();
QImage image(verticalHeader->size(), QImage::Format_ARGB32);
verticalHeader->render(&image);
+ if (!QApplication::style()->objectName().compare(QLatin1String("fusion"), Qt::CaseInsensitive))
+ QEXPECT_FAIL("", "QTBUG-21468", Abort);
QVERIFY(testForColors(image, QColor(0xFF, 0x00, 0x00)));
}
diff --git a/tests/auto/widgets/styles/styles.pro b/tests/auto/widgets/styles/styles.pro
index 1791279b72..508b6ecd41 100644
--- a/tests/auto/widgets/styles/styles.pro
+++ b/tests/auto/widgets/styles/styles.pro
@@ -12,5 +12,5 @@ SUBDIRS=\
!mac:SUBDIRS -= \
qmacstyle \
-!contains( styles, motif ):SUBDIRS -= \
+ios|android|qnx|*wince*:SUBDIRS -= \
qstylesheetstyle \
diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
index 509ccc37b6..abc0129f8b 100644
--- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
@@ -2064,7 +2064,7 @@ void tst_QComboBox::itemListPosition()
topLevel.move(screen.width() - topLevel.sizeHint().width() - 10, 0); //puts the combo to the top-right corner
- topLevel.show();
+ topLevel.showNormal();
//wait because the window manager can move the window if there is a right panel
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
@@ -2232,7 +2232,7 @@ void tst_QComboBox::task190205_setModelAdjustToContents()
box.move(100, 100);
box.setSizeAdjustPolicy(QComboBox::AdjustToContents);
box.addItems(initialContent);
- box.show();
+ box.showNormal();
//wait needed in order to get the combo initial size
QTRY_VERIFY(box.isVisible());
@@ -2244,7 +2244,7 @@ void tst_QComboBox::task190205_setModelAdjustToContents()
correctBox.move(400, 100);
correctBox.addItems(finalContent);
- correctBox.show();
+ correctBox.showNormal();
QVERIFY(QTest::qWaitForWindowExposed(&box));
QVERIFY(QTest::qWaitForWindowExposed(&correctBox));
@@ -2266,7 +2266,7 @@ void tst_QComboBox::task248169_popupWithMinimalSize()
comboBox.setGeometry(desktopSize.width() - (desktopSize.width() / 4), (desktopSize.width() / 4), (desktopSize.width() / 2), (desktopSize.width() / 4));
- comboBox.show();
+ comboBox.showNormal();
QVERIFY(QTest::qWaitForWindowExposed(&comboBox));
QTRY_VERIFY(comboBox.isVisible());
comboBox.showPopup();
@@ -2274,7 +2274,7 @@ void tst_QComboBox::task248169_popupWithMinimalSize()
QTest::qWaitForWindowExposed(comboBox.view());
QTRY_VERIFY(comboBox.view()->isVisible());
-#ifdef QT_BUILD_INTERNAL
+#if defined QT_BUILD_INTERNAL && !defined Q_OS_BLACKBERRY
QFrame *container = comboBox.findChild<QComboBoxPrivateContainer *>();
QVERIFY(container);
QTRY_VERIFY(desktop.screenGeometry(container).contains(container->geometry()));
@@ -2609,7 +2609,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse()
for (int i = 0; i < 80; i++)
combo.addItem( QString::number(i));
- combo.show();
+ combo.showNormal();
centerCursor(&combo); // QTBUG-33973, cursor needs to be within view from start on Mac.
QApplication::setActiveWindow(&combo);
QVERIFY(QTest::qWaitForWindowActive(&combo));
@@ -2629,7 +2629,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse()
QCOMPARE(combo.currentText(), QLatin1String("0"));
// When calling cursor function, Windows CE responds with: This function is not supported on this system.
-#ifndef Q_OS_WINCE
+#if !defined Q_OS_WINCE && !defined Q_OS_QNX
// Force cursor movement to prevent QCursor::setPos() from returning prematurely on QPA:
centerCursor(combo.view());
QTest::qWait(200);
diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
index 6551a88232..095fa3347d 100644
--- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
+++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
@@ -801,13 +801,16 @@ void tst_QDockWidget::task237438_setFloatingCrash()
void tst_QDockWidget::task248604_infiniteResize()
{
+#if defined Q_OS_BLACKBERRY
+ QSKIP("Top level window is stretched to fullscreen");
+#endif
QDockWidget d;
QTabWidget *t = new QTabWidget;
t->addTab(new QWidget, "Foo");
d.setWidget(t);
d.setContentsMargins(2, 2, 2, 2);
d.setMinimumSize(320, 240);
- d.show();
+ d.showNormal();
QTest::qWait(400);
QCOMPARE(d.size(), QSize(320, 240));
}
diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
index 6784ee477b..6b763f5a4c 100644
--- a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
+++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
@@ -825,6 +825,8 @@ void tst_QDoubleSpinBox::editingFinished()
QCOMPARE(editingFinishedSpy1.count(), 4);
QCOMPARE(editingFinishedSpy2.count(), 4);
+ testFocusWidget->show(); // On BlackBerry this is our root window we need to show it again
+ // otherwise subsequent tests will fail
}
void tst_QDoubleSpinBox::removeAll()
diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
index 077e1aa1df..36f14cb1ba 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
@@ -1322,7 +1322,7 @@ void tst_QLineEdit::undo_keypressevents_data()
// unselect any current selection
keys.addKeyClick(Qt::Key_Right);
-#ifdef Q_OS_WIN //Mac has a specialcase to handle jumping to the end of a selection
+#if defined Q_OS_WIN || defined Q_OS_QNX //Windows and QNX do not jump to the beginning of the selection
keys.addKeyClick(Qt::Key_Left);
#endif
@@ -3206,7 +3206,7 @@ void tst_QLineEdit::leftKeyOnSelectedText()
QCOMPARE(testWidget->cursorPosition(), 2);
QCOMPARE(testWidget->selectedText(), QString("23"));
QTest::keyClick(testWidget, Qt::Key_Left);
-#ifdef Q_OS_WIN
+#if defined Q_OS_WIN || defined Q_OS_QNX
QCOMPARE(testWidget->cursorPosition(), 1);
#else
// Selection is cleared ands cursor remains at position 2.
diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
index bc2e4caacd..59021108a2 100644
--- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
+++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
@@ -1007,7 +1007,7 @@ void tst_QMdiArea::activeSubWindow()
qApp->setActiveWindow(&mainWindow);
QCOMPARE(mdiArea->activeSubWindow(), subWindow);
-#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
+#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN) && !defined(Q_OS_QNX)
qApp->setActiveWindow(0);
QVERIFY(!mdiArea->activeSubWindow());
#endif
@@ -1088,7 +1088,7 @@ void tst_QMdiArea::currentSubWindow()
QVERIFY(mdiArea.activeSubWindow());
QVERIFY(mdiArea.currentSubWindow());
-#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
+#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN) && !defined(Q_OS_QNX)
qApp->setActiveWindow(0);
QVERIFY(!mdiArea.activeSubWindow());
QVERIFY(mdiArea.currentSubWindow());
@@ -1701,7 +1701,7 @@ void tst_QMdiArea::tileSubWindows()
qApp->processEvents();
QTRY_COMPARE(workspace.size(), QSize(350, 150));
- const QSize minSize(300, 100);
+ const QSize minSize(600, 130);
foreach (QMdiSubWindow *subWindow, workspace.subWindowList())
subWindow->setMinimumSize(minSize);
@@ -1908,6 +1908,9 @@ void tst_QMdiArea::dontMaximizeSubWindowOnActivation()
for (int i = 0; i < 5; ++i) {
QMdiSubWindow *window = mdiArea.addSubWindow(new QWidget);
window->show();
+#if defined Q_OS_QNX
+ QEXPECT_FAIL("", "QTBUG-38231", Abort);
+#endif
QVERIFY(window->isMaximized());
qApp->processEvents();
}
diff --git a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
index 268638a504..ffc3e3b67d 100644
--- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
+++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
@@ -206,6 +206,7 @@ private slots:
void task_233197();
void task_226929();
void styleChange();
+ void testFullScreenState();
};
void tst_QMdiSubWindow::initTestCase()
@@ -2007,6 +2008,19 @@ void tst_QMdiSubWindow::styleChange()
QCOMPARE(spy.count(), 0);
}
+void tst_QMdiSubWindow::testFullScreenState()
+{
+ QMdiArea mdiArea;
+ mdiArea.showMaximized();
+
+ QMdiSubWindow *subWindow = mdiArea.addSubWindow(new QWidget);
+ subWindow->setGeometry(0, 0, 300, 300);
+ subWindow->showFullScreen(); // QMdiSubWindow does not support the fullscreen state. This call
+ // should be equivalent to setVisible(true) (and not showNormal())
+ QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
+ QCOMPARE(subWindow->size(), QSize(300, 300));
+}
+
QTEST_MAIN(tst_QMdiSubWindow)
#include "tst_qmdisubwindow.moc"
diff --git a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
index 6a3bcc7a7d..fadfc0b48a 100644
--- a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
+++ b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
@@ -60,26 +60,26 @@ class XmlServer : public QThread
{
Q_OBJECT
public:
- XmlServer();
+ XmlServer(QObject *parent = 0) : QThread(parent), quit_soon(false), listening(false) {}
+
bool quit_soon;
+ bool listening;
protected:
virtual void run();
};
-XmlServer::XmlServer()
-{
- quit_soon = false;
-}
-
-#define CHUNK_SIZE 1
+#define CHUNK_SIZE 2048
void XmlServer::run()
{
QTcpServer srv;
- if (!srv.listen(QHostAddress::Any, TEST_PORT))
+ listening = srv.listen(QHostAddress::Any, TEST_PORT);
+ if (!listening) {
+ qWarning() << "Failed to listen on" << TEST_PORT << srv.errorString();
return;
+ }
for (;;) {
srv.waitForNewConnection(100);
@@ -168,12 +168,9 @@ class tst_QXmlSimpleReader : public QObject
QString prefix;
};
-tst_QXmlSimpleReader::tst_QXmlSimpleReader()
+tst_QXmlSimpleReader::tst_QXmlSimpleReader() : server(new XmlServer(this))
{
- server = new XmlServer();
- server->setParent(this);
server->start();
- QTest::qSleep(1000);
}
tst_QXmlSimpleReader::~tst_QXmlSimpleReader()
@@ -568,16 +565,13 @@ void tst_QXmlSimpleReader::inputFromSocket()
{
QFETCH(QString, file_name);
+ QTRY_VERIFY(server->listening);
+
QTcpSocket sock;
sock.connectToHost(QHostAddress::LocalHost, TEST_PORT);
-
- const bool connectionSuccess = sock.waitForConnected();
- if(!connectionSuccess) {
- QTextStream out(stderr);
- out << "QTcpSocket::errorString()" << sock.errorString();
- }
-
- QVERIFY(connectionSuccess);
+ QVERIFY2(sock.waitForConnected(),
+ qPrintable(QStringLiteral("Cannot connect on port ") + QString::number(TEST_PORT)
+ + QStringLiteral(": ") + sock.errorString()));
sock.write(file_name.toLocal8Bit() + "\n");
QVERIFY(sock.waitForBytesWritten());
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index fe2caa2efa..06f78b1116 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -164,6 +164,7 @@ Configure::Configure(int& argc, char** argv)
dictionary[ "GUI" ] = "yes";
dictionary[ "RTTI" ] = "yes";
dictionary[ "STRIP" ] = "yes";
+ dictionary[ "SEPARATE_DEBUG_INFO" ] = "no";
dictionary[ "SSE2" ] = "auto";
dictionary[ "SSE3" ] = "auto";
dictionary[ "SSSE3" ] = "auto";
@@ -445,6 +446,10 @@ void Configure::parseCmdLine()
dictionary[ "BUILDALL" ] = "yes";
else if (configCmdLine.at(i) == "-force-debug-info")
dictionary[ "FORCEDEBUGINFO" ] = "yes";
+ else if (configCmdLine.at(i) == "-no-separate-debug-info")
+ dictionary[ "SEPARATE_DEBUG_INFO" ] = "no";
+ else if (configCmdLine.at(i) == "-separate-debug-info")
+ dictionary[ "SEPARATE_DEBUG_INFO" ] = "yes";
else if (configCmdLine.at(i) == "-compile-examples") {
dictionary[ "COMPILE_EXAMPLES" ] = "yes";
@@ -1765,7 +1770,8 @@ bool Configure::displayHelp()
desc("BUILD", "debug", "-debug", "Compile and link Qt with debugging turned on.");
desc("BUILDALL", "yes", "-debug-and-release", "Compile and link two Qt libraries, with and without debugging turned on.\n");
- desc("FORCEDEBUGINFO", "yes","-force-debug-info", "Create symbol files for release builds.\n");
+ desc("FORCEDEBUGINFO", "yes","-force-debug-info", "Create symbol files for release builds.");
+ desc("SEPARATE_DEBUG_INFO", "yes","-separate-debug-info", "Strip debug information into a separate file.\n");
desc("BUILDDEV", "yes", "-developer-build", "Compile and link Qt with Qt developer options (including auto-tests exporting)\n");
@@ -2165,6 +2171,9 @@ bool Configure::checkAvailability(const QString &part)
if (part == "STYLE_WINDOWSXP")
available = (platform() == WINDOWS) && findFile("uxtheme.h");
+ else if (part == "OBJCOPY")
+ available = tryCompileProject("unix/objcopy");
+
else if (part == "ZLIB")
available = findFile("zlib.h");
@@ -2489,6 +2498,21 @@ bool Configure::verifyConfiguration()
dictionary["C++11"] = "auto";
}
+ if (dictionary["SEPARATE_DEBUG_INFO"] == "yes") {
+ if (dictionary[ "SHARED" ] == "no") {
+ cout << "ERROR: -separate-debug-info is incompatible with -static" << endl << endl;
+ dictionary[ "DONE" ] = "error";
+ } else if (dictionary[ "BUILD" ] != "debug"
+ && dictionary[ "BUILDALL" ] == "no"
+ && dictionary[ "FORCEDEBUGINFO" ] == "no") {
+ cout << "ERROR: -separate-debug-info needs -debug, -debug-and-release, or -force-debug-info" << endl << endl;
+ dictionary[ "DONE" ] = "error";
+ } else if (dictionary["SEPARATE_DEBUG_INFO"] == "yes" && !checkAvailability("OBJCOPY")) {
+ cout << "ERROR: -separate-debug-info was requested but this binutils does not support it." << endl;
+ dictionary[ "DONE" ] = "error";
+ }
+ }
+
if (dictionary["SQL_SQLITE_LIB"] == "no" && dictionary["SQL_SQLITE"] != "no") {
cout << "WARNING: Configure could not detect the presence of a system SQLite3 lib." << endl
<< "Configure will therefore continue with the SQLite3 lib bundled with Qt." << endl;
@@ -2752,6 +2776,8 @@ void Configure::generateOutputVars()
if (dictionary[ "BUILDALL" ] == "yes") {
qtConfig += "build_all";
}
+ if (dictionary[ "SEPARATE_DEBUG_INFO" ] == "yes")
+ qtConfig += "separate_debug_info";
if (dictionary[ "FORCEDEBUGINFO" ] == "yes")
qmakeConfig += "force_debug_info";
qmakeConfig += dictionary[ "BUILD" ];