summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/Qt5CoreConfigExtras.cmake.in9
-rw-r--r--src/corelib/animation/qsequentialanimationgroup.cpp2
-rw-r--r--src/corelib/corelib.pro8
-rw-r--r--src/corelib/doc/images/thread_clock.pngbin5964 -> 0 bytes
-rw-r--r--src/corelib/doc/images/threadsandobjects.pngbin66096 -> 0 bytes
-rw-r--r--src/corelib/doc/images/threadvisual-example.pngbin16823 -> 0 bytes
-rw-r--r--src/corelib/doc/qtcore.qdocconf4
-rw-r--r--src/corelib/doc/snippets/code/doc_src_resources.cpp15
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp4
-rw-r--r--src/corelib/doc/snippets/qtracer/ftracer.cpp180
-rw-r--r--src/corelib/doc/snippets/qtracer/main.cpp59
-rw-r--r--src/corelib/doc/snippets/qtracer/qtracer.pro2
-rw-r--r--src/corelib/doc/src/custom-types.qdoc7
-rw-r--r--src/corelib/doc/src/objectmodel/object.qdoc3
-rw-r--r--src/corelib/doc/src/objectmodel/signalsandslots.qdoc2
-rw-r--r--src/corelib/doc/src/plugins-howto.qdoc5
-rw-r--r--src/corelib/doc/src/resource-system.qdoc34
-rw-r--r--src/corelib/doc/src/threads-basics.qdoc365
-rw-r--r--src/corelib/doc/src/threads.qdoc828
-rw-r--r--src/corelib/global/global.pri1
-rw-r--r--src/corelib/global/qcompilerdetection.h21
-rw-r--r--src/corelib/global/qconfig-large.h28
-rw-r--r--src/corelib/global/qconfig-medium.h45
-rw-r--r--src/corelib/global/qconfig-minimal.h108
-rw-r--r--src/corelib/global/qconfig-nacl.h125
-rw-r--r--src/corelib/global/qconfig-small.h26
-rw-r--r--src/corelib/global/qfeatures.h686
-rw-r--r--src/corelib/global/qfeatures.txt228
-rw-r--r--src/corelib/global/qflags.h16
-rw-r--r--src/corelib/global/qglobal.cpp112
-rw-r--r--src/corelib/global/qglobal.h23
-rw-r--r--src/corelib/global/qlibraryinfo.cpp4
-rw-r--r--src/corelib/global/qlogging.cpp2
-rw-r--r--src/corelib/global/qlogging.h2
-rw-r--r--src/corelib/global/qsysinfo.h15
-rw-r--r--src/corelib/io/io.pri2
-rw-r--r--src/corelib/io/qdir.cpp15
-rw-r--r--src/corelib/io/qfileinfo.cpp2
-rw-r--r--src/corelib/io/qfileselector.cpp32
-rw-r--r--src/corelib/io/qfileselector.h2
-rw-r--r--src/corelib/io/qlockfile_unix.cpp17
-rw-r--r--src/corelib/io/qloggingcategory.cpp323
-rw-r--r--src/corelib/io/qloggingcategory.h76
-rw-r--r--src/corelib/io/qloggingregistry.cpp8
-rw-r--r--src/corelib/io/qsettings.cpp4
-rw-r--r--src/corelib/io/qsettings_mac.cpp3
-rw-r--r--src/corelib/io/qstandardpaths.cpp7
-rw-r--r--src/corelib/io/qstandardpaths.h3
-rw-r--r--src/corelib/io/qstandardpaths_blackberry.cpp1
-rw-r--r--src/corelib/io/qstandardpaths_ios.mm136
-rw-r--r--src/corelib/io/qstandardpaths_mac.cpp2
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp2
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp10
-rw-r--r--src/corelib/io/qurl.cpp2
-rw-r--r--src/corelib/io/qurl.h36
-rw-r--r--src/corelib/kernel/kernel.pri3
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm30
-rw-r--r--src/corelib/kernel/qcore_mac_p.h4
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp82
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h5
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp5
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry.cpp23
-rw-r--r--src/corelib/kernel/qjni.cpp58
-rw-r--r--src/corelib/kernel/qjni_p.h4
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp2
-rw-r--r--src/corelib/kernel/qmath.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp55
-rw-r--r--src/corelib/kernel/qobject_impl.h2
-rw-r--r--src/corelib/kernel/qobject_p.h1
-rw-r--r--src/corelib/kernel/qvariant.cpp62
-rw-r--r--src/corelib/kernel/qwineventnotifier.h2
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp6
-rw-r--r--src/corelib/plugin/quuid.h4
-rw-r--r--src/corelib/thread/qbasicatomic.h5
-rw-r--r--src/corelib/thread/qreadwritelock.cpp2
-rw-r--r--src/corelib/thread/qthread_win.cpp2
-rw-r--r--src/corelib/tools/qbytearray.cpp2
-rw-r--r--src/corelib/tools/qcollator.cpp42
-rw-r--r--src/corelib/tools/qcollator.h24
-rw-r--r--src/corelib/tools/qcollator_icu.cpp5
-rw-r--r--src/corelib/tools/qcollator_macx.cpp5
-rw-r--r--src/corelib/tools/qcollator_posix.cpp5
-rw-r--r--src/corelib/tools/qcollator_win.cpp5
-rw-r--r--src/corelib/tools/qcommandlineparser.cpp49
-rw-r--r--src/corelib/tools/qdatetime.cpp19
-rw-r--r--src/corelib/tools/qlocale.cpp10
-rw-r--r--src/corelib/tools/qlocale_blackberry.cpp17
-rw-r--r--src/corelib/tools/qmap.cpp6
-rw-r--r--src/corelib/tools/qstring.cpp8
-rw-r--r--src/corelib/tools/qstring.h6
-rw-r--r--src/corelib/tools/qtimezone.cpp126
-rw-r--r--src/corelib/tools/qtimezone.h24
-rw-r--r--src/corelib/tools/qtimezoneprivate.cpp26
-rw-r--r--src/corelib/tools/qtimezoneprivate_mac.mm57
-rw-r--r--src/corelib/tools/qtimezoneprivate_p.h11
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp259
-rw-r--r--src/corelib/tools/qtimezoneprivate_win.cpp177
-rw-r--r--src/corelib/tools/qvector.cpp6
-rw-r--r--src/corelib/tools/tools.pri1
-rw-r--r--src/corelib/xml/qxmlstream.cpp7
100 files changed, 1285 insertions, 3623 deletions
diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in
index 2d87783107..9bda70ec07 100644
--- a/src/corelib/Qt5CoreConfigExtras.cmake.in
+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in
@@ -51,8 +51,9 @@ set(Qt5Core_MOC_EXECUTABLE Qt5::moc)
set(Qt5Core_RCC_EXECUTABLE Qt5::rcc)
set_property(TARGET Qt5::Core PROPERTY INTERFACE_QT_MAJOR_VERSION 5)
+set_property(TARGET Qt5::Core PROPERTY INTERFACE_QT_COORD_TYPE $$QT_COORD_TYPE)
set_property(TARGET Qt5::Core APPEND PROPERTY
- COMPATIBLE_INTERFACE_STRING QT_MAJOR_VERSION
+ COMPATIBLE_INTERFACE_STRING QT_MAJOR_VERSION QT_COORD_TYPE
)
include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5CoreConfigExtrasMkspecDir.cmake\")
@@ -80,6 +81,12 @@ list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE)
set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE)
!!ENDIF
+!!IF !isEmpty(CMAKE_DISABLED_FEATURES)
+set(Qt5_DISABLED_FEATURES
+ $$CMAKE_DISABLED_FEATURES
+)
+!!ENDIF
+
set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG>)
!!IF contains(QT_CONFIG, reduce_exports)
diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp
index 42debea782..1c84e3dbc9 100644
--- a/src/corelib/animation/qsequentialanimationgroup.cpp
+++ b/src/corelib/animation/qsequentialanimationgroup.cpp
@@ -303,8 +303,6 @@ QPauseAnimation *QSequentialAnimationGroup::insertPause(int index, int msecs)
/*!
\property QSequentialAnimationGroup::currentAnimation
Returns the animation in the current time.
-
- \sa currentAnimationChanged()
*/
QAbstractAnimation *QSequentialAnimationGroup::currentAnimation() const
{
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 1ed55bb0c8..b513149e7c 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -20,8 +20,7 @@ ANDROID_JAR_DEPENDENCIES = \
jar/QtAndroid.jar \
jar/QtAndroidAccessibility.jar
ANDROID_LIB_DEPENDENCIES = \
- plugins/platforms/android/libqtforandroid.so \
- libs/libgnustl_shared.so
+ plugins/platforms/android/libqtforandroid.so
ANDROID_BUNDLED_JAR_DEPENDENCIES = \
jar/QtAndroid-bundled.jar \
jar/QtAndroidAccessibility-bundled.jar
@@ -49,7 +48,7 @@ mac|darwin {
LIBS_PRIVATE += -framework CoreServices
}
LIBS_PRIVATE += -framework CoreFoundation
- LIBS += -framework Foundation
+ LIBS_PRIVATE += -framework Foundation
}
win32:DEFINES-=QT_NO_CAST_TO_ASCII
DEFINES += $$MODULE_DEFINES
@@ -80,6 +79,9 @@ cmake_umbrella_config_version_file.input = $$PWD/../../mkspecs/features/data/cma
cmake_umbrella_config_version_file.output = $$DESTDIR/cmake/Qt5/Qt5ConfigVersion.cmake
load(cmake_functions)
+load(qfeatures)
+
+CMAKE_DISABLED_FEATURES = $$join(QT_DISABLED_FEATURES, "$$escape_expand(\\n) ")
CMAKE_HOST_DATA_DIR = $$cmakeRelativePath($$[QT_HOST_DATA/src], $$[QT_INSTALL_PREFIX])
contains(CMAKE_HOST_DATA_DIR, "^\\.\\./.*"):!isEmpty(CMAKE_HOST_DATA_DIR) {
diff --git a/src/corelib/doc/images/thread_clock.png b/src/corelib/doc/images/thread_clock.png
deleted file mode 100644
index b8a8aa0a39..0000000000
--- a/src/corelib/doc/images/thread_clock.png
+++ /dev/null
Binary files differ
diff --git a/src/corelib/doc/images/threadsandobjects.png b/src/corelib/doc/images/threadsandobjects.png
deleted file mode 100644
index 8357d2532a..0000000000
--- a/src/corelib/doc/images/threadsandobjects.png
+++ /dev/null
Binary files differ
diff --git a/src/corelib/doc/images/threadvisual-example.png b/src/corelib/doc/images/threadvisual-example.png
deleted file mode 100644
index 2a49874719..0000000000
--- a/src/corelib/doc/images/threadvisual-example.png
+++ /dev/null
Binary files differ
diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index fdd46995c5..9ab66c6645 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -2,7 +2,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
project = QtCore
description = Qt Core Reference Documentation
-url = http://qt-project.org/doc/qt-$QT_VER/qtcore
+url = http://qt-project.org/doc/qt-$QT_VER
version = $QT_VERSION
examplesinstallpath = core
@@ -26,7 +26,7 @@ qhp.QtCore.subprojects.classes.sortPages = true
tagfile = ../../../doc/qtcore/qtcore.tags
-depends += qtgui qtwidgets qtnetwork qtdoc qtquick qtlinguist qtdesigner
+depends += qtgui qtwidgets qtnetwork qtdoc qtquick qtlinguist qtdesigner qtconcurrent qtxml
headerdirs += ..
diff --git a/src/corelib/doc/snippets/code/doc_src_resources.cpp b/src/corelib/doc/snippets/code/doc_src_resources.cpp
index 482c25a222..8ac7b0e970 100644
--- a/src/corelib/doc/snippets/code/doc_src_resources.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_resources.cpp
@@ -44,11 +44,24 @@ QResource::registerResource("/path/to/myresource.rcc");
//! [5]
+MyClass::MyClass() : BaseClass()
+{
+ Q_INIT_RESOURCE(resources);
+
+ QFile file("qrc:/myfile.dat");
+ ...
+}
+//! [5]
+
+
+//! [6]
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Q_INIT_RESOURCE(graphlib);
+
+ QFile file("qrc:/graph.png");
...
return app.exec();
}
-//! [5]
+//! [6]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
index 003fce580b..9210d2737f 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
@@ -416,7 +416,7 @@ text.data(); // returns "Qt is great!"
//! [46]
QString tmp = "test";
QByteArray text = tmp.toLocal8Bit();
-char *data = new char[text.size()]
+char *data = new char[text.size()];
strcpy(data, text.data());
delete [] data;
//! [46]
@@ -424,7 +424,7 @@ delete [] data;
//! [47]
QString tmp = "test";
QByteArray text = tmp.toLocal8Bit();
-char *data = new char[text.size() + 1]
+char *data = new char[text.size() + 1];
strcpy(data, text.data());
delete [] data;
//! [47]
diff --git a/src/corelib/doc/snippets/qtracer/ftracer.cpp b/src/corelib/doc/snippets/qtracer/ftracer.cpp
deleted file mode 100644
index b12e3ed9c3..0000000000
--- a/src/corelib/doc/snippets/qtracer/ftracer.cpp
+++ /dev/null
@@ -1,180 +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 examples 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <QCoreApplication>
-#include <QLoggingCategory>
-
-
-//![1]
-QLoggingCategory theFooArea("foo");
-QLoggingCategory theBarArea("bar");
-QLoggingCategory theBazArea("baz");
-//![1]
-
-// Note: These locations are Ubuntu specific.
-
-// Note: To make the example work with user permissions, make sure
-// the files are user-writable and the path leading there accessible.
-
-const char traceSwitch[] = "/sys/kernel/debug/tracing/tracing_on";
-const char traceSink[] = "/sys/kernel/debug/tracing/trace_marker";
-
-// The base class only serves as a facility to share code
-// between the "single line" data logging aspect and the
-// scoped "measuring" aspect.
-
-// Both aspects and the base class could be combined into
-// a single tracer serving both purposes, but are split
-// here for clarity.
-
-// Error handling is left as an exercise.
-
-//![2]
-class MyTracerBase : public QTracer
-{
-public:
- MyTracerBase() {
- enable = ::open(traceSwitch, O_WRONLY);
- marker = ::open(traceSink, O_WRONLY);
- }
-
- ~MyTracerBase() {
- ::close(enable);
- ::close(marker);
- }
-
-protected:
- int enable;
- int marker;
-};
-//![2]
-
-
-//![2]
-class MyTracer : public MyTracerBase
-{
-public:
- void start() { ::write(marker, "B", 1); }
- void end() { ::write(marker, "E", 1); }
-};
-//![2]
-
-
-//![3]
-class MyDataLogger : public MyTracerBase
-{
-public:
- MyDataLogger() {
- buf[0] = 0;
- pos = 0;
- }
-
- void record(int i) { pos += sprintf(buf + pos, "%d", i); }
- void record(const char *msg) { pos += sprintf(buf + pos, "%s", msg); }
- void end() { ::write(marker, buf, pos); pos = 0; }
-
-private:
- char buf[100];
- int pos;
-};
-//![3]
-
-// Simplest possible example for "measuring".
-//![4]
-int foo(int i)
-{
- qCTraceGuard(theFooArea);
- // Here could be some lengthy code.
- return i * i;
-}
-//![4]
-
-// We can switch on/off tracing dynamically.
-// The tracer will be temporarily switched off at the third call
-// and re-enabled at the eighth.
-//![5]
-int bar(int i)
-{
- static int n = 0;
- ++n;
- if (n == 3)
- theBarArea.setEnabled(QtTraceMsg, false);
- if (n == 8)
- theBarArea.setEnabled(QtTraceMsg, true);
-
- qCTraceGuard(theBarArea);
- return i * i;
-}
-//![5]
-
-// An example to create "complex" log messages.
-//![6]
-int baz(int i)
-{
- qCTrace(theBazArea) << 32 << "some stuff";
-
- return i * i;
-}
-//![6]
-
-
-
-//![7]
-namespace {
-static struct Init
-{
- Init() {
- tracer.addToCategory(theFooArea);
- tracer.addToCategory(theBarArea);
- logger.addToCategory(theBazArea);
- }
-
- MyTracer tracer;
- MyDataLogger logger;
-
-} initializer;
-}
-//![7]
diff --git a/src/corelib/doc/snippets/qtracer/main.cpp b/src/corelib/doc/snippets/qtracer/main.cpp
deleted file mode 100644
index 758a2bbdb8..0000000000
--- a/src/corelib/doc/snippets/qtracer/main.cpp
+++ /dev/null
@@ -1,59 +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 examples 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$
-**
-****************************************************************************/
-
-int foo(int i);
-int bar(int i);
-int baz(int i);
-
-int main()
-{
- int s = 0;
- for (int i = 0; i != 10; ++i)
- s += foo(i);
-
- for (int i = 0; i != 10; ++i)
- s += bar(i);
-
- for (int i = 0; i != 10; ++i)
- s += baz(i);
-
- return s;
-}
-
diff --git a/src/corelib/doc/snippets/qtracer/qtracer.pro b/src/corelib/doc/snippets/qtracer/qtracer.pro
deleted file mode 100644
index 254e22be76..0000000000
--- a/src/corelib/doc/snippets/qtracer/qtracer.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-
-SOURCES += ftracer.cpp main.cpp
diff --git a/src/corelib/doc/src/custom-types.qdoc b/src/corelib/doc/src/custom-types.qdoc
index cbf347a2f7..ed846aee83 100644
--- a/src/corelib/doc/src/custom-types.qdoc
+++ b/src/corelib/doc/src/custom-types.qdoc
@@ -155,10 +155,9 @@
The Q_DECLARE_METATYPE() macro and qRegisterMetaType() function documentation
contain more detailed information about their uses and limitations.
- The \l{Custom Type Example}{Custom Type},
- \l{Custom Type Sending Example}{Custom Type Sending}
- and \l{Queued Custom Type Example}{Queued Custom Type} examples show how to
- implement a custom type with the features outlined in this document.
+ The \l{Custom Type Example}{Custom Type} and \l{Queued Custom Type Example}
+ {Queued Custom Type} examples show how to implement a custom type with the
+ features outlined in this document.
The \l{Debugging Techniques} document provides an overview of the debugging
mechanisms discussed above.
diff --git a/src/corelib/doc/src/objectmodel/object.qdoc b/src/corelib/doc/src/objectmodel/object.qdoc
index 89a781da39..8d24096b7a 100644
--- a/src/corelib/doc/src/objectmodel/object.qdoc
+++ b/src/corelib/doc/src/objectmodel/object.qdoc
@@ -46,7 +46,8 @@
\li queryable and designable \l{Qt's Property System}{object
properties}
\li powerful \l{The Event System}{events and event filters}
- \li contextual \l{i18n}{string translation for internationalization}
+ \li contextual \l{Internationalization with Qt}{string translation for
+ internationalization}
\li sophisticated interval driven \l {Timers}{timers} that make it possible
to elegantly integrate many tasks in an event-driven GUI
\li hierarchical and queryable \l{Object Trees & Ownership}{object
diff --git a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
index dd93b80cae..e894d547d0 100644
--- a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
+++ b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
@@ -275,7 +275,7 @@
and slot members, as well as pointers to these functions.
The meta-object contains additional information such as the
- object's \l{QObject::className()}{class name}. You can
+ object's \l{QMetaObject::className()}{class name}. You can
also check if an object \l{QObject::inherits()}{inherits}
a specific class, for example:
diff --git a/src/corelib/doc/src/plugins-howto.qdoc b/src/corelib/doc/src/plugins-howto.qdoc
index 2dbf1f8141..7565d610cc 100644
--- a/src/corelib/doc/src/plugins-howto.qdoc
+++ b/src/corelib/doc/src/plugins-howto.qdoc
@@ -35,10 +35,7 @@
These \l{Qt Core} classes deal with shared libraries, (e.g. .so and DLL
files), and with Qt plugins.
- See the \l{How to Create Qt Plugins} page for more information..
-
- See also the \l{ActiveQt framework} for Windows.
-
+ See the \l{How to Create Qt Plugins} page for more information.
*/
/*!
diff --git a/src/corelib/doc/src/resource-system.qdoc b/src/corelib/doc/src/resource-system.qdoc
index 5ef6bb285c..91ce8afcf8 100644
--- a/src/corelib/doc/src/resource-system.qdoc
+++ b/src/corelib/doc/src/resource-system.qdoc
@@ -184,15 +184,39 @@
path list is empty at startup; call QDir::addSearchPath() to
add paths to it.
- If you have resources in a static library, you might need to
- force initialization of your resources by calling \l
- Q_INIT_RESOURCE() with the base name of the \c .qrc file. For
- example:
+ \section1 Using Resources in a Library
+
+ If you have resources in a library, you need to force initialization
+ of your resources by calling \l Q_INIT_RESOURCE() with the base name
+ of the \c .qrc file. For example:
\snippet code/doc_src_resources.cpp 5
+ This ensures that the resources are linked into the final application
+ binary in the case of static linking. You should put the initialization
+ code close to where the resources are used in your library, so that
+ clients of your library will only link in the resources if they use
+ the feature of the library that depends on them.
+
+ Note: As the resource initializers generated by rcc are declared in the
+ global namespace, your calls to \l Q_INIT_RESOURCE() also need to be done
+ outside of any namespace.
+
+ If the library includes resources that are not used internally, but
+ instead exposed to clients of the library, the initialization needs
+ to happen in the application code. For example:
+
+ \snippet code/doc_src_resources.cpp 6
+
+ As before, this ensures that the resources are linked into the final
+ application binary in the case of static linking, but also triggers
+ loading of the library in the case of dynamic linking, such as plugins.
+
Similarly, if you must unload a set of resources explicitly
(because a plugin is being unloaded or the resources are not valid
any longer), you can force removal of your resources by calling
- Q_CLEANUP_RESOURCE() with the same base name as above.
+ \l Q_CLEANUP_RESOURCE() with the same base name as above.
+
+ Note: The use of \l Q_INIT_RESOURCE() and \l Q_CLEANUP_RESOURCE() is
+ not necessary when the resource is built as part of the application.
*/
diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc
deleted file mode 100644
index 4f381421b4..0000000000
--- a/src/corelib/doc/src/threads-basics.qdoc
+++ /dev/null
@@ -1,365 +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:FDL$
-** 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 Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \page thread-basics.html
- \ingroup tutorials
- \startpage {index.html}{Qt Reference Documentation}
-
- \title Threading Basics
- \brief An introduction to threads
-
- \section1 What Are Threads?
-
- Threads are about doing things in parallel, just like processes. So how do
- threads differ from processes? While you are making calculations on a
- spreadsheet, there may also be a media player running on the same desktop
- playing your favorite song. Here is an example of two processes working in
- parallel: one running the spreadsheet program; one running a media player.
- Multitasking is a well known term for this. A closer look at the media
- player reveals that there are again things going on in parallel within one
- single process. While the media player is sending music to the audio driver,
- the user interface with all its bells and whistles is being constantly
- updated. This is what threads are for -- concurrency within one single
- process.
-
- So how is concurrency implemented? Parallel work on single core CPUs is an
- illusion which is somewhat similar to the illusion of moving images in
- cinema.
- For processes, the illusion is produced by interrupting the processor's
- work on one process after a very short time. Then the processor moves on to
- the next process. In order to switch between processes, the current program
- counter is saved and the next processor's program counter is loaded. This
- is not sufficient because the same needs to be done with registers and
- certain architecture and OS specific data.
-
- Just as one CPU can power two or more processes, it is also possible to let
- the CPU run on two different code segments of one single process. When a
- process starts, it always executes one code segment and therefore the
- process is said to have one thread. However, the program may decide to
- start a second thread. Then, two different code sequences are processed
- simultaneously inside one process. Concurrency is achieved on single core
- CPUs by repeatedly saving program counters and registers then loading the
- next thread's program counters and registers. No cooperation from the
- program is required to cycle between the active threads. A thread may be in
- any state when the switch to the next thread occurs.
-
- The current trend in CPU design is to have several cores. A typical
- single-threaded application can make use of only one core. However, a
- program with multiple threads can be assigned to multiple cores, making
- things happen in a truly concurrent way. As a result, distributing work
- to more than one thread can make a program run much faster on multicore
- CPUs because additional cores can be used.
-
- \section2 GUI Thread and Worker Thread
-
- As mentioned, each program has one thread when it is started. This thread
- is called the "main thread" (also known as the "GUI thread" in Qt
- applications). The Qt GUI must run in this thread. All widgets and several
- related classes, for example QPixmap, don't work in secondary threads.
- A secondary thread is commonly referred to as a "worker thread" because it
- is used to offload processing work from the main thread.
-
- \section2 Simultaneous Access to Data
-
- Each thread has its own stack, which means each thread has its own call
- history and local variables. Unlike processes, threads share the same
- address space. The following diagram shows how the building blocks of
- threads are located in memory. Program counter and registers of inactive
- threads are typically kept in kernel space. There is a shared copy of the
- code and a separate stack for each thread.
-
- \image threadvisual-example.png "Thread visualization"
-
- If two threads have a pointer to the same object, it is possible that both
- threads will access that object at the same time and this can potentially
- destroy the object's integrity. It's easy to imagine the many things that
- can go wrong when two methods of the same object are executed
- simultaneously.
-
- Sometimes it is necessary to access one object from different threads;
- for example, when objects living in different threads need to communicate.
- Since threads use the same address space, it is easier and faster for
- threads to exchange data than it is for processes. Data does not have to be
- serialized and copied. Passing pointers is possible, but there must be a
- strict coordination of what thread touches which object. Simultaneous
- execution of operations on one object must be prevented. There are several
- ways of achieving this and some of them are described below.
-
- So what can be done safely? All objects created in a thread can be used
- safely within that thread provided that other threads don't have references
- to them and objects don't have implicit coupling with other threads. Such
- implicit coupling may happen when data is shared between instances as with
- static members, singletons or global data. Familiarize yourself with the
- concept of \l{Reentrancy and Thread-Safety}{thread safe and reentrant}
- classes and functions.
-
- \section1 Using Threads
-
- There are basically two use cases for threads:
-
- \list
- \li Make processing faster by making use of multicore processors.
- \li Keep the GUI thread or other time critical threads responsive by
- offloading long lasting processing or blocking calls to other threads.
- \endlist
-
- \section2 When to Use Alternatives to Threads
-
- Developers need to be very careful with threads. It is easy to start other
- threads, but very hard to ensure that all shared data remains consistent.
- Problems are often hard to find because they may only show up once in a
- while or only on specific hardware configurations. Before creating threads
- to solve certain problems, possible alternatives should be considered.
-
- \table
- \header
- \li Alternative
- \li Comment
- \row
- \li QEventLoop::processEvents()
- \li Calling QEventLoop::processEvents() repeatedly during a
- time-consuming calculation prevents GUI blocking. However, this
- solution doesn't scale well because the call to processEvents() may
- occur too often, or not often enough, depending on hardware.
- \row
- \li QTimer
- \li Background processing can sometimes be done conveniently using a
- timer to schedule execution of a slot at some point in the future.
- A timer with an interval of 0 will time out as soon as there are no
- more events to process.
- \row
- \li QSocketNotifier QNetworkAccessManager QIODevice::readyRead()
- \li This is an alternative to having one or multiple threads, each with
- a blocking read on a slow network connection. As long as the
- calculation in response to a chunk of network data can be executed
- quickly, this reactive design is better than synchronous waiting in
- threads. Reactive design is less error prone and energy efficient
- than threading. In many cases there are also performance benefits.
- \endtable
-
- In general, it is recommended to only use safe and tested paths and to
- avoid introducing ad-hoc threading concepts. The QtConcurrent module provides an easy
- interface for distributing work to all of the processor's cores. The
- threading code is completely hidden in the QtConcurrent framework, so you
- don't have to take care of the details. However, QtConcurrent can't be used
- when communication with the running thread is needed, and it shouldn't be
- used to handle blocking operations.
-
- \section2 Which Qt Thread Technology Should You Use?
-
- See the \l{Multithreading Technologies in Qt} page for an introduction to the
- different approaches to multithreading to Qt, and for guidelines on how to
- choose among them.
-
-
- \section1 Qt Thread Basics
-
- The following sections describe how QObjects interact with threads, how
- programs can safely access data from multiple threads, and how asynchronous
- execution produces results without blocking a thread.
-
- \section2 QObject and Threads
-
- As mentioned above, developers must always be careful when calling objects'
- methods from other threads. \l{QObject#Thread Affinity}{Thread affinity}
- does not change this situation.
- Qt documentation marks several methods as thread-safe.
- \l{QCoreApplication::}{postEvent()} is a noteworthy example. A thread-safe
- method may be called from different threads simultaneously.
-
- In cases where there is usually no concurrent access to methods, calling
- non-thread-safe methods of objects in other threads may work thousands
- of times before a concurrent access occurs, causing unexpected behavior.
- Writing test code does not entirely ensure thread correctness, but it is
- still important.
- On Linux, Valgrind and Helgrind can help detect threading errors.
-
- \section2 Protecting the Integrity of Data
-
- When writing a multithread application, extra care must be taken to avoid
- data corruption. See \l{Synchronizing Threads} for a discussion on how to
- use threads safely.
-
- \section2 Dealing with Asynchronous Execution
-
- One way to obtain a worker thread's result is by waiting for the thread
- to terminate. In many cases, however, a blocking wait isn't acceptable. The
- alternative to a blocking wait are asynchronous result deliveries with
- either posted events or queued signals and slots. This generates a certain
- overhead because an operation's result does not appear on the next source
- line, but in a slot located somewhere else in the source file. Qt
- developers are used to working with this kind of asynchronous behavior
- because it is much similar to the kind of event-driven programming used in
- GUI applications.
-
- \section1 Examples
-
- This tutorial comes with examples for Qt's three basic ways of working with
- threads. Two more examples show how to communicate with a running thread
- and how a QObject can be placed in another thread, providing service to the
- main thread.
-
- \list
- \li Using QThread as shown \l{Qt thread basics}{above}
- \li \l{Example 1: Using the Thread Pool}{Using the global QThreadPool}
- \li \l{Example 2: Using QtConcurrent}{Using QtConcurrent}
- \li \l{Example 3: Clock}{Communication with the GUI thread}
- \li \l{Example 4: A Permanent Thread}{A permanent QObject in another thread
- provides service to the main thread}
- \endlist
-
- The following examples can all be compiled and run independently. The source can
- be found in the examples directory: examples/tutorials/threads/
-
- \section2 Example 1: Using the Thread Pool
-
- Creating and destroying threads frequently can be expensive. To avoid the
- cost of thread creation, a thread pool can be used. A thread pool is a
- place where threads can be parked and fetched. We can write the same
- "hello thread" program as \l{Qt Thread Basics}{above} using the global
- thread pool. We derive a class from QRunnable. The code we want to run in
- another thread needs to be placed in the reimplemented QRunnable::run()
- method.
-
- \snippet ../widgets/tutorials/threads/hellothreadpool/hellothreadpool.cpp 1
-
- We instantiate Work in main(), locate the global thread pool and use the
- QThreadPool::start() method. Now the thread pool runs our worker in another
- thread. Using the thread pool has a performance advantage because threads
- are not destroyed after they have finished running. They are kept in a pool
- and wait to be used again later.
-
- \section2 Example 2: Using QtConcurrent
-
- \snippet ../widgets/tutorials/threads/helloconcurrent/helloconcurrent.cpp 1
-
- We write a global function hello() to implement the work. QtConcurrent::run()
- is used to run the function in another thread. The result is a QFuture.
- QFuture provides a method called \l{QFuture::}{waitForFinished()}, which
- blocks until the calculation is completed. The real power of QtConcurrent
- becomes visible when data can be made available in a container. QtConcurrent
- provides several functions that are able to process itemized data on all
- available cores simultaneously. The use of QtConcurrent is very similar to
- applying an STL algorithm to an STL container.
- \l{examples-threadandconcurrent.html}{QtConcurrent Map} is a very short and
- clear example about how a container of images can be scaled on all available
- cores. The image scaling example uses the blocking variants of the functions
- used. For every blocking function there is also a non-blocking, asynchronous
- counterpart. Getting results asynchronously is implemented with QFuture and
- QFutureWatcher.
-
- \section2 Example 3: Clock
-
- \image thread_clock.png "clock"
-
- We want to produce a clock application. The application has a GUI and a
- worker thread. The worker thread checks every 10 milliseconds what time it
- is. If the formatted time has changed, the result will be sent to the GUI
- thread where it is displayed.
-
- Of course, this is an overly complicated way of designing a clock and,
- actually, a separate thread is unnecessary. We would be better off placing
- the timer in the main thread because the calculation made in the timer slot
- is very short-lived. This example is purely for instructional use and shows
- how to communicate from a worker thread to a GUI thread. Note that
- communication in this direction is easy. We only need to add a signal
- to QThread and make a queued signal/slot connection to the main thread.
- Communication from the GUI to the worker thread is shown in the next
- example.
-
- \snippet ../widgets/tutorials/threads/clock/main.cpp 1
-
- We've connected the \c clockThread with the label. The connection must be a
- queued signal-slot connection because we want to put the call in the event
- loop.
-
- \snippet ../widgets/tutorials/threads/clock/clockthread.h 1
-
- We have derived a class from QThread and declared the \c sendTime() signal.
-
- \snippet ../widgets/tutorials/threads/clock/clockthread.cpp 1
-
- The trickiest part of this example is that the timer is connected to its
- slot via a direct connection. A default connection would produce a queued
- signal-slot connection because the connected objects live in different
- threads; remember that QThread does not live in the thread it creates.
-
- Still it is safe to access ClockThread::timerHit() from the worker thread
- because ClockThread::timerHit() is private and only touches local variables
- and a private member that isn't touched by public methods.
- QDateTime::currentDateTime() isn't marked as thread-safe in Qt
- documentation, however we can get away with using it in this small
- example because we know that the QDateTime::currentDateTime() static
- method isn't used in any other threads.
-
- \section2 Example 4: A Permanent Thread
-
- This example shows how it is possible to have a QObject in a worker thread
- that accepts requests from the GUI thread, does polling using a timer and
- continuously reports results back to the GUI thread. The actual work
- including the polling must be implemented in a class derived from QObject.
- We have called this class \c WorkerObject in the code shown below. The
- thread-specific code is hidden in a class called \c Thread, derived from
- QThread.
- \c Thread has two additional public members. The \c launchWorker() member
- takes the worker object and moves it to another thread with a started event
- loop.
- The call blocks for a very short moment until the thread creation operation
- is completed, allowing the worker object to be used again on the next line.
- The \c Thread class's code is short but somewhat involved, so we only show
- how to use the class.
-
- \snippet ../widgets/tutorials/threads/movedobject/main.cpp 1
-
- QMetaObject::invokeMethod() calls a slot via the event loop. The worker
- object's methods should not be called directly after the object has been
- moved to another thread. We let the worker thread do some work and polling,
- and use a timer to shut the application down after 3 seconds. Shutting the
- worker down needs some care. We call \c{Thread::stop()} to exit the event
- loop. We wait for the thread to terminate and, after this has occurred, we
- delete the worker.
-
- \section1 Digging Deeper
-
- Threading is a very complicated subject. Qt offers more classes for
- threading than we have presented in this tutorial. The following materials
- can help you go into the subject in more depth:
-
- \list
- \li Good video tutorials about threads with Qt can be found in the material
- from the \l{Training Day at Qt Developer Days 2009}.
- \li The \l{Thread Support in Qt} document is a good starting point into
- the reference documentation.
- \li Qt comes with several additional examples for
- \l{Threading and Concurrent Programming Examples}{QThread and QtConcurrent}.
- \li Several good books describe how to work with Qt threads. The most
- extensive coverage can be found in \e{Advanced Qt Programming} by Mark
- Summerfield, Prentice Hall - roughly 70 of 500 pages cover QThread and
- QtConcurrent.
- \endlist
-*/
diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc
deleted file mode 100644
index 890fd9f6ff..0000000000
--- a/src/corelib/doc/src/threads.qdoc
+++ /dev/null
@@ -1,828 +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:FDL$
-** 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 Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \group thread
- \title Threading Classes
-
- These \l{Qt Core} classes provide threading support to applications.
- The \l{Thread Support in Qt} page covers how to use these classes.
-*/
-
-/*!
- \page threads.html
- \title Thread Support in Qt
- \ingroup qt-basic-concepts
- \brief A detailed discussion of thread handling in Qt.
-
- \ingroup frameworks-technologies
-
- \nextpage Multithreading Technologies in Qt
-
- Qt provides thread support in the form of platform-independent
- threading classes, a thread-safe way of posting events, and
- signal-slot connections across threads. This makes it easy to
- develop portable multithreaded Qt applications and take advantage
- of multiprocessor machines. Multithreaded programming is also a
- useful paradigm for performing time-consuming operations without
- freezing the user interface of an application.
-
- Earlier versions of Qt offered an option to build the library
- without thread support. Since Qt 4.0, threads are always enabled.
-
- \section1 Topics:
-
- \list
- \li \l{Recommended Reading}
- \li \l{The Threading Classes}
- \li \l{Multithreading Technologies in Qt}
- \li \l{Synchronizing Threads}
- \li \l{Reentrancy and Thread-Safety}
- \li \l{Threads and QObjects}
- \li \l{Thread-Support in Qt Modules}
- \endlist
-
- \section1 Recommended Reading
-
- This document is intended for an audience that has knowledge of,
- and experience with, multithreaded applications. If you are new
- to threading see our Recommended Reading list:
-
- \list
- \li \l {http://www.amazon.com/Threads-Primer-Guide-Multithreaded-Programming/dp/0134436989}{Threads Primer: A Guide to Multithreaded Programming}
- \li \l {http://www.amazon.com/Thread-Time-MultiThreaded-Programming-Guide/dp/0131900676}{Thread Time: The Multithreaded Programming Guide}
- \li \l {http://www.amazon.com/Pthreads-Programming-Standard-Multiprocessing-Nutshell/dp/1565921151a}{Pthreads Programming: A POSIX Standard for Better Multiprocessing}
- \li \l {http://www.amazon.com/WIN32-Multithreaded-Programming-Aaron-Cohen/dp/1565922964}{Win32 Multithreaded Programming}
- \endlist
-
- \section1 The Threading Classes
-
- These classes are relevant to threaded applications.
-
- \annotatedlist thread
-
-\omit
- \list
- \li QThread provides the means to start a new thread.
- \li QThreadStorage provides per-thread data storage.
- \li QThreadPool manages a pool of threads that run QRunnable objects.
- \li QRunnable is an abstract class representing a runnable object.
- \li QMutex provides a mutual exclusion lock, or mutex.
- \li QMutexLocker is a convenience class that automatically locks
- and unlocks a QMutex.
- \li QReadWriteLock provides a lock that allows simultaneous read access.
- \li QReadLocker and QWriteLocker are convenience classes that automatically
- lock and unlock a QReadWriteLock.
- \li QSemaphore provides an integer semaphore (a generalization of a mutex).
- \li QWaitCondition provides a way for threads to go to sleep until
- woken up by another thread.
- \li QAtomicInt provides atomic operations on integers.
- \li QAtomicPointer provides atomic operations on pointers.
- \endlist
-\endomit
-
- \note Qt's threading classes are implemented with native threading APIs;
- e.g., Win32 and pthreads. Therefore, they can be used with threads of the
- same native API.
-*/
-
-/*!
- \page threads-technologies.html
- \title Multithreading Technologies in Qt
- \ingroup qt-basic-concepts
- \brief An overview and comparison of different ways to use threads in Qt.
-
- \ingroup frameworks-technologies
-
- \contentspage Thread Support in Qt
- \previouspage Thread Support in Qt
- \nextpage Synchronizing Threads
-
- Qt offers many classes and functions for working with threads. Below are
- four different approaches that Qt programmers can use to implement
- multithreaded applications.
-
-
- \section1 QThread: Low-Level API with Optional Event Loops
-
- QThread is the foundation of all thread control in Qt. Each QThread
- instance represents and controls one thread.
-
- QThread can either be instantiated directly or subclassed. Instantiating a
- QThread provides a parallel event loop, allowing QObject slots to be invoked
- in a secondary thread. Subclassing a QThread allows the application to initialize
- the new thread before starting its event loop, or to run parallel code
- without an event loop.
-
- See the \l{QThread}{QThread class reference} and the \l{Threading and
- Concurrent Programming Examples}{threading examples} for demonstrations on
- how to use QThread.
-
-
- \section1 QThreadPool and QRunnable: Reusing Threads
-
- Creating and destroying threads frequently can be expensive. To reduce this
- overhead, existing threads can be reused for new tasks. QThreadPool is a
- collection of reuseable QThreads.
-
- To run code in one of a QThreadPool's threads, reimplement QRunnable::run()
- and instantiate the subclassed QRunnable. Use QThreadPool::start() to put
- the QRunnable in the QThreadPool's run queue. When a thread becomes available,
- the code within QRunnable::run() will execute in that thread.
-
- Each Qt application has a global thread pool, which is accessible through
- QThreadPool::globalInstance(). This global thread pool automatically maintains
- an optimal number of threads based on the number of cores in the CPU. However,
- a separate QThreadPool can be created and managed explicitly.
-
-
- \section1 Qt Concurrent: Using a High-level API
-
- The \l{Qt Concurrent} module provides high-level functions that deal with some
- common parallel computation patterns: map, filter, and reduce. Unlike using
- QThread and QRunnable, these functions never require the use of \l{Synchronizing
- Threads#Low-Level Synchronization Primitives}{low-level threading primitives}
- such as mutexes or semaphores. Instead, they return a QFuture object which can
- be used to retrieve the functions' results when they are ready. QFuture can
- also be used to query computation progress and to pause/resume/cancel the
- computation. For convenience, QFutureWatcher enables interactions with
- \l{QFuture}s via signals and slots.
-
- \l{Qt Concurrent}'s map, filter and reduce algorithms automatically distribute
- computation across all available processor cores, so applications written today
- will continue to scale when deployed later on a system with more cores.
-
- This module also provides the QtConcurrent::run() function, which can run any
- function in another thread. However, QtConcurrent::run() only supports a subset
- of features available to the map, filter and reduce functions. The QFuture
- can be used to retrieve the function's return value and to check if the thread
- is running. However, a call to QtConcurrent::run() uses one thread only, cannot
- be paused/resumed/canceled, and cannot be queried for progress.
-
- See the \l{Qt Concurrent} module documentation for details on the individual functions.
-
-
- \section1 WorkerScript: Threading in QML
-
- The WorkerScript QML type lets JavaScript code run in parallel with the GUI
- thread.
-
- Each WorkerScript instance can have one \c{.js} script attached to it. When
- WorkerScript::sendMessage() is called, the script will run in a separate thread
- (and a separate \l{QQmlContext}{QML context}). When the script finishes
- running, it can send a reply back to the GUI thread which will invoke the
- WorkerScript::onMessage() signal handler.
-
- Using a WorkerScript is similar to using a worker QObject that has been moved
- to another thread. Data is transferred between threads via signals.
-
- See the WorkerScript documentation for details on how to implement the script,
- and for a list of data types that can be passed between threads.
-
-
- \section1 Choosing an Appropriate Approach
-
- As demonstrated above, Qt provides different solutions for developing threaded
- applications. The right solution for a given application depends on the purpose
- of the new thread and the thread's lifetime. Below is a comparison of Qt's
- threading technologies, followed by recommended solutions for some example use cases.
-
- \section2 Comparison of Solutions
-
- \table
- \header
- \li Feature
- \li QThread
- \li QRunnable and QThreadPool
- \li QtConcurrent::run()
- \li Qt Concurrent (Map, Filter, Reduce)
- \li WorkerScript
- \row
- \li API
- \li C++
- \li C++
- \li C++
- \li C++
- \li QML
- \row
- \li Thread priority can be specified
- \li Yes
- \li Yes
- \li
- \li
- \li
- \row
- \li Thread can run an event loop
- \li Yes
- \li
- \li
- \li
- \li
- \row
- \li Thread can receive data updates through signals
- \li Yes (received by a worker QObject)
- \li
- \li
- \li
- \li Yes (received by WorkerScript)
- \row
- \li Thread can be controlled using signals
- \li Yes (received by QThread)
- \li
- \li
- \li Yes (received by QFutureWatcher)
- \li
- \row
- \li Thread can be monitored through a QFuture
- \li
- \li
- \li Partially
- \li Yes
- \li
- \row
- \li Built-in ability to pause/resume/cancel
- \li
- \li
- \li
- \li Yes
- \li
- \endtable
-
-
- \section2 Example Use Cases
-
- \table
- \header
- \li Lifetime of thread
- \li Operation
- \li Solution
- \row
- \li One call
- \li Run a new linear function within another thread, optionally with progress
- updates during the run.
- \li Qt provides different solutions:
- \list
- \li Place the function in a reimplementation of QThread::run() and
- start the QThread. Emit signals to update progress. OR
- \li Place the function in a reimplementation of QRunnable::run() and
- add the QRunnable to a QThreadPool. Write to a \l{Synchronizing
- Threads}{thread-safe variable} to update progress. OR
- \li Run the function using QtConcurrent::run(). Write to a \l{Synchronizing
- Threads}{thread-safe variable} to update progress.
- \endlist
- \row
- \li One call
- \li Run an existing function within another thread and get its return value.
- \li Run the function using QtConcurrent::run(). Have a QFutureWatcher emit
- the \l{QFutureWatcher::}{finished()} signal when the function has
- returned, and call QFutureWatcher::result() to get the function's return
- value.
- \row
- \li One call
- \li Perform an operation on all items of a container, using all available
- cores. For example, producing thumbnails from a list of images.
- \li Use Qt Concurrent's \l{QtConcurrent::}{filter()} function to select
- container elements, and the \l{QtConcurrent::}{map()} function to apply
- an operation to each element. To fold the output into a single result,
- use \l{QtConcurrent::}{filteredReduced()} and
- \l{QtConcurrent::}{mappedReduced()} instead.
- \row
- \li One call/Permanent
- \li Perfrom a long computation in a pure QML application, and update the GUI
- when the results are ready.
- \li Place the computation code in a \c{.js} script and attach it to a
- WorkerScript instance. Call \l{WorkerScript::}{sendMessage()} to start the
- computation in a new thread. Let the script call WorkerScript::sendMessage()
- too, to pass the result back to the GUI thread. Handle the result in
- \l{WorkerScript::}{onMessage} and update the GUI there.
- \row
- \li Permanent
- \li Have an object living in another thread that can perform different
- tasks upon request and/or can receive new data to work with.
- \li Subclass a QObject to create a worker. Instantiate this worker object
- and a QThread. Move the worker to the new thread. Send commands or
- data to the worker object over queued signal-slot connections.
- \row
- \li Permanent
- \li Repeatedly perform an expensive operation in another thread, where the
- thread does not need to receive any signals or events.
- \li Write the infinite loop directly within a reimplementation of QThread::run().
- Start the thread without an event loop. Let the thread emit signals to
- send data back to the GUI thread.
- \endtable
-*/
-
-/*!
- \page threads-synchronizing.html
- \title Synchronizing Threads
-
- \previouspage Multithreading Technologies in Qt
- \contentspage Thread Support in Qt
- \nextpage Reentrancy and Thread-Safety
-
- While the purpose of threads is to allow code to run in parallel,
- there are times where threads must stop and wait for other
- threads. For example, if two threads try to write to the same
- variable simultaneously, the result is undefined. The principle of
- forcing threads to wait for one another is called \e{mutual exclusion}.
- It is a common technique for protecting shared resources such as data.
-
- Qt provides low-level primitives as well as high-level mechanisms
- for synchronizing threads.
-
- \section1 Low-Level Synchronization Primitives
-
- QMutex is the basic class for enforcing mutual exclusion. A thread
- locks a mutex in order to gain access to a shared resource. If a second
- thread tries to lock the mutex while it is already locked, the second
- thread will be put to sleep until the first thread completes its task
- and unlocks the mutex.
-
- QReadWriteLock is similar to QMutex, except that it distinguishes
- between "read" and "write" access. When a piece of data is not being
- written to, it is safe for multiple threads to read from it simultaneously.
- A QMutex forces multiple readers to take turns to read shared data, but a
- QReadWriteLock allows simultaneous reading, thus improving parallelism.
-
- QSemaphore is a generalization of QMutex that protects a certain
- number of identical resources. In contrast, a QMutex protects
- exactly one resource. The \l{Semaphores Example} shows a typical application
- of semaphores: synchronizing access to a circular buffer between a producer
- and a consumer.
-
- QWaitCondition synchronizes threads not by enforcing mutual exclusion but by
- providing a \e{condition variable}. While the other primitives make threads
- wait until a resource is unlocked, QWaitCondition makes threads wait until a
- particular condition has been met. To allow the waiting threads to proceed,
- call \l{QWaitCondition::wakeOne()}{wakeOne()} to wake one randomly
- selected thread or \l{QWaitCondition::wakeAll()}{wakeAll()} to wake them all
- simultaneously. The \l{Wait Conditions Example} shows how to solve the
- producer-consumer problem using QWaitCondition instead of QSemaphore.
-
- \note Qt's synchronization classes rely on the use of properly
- aligned pointers. For instance, you cannot use packed classes with
- MSVC.
-
- These synchronization classes can be used to make a method thread safe.
- However, doing so incurs a performance penalty, which is why most Qt methods
- are not made thread safe.
-
- \section2 Risks
-
- If a thread locks a resource but does not unlock it, the application may
- freeze because the resource will become permanently unavailable to other threads.
- This can happen, for example, if a an exception is thrown and forces the current
- function to return without releasing its lock.
-
- Another similar scenario is a \e{deadlock}. For example, suppose that
- thread A is waiting for thread B to unlock a resource. If thread B is also
- waiting for thread A to unlock a different resource, then both threads will
- end up waiting forever, so the application will freeze.
-
- \section2 Convenience classes
-
- QMutexLocker, QReadLocker and QWriteLocker are convenience classes that make it
- easier to use QMutex and QReadWriteLock. They lock a resource when they are
- constructed, and automatically unlock it when they are destroyed. They are
- designed to simplify code that use QMutex and QReadWriteLocker, thus reducing
- the chances that a resource becomes permanently locked by accident.
-
- \section1 High-Level Event Queues
-
- Qt's \l{The Event System}{event system} is very useful for inter-thread
- communication. Every thread may have its own event loop. To call a slot (or
- any \l{Q_INVOKABLE}{invokable} method) in another thread, place that call in
- the target thread's event loop. This lets the target thread finish its current
- task before the slot starts running, while the original thread continues
- running in parallel.
-
- To place an invocation in an event loop, make a queued \l{Signals & Slots}
- {signal-slot} connection. Whenever the signal is emitted, its arguments will
- be recorded by the event system. The thread that the signal receiver
- \l{QObject#Thread Affinity}{lives in} will then run the slot. Alternatively,
- call QMetaObject::invokeMethod() to achieve the same effect without signals.
- In both cases, a \l{Qt::QueuedConnection}{queued connection} must be used
- because a \l{Qt::DirectConnection}{direct connection} bypasses the event
- system and runs the method immediately in the current thread.
-
- There is no risk of deadlocks when using the event system for thread
- synchronization, unlike using low-level primitives. However, the event system
- does not enforce mutual exclusion. If invokable methods access shared data,
- they must still be protected with low-level primitives.
-
- Having said that, Qt's event system, along with \l{Implicit Sharing}{implicitly
- shared} data structures, offers an alternative to traditional thread locking.
- If signals and slots are used exclusively and no variables are shared between
- threads, a multithreaded program can do without low-level primitives altogether.
-
- \sa QThread::exec(), {Threads and QObjects}
-*/
-
-/*!
- \page threads-reentrancy.html
- \title Reentrancy and Thread-Safety
-
- \keyword reentrant
- \keyword thread-safe
-
- \previouspage Synchronizing Threads
- \contentspage Thread Support in Qt
- \nextpage Threads and QObjects
-
- Throughout the documentation, the terms \e{reentrant} and
- \e{thread-safe} are used to mark classes and functions to indicate
- how they can be used in multithread applications:
-
- \list
- \li A \e thread-safe function can be called simultaneously from
- multiple threads, even when the invocations use shared data,
- because all references to the shared data are serialized.
- \li A \e reentrant function can also be called simultaneously from
- multiple threads, but only if each invocation uses its own data.
- \endlist
-
- Hence, a \e{thread-safe} function is always \e{reentrant}, but a
- \e{reentrant} function is not always \e{thread-safe}.
-
- By extension, a class is said to be \e{reentrant} if its member
- functions can be called safely from multiple threads, as long as
- each thread uses a \e{different} instance of the class. The class
- is \e{thread-safe} if its member functions can be called safely
- from multiple threads, even if all the threads use the \e{same}
- instance of the class.
-
- \note Qt classes are only documented as \e{thread-safe} if they
- are intended to be used by multiple threads. If a function is not
- marked as thread-safe or reentrant, it should not be used from
- different threads. If a class is not marked as thread-safe or
- reentrant then a specific instance of that class should not be
- accessed from different threads.
-
- \section1 Reentrancy
-
- C++ classes are often reentrant, simply because they only access
- their own member data. Any thread can call a member function on an
- instance of a reentrant class, as long as no other thread can call
- a member function on the \e{same} instance of the class at the
- same time. For example, the \c Counter class below is reentrant:
-
- \snippet threads/threads.cpp 3
- \snippet threads/threads.cpp 4
-
- The class isn't thread-safe, because if multiple threads try to
- modify the data member \c n, the result is undefined. This is
- because the \c ++ and \c -- operators aren't always atomic.
- Indeed, they usually expand to three machine instructions:
-
- \list 1
- \li Load the variable's value in a register.
- \li Increment or decrement the register's value.
- \li Store the register's value back into main memory.
- \endlist
-
- If thread A and thread B load the variable's old value
- simultaneously, increment their register, and store it back, they
- end up overwriting each other, and the variable is incremented
- only once!
-
- \section1 Thread-Safety
-
- Clearly, the access must be serialized: Thread A must perform
- steps 1, 2, 3 without interruption (atomically) before thread B
- can perform the same steps; or vice versa. An easy way to make
- the class thread-safe is to protect all access to the data
- members with a QMutex:
-
- \snippet threads/threads.cpp 5
- \snippet threads/threads.cpp 6
-
- The QMutexLocker class automatically locks the mutex in its
- constructor and unlocks it when the destructor is invoked, at the
- end of the function. Locking the mutex ensures that access from
- different threads will be serialized. The \c mutex data member is
- declared with the \c mutable qualifier because we need to lock
- and unlock the mutex in \c value(), which is a const function.
-
- \section1 Notes on Qt Classes
-
- Many Qt classes are \e{reentrant}, but they are not made
- \e{thread-safe}, because making them thread-safe would incur the
- extra overhead of repeatedly locking and unlocking a QMutex. For
- example, QString is reentrant but not thread-safe. You can safely
- access \e{different} instances of QString from multiple threads
- simultaneously, but you can't safely access the \e{same} instance
- of QString from multiple threads simultaneously (unless you
- protect the accesses yourself with a QMutex).
-
- Some Qt classes and functions are thread-safe. These are mainly
- the thread-related classes (e.g. QMutex) and fundamental functions
- (e.g. QCoreApplication::postEvent()).
-
- \note Terminology in the multithreading domain isn't entirely
- standardized. POSIX uses definitions of reentrant and thread-safe
- that are somewhat different for its C APIs. When using other
- object-oriented C++ class libraries with Qt, be sure the
- definitions are understood.
-*/
-
-/*!
- \page threads-qobject.html
- \title Threads and QObjects
-
- \previouspage Reentrancy and Thread Safety
- \contentspage Thread Support in Qt
- \nextpage Thread-Support in Qt Modules
-
- QThread inherits QObject. It emits signals to indicate that the
- thread started or finished executing, and provides a few slots as
- well.
-
- More interesting is that \l{QObject}s can be used in multiple
- threads, emit signals that invoke slots in other threads, and
- post events to objects that "live" in other threads. This is
- possible because each thread is allowed to have its own event
- loop.
-
- \section1 QObject Reentrancy
-
- QObject is reentrant. Most of its non-GUI subclasses, such as
- QTimer, QTcpSocket, QUdpSocket and QProcess, are also
- reentrant, making it possible to use these classes from multiple
- threads simultaneously. Note that these classes are designed to be
- created and used from within a single thread; creating an object
- in one thread and calling its functions from another thread is not
- guaranteed to work. There are three constraints to be aware of:
-
- \list
- \li \e{The child of a QObject must always be created in the thread
- where the parent was created.} This implies, among other
- things, that you should never pass the QThread object (\c
- this) as the parent of an object created in the thread (since
- the QThread object itself was created in another thread).
-
- \li \e{Event driven objects may only be used in a single thread.}
- Specifically, this applies to the \l{timers.html}{timer
- mechanism} and the \l{QtNetwork}{network module}. For example,
- you cannot start a timer or connect a socket in a thread that
- is not the \l{QObject::thread()}{object's thread}.
-
- \li \e{You must ensure that all objects created in a thread are
- deleted before you delete the QThread.} This can be done
- easily by creating the objects on the stack in your
- \l{QThread::run()}{run()} implementation.
- \endlist
-
- Although QObject is reentrant, the GUI classes, notably QWidget
- and all its subclasses, are not reentrant. They can only be used
- from the main thread. As noted earlier, QCoreApplication::exec()
- must also be called from that thread.
-
- In practice, the impossibility of using GUI classes in other
- threads than the main thread can easily be worked around by
- putting time-consuming operations in a separate worker thread and
- displaying the results on screen in the main thread when the
- worker thread is finished. This is the approach used for
- implementing the \l{threads/mandelbrot}{Mandelbrot} and
- the \l{network/blockingfortuneclient}{Blocking Fortune Client}
- example.
-
- \section1 Per-Thread Event Loop
-
- Each thread can have its own event loop. The initial thread
- starts its event loops using QCoreApplication::exec(); other
- threads can start an event loop using QThread::exec(). Like
- QCoreApplication, QThread provides an
- \l{QThread::exit()}{exit(int)} function and a
- \l{QThread::quit()}{quit()} slot.
-
- An event loop in a thread makes it possible for the thread to use
- certain non-GUI Qt classes that require the presence of an event
- loop (such as QTimer, QTcpSocket, and QProcess). It also makes it
- possible to connect signals from any threads to slots of a
- specific thread. This is explained in more detail in the
- \l{Signals and Slots Across Threads} section below.
-
- \image threadsandobjects.png Threads, objects, and event loops
-
- A QObject instance is said to \e live in the thread in which it
- is created. Events to that object are dispatched by that thread's
- event loop. The thread in which a QObject lives is available using
- QObject::thread().
-
- Note that for QObjects that are created before QApplication,
- QObject::thread() returns zero. This means that the main thread
- will only handle posted events for these objects; other event
- processing is not done at all for objects with no thread. Use the
- QObject::moveToThread() function to change the thread affinity for
- an object and its children (the object cannot be moved if it has a
- parent).
-
- Calling \c delete on a QObject from a thread other than the one
- that \e owns the object (or accessing the object in other ways) is
- unsafe, unless you guarantee that the object isn't processing
- events at that moment. Use QObject::deleteLater() instead, and a
- \l{QEvent::DeferredDelete}{DeferredDelete} event will be posted,
- which the event loop of the object's thread will eventually pick
- up. By default, the thread that \e owns a QObject is the thread
- that \e creates the QObject, but not after QObject::moveToThread()
- has been called.
-
- If no event loop is running, events won't be delivered to the
- object. For example, if you create a QTimer object in a thread but
- never call \l{QThread::exec()}{exec()}, the QTimer will never emit
- its \l{QTimer::timeout()}{timeout()} signal. Calling
- \l{QObject::deleteLater()}{deleteLater()} won't work
- either. (These restrictions apply to the main thread as well.)
-
- You can manually post events to any object in any thread at any
- time using the thread-safe function
- QCoreApplication::postEvent(). The events will automatically be
- dispatched by the event loop of the thread where the object was
- created.
-
- Event filters are supported in all threads, with the restriction
- that the monitoring object must live in the same thread as the
- monitored object. Similarly, QCoreApplication::sendEvent()
- (unlike \l{QCoreApplication::postEvent()}{postEvent()}) can only
- be used to dispatch events to objects living in the thread from
- which the function is called.
-
- \section1 Accessing QObject Subclasses from Other Threads
-
- QObject and all of its subclasses are not thread-safe. This
- includes the entire event delivery system. It is important to keep
- in mind that the event loop may be delivering events to your
- QObject subclass while you are accessing the object from another
- thread.
-
- If you are calling a function on an QObject subclass that doesn't
- live in the current thread and the object might receive events,
- you must protect all access to your QObject subclass's internal
- data with a mutex; otherwise, you may experience crashes or other
- undesired behavior.
-
- Like other objects, QThread objects live in the thread where the
- object was created -- \e not in the thread that is created when
- QThread::run() is called. It is generally unsafe to provide slots
- in your QThread subclass, unless you protect the member variables
- with a mutex.
-
- On the other hand, you can safely emit signals from your
- QThread::run() implementation, because signal emission is
- thread-safe.
-
- \section1 Signals and Slots Across Threads
-
- Qt supports these signal-slot connection types:
-
- \list
-
- \li \l{Qt::AutoConnection}{Auto Connection} (default) If the signal is
- emitted in the thread which the receiving object has affinity then
- the behavior is the same as the Direct Connection. Otherwise,
- the behavior is the same as the Queued Connection."
-
- \li \l{Qt::DirectConnection}{Direct Connection} The slot is invoked
- immediately, when the signal is emitted. The slot is executed
- in the emitter's thread, which is not necessarily the
- receiver's thread.
-
- \li \l{Qt::QueuedConnection}{Queued Connection} The slot is invoked
- when control returns to the event loop of the receiver's
- thread. The slot is executed in the receiver's thread.
-
- \li \l{Qt::BlockingQueuedConnection}{Blocking Queued Connection}
- The slot is invoked as for the Queued Connection, except the
- current thread blocks until the slot returns. \note Using this
- type to connect objects in the same thread will cause deadlock.
-
- \li \l{Qt::UniqueConnection}{Unique Connection} The behavior is the
- same as the Auto Connection, but the connection is made only if
- it does not duplicate an existing connection. i.e., if the same
- signal is already connected to the same slot for the same pair
- of objects, then the connection is not made and connect()
- returns \c false.
-
- \endlist
-
- The connection type can be specified by passing an additional
- argument to \l{QObject::connect()}{connect()}. Be aware that
- using direct connections when the sender and receiver live in
- different threads is unsafe if an event loop is running in the
- receiver's thread, for the same reason that calling any function
- on an object living in another thread is unsafe.
-
- QObject::connect() itself is thread-safe.
-
- The \l{threads/mandelbrot}{Mandelbrot} example uses a queued
- connection to communicate between a worker thread and the main
- thread. To avoid freezing the main thread's event loop (and, as a
- consequence, the application's user interface), all the
- Mandelbrot fractal computation is done in a separate worker
- thread. The thread emits a signal when it is done rendering the
- fractal.
-
- Similarly, the \l{network/blockingfortuneclient}{Blocking Fortune
- Client} example uses a separate thread for communicating with
- a TCP server asynchronously.
-*/
-
-/*!
- \page threads-modules.html
- \title Thread-Support in Qt Modules
-
- \previouspage Threads and QObjects
- \contentspage Thread Support in Qt
-
- \section1 Threads and the SQL Module
-
- A connection can only be used from within the thread that created it.
- Moving connections between threads or creating queries from a different
- thread is not supported.
-
- In addition, the third party libraries used by the QSqlDrivers can impose
- further restrictions on using the SQL Module in a multithreaded program.
- Consult the manual of your database client for more information
-
- \section1 Painting in Threads
-
- QPainter can be used in a thread to paint onto QImage, QPrinter, and
- QPicture paint devices. Painting onto QPixmaps and QWidgets is \e not
- supported. On Mac OS X the automatic progress dialog will not be
- displayed if you are printing from outside the GUI thread.
-
- Any number of threads can paint at any given time, however only
- one thread at a time can paint on a given paint device. In other
- words, two threads can paint at the same time if each paints onto
- separate QImages, but the two threads cannot paint onto the same
- QImage at the same time.
-
- \section1 Threads and Rich Text Processing
-
- The QTextDocument, QTextCursor, and \l{richtext.html}{all related classes} are reentrant.
-
- Note that a QTextDocument instance created in the GUI thread may
- contain QPixmap image resources. Use QTextDocument::clone() to
- create a copy of the document, and pass the copy to another thread for
- further processing (such as printing).
-
- \section1 Threads and the SVG module
-
- The QSvgGenerator and QSvgRenderer classes in the QtSvg module
- are reentrant.
-
- \section1 Threads and Implicitly Shared Classes
-
- Qt uses an optimization called \l{implicit sharing} for many of
- its value class, notably QImage and QString. Beginning with Qt 4,
- implicit shared classes can safely be copied across threads, like
- any other value classes. They are fully
- \l{Reentrancy and Thread-Safety}{reentrant}. The implicit sharing
- is really \e implicit.
-
- In many people's minds, implicit sharing and multithreading are
- incompatible concepts, because of the way the reference counting
- is typically done. Qt, however, uses atomic reference counting to
- ensure the integrity of the shared data, avoiding potential
- corruption of the reference counter.
-
- Note that atomic reference counting does not guarantee
- \l{Reentrancy and Thread-Safety}{thread-safety}. Proper locking should be used
- when sharing an instance of an implicitly shared class between
- threads. This is the same requirement placed on all
- \l{Reentrancy and Thread-Safety}{reentrant} classes, shared or not. Atomic reference
- counting does, however, guarantee that a thread working on its
- own, local instance of an implicitly shared class is safe. We
- recommend using \l{Signals and Slots Across Threads}{signals and
- slots} to pass data between threads, as this can be done without
- the need for any explicit locking.
-
- To sum it up, implicitly shared classes in Qt 4 are really \e
- implicitly shared. Even in multithreaded applications, you can
- safely use them as if they were plain, non-shared, reentrant
- value-based classes.
-*/
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index a0842a946d..fd031469f6 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -31,6 +31,7 @@ INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global
# configure creates these, not syncqt, so we need to manually inject them
qconfig_h_files = \
+ $$OUT_PWD/global/qfeatures.h \
$$OUT_PWD/global/qconfig.h \
$$QT_BUILD_TREE/include/QtCore/QtConfig
targ_headers.files += $$qconfig_h_files
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 102a6487ee..2b957782e8 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -470,6 +470,7 @@
* N2659 Q_COMPILER_THREAD_LOCAL
* N2765 Q_COMPILER_UDL
* N2442 Q_COMPILER_UNICODE_STRINGS
+ * N2640 Q_COMPILER_UNIFORM_INIT
* N2544 Q_COMPILER_UNRESTRICTED_UNIONS
* N1653 Q_COMPILER_VARIADIC_MACROS
* N2242 N2555 Q_COMPILER_VARIADIC_TEMPLATES
@@ -507,6 +508,7 @@
// constexpr support is only partial
//# define Q_COMPILER_CONSTEXPR
# define Q_COMPILER_INITIALIZER_LISTS
+# define Q_COMPILER_UNIFORM_INIT
# define Q_COMPILER_NOEXCEPT
# endif
# if __INTEL_COMPILER >= 1400
@@ -581,6 +583,7 @@
# endif
# if __has_feature(cxx_generalized_initializers)
# define Q_COMPILER_INITIALIZER_LISTS
+# define Q_COMPILER_UNIFORM_INIT /* both covered by this feature macro, according to docs */
# endif
# if __has_feature(cxx_lambdas)
# define Q_COMPILER_LAMBDA
@@ -653,6 +656,7 @@
# define Q_COMPILER_DELETE_MEMBERS
# define Q_COMPILER_EXTERN_TEMPLATES
# define Q_COMPILER_INITIALIZER_LISTS
+# define Q_COMPILER_UNIFORM_INIT
# define Q_COMPILER_UNICODE_STRINGS
# define Q_COMPILER_VARIADIC_TEMPLATES
# endif
@@ -726,8 +730,9 @@
# define Q_COMPILER_DECLTYPE
# define Q_COMPILER_RVALUE_REFS
# define Q_COMPILER_STATIC_ASSERT
-// MSVC has std::initilizer_list, but does not support the braces initialization
+// MSVC's library has std::initilizer_list, but the compiler does not support the braces initialization
//# define Q_COMPILER_INITIALIZER_LISTS
+//# define Q_COMPILER_UNIFORM_INIT
# endif
# if _MSC_VER >= 1700
/* C++11 features supported in VC11 = VC2012: */
@@ -738,6 +743,20 @@
# define Q_COMPILER_CLASS_ENUM
# define Q_COMPILER_ATOMICS
# endif /* VC 11 */
+# if _MSC_VER >= 1800
+ /* C++11 features in VC12 = VC2013 */
+# define Q_COMPILER_DEFAULT_MEMBERS
+# define Q_COMPILER_DELETE_MEMBERS
+# define Q_COMPILER_DELEGATING_CONSTRUCTORS
+# define Q_COMPILER_EXPLICIT_CONVERSIONS
+# define Q_COMPILER_NONSTATIC_MEMBER_INIT
+# define Q_COMPILER_INITIALIZER_LISTS
+// implemented in principle, but has a bug that makes it unusable: http://connect.microsoft.com/VisualStudio/feedback/details/802058/c-11-unified-initialization-fails-with-c-style-arrays
+// #define Q_COMPILER_UNIFORM_INIT
+# define Q_COMPILER_RAW_STRINGS
+# define Q_COMPILER_TEMPLATE_ALIAS
+# define Q_COMPILER_VARIADIC_TEMPLATES
+# endif /* VC 12 */
#endif /* Q_CC_MSVC */
#ifdef __cplusplus
diff --git a/src/corelib/global/qconfig-large.h b/src/corelib/global/qconfig-large.h
index 584be07067..0c1fcbf7da 100644
--- a/src/corelib/global/qconfig-large.h
+++ b/src/corelib/global/qconfig-large.h
@@ -56,11 +56,6 @@
# define QT_NO_PROGRESSDIALOG
#endif
-/* Fonts */
-#ifndef QT_NO_QWS_QPF
-# define QT_NO_QWS_QPF
-#endif
-
/* Images */
#ifndef QT_NO_IMAGEFORMAT_BMP
# define QT_NO_IMAGEFORMAT_BMP
@@ -76,9 +71,6 @@
#ifndef QT_NO_TRANSLATION
# define QT_NO_TRANSLATION
#endif
-#ifndef QT_NO_TRANSLATION_UTF8
-# define QT_NO_TRANSLATION_UTF8
-#endif
/* ItemViews */
#ifndef QT_NO_TABLEVIEW
@@ -101,23 +93,14 @@
#ifndef QT_NO_PROPERTIES
# define QT_NO_PROPERTIES
#endif
-#ifndef QT_NO_SOUND
-# define QT_NO_SOUND
-#endif
/* Networking */
-#ifndef QT_NO_HOSTINFO
-# define QT_NO_HOSTINFO
-#endif
#ifndef QT_NO_HTTP
# define QT_NO_HTTP
#endif
#ifndef QT_NO_UDPSOCKET
# define QT_NO_UDPSOCKET
#endif
-#ifndef QT_NO_URLINFO
-# define QT_NO_URLINFO
-#endif
#ifndef QT_NO_FTP
# define QT_NO_FTP
#endif
@@ -136,18 +119,7 @@
# define QT_NO_CUPS
#endif
-/* Qt for Embedded Linux */
-#ifndef QT_NO_QWS_SOUNDSERVER
-# define QT_NO_QWS_SOUNDSERVER
-#endif
-
/* Styles */
-#ifndef QT_NO_STYLE_MOTIF
-# define QT_NO_STYLE_MOTIF
-#endif
-#ifndef QT_NO_STYLE_CDE
-# define QT_NO_STYLE_CDE
-#endif
#ifndef QT_NO_STYLE_STYLESHEET
# define QT_NO_STYLE_STYLESHEET
#endif
diff --git a/src/corelib/global/qconfig-medium.h b/src/corelib/global/qconfig-medium.h
index 132c8ce45c..e5ab33faed 100644
--- a/src/corelib/global/qconfig-medium.h
+++ b/src/corelib/global/qconfig-medium.h
@@ -58,14 +58,6 @@
#ifndef QT_NO_PROGRESSDIALOG
# define QT_NO_PROGRESSDIALOG
#endif
-#ifndef QT_NO_TABDIALOG
-# define QT_NO_TABDIALOG
-#endif
-
-/* Fonts */
-#ifndef QT_NO_QWS_QPF
-# define QT_NO_QWS_QPF
-#endif
/* Images */
#ifndef QT_NO_IMAGEFORMAT_BMP
@@ -91,9 +83,6 @@
#ifndef QT_NO_TRANSLATION
# define QT_NO_TRANSLATION
#endif
-#ifndef QT_NO_TRANSLATION_UTF8
-# define QT_NO_TRANSLATION_UTF8
-#endif
/* ItemViews */
#ifndef QT_NO_TABLEVIEW
@@ -125,20 +114,11 @@
#ifndef QT_NO_SHORTCUT
# define QT_NO_SHORTCUT
#endif
-#ifndef QT_NO_SOUND
-# define QT_NO_SOUND
-#endif
#ifndef QT_NO_WHEELEVENT
# define QT_NO_WHEELEVENT
#endif
/* Networking */
-#ifndef QT_NO_COP
-# define QT_NO_COP
-#endif
-#ifndef QT_NO_HOSTINFO
-# define QT_NO_HOSTINFO
-#endif
#ifndef QT_NO_HTTP
# define QT_NO_HTTP
#endif
@@ -151,9 +131,6 @@
#ifndef QT_NO_UDPSOCKET
# define QT_NO_UDPSOCKET
#endif
-#ifndef QT_NO_URLINFO
-# define QT_NO_URLINFO
-#endif
#ifndef QT_NO_FTP
# define QT_NO_FTP
#endif
@@ -172,24 +149,7 @@
# define QT_NO_CUPS
#endif
-/* Qt for Embedded Linux */
-#ifndef QT_NO_QWSEMBEDWIDGET
-# define QT_NO_QWSEMBEDWIDGET
-#endif
-#ifndef QT_NO_QWS_SOUNDSERVER
-# define QT_NO_QWS_SOUNDSERVER
-#endif
-#ifndef QT_NO_QWS_PROPERTIES
-# define QT_NO_QWS_PROPERTIES
-#endif
-
/* Styles */
-#ifndef QT_NO_STYLE_MOTIF
-# define QT_NO_STYLE_MOTIF
-#endif
-#ifndef QT_NO_STYLE_CDE
-# define QT_NO_STYLE_CDE
-#endif
#ifndef QT_NO_STYLE_STYLESHEET
# define QT_NO_STYLE_STYLESHEET
#endif
@@ -281,8 +241,3 @@
#ifndef QT_NO_TREEWIDGET
# define QT_NO_TREEWIDGET
#endif
-
-/* Windows */
-#ifndef QT_NO_WIN_ACTIVEQT
-# define QT_NO_WIN_ACTIVEQT
-#endif
diff --git a/src/corelib/global/qconfig-minimal.h b/src/corelib/global/qconfig-minimal.h
index cc5ac9987c..b27f3271c1 100644
--- a/src/corelib/global/qconfig-minimal.h
+++ b/src/corelib/global/qconfig-minimal.h
@@ -75,9 +75,6 @@
#ifndef QT_NO_PROGRESSDIALOG
# define QT_NO_PROGRESSDIALOG
#endif
-#ifndef QT_NO_TABDIALOG
-# define QT_NO_TABDIALOG
-#endif
#ifndef QT_NO_WIZARD
# define QT_NO_WIZARD
#endif
@@ -109,9 +106,6 @@
#ifndef QT_NO_FREETYPE
# define QT_NO_FREETYPE
#endif
-#ifndef QT_NO_QWS_QPF2
-# define QT_NO_QWS_QPF2
-#endif
/* Images */
#ifndef QT_NO_IMAGEFORMATPLUGIN
@@ -146,9 +140,6 @@
#ifndef QT_NO_BIG_CODECS
# define QT_NO_BIG_CODECS
#endif
-#ifndef QT_NO_QWS_INPUTMETHODS
-# define QT_NO_QWS_INPUTMETHODS
-#endif
#ifndef QT_NO_TEXTCODEC
# define QT_NO_TEXTCODEC
#endif
@@ -158,9 +149,6 @@
#ifndef QT_NO_TRANSLATION
# define QT_NO_TRANSLATION
#endif
-#ifndef QT_NO_TRANSLATION_UTF8
-# define QT_NO_TRANSLATION_UTF8
-#endif
/* ItemViews */
#ifndef QT_NO_ITEMVIEWS
@@ -228,9 +216,6 @@
#ifndef QT_NO_SHORTCUT
# define QT_NO_SHORTCUT
#endif
-#ifndef QT_NO_SOUND
-# define QT_NO_SOUND
-#endif
#ifndef QT_NO_SYSTEMSEMAPHORE
# define QT_NO_SYSTEMSEMAPHORE
#endif
@@ -257,12 +242,6 @@
#endif
/* Networking */
-#ifndef QT_NO_COP
-# define QT_NO_COP
-#endif
-#ifndef QT_NO_HOSTINFO
-# define QT_NO_HOSTINFO
-#endif
#ifndef QT_NO_HTTP
# define QT_NO_HTTP
#endif
@@ -275,9 +254,6 @@
#ifndef QT_NO_UDPSOCKET
# define QT_NO_UDPSOCKET
#endif
-#ifndef QT_NO_URLINFO
-# define QT_NO_URLINFO
-#endif
#ifndef QT_NO_FTP
# define QT_NO_FTP
#endif
@@ -286,12 +262,6 @@
#ifndef QT_NO_COLORNAMES
# define QT_NO_COLORNAMES
#endif
-#ifndef QT_NO_DIRECTPAINTER
-# define QT_NO_DIRECTPAINTER
-#endif
-#ifndef QT_NO_PAINTONSCREEN
-# define QT_NO_PAINTONSCREEN
-#endif
#ifndef QT_NO_PAINT_DEBUG
# define QT_NO_PAINT_DEBUG
#endif
@@ -305,73 +275,6 @@
# define QT_NO_CUPS
#endif
-/* Qt for Embedded Linux */
-#ifndef QT_NO_QWSEMBEDWIDGET
-# define QT_NO_QWSEMBEDWIDGET
-#endif
-#ifndef QT_NO_QWS_ALPHA_CURSOR
-# define QT_NO_QWS_ALPHA_CURSOR
-#endif
-#ifndef QT_NO_QWS_CURSOR
-# define QT_NO_QWS_CURSOR
-#endif
-#ifndef QT_NO_QWS_DECORATION_DEFAULT
-# define QT_NO_QWS_DECORATION_DEFAULT
-#endif
-#ifndef QT_NO_QWS_DECORATION_STYLED
-# define QT_NO_QWS_DECORATION_STYLED
-#endif
-#ifndef QT_NO_QWS_DECORATION_WINDOWS
-# define QT_NO_QWS_DECORATION_WINDOWS
-#endif
-#ifndef QT_NO_QWS_MANAGER
-# define QT_NO_QWS_MANAGER
-#endif
-#ifndef QT_NO_QWS_KEYBOARD
-# define QT_NO_QWS_KEYBOARD
-#endif
-#ifndef QT_NO_QWS_MOUSE
-# define QT_NO_QWS_MOUSE
-#endif
-#ifndef QT_NO_QWS_MOUSE_AUTO
-# define QT_NO_QWS_MOUSE_AUTO
-#endif
-#ifndef QT_NO_QWS_MOUSE_MANUAL
-# define QT_NO_QWS_MOUSE_MANUAL
-#endif
-#ifndef QT_NO_QWS_MULTIPROCESS
-# define QT_NO_QWS_MULTIPROCESS
-#endif
-#ifndef QT_NO_QWS_SOUNDSERVER
-# define QT_NO_QWS_SOUNDSERVER
-#endif
-#ifndef QT_NO_QWS_PROPERTIES
-# define QT_NO_QWS_PROPERTIES
-#endif
-#ifndef QT_NO_QWS_PROXYSCREEN
-# define QT_NO_QWS_PROXYSCREEN
-#endif
-#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
-# define QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
-#endif
-
-/* SVG */
-#ifndef QT_NO_SVG
-# define QT_NO_SVG
-#endif
-#ifndef QT_NO_GRAPHICSSVGITEM
-# define QT_NO_GRAPHICSSVGITEM
-#endif
-#ifndef QT_NO_SVGGENERATOR
-# define QT_NO_SVGGENERATOR
-#endif
-#ifndef QT_NO_SVGRENDERER
-# define QT_NO_SVGRENDERER
-#endif
-#ifndef QT_NO_SVGWIDGET
-# define QT_NO_SVGWIDGET
-#endif
-
/* Styles */
#ifndef QT_NO_STYLE_FUSION
# define QT_NO_STYLE_FUSION
@@ -402,9 +305,6 @@
#ifndef QT_NO_DESKTOPSERVICES
# define QT_NO_DESKTOPSERVICES
#endif
-#ifndef QT_NO_SCRIPT
-# define QT_NO_SCRIPT
-#endif
#ifndef QT_NO_SYSTEMTRAYICON
# define QT_NO_SYSTEMTRAYICON
#endif
@@ -485,9 +385,6 @@
#ifndef QT_NO_SPLITTER
# define QT_NO_SPLITTER
#endif
-#ifndef QT_NO_SIGNALMAPPER
-# define QT_NO_SIGNALMAPPER
-#endif
#ifndef QT_NO_SIZEGRIP
# define QT_NO_SIZEGRIP
#endif
@@ -563,8 +460,3 @@
#ifndef QT_NO_VALIDATOR
# define QT_NO_VALIDATOR
#endif
-
-/* Windows */
-#ifndef QT_NO_WIN_ACTIVEQT
-# define QT_NO_WIN_ACTIVEQT
-#endif
diff --git a/src/corelib/global/qconfig-nacl.h b/src/corelib/global/qconfig-nacl.h
index c2854b26c3..22dd56e772 100644
--- a/src/corelib/global/qconfig-nacl.h
+++ b/src/corelib/global/qconfig-nacl.h
@@ -72,9 +72,6 @@
#ifndef QT_NO_FILESYSTEMWATCHER
# define QT_NO_FILESYSTEMWATCHER
#endif
-#ifndef QT_NO_FSFILEENGINE
-# define QT_NO_FSFILEENGINE
-#endif
#ifndef QT_NO_FILESYSTEMMODEL
# define QT_NO_FILESYSTEMMODEL
#endif
@@ -94,11 +91,6 @@
# define QT_NO_LIBRARY
#endif
-/* Fonts */
-#ifndef QT_NO_QWS_QPF2
-# define QT_NO_QWS_QPF2
-#endif
-
/* Images */
#ifndef QT_NO_IMAGEFORMATPLUGIN
# define QT_NO_IMAGEFORMATPLUGIN
@@ -114,9 +106,6 @@
#ifndef QT_NO_BIG_CODECS
# define QT_NO_BIG_CODECS
#endif
-#ifndef QT_NO_QWS_INPUTMETHODS
-# define QT_NO_QWS_INPUTMETHODS
-#endif
#ifndef QT_NO_TEXTCODEC
# define QT_NO_TEXTCODEC
#endif
@@ -126,9 +115,6 @@
#ifndef QT_NO_TRANSLATION
# define QT_NO_TRANSLATION
#endif
-#ifndef QT_NO_TRANSLATION_UTF8
-# define QT_NO_TRANSLATION_UTF8
-#endif
/* ItemViews */
@@ -158,9 +144,6 @@
#ifndef QT_NO_SHAREDMEMORY
# define QT_NO_SHAREDMEMORY
#endif
-#ifndef QT_NO_SOUND
-# define QT_NO_SOUND
-#endif
#ifndef QT_NO_SYSTEMLOCALE
# define QT_NO_SYSTEMSEMAPHORE
#endif
@@ -187,12 +170,6 @@
#endif
/* Networking */
-#ifndef QT_NO_COP
-# define QT_NO_COP
-#endif
-#ifndef QT_NO_HOSTINFO
-# define QT_NO_HOSTINFO
-#endif
#ifndef QT_NO_HTTP
# define QT_NO_HTTP
#endif
@@ -205,9 +182,6 @@
#ifndef QT_NO_UDPSOCKET
# define QT_NO_UDPSOCKET
#endif
-#ifndef QT_NO_URLINFO
-# define QT_NO_URLINFO
-#endif
#ifndef QT_NO_FTP
# define QT_NO_FTP
#endif
@@ -216,12 +190,6 @@
#ifndef QT_NO_COLORNAMES
# define QT_NO_COLORNAMES
#endif
-#ifndef QT_NO_DIRECTPAINTER
-# define QT_NO_DIRECTPAINTER
-#endif
-#ifndef QT_NO_PAINTONSCREEN
-# define QT_NO_PAINTONSCREEN
-#endif
#ifndef QT_NO_PAINT_DEBUG
# define QT_NO_PAINT_DEBUG
#endif
@@ -235,92 +203,7 @@
# define QT_NO_CUPS
#endif
-/* Qt for Embedded Linux */
-#ifndef QT_NO_QWSEMBEDWIDGET
-# define QT_NO_QWSEMBEDWIDGET
-#endif
-#ifndef QT_NO_QWS_ALPHA_CURSOR
-# define QT_NO_QWS_ALPHA_CURSOR
-#endif
-#ifndef QT_NO_QWS_CURSOR
-# define QT_NO_QWS_CURSOR
-#endif
-#ifndef QT_NO_QWS_DECORATION_DEFAULT
-# define QT_NO_QWS_DECORATION_DEFAULT
-#endif
-#ifndef QT_NO_QWS_DECORATION_STYLED
-# define QT_NO_QWS_DECORATION_STYLED
-#endif
-#ifndef QT_NO_QWS_DECORATION_WINDOWS
-# define QT_NO_QWS_DECORATION_WINDOWS
-#endif
-#ifndef QT_NO_QWS_MANAGER
-# define QT_NO_QWS_MANAGER
-#endif
-#ifndef QT_NO_QWS_KEYBOARD
-# define QT_NO_QWS_KEYBOARD
-#endif
-#ifndef QT_NO_QWS_MOUSE
-# define QT_NO_QWS_MOUSE
-#endif
-#ifndef QT_NO_QWS_MOUSE_AUTO
-# define QT_NO_QWS_MOUSE_AUTO
-#endif
-#ifndef QT_NO_QWS_MOUSE_MANUAL
-# define QT_NO_QWS_MOUSE_MANUAL
-#endif
-#ifndef QT_NO_QWS_MULTIPROCESS
-# define QT_NO_QWS_MULTIPROCESS
-#endif
-#ifndef QT_NO_QWS_SOUNDSERVER
-# define QT_NO_QWS_SOUNDSERVER
-#endif
-#ifndef QT_NO_QWS_PROPERTIES
-# define QT_NO_QWS_PROPERTIES
-#endif
-#ifndef QT_NO_QWS_PROXYSCREEN
-# define QT_NO_QWS_PROXYSCREEN
-#endif
-#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
-# define QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
-#endif
-#ifndef QT_NO_QWS_LINUXFB
-# define QT_NO_QWS_LINUXFB
-#endif
-#ifndef QT_NO_QWS_MOUSE_PC
-# define QT_NO_QWS_MOUSE_PC
-#endif
-#ifndef QT_NO_QWS_MOUSE_LINUXTP
-# define QT_NO_QWS_MOUSE_LINUXTP
-#endif
-#ifndef QT_NO_QWS_QPF
-# define QT_NO_QWS_QPF
-#endif
-
-/* SVG */
-#ifndef QT_NO_SVG
-# define QT_NO_SVG
-#endif
-#ifndef QT_NO_GRAPHICSSVGITEM
-# define QT_NO_GRAPHICSSVGITEM
-#endif
-#ifndef QT_NO_SVGGENERATOR
-# define QT_NO_SVGGENERATOR
-#endif
-#ifndef QT_NO_SVGRENDERER
-# define QT_NO_SVGRENDERER
-#endif
-#ifndef QT_NO_SVGWIDGET
-# define QT_NO_SVGWIDGET
-#endif
-
/* Styles */
-#ifndef QT_NO_STYLE_MOTIF
-# define QT_NO_STYLE_MOTIF
-#endif
-#ifndef QT_NO_STYLE_CDE
-# define QT_NO_STYLE_CDE
-#endif
#ifndef QT_NO_STYLE_STYLESHEET
# define QT_NO_STYLE_STYLESHEET
#endif
@@ -347,14 +230,6 @@
#ifndef QT_NO_DESKTOPSERVICES
# define QT_NO_DESKTOPSERVICES
#endif
-#ifndef QT_NO_SCRIPT
-# define QT_NO_SCRIPT
-#endif
#ifndef QT_NO_SYSTEMTRAYICON
# define QT_NO_SYSTEMTRAYICON
#endif
-
-/* Windows */
-#ifndef QT_NO_WIN_ACTIVEQT
-# define QT_NO_WIN_ACTIVEQT
-#endif
diff --git a/src/corelib/global/qconfig-small.h b/src/corelib/global/qconfig-small.h
index f730b3d5d2..8a0e769383 100644
--- a/src/corelib/global/qconfig-small.h
+++ b/src/corelib/global/qconfig-small.h
@@ -64,9 +64,6 @@
#ifndef QT_NO_PROGRESSDIALOG
# define QT_NO_PROGRESSDIALOG
#endif
-#ifndef QT_NO_TABDIALOG
-# define QT_NO_TABDIALOG
-#endif
/* File I/O */
#ifndef QT_NO_SETTINGS
@@ -105,9 +102,6 @@
#endif
/* Internationalization */
-#ifndef QT_NO_QWS_INPUTMETHODS
-# define QT_NO_QWS_INPUTMETHODS
-#endif
#ifndef QT_NO_TEXTCODEC
# define QT_NO_TEXTCODEC
#endif
@@ -117,9 +111,6 @@
#ifndef QT_NO_TRANSLATION
# define QT_NO_TRANSLATION
#endif
-#ifndef QT_NO_TRANSLATION_UTF8
-# define QT_NO_TRANSLATION_UTF8
-#endif
/* ItemViews */
#ifndef QT_NO_DIRMODEL
@@ -163,20 +154,11 @@
#ifndef QT_NO_SHORTCUT
# define QT_NO_SHORTCUT
#endif
-#ifndef QT_NO_SOUND
-# define QT_NO_SOUND
-#endif
#ifndef QT_NO_WHEELEVENT
# define QT_NO_WHEELEVENT
#endif
/* Networking */
-#ifndef QT_NO_COP
-# define QT_NO_COP
-#endif
-#ifndef QT_NO_HOSTINFO
-# define QT_NO_HOSTINFO
-#endif
#ifndef QT_NO_HTTP
# define QT_NO_HTTP
#endif
@@ -195,14 +177,6 @@
# define QT_NO_CUPS
#endif
-/* Qt for Embedded Linux */
-#ifndef QT_NO_QWS_SOUNDSERVER
-# define QT_NO_QWS_SOUNDSERVER
-#endif
-#ifndef QT_NO_QWS_PROPERTIES
-# define QT_NO_QWS_PROPERTIES
-#endif
-
/* Styles */
#ifndef QT_NO_STYLE_FUSION
# define QT_NO_STYLE_FUSION
diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h
deleted file mode 100644
index 17dd600265..0000000000
--- a/src/corelib/global/qfeatures.h
+++ /dev/null
@@ -1,686 +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 QtCore module 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$
-**
-****************************************************************************/
-
-/*
- * All features and their dependencies.
- *
- * This list is generated from $QTDIR/src/corelib/global/qfeatures.txt
- * by $QTSRCDIR/util/scripts/make_qfeatures_dot_h
- */
-
-// QAction
-//#define QT_NO_ACTION
-
-// QClipboard
-//#define QT_NO_CLIPBOARD
-
-// Color Names
-//#define QT_NO_COLORNAMES
-
-// QtConcurrent
-//#define QT_NO_CONCURRENT
-
-// CssParser
-//#define QT_NO_CSSPARSER
-
-// QCursor
-//#define QT_NO_CURSOR
-
-// QDesktopServices
-//#define QT_NO_DESKTOPSERVICES
-
-// Document Object Model
-//#define QT_NO_DOM
-
-// Effects
-//#define QT_NO_EFFECTS
-
-// QFileSystemIterator
-//#define QT_NO_FILESYSTEMITERATOR
-
-// QFileSystemWatcher
-//#define QT_NO_FILESYSTEMWATCHER
-
-// Freetype Font Engine
-//#define QT_NO_FREETYPE
-
-// Gesture
-//#define QT_NO_GESTURES
-
-// QGroupBox
-//#define QT_NO_GROUPBOX
-
-// QHostInfo
-//#define QT_NO_HOSTINFO
-
-// BMP Image Format
-//#define QT_NO_IMAGEFORMAT_BMP
-
-// JPEG Image Format
-//#define QT_NO_IMAGEFORMAT_JPEG
-
-// PNG Image Format
-//#define QT_NO_IMAGEFORMAT_PNG
-
-// PPM Image Format
-//#define QT_NO_IMAGEFORMAT_PPM
-
-// XBM Image Format
-//#define QT_NO_IMAGEFORMAT_XBM
-
-// XPM Image Format
-//#define QT_NO_IMAGEFORMAT_XPM
-
-// QImage::createHeuristicMask()
-//#define QT_NO_IMAGE_HEURISTIC_MASK
-
-// Image Text
-//#define QT_NO_IMAGE_TEXT
-
-// QKeySequenceEdit
-//#define QT_NO_KEYSEQUENCEEDIT
-
-// QLCDNumber
-//#define QT_NO_LCDNUMBER
-
-// QLibrary
-//#define QT_NO_LIBRARY
-
-// QLineEdit
-//#define QT_NO_LINEEDIT
-
-// QMessageBox
-//#define QT_NO_MESSAGEBOX
-
-// QMovie
-//#define QT_NO_MOVIE
-
-// QNetworkInterface
-//#define QT_NO_NETWORKINTERFACE
-
-// QNetworkProxy
-//#define QT_NO_NETWORKPROXY
-
-// Qt::WA_PaintOnScreen
-//#define QT_NO_PAINTONSCREEN
-
-// Painting Debug Utilities
-//#define QT_NO_PAINT_DEBUG
-
-// QPicture
-//#define QT_NO_PICTURE
-
-// QProcess
-//#define QT_NO_PROCESS
-
-// QProgressBar
-//#define QT_NO_PROGRESSBAR
-
-// Properties
-//#define QT_NO_PROPERTIES
-
-// QRegularExpression
-//#define QT_NO_REGULAREXPRESSION
-
-// Resize Handler
-//#define QT_NO_RESIZEHANDLER
-
-// QRubberBand
-//#define QT_NO_RUBBERBAND
-
-// Session Manager
-//#define QT_NO_SESSIONMANAGER
-
-// QSettings
-//#define QT_NO_SETTINGS
-
-// QSharedMemory
-//#define QT_NO_SHAREDMEMORY
-
-// QShortcut
-//#define QT_NO_SHORTCUT
-
-// QSizeGrip
-//#define QT_NO_SIZEGRIP
-
-// QSlider
-//#define QT_NO_SLIDER
-
-// Spin Widget
-//#define QT_NO_SPINWIDGET
-
-// Splash screen widget
-//#define QT_NO_SPLASHSCREEN
-
-// QStackedWidget
-//#define QT_NO_STACKEDWIDGET
-
-// QStatusBar
-//#define QT_NO_STATUSBAR
-
-// Status Tip
-//#define QT_NO_STATUSTIP
-
-// QWindowsStyle
-//#define QT_NO_STYLE_WINDOWS
-
-// QSystemSemaphore
-//#define QT_NO_SYSTEMSEMAPHORE
-
-// QSystemTrayIcon
-//#define QT_NO_SYSTEMTRAYICON
-
-// QTabletEvent
-//#define QT_NO_TABLETEVENT
-
-// QTemporaryFile
-//#define QT_NO_TEMPORARYFILE
-
-// QTextCodec
-//#define QT_NO_TEXTCODEC
-
-// Text Date
-//#define QT_NO_TEXTDATE
-
-// HtmlParser
-//#define QT_NO_TEXTHTMLPARSER
-
-// QToolTip
-//#define QT_NO_TOOLTIP
-
-// Translation
-//#define QT_NO_TRANSLATION
-
-// QUdpSocket
-//#define QT_NO_UDPSOCKET
-
-// QUndoCommand
-//#define QT_NO_UNDOCOMMAND
-
-// QValidator
-//#define QT_NO_VALIDATOR
-
-// QWheelEvent
-//#define QT_NO_WHEELEVENT
-
-//
-//#define QT_NO_XMLSTREAM
-
-// Animation
-#if !defined(QT_NO_ANIMATION) && (defined(QT_NO_PROPERTIES))
-#define QT_NO_ANIMATION
-#endif
-
-// Big Codecs
-#if !defined(QT_NO_BIG_CODECS) && (defined(QT_NO_TEXTCODEC))
-#define QT_NO_BIG_CODECS
-#endif
-
-// QButtonGroup
-#if !defined(QT_NO_BUTTONGROUP) && (defined(QT_NO_GROUPBOX))
-#define QT_NO_BUTTONGROUP
-#endif
-
-// Codecs
-#if !defined(QT_NO_CODECS) && (defined(QT_NO_TEXTCODEC))
-#define QT_NO_CODECS
-#endif
-
-// QDate/QTime/QDateTime
-#if !defined(QT_NO_DATESTRING) && (defined(QT_NO_TEXTDATE))
-#define QT_NO_DATESTRING
-#endif
-
-// QDial
-#if !defined(QT_NO_DIAL) && (defined(QT_NO_SLIDER))
-#define QT_NO_DIAL
-#endif
-
-// Drag and drop
-#if !defined(QT_NO_DRAGANDDROP) && (defined(QT_NO_IMAGEFORMAT_XPM))
-#define QT_NO_DRAGANDDROP
-#endif
-
-// File Transfer Protocol
-#if !defined(QT_NO_FTP) && (defined(QT_NO_TEXTDATE))
-#define QT_NO_FTP
-#endif
-
-// Hyper Text Transfer Protocol
-#if !defined(QT_NO_HTTP) && (defined(QT_NO_HOSTINFO))
-#define QT_NO_HTTP
-#endif
-
-// iconv
-#if !defined(QT_NO_ICONV) && (defined(QT_NO_TEXTCODEC))
-#define QT_NO_ICONV
-#endif
-
-// QInputContext
-#if !defined(QT_NO_IM) && (defined(QT_NO_LIBRARY))
-#define QT_NO_IM
-#endif
-
-// QImageIOPlugin
-#if !defined(QT_NO_IMAGEFORMATPLUGIN) && (defined(QT_NO_LIBRARY))
-#define QT_NO_IMAGEFORMATPLUGIN
-#endif
-
-// QKeySequenceEdit
-#if !defined(QT_NO_KEYSEQUENCEEDIT) && (defined(QT_NO_SHORTCUT))
-#define QT_NO_KEYSEQUENCEEDIT
-#endif
-
-// QLocalServer
-#if !defined(QT_NO_LOCALSERVER) && (defined(QT_NO_TEMPORARYFILE))
-#define QT_NO_LOCALSERVER
-#endif
-
-// QPdf
-#if !defined(QT_NO_PDF) && (defined(QT_NO_TEMPORARYFILE))
-#define QT_NO_PDF
-#endif
-
-// QMenu
-#if !defined(QT_NO_MENU) && (defined(QT_NO_ACTION))
-#define QT_NO_MENU
-#endif
-
-// QNetworkDiskCache
-#if !defined(QT_NO_NETWORKDISKCACHE) && (defined(QT_NO_TEMPORARYFILE))
-#define QT_NO_NETWORKDISKCACHE
-#endif
-
-// QProgressDialog
-#if !defined(QT_NO_PROGRESSDIALOG) && (defined(QT_NO_PROGRESSBAR))
-#define QT_NO_PROGRESSDIALOG
-#endif
-
-// QScrollBar
-#if !defined(QT_NO_SCROLLBAR) && (defined(QT_NO_SLIDER))
-#define QT_NO_SCROLLBAR
-#endif
-
-// SOCKS5
-#if !defined(QT_NO_SOCKS5) && (defined(QT_NO_NETWORKPROXY))
-#define QT_NO_SOCKS5
-#endif
-
-// QSplitter
-#if !defined(QT_NO_SPLITTER) && (defined(QT_NO_RUBBERBAND))
-#define QT_NO_SPLITTER
-#endif
-
-// State machine
-#if !defined(QT_NO_STATEMACHINE) && (defined(QT_NO_PROPERTIES))
-#define QT_NO_STATEMACHINE
-#endif
-
-// QFusionStyle
-#if !defined(QT_NO_STYLE_FUSION) && (defined(QT_NO_IMAGEFORMAT_XPM))
-#define QT_NO_STYLE_FUSION
-#endif
-
-// QWindowsXPStyle
-#if !defined(QT_NO_STYLE_WINDOWSXP) && (defined(QT_NO_STYLE_WINDOWS))
-#define QT_NO_STYLE_WINDOWSXP
-#endif
-
-// QToolButton
-#if !defined(QT_NO_TOOLBUTTON) && (defined(QT_NO_ACTION))
-#define QT_NO_TOOLBUTTON
-#endif
-
-// QUndoStack
-#if !defined(QT_NO_UNDOSTACK) && (defined(QT_NO_UNDOCOMMAND))
-#define QT_NO_UNDOSTACK
-#endif
-
-// QWizard
-#if !defined(QT_NO_WIZARD) && (defined(QT_NO_PROPERTIES))
-#define QT_NO_WIZARD
-#endif
-
-// QXmlStreamReader
-#if !defined(QT_NO_XMLSTREAMREADER) && (defined(QT_NO_XMLSTREAM))
-#define QT_NO_XMLSTREAMREADER
-#endif
-
-// QXmlStreamWriter
-#if !defined(QT_NO_XMLSTREAMWRITER) && (defined(QT_NO_XMLSTREAM))
-#define QT_NO_XMLSTREAMWRITER
-#endif
-
-// Context menu
-#if !defined(QT_NO_CONTEXTMENU) && (defined(QT_NO_MENU))
-#define QT_NO_CONTEXTMENU
-#endif
-
-// QPrinter
-#if !defined(QT_NO_PRINTER) && (defined(QT_NO_PICTURE) || defined(QT_NO_TEMPORARYFILE))
-#define QT_NO_PRINTER
-#endif
-
-// QScrollArea
-#if !defined(QT_NO_SCROLLAREA) && (defined(QT_NO_SCROLLBAR))
-#define QT_NO_SCROLLAREA
-#endif
-
-// QWindowsCEStyle
-#if !defined(QT_NO_STYLE_WINDOWSCE) && (defined(QT_NO_STYLE_WINDOWS) || defined(QT_NO_IMAGEFORMAT_XPM))
-#define QT_NO_STYLE_WINDOWSCE
-#endif
-
-// QWindowsMobileStyle
-#if !defined(QT_NO_STYLE_WINDOWSMOBILE) && (defined(QT_NO_STYLE_WINDOWS) || defined(QT_NO_IMAGEFORMAT_XPM))
-#define QT_NO_STYLE_WINDOWSMOBILE
-#endif
-
-// QWindowsVistaStyle
-#if !defined(QT_NO_STYLE_WINDOWSVISTA) && (defined(QT_NO_STYLE_WINDOWSXP))
-#define QT_NO_STYLE_WINDOWSVISTA
-#endif
-
-// QTabBar
-#if !defined(QT_NO_TABBAR) && (defined(QT_NO_TOOLBUTTON))
-#define QT_NO_TABBAR
-#endif
-
-// OdfWriter
-#if !defined(QT_NO_TEXTODFWRITER) && (defined(QT_NO_XMLSTREAMWRITER))
-#define QT_NO_TEXTODFWRITER
-#endif
-
-// Translation (UTF-8 representation)
-#if !defined(QT_NO_TRANSLATION_UTF8) && (defined(QT_NO_TRANSLATION) || defined(QT_NO_TEXTCODEC))
-#define QT_NO_TRANSLATION_UTF8
-#endif
-
-// QUndoGroup
-#if !defined(QT_NO_UNDOGROUP) && (defined(QT_NO_UNDOSTACK))
-#define QT_NO_UNDOGROUP
-#endif
-
-// QWhatsThis
-#if !defined(QT_NO_WHATSTHIS) && (defined(QT_NO_TOOLBUTTON))
-#define QT_NO_WHATSTHIS
-#endif
-
-// Bearer Management
-#if !defined(QT_NO_BEARERMANAGEMENT) && (defined(QT_NO_LIBRARY) || defined(QT_NO_NETWORKINTERFACE) || defined(QT_NO_PROPERTIES))
-#define QT_NO_BEARERMANAGEMENT
-#endif
-
-// Qt D-Bus module
-#if !defined(QT_NO_DBUS) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_XMLSTREAMREADER))
-#define QT_NO_DBUS
-#endif
-
-// QGraphicsView
-#if !defined(QT_NO_GRAPHICSVIEW) && (defined(QT_NO_SCROLLAREA))
-#define QT_NO_GRAPHICSVIEW
-#endif
-
-// QMdiArea
-#if !defined(QT_NO_MDIAREA) && (defined(QT_NO_SCROLLAREA))
-#define QT_NO_MDIAREA
-#endif
-
-// QSpinBox
-#if !defined(QT_NO_SPINBOX) && (defined(QT_NO_SPINWIDGET) || defined(QT_NO_LINEEDIT) || defined(QT_NO_VALIDATOR))
-#define QT_NO_SPINBOX
-#endif
-
-// QStyleSheetStyle
-#if !defined(QT_NO_STYLE_STYLESHEET) && (defined(QT_NO_STYLE_WINDOWS) || defined(QT_NO_PROPERTIES) || defined(QT_NO_CSSPARSER))
-#define QT_NO_STYLE_STYLESHEET
-#endif
-
-// QColorDialog
-#if !defined(QT_NO_COLORDIALOG) && (defined(QT_NO_SPINBOX))
-#define QT_NO_COLORDIALOG
-#endif
-
-// Common UNIX Printing System
-#if !defined(QT_NO_CUPS) && (defined(QT_NO_PRINTER) || defined(QT_NO_LIBRARY))
-#define QT_NO_CUPS
-#endif
-
-// QGraphicsEffect
-#if !defined(QT_NO_GRAPHICSEFFECT) && (defined(QT_NO_GRAPHICSVIEW))
-#define QT_NO_GRAPHICSEFFECT
-#endif
-
-// The Model/View Framework
-#if !defined(QT_NO_ITEMVIEWS) && (defined(QT_NO_RUBBERBAND) || defined(QT_NO_SCROLLAREA))
-#define QT_NO_ITEMVIEWS
-#endif
-
-// QMenuBar
-#if !defined(QT_NO_MENUBAR) && (defined(QT_NO_MENU) || defined(QT_NO_TOOLBUTTON))
-#define QT_NO_MENUBAR
-#endif
-
-// QTabWidget
-#if !defined(QT_NO_TABWIDGET) && (defined(QT_NO_TABBAR) || defined(QT_NO_STACKEDWIDGET))
-#define QT_NO_TABWIDGET
-#endif
-
-// QTextEdit
-#if !defined(QT_NO_TEXTEDIT) && (defined(QT_NO_SCROLLAREA) || defined(QT_NO_PROPERTIES))
-#define QT_NO_TEXTEDIT
-#endif
-
-// QErrorMessage
-#if !defined(QT_NO_ERRORMESSAGE) && (defined(QT_NO_TEXTEDIT))
-#define QT_NO_ERRORMESSAGE
-#endif
-
-// QListView
-#if !defined(QT_NO_LISTVIEW) && (defined(QT_NO_ITEMVIEWS))
-#define QT_NO_LISTVIEW
-#endif
-
-// QMainWindow
-#if !defined(QT_NO_MAINWINDOW) && (defined(QT_NO_MENU) || defined(QT_NO_RESIZEHANDLER) || defined(QT_NO_TOOLBUTTON))
-#define QT_NO_MAINWINDOW
-#endif
-
-// QAbstractProxyModel
-#if !defined(QT_NO_PROXYMODEL) && (defined(QT_NO_ITEMVIEWS))
-#define QT_NO_PROXYMODEL
-#endif
-
-// QStandardItemModel
-#if !defined(QT_NO_STANDARDITEMMODEL) && (defined(QT_NO_ITEMVIEWS))
-#define QT_NO_STANDARDITEMMODEL
-#endif
-
-// QStringListModel
-#if !defined(QT_NO_STRINGLISTMODEL) && (defined(QT_NO_ITEMVIEWS))
-#define QT_NO_STRINGLISTMODEL
-#endif
-
-// QSyntaxHighlighter
-#if !defined(QT_NO_SYNTAXHIGHLIGHTER) && (defined(QT_NO_TEXTEDIT))
-#define QT_NO_SYNTAXHIGHLIGHTER
-#endif
-
-// QTableView
-#if !defined(QT_NO_TABLEVIEW) && (defined(QT_NO_ITEMVIEWS))
-#define QT_NO_TABLEVIEW
-#endif
-
-// QTextBrowser
-#if !defined(QT_NO_TEXTBROWSER) && (defined(QT_NO_TEXTEDIT))
-#define QT_NO_TEXTBROWSER
-#endif
-
-// QToolBox
-#if !defined(QT_NO_TOOLBOX) && (defined(QT_NO_TOOLBUTTON) || defined(QT_NO_SCROLLAREA))
-#define QT_NO_TOOLBOX
-#endif
-
-// QTreeView
-#if !defined(QT_NO_TREEVIEW) && (defined(QT_NO_ITEMVIEWS))
-#define QT_NO_TREEVIEW
-#endif
-
-// Accessibility
-#if !defined(QT_NO_ACCESSIBILITY) && (defined(QT_NO_PROPERTIES) || defined(QT_NO_MENUBAR))
-#define QT_NO_ACCESSIBILITY
-#endif
-
-// QColumnView
-#if !defined(QT_NO_COLUMNVIEW) && (defined(QT_NO_LISTVIEW))
-#define QT_NO_COLUMNVIEW
-#endif
-
-// QCompleter
-#if !defined(QT_NO_COMPLETER) && (defined(QT_NO_PROXYMODEL))
-#define QT_NO_COMPLETER
-#endif
-
-// QDataWidgetMapper
-#if !defined(QT_NO_DATAWIDGETMAPPER) && (defined(QT_NO_ITEMVIEWS) || defined(QT_NO_PROPERTIES))
-#define QT_NO_DATAWIDGETMAPPER
-#endif
-
-// QIdentityProxyModel
-#if !defined(QT_NO_IDENTITYPROXYMODEL) && (defined(QT_NO_PROXYMODEL))
-#define QT_NO_IDENTITYPROXYMODEL
-#endif
-
-// QListWidget
-#if !defined(QT_NO_LISTWIDGET) && (defined(QT_NO_LISTVIEW))
-#define QT_NO_LISTWIDGET
-#endif
-
-// QSortFilterProxyModel
-#if !defined(QT_NO_SORTFILTERPROXYMODEL) && (defined(QT_NO_PROXYMODEL))
-#define QT_NO_SORTFILTERPROXYMODEL
-#endif
-
-// QTableWidget
-#if !defined(QT_NO_TABLEWIDGET) && (defined(QT_NO_TABLEVIEW))
-#define QT_NO_TABLEWIDGET
-#endif
-
-// QToolBar
-#if !defined(QT_NO_TOOLBAR) && (defined(QT_NO_MAINWINDOW))
-#define QT_NO_TOOLBAR
-#endif
-
-// QTreeWidget
-#if !defined(QT_NO_TREEWIDGET) && (defined(QT_NO_TREEVIEW))
-#define QT_NO_TREEWIDGET
-#endif
-
-// QDirModel
-#if !defined(QT_NO_DIRMODEL) && (defined(QT_NO_ITEMVIEWS) || defined(QT_NO_FILESYSTEMMODEL))
-#define QT_NO_DIRMODEL
-#endif
-
-// QDockwidget
-#if !defined(QT_NO_DOCKWIDGET) && (defined(QT_NO_RUBBERBAND) || defined(QT_NO_MAINWINDOW))
-#define QT_NO_DOCKWIDGET
-#endif
-
-// QUndoView
-#if !defined(QT_NO_UNDOVIEW) && (defined(QT_NO_UNDOSTACK) || defined(QT_NO_LISTVIEW))
-#define QT_NO_UNDOVIEW
-#endif
-
-// QCompleter
-#if !defined(QT_NO_FSCOMPLETER) && (defined(QT_NO_FILESYSTEMMODEL) || defined(QT_NO_COMPLETER))
-#define QT_NO_FSCOMPLETER
-#endif
-
-// QComboBox
-#if !defined(QT_NO_COMBOBOX) && (defined(QT_NO_LINEEDIT) || defined(QT_NO_STANDARDITEMMODEL) || defined(QT_NO_LISTVIEW))
-#define QT_NO_COMBOBOX
-#endif
-
-// QPrintPreviewWidget
-#if !defined(QT_NO_PRINTPREVIEWWIDGET) && (defined(QT_NO_GRAPHICSVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_MAINWINDOW))
-#define QT_NO_PRINTPREVIEWWIDGET
-#endif
-
-// QCalendarWidget
-#if !defined(QT_NO_CALENDARWIDGET) && (defined(QT_NO_TABLEVIEW) || defined(QT_NO_MENU) || defined(QT_NO_TEXTDATE) || defined(QT_NO_SPINBOX) || defined(QT_NO_TOOLBUTTON))
-#define QT_NO_CALENDARWIDGET
-#endif
-
-// QDateTimeEdit
-#if !defined(QT_NO_DATETIMEEDIT) && (defined(QT_NO_CALENDARWIDGET) || defined(QT_NO_DATESTRING))
-#define QT_NO_DATETIMEEDIT
-#endif
-
-// QInputDialog
-#if !defined(QT_NO_INPUTDIALOG) && (defined(QT_NO_COMBOBOX) || defined(QT_NO_SPINBOX) || defined(QT_NO_STACKEDWIDGET))
-#define QT_NO_INPUTDIALOG
-#endif
-
-// QFontComboBox
-#if !defined(QT_NO_FONTCOMBOBOX) && (defined(QT_NO_COMBOBOX) || defined(QT_NO_STRINGLISTMODEL))
-#define QT_NO_FONTCOMBOBOX
-#endif
-
-// QFontDialog
-#if !defined(QT_NO_FONTDIALOG) && (defined(QT_NO_STRINGLISTMODEL) || defined(QT_NO_COMBOBOX) || defined(QT_NO_VALIDATOR) || defined(QT_NO_GROUPBOX))
-#define QT_NO_FONTDIALOG
-#endif
-
-// QPrintDialog
-#if !defined(QT_NO_PRINTDIALOG) && (defined(QT_NO_PRINTER) || defined(QT_NO_COMBOBOX) || defined(QT_NO_BUTTONGROUP) || defined(QT_NO_SPINBOX) || defined(QT_NO_TREEVIEW) || defined(QT_NO_TABWIDGET))
-#define QT_NO_PRINTDIALOG
-#endif
-
-// QFileDialog
-#if !defined(QT_NO_FILEDIALOG) && (defined(QT_NO_DIRMODEL) || defined(QT_NO_TREEVIEW) || defined(QT_NO_COMBOBOX) || defined(QT_NO_TOOLBUTTON) || defined(QT_NO_BUTTONGROUP) || defined(QT_NO_TOOLTIP) || defined(QT_NO_SPLITTER) || defined(QT_NO_STACKEDWIDGET) || defined(QT_NO_PROXYMODEL))
-#define QT_NO_FILEDIALOG
-#endif
-
-// QPrintPreviewDialog
-#if !defined(QT_NO_PRINTPREVIEWDIALOG) && (defined(QT_NO_PRINTPREVIEWWIDGET) || defined(QT_NO_PRINTDIALOG) || defined(QT_NO_TOOLBAR))
-#define QT_NO_PRINTPREVIEWDIALOG
-#endif
-
diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt
index ec54c7bdbf..84c9379bbc 100644
--- a/src/corelib/global/qfeatures.txt
+++ b/src/corelib/global/qfeatures.txt
@@ -1,3 +1,11 @@
+# Generic entry format
+#Feature: UPPERCASENAME (for the #define)
+#Description: One sentence description of what this does.
+#Section: Categorization
+#Requires: UPPERCASENAME...
+#Name: CamelCaseName (often a class name)
+#SeeAlso: UPPERCASENAME... (currently unused)
+
# Kernel
Feature: PROPERTIES
@@ -5,147 +13,127 @@ Description: Supports scripting Qt-based applications.
Section: Kernel
Requires:
Name: Properties
-SeeAlso: ???
Feature: TEXTHTMLPARSER
Description: Parser for HTML
Section: Kernel
Requires:
Name: HtmlParser
-SeeAlso: ???
Feature: TEXTODFWRITER
Description: Provides an ODF writer
Section: Kernel
Requires: XMLSTREAMWRITER
Name: OdfWriter
-SeeAlso: ???
Feature: CSSPARSER
Description: Parser for Style Sheets
Section: Kernel
Requires:
Name: CssParser
-SeeAlso: ???
Feature: REGULAREXPRESSION
Description: Perl-compatible regular expression APIs
Section: Kernel
Requires:
Name: QRegularExpression
-SeeAlso: ???
Feature: CONCURRENT
Description: Provides a high-level multi-threaded APIs
Section: Kernel
Requires:
Name: QtConcurrent
-SeeAlso: ???
Feature: DRAGANDDROP
Description: Supports the drag and drop mechansim.
Section: Kernel
Requires: IMAGEFORMAT_XPM
Name: Drag and drop
-SeeAlso: ???
Feature: SESSIONMANAGER
Description: Supports session management.
Section: Kernel
Requires:
Name: Session Manager
-SeeAlso: ???
Feature: SHORTCUT
Description: Supports keyboard accelerators and shortcuts.
Section: Kernel
Requires:
Name: QShortcut
-SeeAlso: ???
Feature: ACTION
Description: Supports widget actions.
Section: Kernel
Requires:
Name: QAction
-SeeAlso: ???
Feature: CURSOR
Description: Supports mouse cursors.
Section: Kernel
Requires:
Name: QCursor
-SeeAlso: ???
Feature: CLIPBOARD
Description: Supports cut and paste operations.
Section: Kernel
Requires:
Name: QClipboard
-SeeAlso: ???
Feature: WHEELEVENT
Description: Supports wheel events.
Section: Kernel
Requires:
Name: QWheelEvent
-SeeAlso: ???
Feature: TABLETEVENT
Description: Supports tablet events.
Section: Kernel
Requires:
Name: QTabletEvent
-SeeAlso: ???
Feature: EFFECTS
Description: Supports special widget effects (e.g. fading and scrolling).
Section: Kernel
Requires:
Name: Effects
-SeeAlso: ???
Feature: SHAREDMEMORY
Description: Provides access to a shared memory segment.
Section: Kernel
Requires:
Name: QSharedMemory
-SeeAlso: ???
Feature: SYSTEMSEMAPHORE
Description: Provides a general counting system semaphore.
Section: Kernel
Requires:
Name: QSystemSemaphore
-SeeAlso: ???
Feature: XMLSTREAM
Description: Provides a simple streaming API for XML.
Section: Kernel
Requires:
-Name:
-SeeAlso: ???
+Name: XML Streaming APIs
Feature: XMLSTREAMREADER
Description: Provides a well-formed XML parser with a simple streaming API.
Section: Kernel
Requires: XMLSTREAM
Name: QXmlStreamReader
-SeeAlso: ???
Feature: XMLSTREAMWRITER
Description: Provides a XML writer with a simple streaming API.
Section: Kernel
Requires: XMLSTREAM
Name: QXmlStreamWriter
-SeeAlso: ???
Feature: IM
Description: Inputmethods with QInputContext
Section: Kernel
Requires: LIBRARY
Name: QInputContext
-SeeAlso: ???
+
# Data structures
Feature: TEXTDATE
@@ -153,14 +141,12 @@ Description: Supports month and day names in dates.
Section: Data structures
Requires:
Name: Text Date
-SeeAlso: ???
Feature: DATESTRING
Description: Supports convertion between dates and strings.
Section: Data structures
Requires: TEXTDATE
Name: QDate/QTime/QDateTime
-SeeAlso: ???
# File I/O
@@ -169,58 +155,48 @@ Description: Supports external process invocation.
Section: File I/O
Requires:
Name: QProcess
-SeeAlso: ???
Feature: TEMPORARYFILE
Description: Provides an I/O device that operates on temporary files.
Section: File I/O
Requires:
Name: QTemporaryFile
-SeeAlso: ???
Feature: LIBRARY
Description: Supports a shared library wrapper.
Section: File I/O
Requires:
Name: QLibrary
-SeeAlso: ???
Feature: SETTINGS
Description: Supports persistent application settings.
Section: File I/O
Requires:
Name: QSettings
-SeeAlso: ???
Feature: DOM
Description: Supports the Document Object Model.
Section: File I/O
Requires:
Name: Document Object Model
-SeeAlso: ???
Feature: FILESYSTEMMODEL
Description: Provides a data model for the local filesystem.
Section: File I/O
Requires:
Name: QFileSystemModel
-SeeAlso: ???
Feature: FILESYSTEMWATCHER
-Description: Provides an interface for monitoring files and directories
-for modications.
+Description: Provides an interface for monitoring files and directories for modications.
Section: File I/O
Requires:
Name: QFileSystemWatcher
-SeeAlso: ???
Feature: FILESYSTEMITERATOR
Description: Provides fast file-system iteration.
-for modications.
Section: File I/O
Requires:
Name: QFileSystemIterator
-SeeAlso: ???
# Widgets
@@ -229,326 +205,282 @@ Description: Supports views using tree models.
Section: Widgets
Requires: TREEVIEW
Name: QTreeWidget
-SeeAlso: ???
Feature: LISTWIDGET
Description: Supports item-based list widgets.
Section: Widgets
Requires: LISTVIEW
Name: QListWidget
-SeeAlso: ???
Feature: TABLEWIDGET
Description: Supports item-based table views.
Section: Widgets
Requires: TABLEVIEW
Name: QTableWidget
-SeeAlso: ???
Feature: DATETIMEEDIT
Description: Supports editing dates and times.
Section: Widgets
Requires: CALENDARWIDGET DATESTRING
Name: QDateTimeEdit
-SeeAlso: ???
Feature: STACKEDWIDGET
Description: Supports stacked widgets.
Section: Widgets
Requires:
Name: QStackedWidget
-SeeAlso: ???
Feature: TEXTBROWSER
Description: Supports HTML document browsing.
Section: Widgets
Requires: TEXTEDIT
Name: QTextBrowser
-SeeAlso: ???
Feature: SPLASHSCREEN
Description: Supports splash screens that can be shown during application startup.
Section: Widgets
Requires:
Name: Splash screen widget
-SeeAlso: ???
Feature: SPLITTER
Description: Supports user controlled splitter widgets.
Section: Widgets
Requires: RUBBERBAND
Name: QSplitter
-SeeAlso: ???
Feature: LCDNUMBER
Description: Supports LCD-like digits.
Section: Widgets
Requires:
Name: QLCDNumber
-SeeAlso: ???
Feature: MENU
Description: Supports popup-menus.
Section: Widgets
Requires: ACTION
Name: QMenu
-SeeAlso: ???
Feature: LINEEDIT
Description: Supports single-line edits.
Section: Widgets
Requires:
Name: QLineEdit
-SeeAlso: ???
Feature: SPINBOX
Description: Supports spin boxes handling integers and discrete sets of values.
Section: Widgets
Requires: SPINWIDGET LINEEDIT VALIDATOR
Name: QSpinBox
-SeeAlso: ???
Feature: TABBAR
Description: Supports tab bars, e.g. for use in tabbed dialogs.
Section: Widgets
Requires: TOOLBUTTON
Name: QTabBar
-SeeAlso: ???
Feature: TABWIDGET
Description: Supports stacking tabbed widgets.
Section: Widgets
Requires: TABBAR STACKEDWIDGET
Name: QTabWidget
-SeeAlso: ???
Feature: COMBOBOX
Description: Supports comboboxes presenting a list of options to the user.
Section: Widgets
Requires: LINEEDIT STANDARDITEMMODEL LISTVIEW
Name: QComboBox
-SeeAlso: ???
Feature: FONTCOMBOBOX
Description: Supports a combobox that lets the user select a font family.
Section: Widgets
Requires: COMBOBOX STRINGLISTMODEL
Name: QFontComboBox
-SeeAlso: ???
Feature: TOOLBUTTON
Description: Supports quick-access buttons to commands and options.
Section: Widgets
Requires: ACTION
Name: QToolButton
-SeeAlso: ???
Feature: TOOLBAR
Description: Supports movable panels containing a set of controls.
Section: Widgets
Requires: MAINWINDOW
Name: QToolBar
-SeeAlso: ???
Feature: TOOLBOX
-Description: Supports columns of tabbed widget items.
+Description: Supports columns of tabbed widget items.
Section: Widgets
Requires: TOOLBUTTON SCROLLAREA
Name: QToolBox
-SeeAlso: ???
Feature: GROUPBOX
Description: Supports group box frames.
Section: Widgets
Requires:
Name: QGroupBox
-SeeAlso: ???
Feature: BUTTONGROUP
Description: Supports organizing groups of button widgets.
Section: Widgets
Requires: GROUPBOX
Name: QButtonGroup
-SeeAlso: ???
Feature: MAINWINDOW
Description: Supports main application windows.
Section: Widgets
Requires: MENU RESIZEHANDLER TOOLBUTTON
Name: QMainWindow
-SeeAlso: ???
Feature: DOCKWIDGET
-Description: Supports docking widgets inside a QMainWindow or floated as
-a top-level window on the desktop.
+Description: Supports docking widgets inside a QMainWindow or floated as a top-level window on the desktop.
Section: Widgets
Requires: RUBBERBAND MAINWINDOW
Name: QDockwidget
-SeeAlso: ???
Feature: MDIAREA
Description: Provides an area in which MDI windows are displayed.
Section: Widgets
Requires: SCROLLAREA
Name: QMdiArea
-SeeAlso: ???
Feature: RESIZEHANDLER
Description: Supports an internal resize handler.
Section: Widgets
Requires:
Name: Resize Handler
-SeeAlso: ???
Feature: STATUSBAR
Description: Supports presentation of status information.
Section: Widgets
Requires:
Name: QStatusBar
-SeeAlso: ???
Feature: MENUBAR
Description: Supports pull-down menu items.
Section: Widgets
Requires: MENU TOOLBUTTON
Name: QMenuBar
-SeeAlso: ???
Feature: CONTEXTMENU
Description: Supports pop-up menus on right mouse click
Section: Widgets
Requires: MENU
Name: Context menu
-SeeeAlso: ???
Feature: PROGRESSBAR
Description: Supports presentation of operation progress.
Section: Widgets
Requires:
Name: QProgressBar
-SeeAlso: ???
Feature: SLIDER
Description: Supports sliders controlling a bounded value.
Section: Widgets
Requires:
Name: QSlider
-SeeAlso: ???
Feature: SCROLLBAR
-Description: Supports scrollbars allowing the user access parts of a
-document that is larger than the widget used to display it.
+Description: Supports scrollbars allowing the user access parts of a document that is larger than the widget used to display it.
Section: Widgets
Requires: SLIDER
Name: QScrollBar
-SeeAlso: ???
Feature: DIAL
Description: Supports rounded range control, e.g. like a speedometer.
Section: Widgets
Requires: SLIDER
Name: QDial
-SeeAlso: ???
Feature: SCROLLAREA
Description: Supports scrolling views onto widgets.
Section: Widgets
Requires: SCROLLBAR
Name: QScrollArea
-SeeAlso: ???
Feature: GRAPHICSVIEW
Description: Supports the graphicsview classes.
Section: Widgets
Requires: SCROLLAREA
Name: QGraphicsView
-SeeAlso: ???
Feature: GRAPHICSEFFECT
Description: Supports the graphicseffect classes.
Section: Widgets
Requires: GRAPHICSVIEW
Name: QGraphicsEffect
-SeeAlso: ???
Feature: SPINWIDGET
Description: Supports spinbox control widgets.
Section: Widgets
Requires:
Name: Spin Widget
-SeeAlso: ???
Feature: TEXTEDIT
Description: Supports rich text editing.
Section: Widgets
Requires: SCROLLAREA PROPERTIES
Name: QTextEdit
-SeeAlso: ???
Feature: SYNTAXHIGHLIGHTER
Description: Supports custom syntax highlighting.
Section: Widgets
Requires: TEXTEDIT
Name: QSyntaxHighlighter
-SeeAlso: ???
Feature: RUBBERBAND
Description: Supports using rubberbands to indicate selections and boundaries.
Section: Widgets
Requires:
Name: QRubberBand
-SeeAlso: ???
Feature: TOOLTIP
Description: Supports presentation of tooltips.
Section: Widgets
Requires:
Name: QToolTip
-SeeAlso: ???
Feature: STATUSTIP
Description: Supports status tip functionality and events.
Section: Widgets
Requires:
Name: Status Tip
-SeeAlso: ???
Feature: WHATSTHIS
Description: Supports displaying "What's this" help.
Section: Widgets
Requires: TOOLBUTTON
Name: QWhatsThis
-SeeAlso: ???
Feature: VALIDATOR
Description: Supports validation of input text.
Section: Widgets
Requires:
Name: QValidator
-SeeAlso: ???
Feature: SIZEGRIP
Description: Supports corner-grips for resizing a top-level windows.
Section: Widgets
Requires:
Name: QSizeGrip
-SeeAlso: ???
Feature: CALENDARWIDGET
-Description: Provides a monthly based calendar widget allowing the user to select
-a date.
+Description: Provides a monthly based calendar widget allowing the user to select a date.
Section: Widgets
Requires: TABLEVIEW MENU TEXTDATE SPINBOX TOOLBUTTON
Name: QCalendarWidget
-SeeAlso: ???
Feature: PRINTPREVIEWWIDGET
Description: Provides a widget for previewing page layouts for printer output.
-a date.
Section: Widgets
Requires: GRAPHICSVIEW PRINTER MAINWINDOW
Name: QPrintPreviewWidget
-SeeAlso: ???
+
+Feature: KEYSEQUENCEEDIT
+Description: Provides a widget for editing QKeySequences
+Section: Widgets
+Requires: LINEEDIT SHORTCUT
+Name: QKeySequenceEdit
# Dialogs
@@ -558,158 +490,134 @@ informative messages and simple questions.
Section: Dialogs
Requires:
Name: QMessageBox
-SeeAlso: ???
Feature: COLORDIALOG
Description: Supports a dialog widget for specifying colors.
Section: Dialogs
Requires: SPINBOX
Name: QColorDialog
-SeeAlso: ???
Feature: FILEDIALOG
Description: Supports a dialog widget for selecting files or directories.
Section: Dialogs
Requires: DIRMODEL TREEVIEW COMBOBOX TOOLBUTTON BUTTONGROUP TOOLTIP SPLITTER STACKEDWIDGET PROXYMODEL
Name: QFileDialog
-SeeAlso: ???
Feature: FONTDIALOG
Description: Supports a dialog widget for selecting fonts.
Section: Dialogs
Requires: STRINGLISTMODEL COMBOBOX VALIDATOR GROUPBOX
Name: QFontDialog
-SeeAlso: ???
Feature: PRINTDIALOG
Description: Supports a dialog widget for specifying printer configuration.
Section: Dialogs
Requires: PRINTER COMBOBOX BUTTONGROUP SPINBOX TREEVIEW TABWIDGET
Name: QPrintDialog
-SeeAlso: ???
Feature: PRINTPREVIEWDIALOG
Description: Provides a dialog for previewing and configuring page layouts for printer output.
Section: Dialogs
Requires: PRINTPREVIEWWIDGET PRINTDIALOG TOOLBAR
Name: QPrintPreviewDialog
-SeeAlso: ???
Feature: PROGRESSDIALOG
Description: Supports feedback on the progress of a slow operation.
Section: Dialogs
Requires: PROGRESSBAR
Name: QProgressDialog
-SeeAlso: ???
Feature: INPUTDIALOG
Description: Supports a simple convenience dialog to get a single value from the user.
Section: Dialogs
Requires: COMBOBOX SPINBOX STACKEDWIDGET
Name: QInputDialog
-SeeAlso: ???
Feature: ERRORMESSAGE
-Description: Supports an error message display dialog.
+Description: Supports an error message display dialog.
Section: Dialogs
Requires: TEXTEDIT
Name: QErrorMessage
-SeeAlso: ???
Feature: WIZARD
Description: Provides a framework for wizards.
Section: Dialogs
Requires: PROPERTIES
Name: QWizard
-SeeAlso: ???
# ItemViews
Feature: ITEMVIEWS
-Description: Supports the model/view architecture managing the relationship
-between data and the way it is presented to the user.
+Description: Supports the model/view architecture managing the relationship between data and the way it is presented to the user.
Section: ItemViews
Requires: RUBBERBAND SCROLLAREA
Name: The Model/View Framework
-SeeAlso: ???
Feature: DIRMODEL
Description: Supports a data model for the local filesystem.
Section: ItemViews
Requires: ITEMVIEWS FILESYSTEMMODEL
Name: QDirModel
-SeeAlso: ???
Feature: STANDARDITEMMODEL
Description: Supports a generic model for storing custom data.
Section: ItemViews
Requires: ITEMVIEWS
Name: QStandardItemModel
-SeeAlso: ???
Feature: PROXYMODEL
Description: Supports processing of data passed between another model and a view.
Section: ItemViews
Requires: ITEMVIEWS
Name: QAbstractProxyModel
-SeeAlso: ???
Feature: SORTFILTERPROXYMODEL
-Description: Supports sorting and filtering of data passed between
-another model and a view.
+Description: Supports sorting and filtering of data passed between another model and a view.
Section: ItemViews
Requires: PROXYMODEL
Name: QSortFilterProxyModel
-SeeAlso: ???
Feature: IDENTITYPROXYMODEL
Description: Supports proxying a source model unmodified.
Section: ItemViews
Requires: PROXYMODEL
Name: QIdentityProxyModel
-SeeAlso: ???
Feature: STRINGLISTMODEL
Description: Supports a model that supplies strings to views.
Section: ItemViews
Requires: ITEMVIEWS
Name: QStringListModel
-SeeAlso: ???
Feature: LISTVIEW
Description: Supports a list or icon view onto a model.
Section: ItemViews
Requires: ITEMVIEWS
Name: QListView
-SeeAlso: ???
Feature: TABLEVIEW
Description: Supports a default model/view implementation of a table view.
Section: ItemViews
Requires: ITEMVIEWS
Name: QTableView
-SeeAlso: ???
Feature: TREEVIEW
Description: Supports a default model/view implementation of a tree view.
Section: ItemViews
Requires: ITEMVIEWS
Name: QTreeView
-SeeAlso: ???
Feature: DATAWIDGETMAPPER
Description: Provides mapping between a section of a data model to widgets.
Section: ItemViews
Requires: ITEMVIEWS PROPERTIES
Name: QDataWidgetMapper
-SeeAlso: ???
Feature: COLUMNVIEW
Description: Provides a model/view implementation of a column view.
Section: ItemViews
Requires: LISTVIEW
Name: QColumnView
-SeeAlso: ???
# Styles
@@ -718,49 +626,42 @@ Description: Supports a Microsoft Windows-like look and feel.
Section: Styles
Requires:
Name: QWindowsStyle
-SeeAlso: ???
Feature: STYLE_FUSION
Description: Supports a modern platform independent widget style.
Section: Styles
Requires: IMAGEFORMAT_XPM
Name: QFusionStyle
-SeeAlso: ???
Feature: STYLE_WINDOWSXP
Description: Supports a Microsoft WindowsXP-like look and feel.
Section: Styles
Requires: STYLE_WINDOWS
Name: QWindowsXPStyle
-SeeAlso: ???
Feature: STYLE_WINDOWSVISTA
Description: Supports a Microsoft WindowsVista-like look and feel.
Section: Styles
Requires: STYLE_WINDOWSXP
Name: QWindowsVistaStyle
-SeeAlso: ???
Feature: STYLE_WINDOWSCE
Description: WindowsCE look and feel
Section: Styles
Requires: STYLE_WINDOWS IMAGEFORMAT_XPM
Name: QWindowsCEStyle
-SeeAlso: ???
Feature: STYLE_WINDOWSMOBILE
Description: WindowsMobile look and feel
Section: Styles
Requires: STYLE_WINDOWS IMAGEFORMAT_XPM
Name: QWindowsMobileStyle
-SeeAlso: ???
Feature: STYLE_STYLESHEET
Description:
Section: Styles
Requires: STYLE_WINDOWS PROPERTIES CSSPARSER
Name: QStyleSheetStyle
-SeeAlso: ???
# Images
@@ -769,70 +670,60 @@ Description: Supports writing an image format plugin.
Section: Images
Requires: LIBRARY
Name: QImageIOPlugin
-SeeAlso: ???
Feature: MOVIE
Description: Supports animated images.
Section: Images
Requires:
Name: QMovie
-SeeAlso: ???
Feature: IMAGEFORMAT_BMP
-Description: Supports Microsoft's Bitmap image file format.
+Description: Supports Microsoft's Bitmap image file format.
Section: Images
Requires:
Name: BMP Image Format
-SeeAlso: ???
Feature: IMAGEFORMAT_PPM
Description: Supports the Portable Pixmap image file format.
Section: Images
Requires:
Name: PPM Image Format
-SeeAlso: ???
Feature: IMAGEFORMAT_XBM
Description: Supports the X11 Bitmap image file format.
Section: Images
Requires:
Name: XBM Image Format
-SeeAlso: ???
Feature: IMAGEFORMAT_XPM
Description: Supports the X11 Pixmap image file format.
Section: Images
Requires:
Name: XPM Image Format
-SeeAlso: ???
Feature: IMAGEFORMAT_PNG
Description: Supports the Portable Network Graphics image file format.
Section: Images
Requires:
Name: PNG Image Format
-SeeAlso: ???
Feature: IMAGEFORMAT_JPEG
Description: Supports the Joint Photographic Experts Group image file format.
Section: Images
Requires:
Name: JPEG Image Format
-SeeAlso: ???
Feature: IMAGE_HEURISTIC_MASK
Description: Supports creating a 1-bpp heuristic mask for images.
Section: Images
Requires:
Name: QImage::createHeuristicMask()
-SeeAlso: ???
Feature: IMAGE_TEXT
Description: Supports image file text strings.
Section: Images
Requires:
Name: Image Text
-SeeAlso: ???
# Painting
@@ -841,50 +732,36 @@ Description: Supports recording and replaying QPainter commands.
Section: Painting
Requires:
Name: QPicture
-SeeAlso: ???
Feature: COLORNAMES
-Description: Supports color names such as "red", used by QColor
-and by some HTML documents.
+Description: Supports color names such as "red", used by QColor and by some HTML documents.
Section: Painting
Requires:
Name: Color Names
-SeeAlso: ???
Feature: PDF
Description: Supports pdf format
Section: Painting
Requires: TEMPORARYFILE
Name: QPdf
-SeeAlso: ???
Feature: PRINTER
Description: Supports printing
Section: Painting
Requires: PICTURE TEMPORARYFILE
Name: QPrinter
-SeeAlso: ???
Feature: CUPS
Description Supports the Common UNIX Printing System
Section: Painting
Requires: PRINTER LIBRARY
Name: Common UNIX Printing System
-SeeAlso: ???
-
-Feature: PAINTONSCREEN
-Description: Supports the Qt::WA_PaintOnScreen widget attribute.
-Section: Painting
-Requires:
-Name: Qt::WA_PaintOnScreen
-SeeAlso: ???
Feature: PAINT_DEBUG
Description: Debug painting with the environment variables QT_FLUSH_UPDATE and QT_FLUSH_PAINT
Section: Painting
Requires:
Name: Painting Debug Utilities
-SeeAlso: ???
# Fonts
@@ -893,7 +770,6 @@ Description: Supports the FreeType 2 font engine (and its supported font formats
Section: Fonts
Requires:
Name: Freetype Font Engine
-SeeAlso: ???
# Internationalization
@@ -902,114 +778,86 @@ Description: Supports translations using QObject::tr().
Section: Internationalization
Requires:
Name: Translation
-SeeAlso: ???
-
-Feature: TRANSLATION_UTF8
-Description: Supports translations using QObject::trUtf8().
-Section: Internationalization
-Requires: TRANSLATION TEXTCODEC
-Name: Translation (UTF-8 representation)
-SeeAlso: ???
Feature: TEXTCODEC
Description: Supports conversions between text encodings.
Section: Internationalization
Requires:
Name: QTextCodec
-SeeAlso: ???
Feature: CODECS
Description: Supports non-unicode text conversions.
Section: Internationalization
Requires: TEXTCODEC
Name: Codecs
-SeeAlso: ???
Feature: BIG_CODECS
Description: Supports big codecs, e.g. CJK.
Section: Internationalization
Requires: TEXTCODEC
Name: Big Codecs
-SeeAlso: ???
Feature: ICONV
Description: Supports conversions between text encodings using iconv.
Section: Internationalization
Requires: TEXTCODEC
Name: iconv
-SeeAlso: ???
# Networking
-Feature: HOSTINFO
-Description: Supports host name lookups.
-Section: Networking
-Requires:
-Name: QHostInfo
-SeeAlso: ???
-
Feature: FTP
Description: Supports FTP file access.
Section: Networking
Requires: TEXTDATE
Name: File Transfer Protocol
-SeeAlso: ???
Feature: HTTP
Description: Supports HTTP file access.
Section: Networking
-Requires: HOSTINFO
+Requires:
Name: Hyper Text Transfer Protocol
-SeeAlso: ???
Feature: UDPSOCKET
Description: Supports User Datagram Protocol sockets.
Section: Networking
Requires:
Name: QUdpSocket
-SeeAlso: ???
Feature: NETWORKPROXY
Description: Supports configuring network layer proxy support to the Qt network classes.
Section: Networking
Requires:
Name: QNetworkProxy
-SeeAlso: ???
Feature: SOCKS5
Description: Supports SOCKS v5 network proxy.
Section: Networking
Requires: NETWORKPROXY
-Name: SOCKS5
-SeeAlso: ???
+Name: SOCKS5
Feature: NETWORKINTERFACE
Description: Supports listing the host's IP addresses and network interfaces
Section: Networking
Requires:
Name: QNetworkInterface
-SeeAlso: ???
Feature: NETWORKDISKCACHE
Description: Supports a disk cache for network resources
Section: Networking
Requires: TEMPORARYFILE
Name: QNetworkDiskCache
-SeeAlso: ???
Feature: BEARERMANAGEMENT
Description: Provides bearer management support
Section: Networking
Requires: LIBRARY NETWORKINTERFACE PROPERTIES
Name: Bearer Management
-SeeAlso: ???
Feature: LOCALSERVER
Description: Supports a local socket based server
Section: Networking
Requires: TEMPORARYFILE
Name: QLocalServer
-SeeAlso: ???
# Utilities
@@ -1018,84 +866,72 @@ Description: Provides completions based on an item model.
Section: Utilities
Requires: PROXYMODEL
Name: QCompleter
-SeeAlso: ???
Feature: FSCOMPLETER
Description: Provides completions based on an item model.
Section: Utilities
Requires: FILESYSTEMMODEL COMPLETER
Name: QCompleter
-SeeAlso: ???
Feature: DESKTOPSERVICES
Description: Provides methods for accessing common desktop services.
Section: Utilities
Requires:
Name: QDesktopServices
-SeeAlso: ???
Feature: SYSTEMTRAYICON
Description: Provides an icon for an application in the system tray.
Section: Utilities
Requires:
Name: QSystemTrayIcon
-SeeAlso: ???
Feature: UNDOCOMMAND
Description: Applies (redo or) undo of a single change in a document.
Section: Utilities
Requires:
Name: QUndoCommand
-SeeAlso: ???
Feature: UNDOSTACK
Description: Provides the ability to (redo or) undo a list of changes in a document.
Section: Utilities
Requires: UNDOCOMMAND
Name: QUndoStack
-SeeAlso: ???
Feature: UNDOGROUP
Description:
Section: Utilities
Requires: UNDOSTACK
Name: QUndoGroup
-SeeAlso: ???
Feature: UNDOVIEW
Description: A widget which shows the contents of an undo stack.
Section: Utilities
Requires: UNDOSTACK LISTVIEW
Name: QUndoView
-SeeAlso: ???
Feature: ACCESSIBILITY
Description: Provides accessibility support.
Section: Utilities
Requires: PROPERTIES MENUBAR
Name: Accessibility
-SeeAlso: ???
Feature: ANIMATION
Description: Provides a framework for animations.
Section: Utilities
Requires: PROPERTIES
Name: Animation
-SeeAlso: ???
Feature: STATEMACHINE
Description: Provides hierarchical finite state machines.
Section: Utilities
Requires: PROPERTIES
Name: State machine
-SeeAlso: ???
Feature: GESTURES
Description: Provides a framework for gestures.
Section: Utilities
Requires:
Name: Gesture
-SeeAlso: ???
# D-Bus
@@ -1104,5 +940,11 @@ Description: Provides classes for D-Bus.
Section: D-Bus
Requires: PROPERTIES XMLSTREAMREADER
Name: Qt D-Bus module
-SeeAlso: ???
+# XML Patterns
+
+Feature: XMLSCHEMA
+Description: Provides XML schema validation.
+Section: Xml Patterns
+Requires:
+Name: XML Schema APIs
diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h
index 5b7edbafa6..dd4222b89f 100644
--- a/src/corelib/global/qflags.h
+++ b/src/corelib/global/qflags.h
@@ -111,14 +111,14 @@ public:
Q_DECL_CONSTEXPR inline operator Int() const { return i; }
- Q_DECL_CONSTEXPR inline QFlags operator|(QFlags f) const { return QFlags(Enum(i | f.i)); }
- Q_DECL_CONSTEXPR inline QFlags operator|(Enum f) const { return QFlags(Enum(i | Int(f))); }
- Q_DECL_CONSTEXPR inline QFlags operator^(QFlags f) const { return QFlags(Enum(i ^ f.i)); }
- Q_DECL_CONSTEXPR inline QFlags operator^(Enum f) const { return QFlags(Enum(i ^ Int(f))); }
- Q_DECL_CONSTEXPR inline QFlags operator&(int mask) const { return QFlags(Enum(i & mask)); }
- Q_DECL_CONSTEXPR inline QFlags operator&(uint mask) const { return QFlags(Enum(i & mask)); }
- Q_DECL_CONSTEXPR inline QFlags operator&(Enum f) const { return QFlags(Enum(i & Int(f))); }
- Q_DECL_CONSTEXPR inline QFlags operator~() const { return QFlags(Enum(~i)); }
+ Q_DECL_CONSTEXPR inline QFlags operator|(QFlags f) const { return QFlags(QFlag(i | f.i)); }
+ Q_DECL_CONSTEXPR inline QFlags operator|(Enum f) const { return QFlags(QFlag(i | Int(f))); }
+ Q_DECL_CONSTEXPR inline QFlags operator^(QFlags f) const { return QFlags(QFlag(i ^ f.i)); }
+ Q_DECL_CONSTEXPR inline QFlags operator^(Enum f) const { return QFlags(QFlag(i ^ Int(f))); }
+ Q_DECL_CONSTEXPR inline QFlags operator&(int mask) const { return QFlags(QFlag(i & mask)); }
+ Q_DECL_CONSTEXPR inline QFlags operator&(uint mask) const { return QFlags(QFlag(i & mask)); }
+ Q_DECL_CONSTEXPR inline QFlags operator&(Enum f) const { return QFlags(QFlag(i & Int(f))); }
+ Q_DECL_CONSTEXPR inline QFlags operator~() const { return QFlags(QFlag(~i)); }
Q_DECL_CONSTEXPR inline bool operator!() const { return !i; }
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 6f74c7de88..f72d27c2e5 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -88,6 +88,14 @@ Q_CORE_EXPORT void *qMemCopy(void *dest, const void *src, size_t n);
Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n);
#endif
+// Statically check assumptions about the environment we're running
+// in. The idea here is to error or warn if otherwise implicit Qt
+// assumptions are not fulfilled on new hardware or compilers
+// (if this list becomes too long, consider factoring into a separate file)
+Q_STATIC_ASSERT_X(sizeof(int) == 4, "Qt assumes that int is 32 bits");
+Q_STATIC_ASSERT_X(UCHAR_MAX == 255, "Qt assumes that char is 8 bits");
+
+
/*!
\class QFlag
\inmodule QtCore
@@ -721,10 +729,6 @@ Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n);
A message generated by the qCritical() function.
\value QtFatalMsg
A message generated by the qFatal() function.
- \value QtTraceMsg
- Used by the qCTrace() macro. Trace events are usually passed only
- to dedicated \a QTracer objects, and do not appear in the installed
- message handler.
\value QtSystemMsg
@@ -981,8 +985,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
/*!
\fn QSysInfo::MacVersion QSysInfo::macVersion()
- Returns the version of Mac OS X on which the application is run (Mac OS X
- Only).
+ Returns the version of Darwin (OS X or iOS) on which the application is run.
*/
/*!
@@ -1018,6 +1021,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
\value WV_VISTA Windows Vista, Windows Server 2008 (operating system version 6.0)
\value WV_WINDOWS7 Windows 7, Windows Server 2008 R2 (operating system version 6.1)
\value WV_WINDOWS8 Windows 8 (operating system version 6.2)
+ \value WV_WINDOWS8_1 Windows 8.1 (operating system version 6.3), introduced in Qt 5.2
Alternatively, you may use the following macros which correspond directly to the Windows operating system version number:
@@ -1028,6 +1032,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
\value WV_6_0 Operating system version 6.0, corresponds to Windows Vista and Windows Server 2008
\value WV_6_1 Operating system version 6.1, corresponds to Windows 7 and Windows Server 2008 R2
\value WV_6_2 Operating system version 6.2, corresponds to Windows 8
+ \value WV_6_3 Operating system version 6.3, corresponds to Windows 8.1, introduced in Qt 5.2
CE-based versions:
@@ -1050,7 +1055,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
\enum QSysInfo::MacVersion
This enum provides symbolic names for the various versions of the
- OS X operating system. On OS X, the
+ Darwin operating system, covering both OS X and iOS. The
QSysInfo::MacintoshVersion variable gives the version of the
system on which the application is run.
@@ -1078,6 +1083,15 @@ bool qSharedBuild() Q_DECL_NOTHROW
\value MV_MOUNTAINLION Apple codename for MV_10_8
\value MV_MAVERICKS Apple codename for MV_10_9
+ \value MV_IOS iOS (any)
+ \value MV_IOS_4_3 iOS 4.3
+ \value MV_IOS_5_0 iOS 5.0
+ \value MV_IOS_5_1 iOS 5.1
+ \value MV_IOS_6_0 iOS 6.0
+ \value MV_IOS_6_1 iOS 6.1
+ \value MV_IOS_7_0 iOS 7.0
+ \value MV_IOS_7_1 iOS 7.1
+
\sa WinVersion
*/
@@ -1700,13 +1714,15 @@ static const unsigned int qt_one = 1;
const int QSysInfo::ByteOrder = ((*((unsigned char *) &qt_one) == 0) ? BigEndian : LittleEndian);
#endif
-#if defined(Q_OS_MACX)
+#if defined(Q_OS_MAC)
QT_BEGIN_INCLUDE_NAMESPACE
#include "private/qcore_mac_p.h"
#include "qnamespace.h"
QT_END_INCLUDE_NAMESPACE
+#if defined(Q_OS_OSX)
+
Q_CORE_EXPORT OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref)
{
return FSPathMakeRef(reinterpret_cast<const UInt8 *>(file.toUtf8().constData()), fsref, 0);
@@ -1722,17 +1738,17 @@ Q_CORE_EXPORT void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding e
Q_CORE_EXPORT QString qt_mac_from_pascal_string(const Str255 pstr) {
return QCFString(CFStringCreateWithPascalString(0, pstr, CFStringGetSystemEncoding()));
}
-#endif // defined(Q_OS_MACX)
-
-#if defined(Q_OS_MAC)
+#endif // defined(Q_OS_OSX)
QSysInfo::MacVersion QSysInfo::macVersion()
{
-#ifdef Q_OS_MACX
+#if defined(Q_OS_OSX)
SInt32 gestalt_version;
if (Gestalt(gestaltSystemVersion, &gestalt_version) == noErr) {
return QSysInfo::MacVersion(((gestalt_version & 0x00F0) >> 4) + 2);
}
+#elif defined(Q_OS_IOS)
+ return qt_ios_version(); // qtcore_mac_objc.mm
#endif
return QSysInfo::MV_Unknown;
}
@@ -1744,6 +1760,38 @@ QT_BEGIN_INCLUDE_NAMESPACE
#include "qt_windows.h"
QT_END_INCLUDE_NAMESPACE
+#ifndef Q_OS_WINRT
+static inline OSVERSIONINFO winOsVersion()
+{
+ OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0, {'\0'}};
+ // GetVersionEx() has been deprecated in Windows 8.1 and will return
+ // only Windows 8 from that version on.
+# if defined(_MSC_VER) && _MSC_VER >= 1800
+# pragma warning( push )
+# pragma warning( disable : 4996 )
+# endif
+ GetVersionEx(&result);
+# if defined(_MSC_VER) && _MSC_VER >= 1800
+# pragma warning( pop )
+# endif
+# ifndef Q_OS_WINCE
+ if (result.dwMajorVersion == 6 && result.dwMinorVersion == 2) {
+ // This could be Windows 8.1 or higher. Note that as of Windows 9,
+ // the major version needs to be checked as well.
+ DWORDLONG conditionMask = 0;
+ VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
+ VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
+ VER_SET_CONDITION(conditionMask, VER_PLATFORMID, VER_EQUAL);
+ OSVERSIONINFOEX checkVersion = { sizeof(OSVERSIONINFOEX), result.dwMajorVersion, result.dwMinorVersion,
+ result.dwBuildNumber, result.dwPlatformId, {'\0'}, 0, 0, 0, 0, 0 };
+ for ( ; VerifyVersionInfo(&checkVersion, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, conditionMask); ++checkVersion.dwMinorVersion)
+ result.dwMinorVersion = checkVersion.dwMinorVersion;
+ }
+# endif // !Q_OS_WINCE
+ return result;
+}
+#endif // !Q_OS_WINRT
+
QSysInfo::WinVersion QSysInfo::windowsVersion()
{
#ifndef VER_PLATFORM_WIN32s
@@ -1766,9 +1814,7 @@ QSysInfo::WinVersion QSysInfo::windowsVersion()
winver = QSysInfo::WV_WINDOWS8;
#else
winver = QSysInfo::WV_NT;
- OSVERSIONINFO osver;
- osver.dwOSVersionInfoSize = sizeof(osver);
- GetVersionEx(&osver);
+ const OSVERSIONINFO osver = winOsVersion();
#ifdef Q_OS_WINCE
DWORD qt_cever = 0;
qt_cever = osver.dwMajorVersion * 100;
@@ -1814,6 +1860,8 @@ QSysInfo::WinVersion QSysInfo::windowsVersion()
winver = QSysInfo::WV_WINDOWS7;
} else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2) {
winver = QSysInfo::WV_WINDOWS8;
+ } else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 3) {
+ winver = QSysInfo::WV_WINDOWS8_1;
} else {
qWarning("Qt: Untested Windows version %d.%d detected!",
int(osver.dwMajorVersion), int(osver.dwMinorVersion));
@@ -2389,9 +2437,14 @@ void qsrand(uint seed)
srand(seed);
}
#elif defined(Q_OS_ANDROID)
- QJNIObjectPrivate random = QJNIObjectPrivate("java/util/Random",
- "(J)V",
- jlong(seed));
+ if (randomTLS->hasLocalData()) {
+ randomTLS->localData().callMethod<void>("setSeed", "(J)V", jlong(seed));
+ return;
+ }
+
+ QJNIObjectPrivate random("java/util/Random",
+ "(J)V",
+ jlong(seed));
if (!random.isValid()) {
srand(seed);
return;
@@ -2444,19 +2497,20 @@ int qrand()
if (!randomStorage)
return rand();
- QJNIObjectPrivate random;
- if (!randomStorage->hasLocalData()) {
- random = QJNIObjectPrivate("java/util/Random",
- "(J)V",
- jlong(1));
- if (!random.isValid())
- return rand();
-
- randomStorage->setLocalData(random);
- } else {
- random = randomStorage->localData();
+ if (randomStorage->hasLocalData()) {
+ return randomStorage->localData().callMethod<jint>("nextInt",
+ "(I)I",
+ RAND_MAX);
}
+ QJNIObjectPrivate random("java/util/Random",
+ "(J)V",
+ jlong(1));
+
+ if (!random.isValid())
+ return rand();
+
+ randomStorage->setLocalData(random);
return random.callMethod<jint>("nextInt", "(I)I", RAND_MAX);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index b654ba3ac8..da5f65fafb 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -55,12 +55,11 @@
*/
#define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
-#if !defined(QT_BUILD_MOC) && !defined(QT_BUILD_QMAKE) && !defined(QT_BUILD_CONFIGURE)
+#if !defined(QT_BUILD_QMAKE) && !defined(QT_BUILD_CONFIGURE)
#include <QtCore/qconfig.h>
-#endif
-
#include <QtCore/qfeatures.h>
#define QT_SUPPORTS(FEATURE) (!defined(QT_NO_##FEATURE))
+#endif
/* These two macros makes it possible to turn the builtin line expander into a
* string literal. */
@@ -198,6 +197,8 @@ typedef quint64 qulonglong;
# define QT_POINTER_SIZE 4
# elif defined(Q_OS_ANDROID)
# define QT_POINTER_SIZE 4 // ### Add auto-detection to Windows configure
+# elif !defined(QT_BOOTSTRAPPED)
+# error could not determine QT_POINTER_SIZE
# endif
#endif
@@ -212,11 +213,8 @@ typedef unsigned int uint;
typedef unsigned long ulong;
QT_END_INCLUDE_NAMESPACE
-// This logic must match the one in qmetatype.h
#if defined(QT_COORD_TYPE)
typedef QT_COORD_TYPE qreal;
-#elif defined(QT_NO_FPU) || defined(Q_PROCESSOR_ARM) || defined(Q_OS_WINCE)
-typedef float qreal;
#else
typedef double qreal;
#endif
@@ -333,9 +331,6 @@ typedef double qreal;
# define Q_AUTOTEST_EXPORT
#endif
-#define Q_INIT_RESOURCE_EXTERN(name) \
- extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) ();
-
#define Q_INIT_RESOURCE(name) \
do { extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); \
QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); } while (0)
@@ -530,6 +525,16 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max
# define QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, ios) \
(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && osx != __MAC_NA && __MAC_OS_X_VERSION_MIN_REQUIRED < osx) || \
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MIN_REQUIRED < ios)
+
+# define QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(ios) \
+ QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, ios)
+# define QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(osx) \
+ QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, __IPHONE_NA)
+
+# define QT_IOS_DEPLOYMENT_TARGET_BELOW(ios) \
+ QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_NA, ios)
+# define QT_OSX_DEPLOYMENT_TARGET_BELOW(osx) \
+ QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, __IPHONE_NA)
#endif
/*
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index a279498e93..22a9980812 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -225,7 +225,7 @@ QLibraryInfo::QLibraryInfo()
QString
QLibraryInfo::licensee()
{
- const char *str = QT_CONFIGURE_LICENSEE;
+ const char * volatile str = QT_CONFIGURE_LICENSEE;
return QString::fromLocal8Bit(str);
}
@@ -238,7 +238,7 @@ QLibraryInfo::licensee()
QString
QLibraryInfo::licensedProducts()
{
- const char *str = QT_CONFIGURE_LICENSED_PRODUCTS;
+ const char * volatile str = QT_CONFIGURE_LICENSED_PRODUCTS;
return QString::fromLatin1(str);
}
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 0a261acc77..cc20891c76 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -816,7 +816,6 @@ Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogCont
case QtWarningMsg: message.append(QLatin1String("warning")); break;
case QtCriticalMsg:message.append(QLatin1String("critical")); break;
case QtFatalMsg: message.append(QLatin1String("fatal")); break;
- case QtTraceMsg: message.append(QLatin1String("trace")); break;
}
} else if (token == fileTokenC) {
if (context.file)
@@ -874,7 +873,6 @@ static void android_default_message_handler(QtMsgType type,
{
android_LogPriority priority;
switch (type) {
- case QtTraceMsg:
case QtDebugMsg: priority = ANDROID_LOG_DEBUG; break;
case QtWarningMsg: priority = ANDROID_LOG_WARN; break;
case QtCriticalMsg: priority = ANDROID_LOG_ERROR; break;
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index 68a24d0397..2b798f9ea0 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
class QDebug;
class QNoDebug;
-enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtTraceMsg, QtSystemMsg = QtCriticalMsg };
+enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtSystemMsg = QtCriticalMsg };
class QMessageLogContext
{
diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h
index a6accdfebc..38735c12de 100644
--- a/src/corelib/global/qsysinfo.h
+++ b/src/corelib/global/qsysinfo.h
@@ -96,6 +96,7 @@ public:
WV_VISTA = 0x0080,
WV_WINDOWS7 = 0x0090,
WV_WINDOWS8 = 0x00a0,
+ WV_WINDOWS8_1 = 0x00b0,
WV_NT_based = 0x00f0,
/* version numbers */
@@ -106,6 +107,7 @@ public:
WV_6_0 = WV_VISTA,
WV_6_1 = WV_WINDOWS7,
WV_6_2 = WV_WINDOWS8,
+ WV_6_3 = WV_WINDOWS8_1,
WV_CE = 0x0100,
WV_CENET = 0x0200,
@@ -118,6 +120,7 @@ public:
#endif
#ifdef Q_OS_MAC
+# define Q_MV_IOS(major, minor) (QSysInfo::MV_IOS | major << 4 | minor)
enum MacVersion {
MV_Unknown = 0x0000,
@@ -144,7 +147,17 @@ public:
MV_SNOWLEOPARD = MV_10_6,
MV_LION = MV_10_7,
MV_MOUNTAINLION = MV_10_8,
- MV_MAVERICKS = MV_10_9
+ MV_MAVERICKS = MV_10_9,
+
+ /* iOS */
+ MV_IOS = 1 << 8,
+ MV_IOS_4_3 = Q_MV_IOS(4, 3),
+ MV_IOS_5_0 = Q_MV_IOS(5, 0),
+ MV_IOS_5_1 = Q_MV_IOS(5, 1),
+ MV_IOS_6_0 = Q_MV_IOS(6, 0),
+ MV_IOS_6_1 = Q_MV_IOS(6, 1),
+ MV_IOS_7_0 = Q_MV_IOS(7, 0),
+ MV_IOS_7_1 = Q_MV_IOS(7, 1)
};
static const MacVersion MacintoshVersion;
static MacVersion macVersion();
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 701f79d21e..0ec3d949b9 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -137,6 +137,8 @@ win32 {
mac {
macx {
SOURCES += io/qstandardpaths_mac.cpp
+ } else:ios {
+ OBJECTIVE_SOURCES += io/qstandardpaths_ios.mm
} else {
SOURCES += io/qstandardpaths_unix.cpp
}
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index bb2b2e99f3..624f45caaf 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -1863,9 +1863,12 @@ bool QDir::setCurrent(const QString &path)
*/
/*!
- Returns the absolute path of the application's current directory.
+ Returns the absolute path of the application's current directory. The
+ current directory is the last directory set with QDir::setCurrent() or, if
+ that was never called, the directory at which this application was started
+ at by the parent process.
- \sa current(), setCurrent(), homePath(), rootPath(), tempPath()
+ \sa current(), setCurrent(), homePath(), rootPath(), tempPath(), QCoreApplication::applicationDirPath()
*/
QString QDir::currentPath()
{
@@ -2205,10 +2208,10 @@ QStringList QDir::nameFiltersFromString(const QString &nameFilter)
\relates QDir
Initializes the resources specified by the \c .qrc file with the
- specified base \a name. Normally, Qt resources are loaded
- automatically at startup. The Q_INIT_RESOURCE() macro is
- necessary on some platforms for resources stored in a static
- library.
+ specified base \a name. Normally, when resources are built as part
+ of the application, the resources are loaded automatically at
+ startup. The Q_INIT_RESOURCE() macro is necessary on some platforms
+ for resources stored in a static library.
For example, if your application's resources are listed in a file
called \c myapp.qrc, you can ensure that the resources are
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 897af352c9..2cf97ef94e 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -682,7 +682,7 @@ bool QFileInfo::exists() const
\note If \a file is a symlink that points to a non-existing
file, false is returned.
- \note Using this function is faster for than using
+ \note Using this function is faster than using
\c QFileInfo(file).exists() for file system access.
*/
bool QFileInfo::exists(const QString &file)
diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp
index d67ea80e51..72e4198fb0 100644
--- a/src/corelib/io/qfileselector.cpp
+++ b/src/corelib/io/qfileselector.cpp
@@ -348,22 +348,30 @@ void QFileSelectorPrivate::updateSelectors()
QStringList QFileSelectorPrivate::platformSelectors()
{
QStringList ret;
-#if defined(Q_OS_LINUX_ANDROID)
+#if defined(Q_OS_WIN)
+ ret << QStringLiteral("windows");
+# if defined(Q_OS_WINCE)
+ ret << QStringLiteral("wince");
+# endif
+#elif defined(Q_OS_UNIX)
+ ret << QStringLiteral("unix");
+# if defined(Q_OS_LINUX_ANDROID)
ret << QStringLiteral("android");
-#elif defined(Q_OS_BLACKBERRY)
+# elif defined(Q_OS_BLACKBERRY)
ret << QStringLiteral("blackberry");
-#elif defined(Q_OS_IOS)
+# elif defined(Q_OS_QNX)
+ ret << QStringLiteral("qnx");
+# elif defined(Q_OS_IOS)
ret << QStringLiteral("ios");
-#elif defined(Q_OS_WINCE)
- ret << QStringLiteral("wince");
-#elif defined(Q_OS_WIN)
- ret << QStringLiteral("windows");
-#elif defined(Q_OS_LINUX)
+# elif defined(Q_OS_LINUX)
ret << QStringLiteral("linux");
-#elif defined(Q_OS_OSX)
- ret << QStringLiteral("osx");
-#elif defined(Q_OS_UNIX)
- ret << QStringLiteral("generic_unix");
+# elif defined(Q_OS_MAC)
+ ret << QStringLiteral("mac");
+# else
+ struct utsname u;
+ if (uname(&u) != -1)
+ ret << QString::fromLatin1(u.sysname).toLower();
+# endif
#endif
return ret;
}
diff --git a/src/corelib/io/qfileselector.h b/src/corelib/io/qfileselector.h
index 9afd985757..cb5f71faae 100644
--- a/src/corelib/io/qfileselector.h
+++ b/src/corelib/io/qfileselector.h
@@ -52,7 +52,7 @@ class Q_CORE_EXPORT QFileSelector : public QObject
{
Q_OBJECT
public:
- QFileSelector(QObject *parent = 0);
+ explicit QFileSelector(QObject *parent = 0);
~QFileSelector();
QString select(const QString &filePath) const;
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index dc8817706c..d1ef9c1770 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -54,16 +54,17 @@
#include <sys/file.h> // flock
#include <sys/types.h> // kill
#include <signal.h> // kill
+#include <unistd.h> // gethostname
QT_BEGIN_NAMESPACE
-static QString localHostName() // from QHostInfo::localHostName()
+static QByteArray localHostName() // from QHostInfo::localHostName(), modified to return a QByteArray
{
- char hostName[512];
- if (gethostname(hostName, sizeof(hostName)) == -1)
- return QString();
- hostName[sizeof(hostName) - 1] = '\0';
- return QString::fromLocal8Bit(hostName);
+ QByteArray hostName(512, Qt::Uninitialized);
+ if (gethostname(hostName.data(), hostName.size()) == -1)
+ return QByteArray();
+ hostName.truncate(strlen(hostName.data()));
+ return hostName;
}
// ### merge into qt_safe_write?
@@ -145,7 +146,7 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
// Use operator% from the fast builder to avoid multiple memory allocations.
QByteArray fileData = QByteArray::number(QCoreApplication::applicationPid()) % '\n'
% qAppName().toUtf8() % '\n'
- % localHostName().toUtf8() % '\n';
+ % localHostName() % '\n';
const QByteArray lockFileName = QFile::encodeName(fileName);
const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0644);
@@ -190,7 +191,7 @@ bool QLockFilePrivate::isApparentlyStale() const
QString hostname, appname;
if (!getLockInfo(&pid, &hostname, &appname))
return false;
- if (hostname == localHostName()) {
+ if (hostname == QString::fromLocal8Bit(localHostName())) {
if (::kill(pid, 0) == -1 && errno == ESRCH)
return true; // PID doesn't exist anymore
}
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 8d337ec630..93a98b1835 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -75,10 +75,9 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
\l isCriticalEnabled(), \l isTraceEnabled(), as well as \l isEnabled()
to check whether messages for the given message type should be logged.
- \note The qCDebug(), qCWarning(), qCCritical(), qCTrace() and
- qCTraceGuard() macros prevent arguments from being evaluated if the
- respective message types are not enabled for the category, so explicit
- checking is not needed:
+ \note The qCDebug(), qCWarning(), qCCritical() macros prevent arguments
+ from being evaluated if the respective message types are not enabled for the
+ category, so explicit checking is not needed:
\snippet qloggingcategory/main.cpp 4
@@ -103,14 +102,6 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
\snippet qloggingcategory/main.cpp 3
*/
-typedef QVector<QTracer *> Tracers;
-
-class QLoggingCategoryPrivate
-{
-public:
- Tracers tracers;
-};
-
/*!
Constructs a QLoggingCategory object with the provided \a category name.
The object becomes the local identifier for the category.
@@ -118,16 +109,15 @@ public:
If \a category is \c{0}, the category name is changed to \c "default".
*/
QLoggingCategory::QLoggingCategory(const char *category)
- : d(new QLoggingCategoryPrivate),
+ : d(0),
name(0),
enabledDebug(false),
enabledWarning(true),
- enabledCritical(true),
- enabledTrace(false),
- placeholder1(false),
- placeholder2(false),
- placeholder3(false)
+ enabledCritical(true)
{
+ Q_UNUSED(d);
+ Q_UNUSED(placeholder);
+
bool isDefaultCategory
= (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
@@ -151,7 +141,6 @@ QLoggingCategory::~QLoggingCategory()
{
if (QLoggingRegistry *reg = QLoggingRegistry::instance())
reg->unregisterCategory(this);
- delete d;
}
/*!
@@ -194,18 +183,6 @@ QLoggingCategory::~QLoggingCategory()
*/
/*!
- \fn bool QLoggingCategory::isTraceEnabled() const
-
- Returns \c true if the tracers associated with this category should
- receive messages. Returns \c false otherwise.
-
- \note The \l qCTrace() and \l qCTraceGuard() macros already do this check
- before executing any
- code. However, calling this method may be useful to avoid
- expensive generation of data that is only used for debug output.
-*/
-
-/*!
Returns \c true if a message of type \a msgtype for the category should be
shown. Returns \c false otherwise.
*/
@@ -215,7 +192,6 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
case QtDebugMsg: return enabledDebug;
case QtWarningMsg: return enabledWarning;
case QtCriticalMsg: return enabledCritical;
- case QtTraceMsg: return enabledTrace;
case QtFatalMsg: return true;
}
return false;
@@ -237,7 +213,6 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
case QtDebugMsg: enabledDebug = enable; break;
case QtWarningMsg: enabledWarning = enable; break;
case QtCriticalMsg: enabledCritical = enable; break;
- case QtTraceMsg: enabledTrace = enable; break;
case QtFatalMsg: break;
}
}
@@ -313,7 +288,7 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
where \c <category> is the name of the category, potentially with \c{*} as a
wildcard symbol at the start and/or the end. The optional \c <type> must
- be either \c debug, \c warning, \c critical, or \c trace.
+ be either \c debug, \c warning, or \c critical.
Example:
@@ -395,56 +370,6 @@ void QLoggingCategory::setFilterRules(const QString &rules)
*/
/*!
- \relates QLoggingCategory
- \macro qCTrace(category)
- \since 5.2
-
- Returns an output stream for trace messages in the logging category
- \a category.
-
- The macro expands to code that checks whether
- \l QLoggingCategory::isTraceEnabled() evaluates to \c true.
- If so, the stream arguments are processed and sent to the \l QTracer objects
- registered with the category.
-
- \note Arguments are not processed if trace output for the category is not
- enabled, so do not rely on any side effects.
-
- Example:
-
- \snippet qtracer/ftracer.cpp 6
-
- \sa qCTraceGuard() QTraceGuard
-*/
-
-/*!
- \relates QLoggingCategory
- \macro qCTraceGuard(category)
- \since 5.2
-
- The macro expands to code that creates a guard object with automatic
- storage. The guard constructor checks whether
- \l QLoggingCategory::isTraceEnabled() evaluates to \c true.
- If so, the stream arguments are processed and the \c{start()}
- functions of the \l QTracer objects registered with the \a category are
- called.
-
- The guard destructor also checks whether the category is enabled for
- tracing and if so, the \c{end()}
- functions of the \l QTracer objects registered with the \a category are called.
-
- \note Arguments are always processed, even if trace output for the
- category is disabled. They will, however, in that case not be passed
- to the \c{record()} functions of the registered tracers.
-
- Example:
-
- \snippet qtracer/ftracer.cpp 4
-
- \sa qCTrace() QTracer
-*/
-
-/*!
\macro Q_DECLARE_LOGGING_CATEGORY(name)
\relates QLoggingCategory
\since 5.2
@@ -469,234 +394,4 @@ void QLoggingCategory::setFilterRules(const QString &rules)
This macro must be used outside of a class or method.
*/
-
-/*!
- \class QTracer
- \inmodule QtCore
- \since 5.2
-
- \brief The QTracer class provides an interface for handling
- trace events associated with a logging category.
-
- \c QTracer objects are registered with logging categories.
- Multiple \c QTracer objects
- can be registered with the same category, and the same
- \c QTracer object can be registered with different categories.
-
- If code containing \c qCTrace is executed, and the associated
- logging category is enabled for tracing, all \c QTracer objects
- that are registered with the category are notified.
-
- \c QTracer objects
-*/
-
-/*!
- \fn QTracer::QTracer()
-
- Constructs a tracer object.
-
- Example:
-
- \snippet qtracer/ftracer.cpp 2
-*/
-
-/*!
- \fn QTracer::~QTracer()
-
- Destroys the tracer object.
-*/
-
-/*!
- Registers this tracer for the \a category.
-
- The tracer will later be notified of messages of type
- \c QtTraceMsg, as long as that message type
- is enabled in the category.
-
- Example:
-
- \snippet qtracer/ftracer.cpp 1
- \codeline
- \snippet qtracer/ftracer.cpp 7
-*/
-
-void QTracer::addToCategory(QLoggingCategory &category)
-{
- category.d->tracers.append(this);
-}
-
-/*!
- \fn void QTracer::start()
-
- This function is invoked when a tracing activity starts,
- typically from the constructor of a \c QTraceGuard object
- defined by \c qCTrace() or \c qCTraceGuard().
-
- The base implementation does nothing. \c QTracer subclasses
- are advised to override it if needed.
-
- \sa qCTrace(), qCTraceGuard()
-*/
-
-/*!
- \fn void QTracer::end()
-
- This function is invoked when a tracing activity ends,
- typically from the destructor of a \c QTraceGuard object
- defined by \c qCTrace() or \c qCTraceGuard().
-
- The base implementation does nothing. It is common for
- \c QTracer subclasses to override it to perform flushing
- of collected data.
-
- \sa qCTrace(), qCTraceGuard()
-*/
-
-/*!
- \fn void QTracer::record(int data)
-
- This function is invoked during a tracing activity to
- pass integer \a data to the \c QTracer object.
-
- Example:
-
- \snippet qtracer/ftracer.cpp 3
-*/
-
-/*!
- \fn void QTracer::record(const char *data)
-
- This function is invoked during a tracing activity to
- pass string \a data to the \c QTracer object.
-*/
-
-/*!
- \fn void QTracer::record(const QVariant &data)
-
- This function is invoked during a tracing activity to
- pass abitrary (non-integer, non-string) \a data to
- the \c QTracer object.
-*/
-
-/*!
- \class QTraceGuard
- \since 5.2
- \inmodule QtCore
-
- \brief The QTraceGuard class facilitates notifications to
- \c QTracer objects.
-
- \c QTraceGuard objects are typically implicitly created on the
- stack when using the \c qCTrace or \c qCTraceGuard macros and
- are associated to a \c QLoggingCategory.
-
- The constructor of a \c QTraceGuard objects checks whether
- its associated category is enabled, and if so, informs all
- \c QTracer objects registered with the category that a
- tracing activity starts.
-
- The destructor of a \c QTraceGuard objects checks whether
- its associated category is enabled, and if so, informs all
- \c QTracer objects registered with the category that a
- tracing activity ended.
-
- A \c QTraceGuard object created by \c qCTrace will be destroyed
- at the end of the full expression, a guard created by
- \c qCTraceGuard at the end of the block containing the macro.
-
- During the lifetime of a QTraceGuard object, its \c operator<<()
- can be used to pass additional data to the active tracers.
- The fast path handles only \c int and \c{const char *} data,
- but it is possible to use arbitrary values wrapped in \c QVariants.
-
- \sa QTracer
-*/
-
-/*!
- \fn QTraceGuard::QTraceGuard(QLoggingCategory &category)
- \internal
-
- Constructs a trace guard object relaying to \a category.
-*/
-
-/*!
- \fn QTraceGuard::~QTraceGuard()
- \internal
-
- Destroys the trace guard object.
-*/
-
-/*!
- \internal
-
- Calls \c start() on all registered tracers.
-*/
-
-void QTraceGuard::start()
-{
- const Tracers &tracers = target->d->tracers;
- for (int i = tracers.size(); --i >= 0; )
- tracers.at(i)->start();
-}
-
-/*!
- \internal
-
- Calls \c end() on all registered tracers.
-*/
-
-void QTraceGuard::end()
-{
- const Tracers &tracers = target->d->tracers;
- for (int i = tracers.size(); --i >= 0; )
- tracers.at(i)->end();
-}
-
-
-/*!
- \internal
-
- This function is called for int parameters passed to the
- qCTrace stream.
-*/
-
-QTraceGuard &QTraceGuard::operator<<(int msg)
-{
- const Tracers &tracers = target->d->tracers;
- for (int i = tracers.size(); --i >= 0; )
- tracers.at(i)->record(msg);
- return *this;
-}
-
-/*!
- \internal
-
- This function is called for string parameters passed to the
- qCTrace stream.
-*/
-
-QTraceGuard &QTraceGuard::operator<<(const char *msg)
-{
- const Tracers &tracers = target->d->tracers;
- for (int i = tracers.size(); --i >= 0; )
- tracers.at(i)->record(msg);
- return *this;
-}
-
-
-/*!
- \internal
-
- This function is called for QVariant parameters passed to the
- qCTrace stream.
-*/
-
-QTraceGuard &QTraceGuard::operator<<(const QVariant &msg)
-{
- const Tracers &tracers = target->d->tracers;
- for (int i = tracers.size(); --i >= 0; )
- tracers.at(i)->record(msg);
- return *this;
-}
-
QT_END_NAMESPACE
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index 7a119f4937..15c0519827 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -44,14 +44,9 @@
#include <QtCore/qglobal.h>
#include <QtCore/qdebug.h>
-#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
-class QTracer;
-class QTraceGuard;
-class QLoggingCategoryPrivate;
-
class Q_CORE_EXPORT QLoggingCategory
{
Q_DISABLE_COPY(QLoggingCategory)
@@ -65,7 +60,6 @@ public:
bool isDebugEnabled() const { return enabledDebug; }
bool isWarningEnabled() const { return enabledWarning; }
bool isCriticalEnabled() const { return enabledCritical; }
- bool isTraceEnabled() const { return enabledTrace; }
const char *categoryName() const { return name; }
@@ -80,66 +74,13 @@ public:
static void setFilterRules(const QString &rules);
private:
- friend class QLoggingCategoryPrivate;
- friend class QLoggingRegistry;
- friend class QTraceGuard;
- friend class QTracer;
-
- QLoggingCategoryPrivate *d;
+ void *d; // reserved for future use
const char *name;
bool enabledDebug;
bool enabledWarning;
bool enabledCritical;
- bool enabledTrace;
- // reserve space for future use
- bool placeholder1;
- bool placeholder2;
- bool placeholder3;
-};
-
-class Q_CORE_EXPORT QTracer
-{
- Q_DISABLE_COPY(QTracer)
-public:
- QTracer() {}
- virtual ~QTracer() {}
-
- void addToCategory(QLoggingCategory &category);
-
- virtual void start() {}
- virtual void end() {}
- virtual void record(int) {}
- virtual void record(const char *) {}
- virtual void record(const QVariant &) {}
-};
-
-class Q_CORE_EXPORT QTraceGuard
-{
- Q_DISABLE_COPY(QTraceGuard)
-public:
- QTraceGuard(QLoggingCategory &category)
- {
- target = category.isTraceEnabled() ? &category : 0;
- if (target)
- start();
- }
-
- ~QTraceGuard()
- {
- if (target)
- end();
- }
-
- QTraceGuard &operator<<(int msg);
- QTraceGuard &operator<<(const char *msg);
- QTraceGuard &operator<<(const QVariant &msg);
-
-private:
- void start();
- void end();
-
- QLoggingCategory *target;
+ bool placeholder[5]; // reserve for future use
};
#define Q_DECLARE_LOGGING_CATEGORY(name) \
@@ -154,7 +95,7 @@ private:
}
#define qCDebug(category) \
- for (bool enabled = category().isDebugEnabled(); enabled; enabled = false) \
+ for (bool enabled = category().isDebugEnabled(); Q_UNLIKELY(enabled); enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).debug()
#define qCWarning(category) \
for (bool enabled = category().isWarningEnabled(); enabled; enabled = false) \
@@ -162,17 +103,6 @@ private:
#define qCCritical(category) \
for (bool enabled = category().isCriticalEnabled(); enabled; enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).critical()
-#define qCTrace(category) \
- for (bool enabled = category.isTraceEnabled(); enabled; enabled = false) \
- QTraceGuard(category)
-
-
-#define Q_TRACE_GUARD_NAME_HELPER(line) qTraceGuard ## line
-#define Q_TRACE_GUARD_NAME(line) Q_TRACE_GUARD_NAME_HELPER(line)
-
-#define qCTraceGuard(category) \
- QTraceGuard Q_TRACE_GUARD_NAME(__LINE__)(category);
-
#if defined(QT_NO_DEBUG_OUTPUT)
# undef qCDebug
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 885b51709d..a82e6f65f4 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -86,9 +86,6 @@ int QLoggingRule::pass(const QString &categoryName, QtMsgType msgType) const
case QtCriticalMsg:
fullCategory += QLatin1String(".critical");
break;
- case QtTraceMsg:
- fullCategory += QLatin1String(".trace");
- break;
default:
break;
}
@@ -291,7 +288,6 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
bool debug = (cat->categoryName() == qtDefaultCategoryName);
bool warning = true;
bool critical = true;
- bool trace = true;
QString categoryName = QLatin1String(cat->categoryName());
QLoggingRegistry *reg = QLoggingRegistry::instance();
@@ -305,15 +301,11 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
filterpass = item.pass(categoryName, QtCriticalMsg);
if (filterpass != 0)
critical = (filterpass > 0);
- filterpass = item.pass(categoryName, QtTraceMsg);
- if (filterpass != 0)
- trace = (filterpass > 0);
}
cat->setEnabled(QtDebugMsg, debug);
cat->setEnabled(QtWarningMsg, warning);
cat->setEnabled(QtCriticalMsg, critical);
- cat->setEnabled(QtTraceMsg, trace);
}
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index a0910869c6..8b67fc1962 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -900,7 +900,9 @@ StNormal:
++j;
}
-#ifndef QT_NO_TEXTCODEC
+#ifdef QT_NO_TEXTCODEC
+ Q_UNUSED(codec)
+#else
if (codec) {
stringResult += codec->toUnicode(str.constData() + i, j - i);
} else
diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp
index f6b14c3027..23cff6af27 100644
--- a/src/corelib/io/qsettings_mac.cpp
+++ b/src/corelib/io/qsettings_mac.cpp
@@ -691,7 +691,8 @@ bool QConfFileSettingsPrivate::writePlistFile(const QString &fileName,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- QCFType<CFDataRef> xmlData = CFPropertyListCreateXMLData(kCFAllocatorDefault, propertyList);
+ QCFType<CFDataRef> xmlData = CFPropertyListCreateData(
+ kCFAllocatorDefault, propertyList, kCFPropertyListXMLFormat_v1_0, 0, 0);
SInt32 code;
return CFURLWriteDataAndPropertiesToResource(urlFromFileName(fileName), xmlData, 0, &code);
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 5e2428527c..1181d1b980 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -139,6 +139,9 @@ QT_BEGIN_NAMESPACE
\value DownloadLocation Returns a directory for user's downloaded files. This is a generic value.
If no directory specific for downloads exists, a sensible fallback for storing user
documents is returned.
+ \value GenericConfigLocation Returns a directory location where user-specific
+ configuration files shared between multiple applications should be written.
+ This is a generic value and the returned path is never empty.
The following table gives examples of paths on different operating systems.
The first path is the writable path (unless noted). Other, additional
@@ -499,6 +502,8 @@ QString QStandardPaths::displayName(StandardLocation type)
return QCoreApplication::translate("QStandardPaths", "Runtime");
case ConfigLocation:
return QCoreApplication::translate("QStandardPaths", "Configuration");
+ case GenericConfigLocation:
+ return QCoreApplication::translate("QStandardPaths", "Shared Configuration");
case GenericCacheLocation:
return QCoreApplication::translate("QStandardPaths", "Shared Cache");
case DownloadLocation:
@@ -522,7 +527,7 @@ QString QStandardPaths::displayName(StandardLocation type)
or writing to the current user's configuration.
This affects the locations into which test programs might write files:
- GenericDataLocation, DataLocation, ConfigLocation,
+ GenericDataLocation, DataLocation, ConfigLocation, GenericConfigLocation,
GenericCacheLocation, CacheLocation.
Other locations are not affected.
diff --git a/src/corelib/io/qstandardpaths.h b/src/corelib/io/qstandardpaths.h
index df9089ace7..08d6d7b50c 100644
--- a/src/corelib/io/qstandardpaths.h
+++ b/src/corelib/io/qstandardpaths.h
@@ -69,7 +69,8 @@ public:
RuntimeLocation,
ConfigLocation,
DownloadLocation,
- GenericCacheLocation
+ GenericCacheLocation,
+ GenericConfigLocation
};
static QString writableLocation(StandardLocation type);
diff --git a/src/corelib/io/qstandardpaths_blackberry.cpp b/src/corelib/io/qstandardpaths_blackberry.cpp
index a801c2fba3..815756ff9a 100644
--- a/src/corelib/io/qstandardpaths_blackberry.cpp
+++ b/src/corelib/io/qstandardpaths_blackberry.cpp
@@ -75,6 +75,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case GenericCacheLocation:
return QDir::homePath() + testModeInsert() + QLatin1String("/Cache");
case ConfigLocation:
+ case GenericConfigLocation:
return QDir::homePath() + testModeInsert() + QLatin1String("/Settings");
case GenericDataLocation:
return sharedRoot + testModeInsert() + QLatin1String("/misc");
diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm
new file mode 100644
index 0000000000..e2100045a6
--- /dev/null
+++ b/src/corelib/io/qstandardpaths_ios.mm
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module 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$
+**
+****************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+#include "qstandardpaths.h"
+
+#ifndef QT_NO_STANDARDPATHS
+
+QT_BEGIN_NAMESPACE
+
+static QString pathForDirectory(NSSearchPathDirectory directory)
+{
+ return QString::fromNSString(
+ [NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES) lastObject]);
+}
+
+static QString bundlePath()
+{
+ return QString::fromNSString([[NSBundle mainBundle] bundlePath]);
+}
+
+QString QStandardPaths::writableLocation(StandardLocation type)
+{
+ QString location;
+
+ switch (type) {
+ case DesktopLocation:
+ location = pathForDirectory(NSDesktopDirectory);
+ break;
+ case DocumentsLocation:
+ location = pathForDirectory(NSDocumentDirectory);
+ break;
+ case FontsLocation:
+ location = bundlePath() + QLatin1String("/.fonts");
+ break;
+ case ApplicationsLocation:
+ location = pathForDirectory(NSApplicationDirectory);
+ break;
+ case MusicLocation:
+ location = pathForDirectory(NSMusicDirectory);
+ break;
+ case MoviesLocation:
+ location = pathForDirectory(NSMoviesDirectory);
+ break;
+ case PicturesLocation:
+ location = pathForDirectory(NSPicturesDirectory);
+ break;
+ case TempLocation:
+ location = QString::fromNSString(NSTemporaryDirectory());
+ break;
+ case HomeLocation:
+ location = bundlePath();
+ break;
+ case DataLocation:
+ case GenericDataLocation:
+ location = pathForDirectory(NSDocumentDirectory);
+ break;
+ case CacheLocation:
+ case GenericCacheLocation:
+ location = pathForDirectory(NSCachesDirectory);
+ break;
+ case ConfigLocation:
+ case GenericConfigLocation:
+ location = pathForDirectory(NSDocumentDirectory);
+ break;
+ case DownloadLocation:
+ location = pathForDirectory(NSDownloadsDirectory);
+ break;
+ default:
+ break;
+ }
+
+ switch (type) {
+ case RuntimeLocation:
+ break;
+ default:
+ // All other types must return something, so use the document directory
+ // as a reasonable fall-back (which will always exist).
+ if (location.isEmpty())
+ location = pathForDirectory(NSDocumentDirectory);
+ break;
+ }
+
+ return location;
+}
+
+QStringList QStandardPaths::standardLocations(StandardLocation type)
+{
+ QStringList dirs;
+ const QString localDir = writableLocation(type);
+ dirs.prepend(localDir);
+ return dirs;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STANDARDPATHS
diff --git a/src/corelib/io/qstandardpaths_mac.cpp b/src/corelib/io/qstandardpaths_mac.cpp
index 6744bfeab4..0efdfae253 100644
--- a/src/corelib/io/qstandardpaths_mac.cpp
+++ b/src/corelib/io/qstandardpaths_mac.cpp
@@ -58,6 +58,7 @@ OSType translateLocation(QStandardPaths::StandardLocation type)
{
switch (type) {
case QStandardPaths::ConfigLocation:
+ case QStandardPaths::GenericConfigLocation:
return kPreferencesFolderType;
case QStandardPaths::DesktopLocation:
return kDesktopFolderType;
@@ -149,6 +150,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
if (type == CacheLocation)
appendOrganizationAndApp(path);
return path;
+ case GenericConfigLocation:
case ConfigLocation:
return qttestDir + QLatin1String("/Preferences");
default:
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index 61e2e03a3d..1b9078f712 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -103,6 +103,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return xdgDataHome;
}
case ConfigLocation:
+ case GenericConfigLocation:
{
// http://standards.freedesktop.org/basedir-spec/latest/
QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
@@ -277,6 +278,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
QStringList dirs;
switch (type) {
case ConfigLocation:
+ case GenericConfigLocation:
{
// http://standards.freedesktop.org/basedir-spec/latest/
const QString xdgConfigDirs = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS"));
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index d4e0779381..6a79c7c00b 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -99,7 +99,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
wchar_t path[MAX_PATH];
switch (type) {
- case ConfigLocation: // same as DataLocation, on Windows
+ case ConfigLocation: // same as DataLocation, on Windows (oversight, but too late to fix it)
+ case GenericConfigLocation: // same as GenericDataLocation, on Windows
case DataLocation:
case GenericDataLocation:
#if defined Q_OS_WINCE
@@ -111,7 +112,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
if (isTestModeEnabled())
result += QLatin1String("/qttest");
#ifndef QT_BOOTSTRAPPED
- if (type != GenericDataLocation) {
+ if (type != GenericDataLocation && type != GenericConfigLocation) {
if (!QCoreApplication::organizationName().isEmpty())
result += QLatin1Char('/') + QCoreApplication::organizationName();
if (!QCoreApplication::applicationName().isEmpty())
@@ -188,12 +189,13 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
if (SHGetSpecialFolderPath) {
wchar_t path[MAX_PATH];
switch (type) {
- case ConfigLocation: // same as DataLocation, on Windows
+ case ConfigLocation: // same as DataLocation, on Windows (oversight, but too late to fix it)
+ case GenericConfigLocation: // same as GenericDataLocation, on Windows
case DataLocation:
case GenericDataLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) {
QString result = convertCharArray(path);
- if (type != GenericDataLocation) {
+ if (type != GenericDataLocation && type != GenericConfigLocation) {
#ifndef QT_BOOTSTRAPPED
if (!QCoreApplication::organizationName().isEmpty())
result += QLatin1Char('/') + QCoreApplication::organizationName();
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index fe5faa2be7..77aa3c4821 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -3586,7 +3586,7 @@ bool QUrl::matches(const QUrl &url, FormattingOptions options) const
else if (d->fragment != url.d->fragment)
return false;
- if (!(d->sectionIsPresent & mask) == (url.d->sectionIsPresent & mask))
+ if ((d->sectionIsPresent & mask) != (url.d->sectionIsPresent & mask))
return false;
// Compare paths, after applying path-related options
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index e7edb4365e..602e91ce30 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -51,8 +51,10 @@
#include <QtCore/qglobal.h>
#ifdef Q_OS_MAC
-Q_FORWARD_DECLARE_OBJC_CLASS(NSURL);
Q_FORWARD_DECLARE_CF_TYPE(CFURL);
+# ifdef __OBJC__
+Q_FORWARD_DECLARE_OBJC_CLASS(NSURL);
+# endif
#endif
QT_BEGIN_NAMESPACE
@@ -84,36 +86,36 @@ public:
inline QUrlTwoFlags &operator^=(E1 f) { i ^= f; return *this; }
inline QUrlTwoFlags &operator^=(E2 f) { i ^= f; return *this; }
- Q_DECL_CONSTEXPR inline operator QFlags<E1>() const { return E1(i); }
- Q_DECL_CONSTEXPR inline operator QFlags<E2>() const { return E2(i); }
+ Q_DECL_CONSTEXPR inline operator QFlags<E1>() const { return QFlag(i); }
+ Q_DECL_CONSTEXPR inline operator QFlags<E2>() const { return QFlag(i); }
Q_DECL_CONSTEXPR inline operator int() const { return i; }
Q_DECL_CONSTEXPR inline bool operator!() const { return !i; }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator|(QUrlTwoFlags f) const
- { return QUrlTwoFlags(E1(i | f.i)); }
+ { return QUrlTwoFlags(QFlag(i | f.i)); }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator|(E1 f) const
- { return QUrlTwoFlags(E1(i | f)); }
+ { return QUrlTwoFlags(QFlag(i | f)); }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator|(E2 f) const
- { return QUrlTwoFlags(E2(i | f)); }
+ { return QUrlTwoFlags(QFlag(i | f)); }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator^(QUrlTwoFlags f) const
- { return QUrlTwoFlags(E1(i ^ f.i)); }
+ { return QUrlTwoFlags(QFlag(i ^ f.i)); }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator^(E1 f) const
- { return QUrlTwoFlags(E1(i ^ f)); }
+ { return QUrlTwoFlags(QFlag(i ^ f)); }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator^(E2 f) const
- { return QUrlTwoFlags(E2(i ^ f)); }
+ { return QUrlTwoFlags(QFlag(i ^ f)); }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator&(int mask) const
- { return QUrlTwoFlags(E1(i & mask)); }
+ { return QUrlTwoFlags(QFlag(i & mask)); }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator&(uint mask) const
- { return QUrlTwoFlags(E1(i & mask)); }
+ { return QUrlTwoFlags(QFlag(i & mask)); }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator&(E1 f) const
- { return QUrlTwoFlags(E1(i & f)); }
+ { return QUrlTwoFlags(QFlag(i & f)); }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator&(E2 f) const
- { return QUrlTwoFlags(E2(i & f)); }
+ { return QUrlTwoFlags(QFlag(i & f)); }
Q_DECL_CONSTEXPR inline QUrlTwoFlags operator~() const
- { return QUrlTwoFlags(E1(~i)); }
+ { return QUrlTwoFlags(QFlag(~i)); }
- inline bool testFlag(E1 f) const { return (i & f) == f && (f != 0 || i == int(f)); }
- inline bool testFlag(E2 f) const { return (i & f) == f && (f != 0 || i == int(f)); }
+ Q_DECL_CONSTEXPR inline bool testFlag(E1 f) const { return (i & f) == f && (f != 0 || i == int(f)); }
+ Q_DECL_CONSTEXPR inline bool testFlag(E2 f) const { return (i & f) == f && (f != 0 || i == int(f)); }
};
template<typename E1, typename E2>
@@ -265,8 +267,10 @@ public:
#if defined(Q_OS_MAC) || defined(Q_QDOC)
static QUrl fromCFURL(CFURLRef url);
CFURLRef toCFURL() const Q_DECL_CF_RETURNS_RETAINED;
+# if defined(__OBJC__) || defined(Q_QDOC)
static QUrl fromNSURL(const NSURL *url);
NSURL *toNSURL() const Q_DECL_NS_RETURNS_AUTORELEASED;
+# endif
#endif
#if QT_DEPRECATED_SINCE(5,0)
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 998bf56874..4c43f292fb 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -110,6 +110,9 @@ mac:!nacl {
kernel/qcore_mac.cpp
OBJECTIVE_SOURCES += \
kernel/qcore_mac_objc.mm
+
+ # We need UIKit for UIDevice
+ ios: LIBS_PRIVATE += -framework UIKit
}
nacl {
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index 7b9eb67969..73f8296021 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -41,6 +41,10 @@
#include <private/qcore_mac_p.h>
+#ifdef Q_OS_IOS
+#import <UIKit/UIKit.h>
+#endif
+
QT_BEGIN_NAMESPACE
NSString *QCFString::toNSString(const QString &string)
@@ -54,5 +58,31 @@ QString QCFString::toQString(const NSString *nsstr)
return toQString(reinterpret_cast<CFStringRef>(nsstr));
}
+#ifdef Q_OS_IOS
+QSysInfo::MacVersion qt_ios_version()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ int major = 0, minor = 0;
+ NSArray *components = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
+ switch ([components count]) {
+ case 3:
+ // We don't care about the patch version
+ case 2:
+ minor = [[components objectAtIndex:1] intValue];
+ // fall through
+ case 1:
+ major = [[components objectAtIndex:0] intValue];
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+
+ [pool release];
+
+ return QSysInfo::MacVersion(Q_MV_IOS(major, minor));
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index fa911fb967..f491be9768 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -143,6 +143,10 @@ private:
QString string;
};
+#ifdef Q_OS_IOS
+QSysInfo::MacVersion qt_ios_version();
+#endif
+
QT_END_NAMESPACE
#endif // QCORE_MAC_P_H
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 00e98a69bc..e83a6e2ac4 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -151,23 +151,21 @@ QString QCoreApplicationPrivate::macMenuBarName()
#endif
QString QCoreApplicationPrivate::appName() const
{
- static QBasicMutex applicationNameMutex;
- QMutexLocker locker(&applicationNameMutex);
-
- if (applicationName.isNull()) {
+ QString applicationName;
#ifdef Q_OS_MAC
- applicationName = macMenuBarName();
+ applicationName = macMenuBarName();
#endif
- if (applicationName.isEmpty() && argv[0]) {
- char *p = strrchr(argv[0], '/');
- applicationName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
- }
+ if (applicationName.isEmpty() && argv[0]) {
+ char *p = strrchr(argv[0], '/');
+ applicationName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
}
return applicationName;
}
#endif
+QString *QCoreApplicationPrivate::cachedApplicationFilePath = 0;
+
bool QCoreApplicationPrivate::checkInstance(const char *function)
{
bool b = (QCoreApplication::self != 0);
@@ -433,6 +431,7 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate()
#ifdef Q_OS_WIN
delete [] origArgv;
#endif
+ QCoreApplicationPrivate::clearApplicationFilePath();
}
#ifndef QT_NO_QOBJECT
@@ -1041,7 +1040,7 @@ bool QCoreApplication::closingDown()
You can call this function occasionally when your program is busy
performing a long operation (e.g. copying a file).
- In event you are running a local loop which calls this function
+ In the event that you are running a local loop which calls this function
continuously, without an event loop, the
\l{QEvent::DeferredDelete}{DeferredDelete} events will
not be processed. This can affect the behaviour of widgets,
@@ -1898,6 +1897,20 @@ QString QCoreApplication::translate(const char *context, const char *sourceText,
#endif //QT_NO_TRANSLATE
+// Makes it possible to point QCoreApplication to a custom location to ensure
+// the directory is added to the patch, and qt.conf and deployed plugins are
+// found from there. This is for use cases in which QGuiApplication is
+// instantiated by a library and not by an application executable, for example,
+// Active X servers.
+
+void QCoreApplicationPrivate::setApplicationFilePath(const QString &path)
+{
+ if (QCoreApplicationPrivate::cachedApplicationFilePath)
+ *QCoreApplicationPrivate::cachedApplicationFilePath = path;
+ else
+ QCoreApplicationPrivate::cachedApplicationFilePath = new QString(path);
+}
+
/*!
Returns the directory that contains the application executable.
@@ -1953,20 +1966,28 @@ QString QCoreApplication::applicationFilePath()
}
QCoreApplicationPrivate *d = self->d_func();
- if (!d->cachedApplicationFilePath.isNull())
- return d->cachedApplicationFilePath;
+
+ static char *procName = d->argv[0];
+ if (qstrcmp(procName, d->argv[0]) != 0) {
+ // clear the cache if the procname changes, so we reprocess it.
+ QCoreApplicationPrivate::clearApplicationFilePath();
+ procName = d->argv[0];
+ }
+
+ if (QCoreApplicationPrivate::cachedApplicationFilePath)
+ return *QCoreApplicationPrivate::cachedApplicationFilePath;
#if defined(Q_OS_WIN)
- d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
- return d->cachedApplicationFilePath;
+ QCoreApplicationPrivate::setApplicationFilePath(QFileInfo(qAppFileName()).filePath());
+ return *QCoreApplicationPrivate::cachedApplicationFilePath;
#elif defined(Q_OS_BLACKBERRY)
if (!arguments().isEmpty()) { // args is never empty, but the navigator can change behaviour some day
QFileInfo fileInfo(arguments().at(0));
const bool zygotized = fileInfo.exists();
if (zygotized) {
// Handle the zygotized case:
- d->cachedApplicationFilePath = QDir::cleanPath(fileInfo.absoluteFilePath());
- return d->cachedApplicationFilePath;
+ QCoreApplicationPrivate::setApplicationFilePath(QDir::cleanPath(fileInfo.absoluteFilePath()));
+ return *QCoreApplicationPrivate::cachedApplicationFilePath;
}
}
@@ -1974,7 +1995,7 @@ QString QCoreApplication::applicationFilePath()
const size_t maximum_path = static_cast<size_t>(pathconf("/",_PC_PATH_MAX));
char buff[maximum_path+1];
if (_cmdname(buff)) {
- d->cachedApplicationFilePath = QDir::cleanPath(QString::fromLocal8Bit(buff));
+ QCoreApplicationPrivate::setApplicationFilePath(QDir::cleanPath(QString::fromLocal8Bit(buff)));
} else {
qWarning("QCoreApplication::applicationFilePath: _cmdname() failed");
// _cmdname() won't fail, but just in case, fallback to the old method
@@ -1982,18 +2003,19 @@ QString QCoreApplication::applicationFilePath()
QStringList executables = dir.entryList(QDir::Executable | QDir::Files);
if (!executables.empty()) {
//We assume that there is only one executable in the folder
- d->cachedApplicationFilePath = dir.absoluteFilePath(executables.first());
- } else {
- d->cachedApplicationFilePath = QString();
+ QCoreApplicationPrivate::setApplicationFilePath(dir.absoluteFilePath(executables.first()));
}
}
- return d->cachedApplicationFilePath;
+ return *QCoreApplicationPrivate::cachedApplicationFilePath;
#elif defined(Q_OS_MAC)
QString qAppFileName_str = qAppFileName();
if(!qAppFileName_str.isEmpty()) {
QFileInfo fi(qAppFileName_str);
- d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
- return d->cachedApplicationFilePath;
+ if (fi.exists()) {
+ QCoreApplicationPrivate::setApplicationFilePath(fi.canonicalFilePath());
+ return *QCoreApplicationPrivate::cachedApplicationFilePath;
+ }
+ return QString();
}
#endif
#if defined( Q_OS_UNIX )
@@ -2002,8 +2024,8 @@ QString QCoreApplication::applicationFilePath()
// the absolute path of the executable
QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
if (pfi.exists() && pfi.isSymLink()) {
- d->cachedApplicationFilePath = pfi.canonicalFilePath();
- return d->cachedApplicationFilePath;
+ QCoreApplicationPrivate::setApplicationFilePath(pfi.canonicalFilePath());
+ return *QCoreApplicationPrivate::cachedApplicationFilePath;
}
# endif
if (!arguments().isEmpty()) {
@@ -2033,13 +2055,15 @@ QString QCoreApplication::applicationFilePath()
absPath = QDir::cleanPath(absPath);
QFileInfo fi(absPath);
- d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
- } else {
- d->cachedApplicationFilePath = QString();
+ if (fi.exists()) {
+ QCoreApplicationPrivate::setApplicationFilePath(fi.canonicalFilePath());
+ return *QCoreApplicationPrivate::cachedApplicationFilePath;
+ }
}
- return d->cachedApplicationFilePath;
+ return QString();
#endif
+ Q_UNREACHABLE();
}
/*!
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index 4b57a7b67d..0c00f396b5 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -83,7 +83,6 @@ public:
~QCoreApplicationPrivate();
QString appName() const;
- mutable QString applicationName;
#ifdef Q_OS_MAC
static QString macMenuBarName();
@@ -140,7 +139,9 @@ public:
QCoreApplicationPrivate::Type application_type;
QString cachedApplicationDirPath;
- QString cachedApplicationFilePath;
+ static QString *cachedApplicationFilePath;
+ static void setApplicationFilePath(const QString &path);
+ static inline void clearApplicationFilePath() { delete cachedApplicationFilePath; cachedApplicationFilePath = 0; }
#ifndef QT_NO_QOBJECT
bool in_exec;
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 418074dc7a..65ca6b0dcb 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -831,6 +831,11 @@ QString decodeMSG(const MSG& msg)
}
break;
#endif
+#ifdef WM_INPUTLANGCHANGE
+ case WM_INPUTLANGCHANGE:
+ parameters = QStringLiteral("Keyboard layout changed");
+ break;
+#endif // WM_INPUTLANGCHANGE
#ifdef WM_NCACTIVATE
case WM_NCACTIVATE:
{
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
index b9137ec139..a52cc60eaa 100644
--- a/src/corelib/kernel/qeventdispatcher_blackberry.cpp
+++ b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
@@ -237,9 +237,6 @@ void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifie
return;
}
- // Call the base Unix implementation. Needed to allow select() to be called correctly
- QEventDispatcherUNIX::registerSocketNotifier(notifier);
-
// Register the fd with bps
BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
int io_events = ioEvents(sockfd);
@@ -265,6 +262,9 @@ void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifie
const int result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
if (Q_UNLIKELY(result != BPS_SUCCESS))
qWarning() << "QEventDispatcherBlackberry: bps_add_fd failed";
+
+ // Call the base Unix implementation. Needed to allow select() to be called correctly
+ QEventDispatcherUNIX::registerSocketNotifier(notifier);
}
void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notifier)
@@ -280,23 +280,22 @@ void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notif
return;
}
- // Allow the base Unix implementation to unregister the fd too
+ // Allow the base Unix implementation to unregister the fd too (before call to ioEvents()!)
QEventDispatcherUNIX::unregisterSocketNotifier(notifier);
// Unregister the fd with bps
BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
- const int io_events = ioEvents(sockfd);
int result = bps_remove_fd(sockfd);
if (Q_UNLIKELY(result != BPS_SUCCESS))
qWarning() << "QEventDispatcherBlackberry: bps_remove_fd failed" << sockfd;
- // if no other socket notifier is watching sockfd, our job ends here
- if (!io_events)
- return;
-
- result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
- if (Q_UNLIKELY(result != BPS_SUCCESS))
- qWarning("QEventDispatcherBlackberry: bps_add_fd error");
+ const int io_events = ioEvents(sockfd);
+ // if other socket notifier is watching sockfd, readd it
+ if (io_events) {
+ result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
+ if (Q_UNLIKELY(result != BPS_SUCCESS))
+ qWarning("QEventDispatcherBlackberry: bps_add_fd error");
+ }
}
static inline int timespecToMillisecs(const timespec &tv)
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index 54cd2b5a75..4e06d12aee 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -162,24 +162,31 @@ static jfieldID getCachedFieldID(JNIEnv *env,
return id;
}
-Q_GLOBAL_STATIC(QThreadStorage<int>, refCount)
+class QJNIEnvironmentPrivateTLS
+{
+public:
+ inline ~QJNIEnvironmentPrivateTLS()
+ {
+ QtAndroidPrivate::javaVM()->DetachCurrentThread();
+ }
+};
+
+Q_GLOBAL_STATIC(QThreadStorage<QJNIEnvironmentPrivateTLS *>, jniEnvTLS)
QJNIEnvironmentPrivate::QJNIEnvironmentPrivate()
: jniEnv(0)
{
JavaVM *vm = QtAndroidPrivate::javaVM();
if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) == JNI_EDETACHED) {
- if (vm->AttachCurrentThread(&jniEnv, 0) < 0)
+ if (vm->AttachCurrentThread(&jniEnv, 0) != JNI_OK)
return;
}
if (!jniEnv)
return;
- if (!refCount->hasLocalData())
- refCount->setLocalData(1);
- else
- refCount->setLocalData(refCount->localData() + 1);
+ if (!jniEnvTLS->hasLocalData())
+ jniEnvTLS->setLocalData(new QJNIEnvironmentPrivateTLS);
}
JNIEnv *QJNIEnvironmentPrivate::operator->()
@@ -194,16 +201,6 @@ QJNIEnvironmentPrivate::operator JNIEnv* () const
QJNIEnvironmentPrivate::~QJNIEnvironmentPrivate()
{
- if (!jniEnv)
- return;
-
- const int newRef = refCount->localData() - 1;
- refCount->setLocalData(newRef);
-
- if (newRef == 0)
- QtAndroidPrivate::javaVM()->DetachCurrentThread();
-
- jniEnv = 0;
}
QJNIObjectData::QJNIObjectData()
@@ -354,7 +351,9 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj)
QJNIEnvironmentPrivate env;
d->m_jobject = env->NewGlobalRef(obj);
- d->m_jclass = static_cast<jclass>(env->NewGlobalRef(env->GetObjectClass(d->m_jobject)));
+ jclass objectClass = env->GetObjectClass(d->m_jobject);
+ d->m_jclass = static_cast<jclass>(env->NewGlobalRef(objectClass));
+ env->DeleteLocalRef(objectClass);
}
template <>
@@ -1265,7 +1264,10 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName,
if (id) {
res = env->CallObjectMethodV(d->m_jobject, id, args);
}
- return res;
+
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName,
@@ -1342,7 +1344,9 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(const char *classNam
}
}
- return res;
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(const char *className,
@@ -1369,7 +1373,9 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz,
res = env->CallStaticObjectMethodV(clazz, id, args);
}
- return res;
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz,
@@ -1681,7 +1687,9 @@ QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName,
if (id)
res = env->GetObjectField(d->m_jobject, id);
- return res;
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(const char *className,
@@ -1707,7 +1715,9 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz,
if (id)
res = env->GetStaticObjectField(clazz, id);
- return res;
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
template <>
@@ -2109,7 +2119,9 @@ QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string)
QJNIEnvironmentPrivate env;
jstring res = env->NewString(reinterpret_cast<const jchar*>(string.constData()),
string.length());
- return res;
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
QString QJNIObjectPrivate::toString() const
diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h
index c5bbae26b9..ab98aec1bf 100644
--- a/src/corelib/kernel/qjni_p.h
+++ b/src/corelib/kernel/qjni_p.h
@@ -180,7 +180,9 @@ public:
d = QSharedPointer<QJNIObjectData>(new QJNIObjectData());
QJNIEnvironmentPrivate env;
d->m_jobject = env->NewGlobalRef(jobj);
- d->m_jclass = static_cast<jclass>(env->NewGlobalRef(env->GetObjectClass(jobj)));
+ jclass objectClass = env->GetObjectClass(jobj);
+ d->m_jclass = static_cast<jclass>(env->NewGlobalRef(objectClass));
+ env->DeleteLocalRef(objectClass);
}
return *this;
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index fbcd0606e6..9ec491f6a9 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -94,7 +94,9 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
return JNI_ERR;
g_jClassLoader = env->NewGlobalRef(classLoader);
+ env->DeleteLocalRef(classLoader);
g_jActivity = env->NewGlobalRef(activity);
+ env->DeleteLocalRef(activity);
g_javaVM = vm;
return JNI_OK;
diff --git a/src/corelib/kernel/qmath.cpp b/src/corelib/kernel/qmath.cpp
index 8f900e2101..b1860fa24a 100644
--- a/src/corelib/kernel/qmath.cpp
+++ b/src/corelib/kernel/qmath.cpp
@@ -310,8 +310,6 @@ const qreal qt_sine_table[QT_SINE_TABLE_SIZE] = {
\brief The <QtMath> header file includes generic math declarations.
- The global declarations include \l{functions}.
-
These functions are partly convenience definitions for basic
operations, for instance not available in the Standard Template Library et
al.
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 72ce941b6e..29c5a3dd24 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -177,6 +178,7 @@ private:
void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
+void (*QAbstractDeclarativeData::destroyed_qml1)(QAbstractDeclarativeData *, QObject *) = 0;
void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
void (*QAbstractDeclarativeData::signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **) = 0;
int (*QAbstractDeclarativeData::receivers)(QAbstractDeclarativeData *, const QObject *, int) = 0;
@@ -639,7 +641,7 @@ void QMetaCallEvent::placeMetaCall(QObject *object)
\li When a QObject is moved to another thread, all its children
will be automatically moved too.
\li moveToThread() will fail if the QObject has a parent.
- \li If \l{QObject}s are created within QThread::run(), they cannot
+ \li If QObjects are created within QThread::run(), they cannot
become children of the QThread object because the QThread does
not live in the thread that calls QThread::run().
\endlist
@@ -878,8 +880,12 @@ QObject::~QObject()
}
}
- if (d->declarativeData)
- QAbstractDeclarativeData::destroyed(d->declarativeData, this);
+ if (d->declarativeData) {
+ if (QAbstractDeclarativeData::destroyed)
+ QAbstractDeclarativeData::destroyed(d->declarativeData, this);
+ if (QAbstractDeclarativeData::destroyed_qml1)
+ QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
+ }
// set ref to zero to indicate that this object has been deleted
if (d->currentSender != 0)
@@ -920,9 +926,9 @@ QObject::~QObject()
// The destroy operation must happen outside the lock
if (c->isSlotObject) {
+ c->isSlotObject = false;
locker.unlock();
c->slotObj->destroyIfLastRef();
- c->isSlotObject = false;
locker.relock();
}
c->deref();
@@ -937,15 +943,29 @@ QObject::~QObject()
d->connectionLists = 0;
}
- // disconnect all senders
+ /* Disconnect all senders:
+ * This loop basically just does
+ * for (node = d->senders; node; node = node->next) { ... }
+ *
+ * We need to temporarily unlock the receiver mutex to destroy the functors or to lock the
+ * sender's mutex. And when the mutex is released, node->next might be destroyed by another
+ * thread. That's why we set node->prev to &node, that way, if node is destroyed, node will
+ * be updated.
+ */
QObjectPrivate::Connection *node = d->senders;
while (node) {
QObject *sender = node->sender;
+ // Send disconnectNotify before removing the connection from sender's connection list.
+ // This ensures any eventual destructor of sender will block on getting receiver's lock
+ // and not finish until we release it.
+ sender->disconnectNotify(QMetaObjectPrivate::signal(sender->metaObject(), node->signal_index));
QMutex *m = signalSlotLock(sender);
node->prev = &node;
bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
//the node has maybe been removed while the mutex was unlocked in relock?
if (!node || node->sender != sender) {
+ // We hold the wrong mutex
+ Q_ASSERT(needToUnlock);
m->unlock();
continue;
}
@@ -954,8 +974,6 @@ QObject::~QObject()
if (senderLists)
senderLists->dirty = true;
- int signal_index = node->signal_index;
-
QtPrivate::QSlotObjectBase *slotObj = Q_NULLPTR;
if (node->isSlotObject) {
slotObj = node->slotObj;
@@ -967,12 +985,12 @@ QObject::~QObject()
m->unlock();
if (slotObj) {
+ if (node)
+ node->prev = &node;
locker.unlock();
slotObj->destroyIfLastRef();
locker.relock();
}
-
- sender->disconnectNotify(QMetaObjectPrivate::signal(sender->metaObject(), signal_index));
}
}
@@ -1557,12 +1575,12 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)
Q_D(QObject);
if (interval < 0) {
- qWarning("QObject::startTimer: QTimer cannot have a negative interval");
+ qWarning("QObject::startTimer: Timers cannot have negative intervals");
return 0;
}
if (!d->threadData->eventDispatcher.load()) {
- qWarning("QObject::startTimer: QTimer can only be used with threads started with QThread");
+ qWarning("QObject::startTimer: Timers can only be used with threads started with QThread");
return 0;
}
int timerId = d->threadData->eventDispatcher.load()->registerTimer(interval, timerType, this);
@@ -1931,7 +1949,7 @@ void QObjectPrivate::setParent_helper(QObject *o)
}
}
}
- if (!isDeletingChildren && declarativeData)
+ if (!isDeletingChildren && declarativeData && QAbstractDeclarativeData::parentChanged)
QAbstractDeclarativeData::parentChanged(declarativeData, q, o);
}
@@ -3236,7 +3254,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
&& (slot == 0 || (c->isSlotObject && c->slotObj->compare(slot)))))) {
bool needToUnlock = false;
QMutex *receiverMutex = 0;
- if (!receiver) {
+ if (c->receiver) {
receiverMutex = signalSlotLock(c->receiver);
// need to relock this receiver and sender in the correct order
needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex);
@@ -3253,9 +3271,9 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
c->receiver = 0;
if (c->isSlotObject) {
+ c->isSlotObject = false;
senderMutex->unlock();
c->slotObj->destroyIfLastRef();
- c->isSlotObject = false;
senderMutex->lock();
}
@@ -3284,8 +3302,7 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender,
QObject *s = const_cast<QObject *>(sender);
QMutex *senderMutex = signalSlotLock(sender);
- QMutex *receiverMutex = receiver ? signalSlotLock(receiver) : 0;
- QOrderedMutexLocker locker(senderMutex, receiverMutex);
+ QMutexLocker locker(senderMutex);
QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
if (!connectionLists)
@@ -4213,7 +4230,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) {
\macro Q_INVOKABLE
\relates QObject
- Apply this macro to definitions of member functions to allow them to
+ Apply this macro to declarations of member functions to allow them to
be invoked via the meta-object system. The macro is written before
the return type, as shown in the following example:
@@ -4230,7 +4247,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) {
\macro Q_REVISION
\relates QObject
- Apply this macro to definitions of member functions to tag them with a
+ Apply this macro to declarations of member functions to tag them with a
revision number in the meta-object system. The macro is written before
the return type, as shown in the following example:
@@ -4695,7 +4712,7 @@ bool QObjectPrivate::disconnect(const QObject *sender, int signal_index, void **
It can be used to disconnect that connection, or check if
the connection was successful
- \sa QObject::disconnect
+ \sa QObject::disconnect()
*/
/*!
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index 1bbd548be6..d2996e6e4d 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -99,6 +99,8 @@ namespace QtPrivate {
template <typename ArgList, bool Declared = TypesAreDeclaredMetaType<ArgList>::Value > struct ConnectionTypes
{ static const int *types() { return 0; } };
+ template <> struct ConnectionTypes<List<>, true>
+ { static const int *types() { return 0; } };
template <typename... Args> struct ConnectionTypes<List<Args...>, true>
{ static const int *types() { static const int t[sizeof...(Args) + 1] = { (QtPrivate::QMetaTypeIdHelper<Args>::qt_metatype_id())..., 0 }; return t; } };
#endif
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index f5745515c9..cd2d592cec 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -90,6 +90,7 @@ class Q_CORE_EXPORT QAbstractDeclarativeData
{
public:
static void (*destroyed)(QAbstractDeclarativeData *, QObject *);
+ static void (*destroyed_qml1)(QAbstractDeclarativeData *, QObject *);
static void (*parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *);
static void (*signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **);
static int (*receivers)(QAbstractDeclarativeData *, const QObject *, int);
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index db3b96d202..91ccf3996e 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -221,6 +222,19 @@ static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
return qlonglong(qMetaTypeUNumber(d));
}
+ if (QMetaType::typeFlags(d->type) & QMetaType::IsEnumeration) {
+ switch (QMetaType::sizeOf(d->type)) {
+ case 1:
+ return d->is_shared ? *reinterpret_cast<signed char *>(d->data.shared->ptr) : d->data.sc;
+ case 2:
+ return d->is_shared ? *reinterpret_cast<qint16 *>(d->data.shared->ptr) : d->data.s;
+ case 4:
+ return d->is_shared ? *reinterpret_cast<qint32 *>(d->data.shared->ptr) : d->data.i;
+ case 8:
+ return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->ptr) : d->data.ll;
+ }
+ }
+
*ok = false;
return Q_INT64_C(0);
}
@@ -256,6 +270,19 @@ static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
return qMetaTypeUNumber(d);
}
+ if (QMetaType::typeFlags(d->type) & QMetaType::IsEnumeration) {
+ switch (QMetaType::sizeOf(d->type)) {
+ case 1:
+ return d->is_shared ? *reinterpret_cast<uchar *>(d->data.shared->ptr) : d->data.uc;
+ case 2:
+ return d->is_shared ? *reinterpret_cast<quint16 *>(d->data.shared->ptr) : d->data.us;
+ case 4:
+ return d->is_shared ? *reinterpret_cast<quint32 *>(d->data.shared->ptr) : d->data.u;
+ case 8:
+ return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->ptr) : d->data.ull;
+ }
+ }
+
*ok = false;
return Q_UINT64_C(0);
}
@@ -888,15 +915,13 @@ static bool customCompare(const QVariant::Private *a, const QVariant::Private *b
static bool customConvert(const QVariant::Private *d, int t, void *result, bool *ok)
{
if (d->type >= QMetaType::User || t >= QMetaType::User) {
- const bool isOk = QMetaType::convert(constData(*d), d->type, result, t);
- if (ok)
- *ok = isOk;
- return isOk;
+ if (QMetaType::convert(constData(*d), d->type, result, t)) {
+ if (ok)
+ *ok = true;
+ return true;
+ }
}
-
- if (ok)
- *ok = false;
- return false;
+ return convert(d, t, result, ok);
}
#if !defined(QT_NO_DEBUG_STREAM)
@@ -2854,8 +2879,13 @@ bool QVariant::canConvert(int targetTypeId) const
if (targetTypeId < 0)
return false;
- if (targetTypeId >= QMetaType::User)
- return canConvertMetaObject(currentType, targetTypeId, d.data.o);
+ if (targetTypeId >= QMetaType::User) {
+ if (QMetaType::typeFlags(targetTypeId) & QMetaType::IsEnumeration) {
+ targetTypeId = QMetaType::Int;
+ } else {
+ return canConvertMetaObject(currentType, targetTypeId, d.data.o);
+ }
+ }
if (currentType == QMetaType::QJsonValue) {
switch (targetTypeId) {
@@ -2888,13 +2918,16 @@ bool QVariant::canConvert(int targetTypeId) const
return true;
// fall through
case QVariant::UInt:
+ case QVariant::LongLong:
+ case QVariant::ULongLong:
return currentType == QMetaType::ULong
|| currentType == QMetaType::Long
|| currentType == QMetaType::UShort
|| currentType == QMetaType::UChar
|| currentType == QMetaType::Char
|| currentType == QMetaType::SChar
- || currentType == QMetaType::Short;
+ || currentType == QMetaType::Short
+ || QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration;
case QVariant::Image:
return currentType == QVariant::Pixmap || currentType == QVariant::Bitmap;
case QVariant::Pixmap:
@@ -2923,7 +2956,9 @@ bool QVariant::canConvert(int targetTypeId) const
case QMetaType::ULong:
case QMetaType::Short:
case QMetaType::UShort:
- return qCanConvertMatrix[QVariant::Int] & (1 << currentType) || currentType == QVariant::Int;
+ return qCanConvertMatrix[QVariant::Int] & (1 << currentType)
+ || currentType == QVariant::Int
+ || QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration;
case QMetaType::QObjectStar:
return canConvertMetaObject(currentType, targetTypeId, d.data.o);
default:
@@ -2974,7 +3009,8 @@ bool QVariant::convert(int targetTypeId)
}
bool isOk = true;
- if (!handlerManager[d.type]->convert(&oldValue.d, targetTypeId, data(), &isOk))
+ int converterType = std::max(oldValue.userType(), targetTypeId);
+ if (!handlerManager[converterType]->convert(&oldValue.d, targetTypeId, data(), &isOk))
isOk = false;
d.is_null = !isOk;
return isOk;
diff --git a/src/corelib/kernel/qwineventnotifier.h b/src/corelib/kernel/qwineventnotifier.h
index 56605d9aaa..cddb9d73be 100644
--- a/src/corelib/kernel/qwineventnotifier.h
+++ b/src/corelib/kernel/qwineventnotifier.h
@@ -45,7 +45,6 @@
#include "QtCore/qobject.h"
#ifdef Q_OS_WIN
-#include "QtCore/qt_windows.h"
QT_BEGIN_NAMESPACE
@@ -54,6 +53,7 @@ class Q_CORE_EXPORT QWinEventNotifier : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QWinEventNotifier)
+ typedef Qt::HANDLE HANDLE;
public:
explicit QWinEventNotifier(QObject *parent = 0);
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index aa03395f94..bdea75a3b9 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -53,6 +53,11 @@
#include <QDateTime>
#include <QtEndian>
+static void initResources()
+{
+ Q_INIT_RESOURCE(mimetypes);
+}
+
QT_BEGIN_NAMESPACE
static QString fallbackParent(const QString &mimeTypeName)
@@ -704,6 +709,7 @@ void QMimeBinaryProvider::loadGenericIcon(QMimeTypePrivate &data)
QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db)
: QMimeProviderBase(db), m_loaded(false)
{
+ initResources();
}
bool QMimeXMLProvider::isValid()
diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h
index 31b9890351..a0d2923bed 100644
--- a/src/corelib/plugin/quuid.h
+++ b/src/corelib/plugin/quuid.h
@@ -82,7 +82,7 @@ public:
Sha1 = 5 // 0 1 0 1
};
-#if defined(Q_COMPILER_INITIALIZER_LISTS) && !defined(Q_QDOC)
+#if defined(Q_COMPILER_UNIFORM_INIT) && !defined(Q_QDOC)
Q_DECL_CONSTEXPR QUuid() : data1(0), data2(0), data3(0), data4{0,0,0,0,0,0,0,0} {}
Q_DECL_CONSTEXPR QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3,
@@ -147,7 +147,7 @@ public:
#if defined(Q_OS_WIN)
// On Windows we have a type GUID that is used by the platform API, so we
// provide convenience operators to cast from and to this type.
-#if defined(Q_COMPILER_INITIALIZER_LISTS) && !defined(Q_QDOC)
+#if defined(Q_COMPILER_UNIFORM_INIT) && !defined(Q_QDOC)
Q_DECL_CONSTEXPR QUuid(const GUID &guid)
: data1(guid.Data1), data2(guid.Data2), data3(guid.Data3),
data4{guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index ddcc25f7b7..782ae90698 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -137,12 +137,11 @@ public:
typename Ops::Type _q_value;
- // Non-atomic API
+ // Everything below is either implemented in ../arch/qatomic_XXX.h or (as fallback) in qgenericatomic.h
+
T load() const Q_DECL_NOTHROW { return Ops::load(_q_value); }
void store(T newValue) Q_DECL_NOTHROW { Ops::store(_q_value, newValue); }
- // Atomic API, implemented in qatomic_XXX.h
-
T loadAcquire() const Q_DECL_NOTHROW { return Ops::loadAcquire(_q_value); }
void storeRelease(T newValue) Q_DECL_NOTHROW { Ops::storeRelease(_q_value, newValue); }
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp
index e4cdf7a985..ffda3c4fad 100644
--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -98,7 +98,7 @@ QT_BEGIN_NAMESPACE
\since 4.4
\value Recursive In this mode, a thread can lock the same
- QReadWriteLock multiple times and the mutex won't be unlocked
+ QReadWriteLock multiple times. The QReadWriteLock won't be unlocked
until a corresponding number of unlock() calls have been made.
\value NonRecursive In this mode, a thread may only lock a
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 3de1e991c1..903e72c151 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -232,7 +232,7 @@ void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread)
qt_adopted_thread_handles.prepend(qt_adopted_thread_wakeup);
}
- CreateThread(0, 0, qt_adopted_thread_watcher_function, 0, 0, &qt_adopted_thread_watcher_id);
+ CloseHandle(CreateThread(0, 0, qt_adopted_thread_watcher_function, 0, 0, &qt_adopted_thread_watcher_id));
} else {
SetEvent(qt_adopted_thread_wakeup);
}
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index eb06bd4713..03b10903ab 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -1854,7 +1854,7 @@ QByteArray &QByteArray::remove(int pos, int len)
if (len <= 0 || uint(pos) >= uint(d->size))
return *this;
detach();
- if (pos + len >= d->size) {
+ if (len >= d->size - pos) {
resize(pos);
} else {
memmove(d->data() + pos, d->data() + pos + len, d->size - pos - len);
diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp
index a3a9ef940b..9c97d6b158 100644
--- a/src/corelib/tools/qcollator.cpp
+++ b/src/corelib/tools/qcollator.cpp
@@ -99,7 +99,7 @@ QCollator::QCollator(const QCollator &other)
*/
QCollator::~QCollator()
{
- if (!d->ref.deref())
+ if (d && !d->ref.deref())
delete d;
}
@@ -109,14 +109,41 @@ QCollator::~QCollator()
QCollator &QCollator::operator=(const QCollator &other)
{
if (this != &other) {
- if (!d->ref.deref())
+ if (d && !d->ref.deref())
delete d;
d = other.d;
- d->ref.ref();
+ if (d) d->ref.ref();
}
return *this;
}
+/*
+ \fn void QCollator::QCollator(QCollator &&other)
+
+ Move constructor. Moves from \a other into this collator.
+
+ Note that a moved-from QCollator can only be destroyed or assigned
+ to. The effect of calling other functions than the destructor or
+ one of the assignment operators is undefined.
+*/
+
+/*
+ \fn QCollator &QCollator::operator=(QCollator &&other)
+
+ Move-assigns from \a other to this collator.
+
+ Note that a moved-from QCollator can only be destroyed or assigned
+ to. The effect of calling other functions than the destructor or
+ one of the assignment operators is undefined.
+*/
+
+/*!
+ \fn void QCollator::swap(QCollator &other)
+
+ Swaps this collator with \a other. This function is very fast and
+ never fails.
+*/
+
/*!
\internal
*/
@@ -301,12 +328,13 @@ QCollatorSortKey& QCollatorSortKey::operator=(const QCollatorSortKey &other)
}
/*!
- \fn bool QCollatorSortKey::operator<(const QCollatorSortKey &otherKey) const
+ \fn bool operator<(const QCollatorSortKey &lhs, const QCollatorSortKey &rhs)
+ \relates QCollatorSortKey
- According to the QCollator that created the key, returns \c true if the
- key should be sorted before than \a otherKey; otherwise returns \c false.
+ According to the QCollator that created the keys, returns \c true if \a lhs
+ should be sorted before \a rhs; otherwise returns \c false.
- \sa compare()
+ \sa QCollatorSortKey::compare()
*/
/*!
diff --git a/src/corelib/tools/qcollator.h b/src/corelib/tools/qcollator.h
index b99fd1c0cc..781e95b10c 100644
--- a/src/corelib/tools/qcollator.h
+++ b/src/corelib/tools/qcollator.h
@@ -61,10 +61,11 @@ public:
QCollatorSortKey &operator=(const QCollatorSortKey &other);
#ifdef Q_COMPILER_RVALUE_REFS
inline QCollatorSortKey &operator=(QCollatorSortKey &&other)
- { qSwap(d, other.d); return *this; }
+ { swap(other); return *this; }
#endif
+ void swap(QCollatorSortKey &other)
+ { d.swap(other.d); }
- bool operator<(const QCollatorSortKey &key) const;
int compare(const QCollatorSortKey &key) const;
protected:
@@ -76,13 +77,27 @@ private:
QCollatorSortKey();
};
+inline bool operator<(const QCollatorSortKey &lhs, const QCollatorSortKey &rhs)
+{
+ return lhs.compare(rhs) < 0;
+}
+
class Q_CORE_EXPORT QCollator
{
public:
- QCollator(const QLocale &locale = QLocale());
+ explicit QCollator(const QLocale &locale = QLocale());
QCollator(const QCollator &);
~QCollator();
QCollator &operator=(const QCollator &);
+#ifdef Q_COMPILER_RVALUE_REFS
+ QCollator(QCollator &&other)
+ : d(other.d) { other.d = 0; }
+ QCollator &operator=(QCollator &&other)
+ { swap(other); return *this; }
+#endif
+
+ void swap(QCollator &other)
+ { qSwap(d, other.d); }
void setLocale(const QLocale &locale);
QLocale locale() const;
@@ -111,6 +126,9 @@ private:
void detach();
};
+Q_DECLARE_SHARED(QCollatorSortKey)
+Q_DECLARE_SHARED(QCollator)
+
QT_END_NAMESPACE
#endif // QCOLLATOR_P_H
diff --git a/src/corelib/tools/qcollator_icu.cpp b/src/corelib/tools/qcollator_icu.cpp
index 46f830a34c..407a493d25 100644
--- a/src/corelib/tools/qcollator_icu.cpp
+++ b/src/corelib/tools/qcollator_icu.cpp
@@ -151,11 +151,6 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const
return QCollatorSortKey(new QCollatorSortKeyPrivate(result));
}
-bool QCollatorSortKey::operator<(const QCollatorSortKey &otherKey) const
-{
- return d->m_key < otherKey.d->m_key;
-}
-
int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
{
return qstrcmp(d->m_key, otherKey.d->m_key);
diff --git a/src/corelib/tools/qcollator_macx.cpp b/src/corelib/tools/qcollator_macx.cpp
index 8edd190fbe..8985cd4eba 100644
--- a/src/corelib/tools/qcollator_macx.cpp
+++ b/src/corelib/tools/qcollator_macx.cpp
@@ -162,11 +162,6 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const
return QCollatorSortKey(new QCollatorSortKeyPrivate(ret));
}
-bool QCollatorSortKey::operator<(const QCollatorSortKey &key) const
-{
- return compare(key) < 0;
-}
-
int QCollatorSortKey::compare(const QCollatorSortKey &key) const
{
SInt32 order;
diff --git a/src/corelib/tools/qcollator_posix.cpp b/src/corelib/tools/qcollator_posix.cpp
index a43618dcf1..b47b546d01 100644
--- a/src/corelib/tools/qcollator_posix.cpp
+++ b/src/corelib/tools/qcollator_posix.cpp
@@ -135,11 +135,6 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const
return QCollatorSortKey(new QCollatorSortKeyPrivate(result));
}
-bool QCollatorSortKey::operator<(const QCollatorSortKey &otherKey) const
-{
- return compare(otherKey) < 0;
-}
-
int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
{
return std::wcscmp(d->m_key.constData(),
diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp
index 6cc15891f5..9a672a0505 100644
--- a/src/corelib/tools/qcollator_win.cpp
+++ b/src/corelib/tools/qcollator_win.cpp
@@ -179,11 +179,6 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const
return QCollatorSortKey(new QCollatorSortKeyPrivate(ret));
}
-bool QCollatorSortKey::operator<(const QCollatorSortKey &otherKey) const
-{
- return d->m_key < otherKey.d->m_key;
-}
-
int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
{
return d->m_key.compare(otherKey.d->m_key);
diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp
index 8054542333..5463e4f0c1 100644
--- a/src/corelib/tools/qcommandlineparser.cpp
+++ b/src/corelib/tools/qcommandlineparser.cpp
@@ -845,11 +845,50 @@ static QString wrapText(const QString &names, int longestOptionNameString, const
{
const QLatin1Char nl('\n');
QString text = QStringLiteral(" ") + names.leftJustified(longestOptionNameString) + QLatin1Char(' ');
- const int leftColumnWidth = text.length();
- const int rightColumnWidth = 79 - leftColumnWidth;
- text += description.left(rightColumnWidth) + nl;
- for (int n = rightColumnWidth; n < description.length(); n += rightColumnWidth)
- text += QStringLiteral(" ").repeated(leftColumnWidth) + description.mid(n, rightColumnWidth) + nl;
+ const int indent = text.length();
+ int lineStart = 0;
+ int lastBreakable = -1;
+ const int max = 79 - indent;
+ int x = 0;
+ const int len = description.length();
+
+ for (int i = 0; i < len; ++i) {
+ ++x;
+ const QChar c = description.at(i);
+ if (c.isSpace())
+ lastBreakable = i;
+
+ int breakAt = -1;
+ int nextLineStart = -1;
+ if (x > max && lastBreakable != -1) {
+ // time to break and we know where
+ breakAt = lastBreakable;
+ nextLineStart = lastBreakable + 1;
+ } else if ((x > max - 1 && lastBreakable == -1) || i == len - 1) {
+ // time to break but found nowhere [-> break here], or end of last line
+ breakAt = i + 1;
+ nextLineStart = breakAt;
+ } else if (c == nl) {
+ // forced break
+ breakAt = i;
+ nextLineStart = i + 1;
+ }
+
+ if (breakAt != -1) {
+ const int numChars = breakAt - lineStart;
+ //qDebug() << "breakAt=" << description.at(breakAt) << "breakAtSpace=" << breakAtSpace << lineStart << "to" << breakAt << description.mid(lineStart, numChars);
+ if (lineStart > 0)
+ text += QString(indent, QLatin1Char(' '));
+ text += description.midRef(lineStart, numChars) + nl;
+ x = 0;
+ lastBreakable = -1;
+ lineStart = nextLineStart;
+ if (lineStart < len && description.at(lineStart).isSpace())
+ ++lineStart; // don't start a line with a space
+ i = lineStart;
+ }
+ }
+
return text;
}
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 6620c55a0f..a95c7f53f7 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -2685,10 +2685,10 @@ void QDateTimePrivate::getDateTime(QDate *date, QTime *time) const
{
msecsToTime(m_msecs, date, time);
- if (isNullDate())
+ if (date && isNullDate())
*date = QDate();
- if (isNullTime())
+ if (time && isNullTime())
*time = QTime();
}
@@ -2768,9 +2768,6 @@ void QDateTimePrivate::refreshDateTime()
}
// We have a valid date and time and a Qt::LocalTime or Qt::TimeZone that needs calculating
- QDate date;
- QTime time;
- getDateTime(&date, &time);
// LocalTime and TimeZone might fall into "missing" DaylightTime transition hour
// Calling toEpochMSecs will adjust the returned date/time if it does
QDate testDate;
@@ -2784,7 +2781,7 @@ void QDateTimePrivate::refreshDateTime()
epochMSecs = zoneMSecsToEpochMSecs(m_msecs, m_timeZone, &testDate, &testTime);
#endif // QT_BOOTSTRAPPED
}
- if (testDate == date && testTime == time) {
+ if (timeToMSecs(testDate, testTime) == m_msecs) {
setValidDateTime();
// Cache the offset to use in toMSecsSinceEpoch()
m_offsetFromUtc = (m_msecs - epochMSecs) / 1000;
@@ -3097,9 +3094,10 @@ bool QDateTime::isValid() const
QDate QDateTime::date() const
{
+ if (d->isNullDate())
+ return QDate();
QDate dt;
- QTime tm;
- d->getDateTime(&dt, &tm);
+ msecsToTime(d->m_msecs, &dt, 0);
return dt;
}
@@ -3111,9 +3109,10 @@ QDate QDateTime::date() const
QTime QDateTime::time() const
{
- QDate dt;
+ if (d->isNullTime())
+ return QTime();
QTime tm;
- d->getDateTime(&dt, &tm);
+ msecsToTime(d->m_msecs, 0, &tm);
return tm;
}
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index fb233c0640..0eb202c5e2 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -531,7 +531,11 @@ static const QLocaleData *default_data = 0;
static uint default_number_options = 0;
static const QLocaleData *const c_data = locale_data;
-static QLocalePrivate c_private = { c_data, Q_BASIC_ATOMIC_INITIALIZER(1), 0 };
+static QLocalePrivate *c_private()
+{
+ static QLocalePrivate c_locale = { c_data, Q_BASIC_ATOMIC_INITIALIZER(1), 0 };
+ return &c_locale;
+}
#ifndef QT_NO_SYSTEMLOCALE
@@ -700,7 +704,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, defaultLocalePriva
static QLocalePrivate *localePrivateByName(const QString &name)
{
if (name == QLatin1String("C"))
- return &c_private;
+ return c_private();
return QLocalePrivate::create(findLocaleData(name));
}
@@ -708,7 +712,7 @@ static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Sc
QLocale::Country country)
{
if (language == QLocale::C)
- return &c_private;
+ return c_private();
const QLocaleData *data = QLocaleData::findLocaleData(language, script, country);
diff --git a/src/corelib/tools/qlocale_blackberry.cpp b/src/corelib/tools/qlocale_blackberry.cpp
index e2dfa6c801..48faa73070 100644
--- a/src/corelib/tools/qlocale_blackberry.cpp
+++ b/src/corelib/tools/qlocale_blackberry.cpp
@@ -68,17 +68,20 @@ QBBSystemLocaleData::QBBSystemLocaleData()
, measurementNotifier(0)
, hourNotifier(0)
{
+ // Do not use qWarning to log warnings if qt_safe_open fails to open the pps file
+ // since the user code may install a message handler that invokes QLocale API again
+ // (i.e QDate, QDateTime, ...) which will cause a deadlock.
if ((measurementFd = qt_safe_open(ppsUomPath, O_RDONLY)) == -1)
- qWarning("Failed to open uom pps, errno=%d", errno);
+ fprintf(stderr, "Failed to open uom pps, errno=%d\n", errno);
if ((regionFd = qt_safe_open(ppsRegionLocalePath, O_RDONLY)) == -1)
- qWarning("Failed to open region pps, errno=%d", errno);
+ fprintf(stderr, "Failed to open region pps, errno=%d\n", errno);
if ((languageFd = qt_safe_open(ppsLanguageLocalePath, O_RDONLY)) == -1)
- qWarning("Failed to open language pps, errno=%d", errno);
+ fprintf(stderr, "Failed to open language pps, errno=%d\n", errno);
if ((hourFd = qt_safe_open(ppsHourFormatPath, O_RDONLY)) == -1)
- qWarning("Failed to open hour format pps, errno=%d", errno);
+ fprintf(stderr, "Failed to open hour format pps, errno=%d\n", errno);
// we cannot call this directly, because by the time this constructor is
// called, the event dispatcher has not yet been created, causing the
@@ -186,8 +189,12 @@ QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd)
char buffer[ppsBufferSize];
int bytes = qt_safe_read(ppsFd, buffer, ppsBufferSize - 1);
+ // This method is called in the ctor(), so do not use qWarning to log warnings
+ // if qt_safe_read fails to read the pps file
+ // since the user code may install a message handler that invokes QLocale API again
+ // (i.e QDate, QDateTime, ...) which will cause a deadlock.
if (bytes == -1) {
- qWarning("Failed to read Locale pps, errno=%d", errno);
+ fprintf(stderr, "Failed to read pps object:%s, errno=%d\n", ppsObject, errno);
return result;
}
// ensure data is null terminated
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index 9aebbb7b3c..22d744f869 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -897,6 +897,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
*/
/*! \fn const Key &QMap::firstKey() const
+ \since 5.2
Returns a reference to the smallest key in the map.
This function assumes that the map is not empty.
@@ -907,6 +908,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
*/
/*! \fn const Key &QMap::lastKey() const
+ \since 5.2
Returns a reference to the largest key in the map.
This function assumes that the map is not empty.
@@ -917,6 +919,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
*/
/*! \fn T &QMap::first()
+ \since 5.2
Returns a reference to the first value in the map, that is the value mapped
to the smallest key. This function assumes that the map is not empty.
@@ -927,11 +930,13 @@ void QMapDataBase::freeData(QMapDataBase *d)
*/
/*! \fn const T &QMap::first() const
+ \since 5.2
\overload
*/
/*! \fn T &QMap::last()
+ \since 5.2
Returns a reference to the last value in the map, that is the value mapped
to the largest key. This function assumes that the map is not empty.
@@ -942,6 +947,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
*/
/*! \fn const T &QMap::last() const
+ \since 5.2
\overload
*/
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 150adfe192..77d002e4d5 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -455,8 +455,8 @@ const QString::Null QString::null = { };
your applications will be easy to translate if you want to expand
your application's market at some point. The two main cases where
QByteArray is appropriate are when you need to store raw binary
- data, and when memory conservation is critical (e.g., with
- \l{Qt for Embedded Linux}).
+ data, and when memory conservation is critical (like in embedded
+ systems).
\tableofcontents
@@ -5048,7 +5048,7 @@ int QString::compare_helper(const QChar *data1, int length1, QLatin1String s2,
On Mac OS X since Qt 4.3, this function compares according the
"Order for sorted lists" setting in the International preferences panel.
- \sa compare(), QTextCodec::locale()
+ \sa compare(), QLocale
*/
/*!
@@ -8463,7 +8463,7 @@ QStringRef QStringRef::appendTo(QString *string) const
On Mac OS X, this function compares according the
"Order for sorted lists" setting in the International prefereces panel.
- \sa compare(), QTextCodec::locale()
+ \sa compare(), QLocale
*/
/*!
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 3933e3978e..798ff2f3e0 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -65,8 +65,10 @@ namespace std
#endif
#ifdef Q_OS_MAC
-Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
Q_FORWARD_DECLARE_CF_TYPE(CFString);
+# ifdef __OBJC__
+Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
+# endif
#endif
QT_BEGIN_NAMESPACE
@@ -682,8 +684,10 @@ public:
#if defined(Q_OS_MAC) || defined(Q_QDOC)
static QString fromCFString(CFStringRef string);
CFStringRef toCFString() const Q_DECL_CF_RETURNS_RETAINED;
+# if defined(__OBJC__) || defined(Q_QDOC)
static QString fromNSString(const NSString *string);
NSString *toNSString() const Q_DECL_NS_RETURNS_AUTORELEASED;
+# endif
#endif
// compatibility
struct Null { };
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index 9c7c54ea09..24c20b46c7 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -107,7 +107,7 @@ public:
QTimeZoneSingleton() : backend(newBackendTimeZone()) {}
// The backend_tz is the tz to use in static methods such as availableTimeZoneIds() and
- // isTimeZoneIdAvailable() and to create named Olsen time zones. This is usually the host
+ // isTimeZoneIdAvailable() and to create named IANA time zones. This is usually the host
// system, but may be different if the host resources are insufficient or if
// QT_NO_SYSTEMLOCALE is set. A simple UTC backend is used if no alternative is available.
QSharedDataPointer<QTimeZonePrivate> backend;
@@ -137,18 +137,21 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
\section1
- \section2 Olsen Time Zone IDs
+ \section2 IANA Time Zone IDs
- QTimeZone uses the Olsen time zone IDs as defined in the IANA Time Zone
+ QTimeZone uses the IANA time zone IDs as defined in the IANA Time Zone
Database (http://www.iana.org/time-zones). This is to ensure a standard ID
- across all supported platforms. Most platforms support the Olsen IDs
+ across all supported platforms. Most platforms support the IANA IDs
and the IANA Database natively, but for Windows a mapping is required to
the native IDs. See below for more details.
- The Olsen IDs can and do change on a regular basis, and can vary depending
+ The IANA IDs can and do change on a regular basis, and can vary depending
on how recently the host system data was updated. As such you cannot rely
on any given ID existing on any host system. You must use
- availableTimeZoneIds() to determine what Olsen IDs are available.
+ availableTimeZoneIds() to determine what IANA IDs are available.
+
+ The IANA IDs and database are also know as the Olson IDs and database,
+ named after their creator.
\section2 UTC Offset Time Zones
@@ -167,7 +170,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
the current year.
QTimeZone uses a conversion table derived form the Unicode CLDR data to map
- between Olsen IDs and Windows IDs. Depending on your version of Windows
+ between IANA IDs and Windows IDs. Depending on your version of Windows
and Qt, this table may not be able to provide a valid conversion, in which
"UTC" will be returned.
@@ -182,7 +185,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
If you require a QDateTime that uses the current system time zone at any
given moment then you should use a Qt::TimeSpec of Qt::LocalTime.
- The method systemTimeZoneId() returns the current system Olsen time zone
+ The method systemTimeZoneId() returns the current system IANA time zone
ID which on OSX and Linux will always be correct. On Windows this ID is
translated from the the Windows system ID using an internal translation
table and the user's selected country. As a consequence there is a small
@@ -325,7 +328,7 @@ QTimeZone::QTimeZone()
}
/*!
- Creates an instance of the requested time zone \a olsenId.
+ Creates an instance of the requested time zone \a ianaId.
The ID must be one of the available system IDs otherwise an invalid
time zone will be returned.
@@ -333,14 +336,14 @@ QTimeZone::QTimeZone()
\sa availableTimeZoneIds()
*/
-QTimeZone::QTimeZone(const QByteArray &olsenId)
+QTimeZone::QTimeZone(const QByteArray &ianaId)
{
// Try and see if it's a valid UTC offset ID, just as quick to try create as look-up
- d = new QUtcTimeZonePrivate(olsenId);
+ d = new QUtcTimeZonePrivate(ianaId);
// If not a valid UTC offset ID then try create it with the system backend
// Relies on backend not creating valid tz with invalid name
if (!d->isValid())
- d = newBackendTimeZone(olsenId);
+ d = newBackendTimeZone(ianaId);
}
/*!
@@ -361,14 +364,14 @@ QTimeZone::QTimeZone(int offsetSeconds)
}
/*!
- Creates a custom time zone with an ID of \a olsenId and an offset from UTC
+ Creates a custom time zone with an ID of \a ianaId and an offset from UTC
of \a offsetSeconds. The \a name will be the name used by displayName()
for the LongName, the \a abbreviation will be used by displayName() for the
ShortName and by abbreviation(), and the optional \a country will be used
by country(). The \a comment is an optional note that may be displayed in
a GUI to assist users in selecting a time zone.
- The \a olsenId must not be one of the available system IDs returned by
+ The \a ianaId must not be one of the available system IDs returned by
availableTimeZoneIds(). The \a offsetSeconds from UTC must be in the range
-14 hours to +14 hours.
@@ -376,12 +379,12 @@ QTimeZone::QTimeZone(int offsetSeconds)
default value of QLocale::AnyCountry.
*/
-QTimeZone::QTimeZone(const QByteArray &olsenId, int offsetSeconds, const QString &name,
+QTimeZone::QTimeZone(const QByteArray &ianaId, int offsetSeconds, const QString &name,
const QString &abbreviation, QLocale::Country country, const QString &comment)
{
- // olsenId must be a valid ID and must not clash with the standard system names
- if (QTimeZonePrivate::isValidId(olsenId) && !availableTimeZoneIds().contains(olsenId))
- d = new QUtcTimeZonePrivate(olsenId, offsetSeconds, name, abbreviation, country, comment);
+ // ianaId must be a valid ID and must not clash with the standard system names
+ if (QTimeZonePrivate::isValidId(ianaId) && !availableTimeZoneIds().contains(ianaId))
+ d = new QUtcTimeZonePrivate(ianaId, offsetSeconds, name, abbreviation, country, comment);
else
d = 0;
}
@@ -424,13 +427,18 @@ QTimeZone &QTimeZone::operator=(const QTimeZone &other)
return *this;
}
+/*
+ \fn void QTimeZone::swap(QTimeZone &other)
+
+ Swaps this timezone with \a other. This function is very fast and
+ never fails.
+*/
+
/*!
\fn QTimeZone &QTimeZone::operator=(QTimeZone &&other)
Move-assigns \a other to this QTimeZone instance, transferring the
ownership of the managed pointer to this instance.
-
- \since 5.2
*/
/*!
@@ -470,10 +478,10 @@ bool QTimeZone::isValid() const
}
/*!
- Returns the Olsen ID for the time zone.
+ Returns the IANA ID for the time zone.
- Olsen IDs are used on all platforms. On Windows these are translated
- from the Windows ID into the closest Olsen ID for the time zone and country.
+ IANA IDs are used on all platforms. On Windows these are translated
+ from the Windows ID into the closest IANA ID for the time zone and country.
*/
QByteArray QTimeZone::id() const
@@ -702,6 +710,9 @@ bool QTimeZone::hasTransitions() const
This is most useful when you have a Transition time and wish to find the
Transition after it.
+ If there is no transition after the given \a afterDateTime then an invalid
+ OffsetData will be returned with an invalid QDateTime.
+
The given \a afterDateTime is exclusive.
\sa hasTransitions(), previousTransition(), transitions()
@@ -720,6 +731,9 @@ QTimeZone::OffsetData QTimeZone::nextTransition(const QDateTime &afterDateTime)
This is most useful when you have a Transition time and wish to find the
Transition before it.
+ If there is no transition before the given \a beforeDateTime then an invalid
+ OffsetData will be returned with an invalid QDateTime.
+
The given \a beforeDateTime is exclusive.
\sa hasTransitions(), nextTransition(), transitions()
@@ -757,7 +771,7 @@ QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime,
// Static methods
/*!
- Returns the current system time zone Olsen ID.
+ Returns the current system time zone IANA ID.
On Windows this ID is translated from the the Windows ID using an internal
translation table and the user's selected country. As a consequence there
@@ -771,20 +785,20 @@ QByteArray QTimeZone::systemTimeZoneId()
}
/*!
- Returns \c true if a given time zone \a olsenId is available on this system.
+ Returns \c true if a given time zone \a ianaId is available on this system.
\sa availableTimeZoneIds()
*/
-bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &olsenId)
+bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &ianaId)
{
// isValidId is not strictly required, but faster to weed out invalid
// IDs as availableTimeZoneIds() may be slow
- return (QTimeZonePrivate::isValidId(olsenId) && (availableTimeZoneIds().contains(olsenId)));
+ return (QTimeZonePrivate::isValidId(ianaId) && (availableTimeZoneIds().contains(ianaId)));
}
/*!
- Returns a list of all available Olsen time zone IDs on this system.
+ Returns a list of all available IANA time zone IDs on this system.
\sa isTimeZoneIdAvailable()
*/
@@ -799,7 +813,7 @@ QList<QByteArray> QTimeZone::availableTimeZoneIds()
}
/*!
- Returns a list of all available Olsen time zone IDs for a given \a country.
+ Returns a list of all available IANA time zone IDs for a given \a country.
As a special case, a \a country of Qt::AnyCountry returns those time zones
that do not have any country related to them, such as UTC. If you require
@@ -819,7 +833,7 @@ QList<QByteArray> QTimeZone::availableTimeZoneIds(QLocale::Country country)
}
/*!
- Returns a list of all available Olsen time zone IDs with a given standard
+ Returns a list of all available IANA time zone IDs with a given standard
time offset of \a offsetSeconds.
\sa isTimeZoneIdAvailable()
@@ -835,79 +849,79 @@ QList<QByteArray> QTimeZone::availableTimeZoneIds(int offsetSeconds)
}
/*!
- Returns the Windows ID equivalent to the given \a olsenId.
+ Returns the Windows ID equivalent to the given \a ianaId.
- \sa windowsIdToDefaultOlsenId(), windowsIdToOlsenIds()
+ \sa windowsIdToDefaultIanaId(), windowsIdToIanaIds()
*/
-QByteArray QTimeZone::olsenIdToWindowsId(const QByteArray &olsenId)
+QByteArray QTimeZone::ianaIdToWindowsId(const QByteArray &ianaId)
{
- return QTimeZonePrivate::olsenIdToWindowsId(olsenId);
+ return QTimeZonePrivate::ianaIdToWindowsId(ianaId);
}
/*!
- Returns the default Olsen ID for a given \a windowsId.
+ Returns the default IANA ID for a given \a windowsId.
- Because a Windows ID can cover several Olsen IDs in several different
- countries, this function returns the most frequently used Olsen ID with no
+ Because a Windows ID can cover several IANA IDs in several different
+ countries, this function returns the most frequently used IANA ID with no
regard for the country and should thus be used with care. It is usually
best to request the default for a specific country.
- \sa olsenIdToWindowsId(), windowsIdToOlsenIds()
+ \sa ianaIdToWindowsId(), windowsIdToIanaIds()
*/
-QByteArray QTimeZone::windowsIdToDefaultOlsenId(const QByteArray &windowsId)
+QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId)
{
- return QTimeZonePrivate::windowsIdToDefaultOlsenId(windowsId);
+ return QTimeZonePrivate::windowsIdToDefaultIanaId(windowsId);
}
/*!
- Returns the default Olsen ID for a given \a windowsId and \a country.
+ Returns the default IANA ID for a given \a windowsId and \a country.
- Because a Windows ID can cover several Olsen IDs within a given country,
- the most frequently used Olsen ID in that country is returned.
+ Because a Windows ID can cover several IANA IDs within a given country,
+ the most frequently used IANA ID in that country is returned.
- As a special case, QLocale::AnyCountry returns the default of those Olsen IDs
+ As a special case, QLocale::AnyCountry returns the default of those IANA IDs
that do not have any specific country.
- \sa olsenIdToWindowsId(), windowsIdToOlsenIds()
+ \sa ianaIdToWindowsId(), windowsIdToIanaIds()
*/
-QByteArray QTimeZone::windowsIdToDefaultOlsenId(const QByteArray &windowsId,
+QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId,
QLocale::Country country)
{
- return QTimeZonePrivate::windowsIdToDefaultOlsenId(windowsId, country);
+ return QTimeZonePrivate::windowsIdToDefaultIanaId(windowsId, country);
}
/*!
- Returns all the Olsen IDs for a given \a windowsId.
+ Returns all the IANA IDs for a given \a windowsId.
The returned list is sorted alphabetically.
- \sa olsenIdToWindowsId(), windowsIdToDefaultOlsenId()
+ \sa ianaIdToWindowsId(), windowsIdToDefaultIanaId()
*/
-QList<QByteArray> QTimeZone::windowsIdToOlsenIds(const QByteArray &windowsId)
+QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId)
{
- return QTimeZonePrivate::windowsIdToOlsenIds(windowsId);
+ return QTimeZonePrivate::windowsIdToIanaIds(windowsId);
}
/*!
- Returns all the Olsen IDs for a given \a windowsId and \a country.
+ Returns all the IANA IDs for a given \a windowsId and \a country.
- As a special case QLocale::AnyCountry returns those Olsen IDs that do
+ As a special case QLocale::AnyCountry returns those IANA IDs that do
not have any specific country.
The returned list is in order of frequency of usage, i.e. larger zones
within a country are listed first.
- \sa olsenIdToWindowsId(), windowsIdToDefaultOlsenId()
+ \sa ianaIdToWindowsId(), windowsIdToDefaultIanaId()
*/
-QList<QByteArray> QTimeZone::windowsIdToOlsenIds(const QByteArray &windowsId,
+QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
QLocale::Country country)
{
- return QTimeZonePrivate::windowsIdToOlsenIds(windowsId, country);
+ return QTimeZonePrivate::windowsIdToIanaIds(windowsId, country);
}
#ifndef QT_NO_DATASTREAM
diff --git a/src/corelib/tools/qtimezone.h b/src/corelib/tools/qtimezone.h
index 1a6a923cf4..b038d66a65 100644
--- a/src/corelib/tools/qtimezone.h
+++ b/src/corelib/tools/qtimezone.h
@@ -77,9 +77,9 @@ public:
typedef QVector<OffsetData> OffsetDataList;
QTimeZone();
- explicit QTimeZone(const QByteArray &olsenId);
- QTimeZone(int offsetSeconds);
- QTimeZone(const QByteArray &zoneId, int offsetSeconds, const QString &name,
+ explicit QTimeZone(const QByteArray &ianaId);
+ explicit QTimeZone(int offsetSeconds);
+ /*implicit*/ QTimeZone(const QByteArray &zoneId, int offsetSeconds, const QString &name,
const QString &abbreviation, QLocale::Country country = QLocale::AnyCountry,
const QString &comment = QString());
QTimeZone(const QTimeZone &other);
@@ -87,9 +87,12 @@ public:
QTimeZone &operator=(const QTimeZone &other);
#ifdef Q_COMPILER_RVALUE_REFS
- QTimeZone &operator=(QTimeZone &&other) { std::swap(d, other.d); return *this; }
+ QTimeZone &operator=(QTimeZone &&other) { swap(other); return *this; }
#endif
+ void swap(QTimeZone &other)
+ { d.swap(other.d); }
+
bool operator==(const QTimeZone &other) const;
bool operator!=(const QTimeZone &other) const;
@@ -123,18 +126,18 @@ public:
static QByteArray systemTimeZoneId();
- static bool isTimeZoneIdAvailable(const QByteArray &olsenId);
+ static bool isTimeZoneIdAvailable(const QByteArray &ianaId);
static QList<QByteArray> availableTimeZoneIds();
static QList<QByteArray> availableTimeZoneIds(QLocale::Country country);
static QList<QByteArray> availableTimeZoneIds(int offsetSeconds);
- static QByteArray olsenIdToWindowsId(const QByteArray &olsenId);
- static QByteArray windowsIdToDefaultOlsenId(const QByteArray &windowsId);
- static QByteArray windowsIdToDefaultOlsenId(const QByteArray &windowsId,
+ static QByteArray ianaIdToWindowsId(const QByteArray &ianaId);
+ static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId);
+ static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId,
QLocale::Country country);
- static QList<QByteArray> windowsIdToOlsenIds(const QByteArray &windowsId);
- static QList<QByteArray> windowsIdToOlsenIds(const QByteArray &windowsId,
+ static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId);
+ static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId,
QLocale::Country country);
private:
@@ -149,6 +152,7 @@ private:
};
Q_DECLARE_TYPEINFO(QTimeZone::OffsetData, Q_MOVABLE_TYPE);
+Q_DECLARE_SHARED(QTimeZone)
#ifndef QT_NO_DATASTREAM
Q_CORE_EXPORT QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz);
diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp
index 8d5d60bf37..08a5ce0861 100644
--- a/src/corelib/tools/qtimezoneprivate.cpp
+++ b/src/corelib/tools/qtimezoneprivate.cpp
@@ -264,7 +264,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs)
// If the local msecs is less than the real local time of the transition
// then get the previous transition to use instead
if (forLocalMSecs < tran.atMSecsSinceEpoch + (tran.offsetFromUtc * 1000)) {
- while (forLocalMSecs < tran.atMSecsSinceEpoch + (tran.offsetFromUtc * 1000)) {
+ while (tran.atMSecsSinceEpoch != invalidMSecs()
+ && forLocalMSecs < tran.atMSecsSinceEpoch + (tran.offsetFromUtc * 1000)) {
nextTran = tran;
tran = previousTransition(tran.atMSecsSinceEpoch);
}
@@ -272,7 +273,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs)
// The zone msecs is after the transition, so check it is before the next tran
// If not try use the next transition instead
nextTran = nextTransition(tran.atMSecsSinceEpoch);
- while (forLocalMSecs >= nextTran.atMSecsSinceEpoch + (nextTran.offsetFromUtc * 1000)) {
+ while (nextTran.atMSecsSinceEpoch != invalidMSecs()
+ && forLocalMSecs >= nextTran.atMSecsSinceEpoch + (nextTran.offsetFromUtc * 1000)) {
tran = nextTran;
nextTran = nextTransition(tran.atMSecsSinceEpoch);
}
@@ -292,7 +294,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs)
// then use the prev tran as we default to the FirstOccurrence
// TODO Check if faster to just always get prev tran, or if faster using 6 hour check.
Data dstTran = previousTransition(tran.atMSecsSinceEpoch);
- if (dstTran.daylightTimeOffset > 0 && diffPrevTran < (dstTran.daylightTimeOffset * 1000))
+ if (dstTran.atMSecsSinceEpoch != invalidMSecs()
+ && dstTran.daylightTimeOffset > 0 && diffPrevTran < (dstTran.daylightTimeOffset * 1000))
tran = dstTran;
} else if (diffNextTran >= 0 && diffNextTran <= (nextTran.daylightTimeOffset * 1000)) {
// If time falls within last hour of standard time then is actually the missing hour
@@ -328,10 +331,11 @@ QTimeZonePrivate::DataList QTimeZonePrivate::transitions(qint64 fromMSecsSinceEp
qint64 toMSecsSinceEpoch) const
{
DataList list;
- if (toMSecsSinceEpoch > fromMSecsSinceEpoch) {
+ if (toMSecsSinceEpoch >= fromMSecsSinceEpoch) {
// fromMSecsSinceEpoch is inclusive but nextTransitionTime() is exclusive so go back 1 msec
Data next = nextTransition(fromMSecsSinceEpoch - 1);
- while (next.atMSecsSinceEpoch <= toMSecsSinceEpoch) {
+ while (next.atMSecsSinceEpoch != invalidMSecs()
+ && next.atMSecsSinceEpoch <= toMSecsSinceEpoch) {
list.append(next);
next = nextTransition(next.atMSecsSinceEpoch);
}
@@ -477,7 +481,7 @@ QString QTimeZonePrivate::isoOffsetFormat(int offsetFromUtc)
.arg(qAbs(mins) % 60, 2, 10, QLatin1Char('0'));
}
-QByteArray QTimeZonePrivate::olsenIdToWindowsId(const QByteArray &id)
+QByteArray QTimeZonePrivate::ianaIdToWindowsId(const QByteArray &id)
{
for (int i = 0; i < zoneDataTableSize; ++i) {
const QZoneData *data = zoneData(i);
@@ -487,7 +491,7 @@ QByteArray QTimeZonePrivate::olsenIdToWindowsId(const QByteArray &id)
return QByteArray();
}
-QByteArray QTimeZonePrivate::windowsIdToDefaultOlsenId(const QByteArray &windowsId)
+QByteArray QTimeZonePrivate::windowsIdToDefaultIanaId(const QByteArray &windowsId)
{
const quint16 windowsIdKey = toWindowsIdKey(windowsId);
for (int i = 0; i < windowsDataTableSize; ++i) {
@@ -498,17 +502,17 @@ QByteArray QTimeZonePrivate::windowsIdToDefaultOlsenId(const QByteArray &windows
return QByteArray();
}
-QByteArray QTimeZonePrivate::windowsIdToDefaultOlsenId(const QByteArray &windowsId,
+QByteArray QTimeZonePrivate::windowsIdToDefaultIanaId(const QByteArray &windowsId,
QLocale::Country country)
{
- const QList<QByteArray> list = windowsIdToOlsenIds(windowsId, country);
+ const QList<QByteArray> list = windowsIdToIanaIds(windowsId, country);
if (list.count() > 0)
return list.first();
else
return QByteArray();
}
-QList<QByteArray> QTimeZonePrivate::windowsIdToOlsenIds(const QByteArray &windowsId)
+QList<QByteArray> QTimeZonePrivate::windowsIdToIanaIds(const QByteArray &windowsId)
{
const quint16 windowsIdKey = toWindowsIdKey(windowsId);
QList<QByteArray> list;
@@ -524,7 +528,7 @@ QList<QByteArray> QTimeZonePrivate::windowsIdToOlsenIds(const QByteArray &window
return list;
}
-QList<QByteArray> QTimeZonePrivate::windowsIdToOlsenIds(const QByteArray &windowsId,
+QList<QByteArray> QTimeZonePrivate::windowsIdToIanaIds(const QByteArray &windowsId,
QLocale::Country country)
{
const quint16 windowsIdKey = toWindowsIdKey(windowsId);
diff --git a/src/corelib/tools/qtimezoneprivate_mac.mm b/src/corelib/tools/qtimezoneprivate_mac.mm
index 8d319aebbd..69d2c42d27 100644
--- a/src/corelib/tools/qtimezoneprivate_mac.mm
+++ b/src/corelib/tools/qtimezoneprivate_mac.mm
@@ -185,15 +185,14 @@ bool QMacTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
QTimeZonePrivate::Data QMacTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
{
const NSTimeInterval seconds = forMSecsSinceEpoch / 1000.0;
+ NSDate *date = [NSDate dateWithTimeIntervalSince1970:seconds];
Data data;
data.atMSecsSinceEpoch = forMSecsSinceEpoch;
- data.offsetFromUtc = [m_nstz secondsFromGMTForDate:
- [NSDate dateWithTimeIntervalSince1970:seconds]];
- data.daylightTimeOffset = [m_nstz daylightSavingTimeOffsetForDate:
- [NSDate dateWithTimeIntervalSince1970:seconds]];
+ data.offsetFromUtc = [m_nstz secondsFromGMTForDate:date];
+ data.daylightTimeOffset = [m_nstz daylightSavingTimeOffsetForDate:date];
data.standardTimeOffset = data.offsetFromUtc - data.daylightTimeOffset;
- data.abbreviation = QCFString::toQString([m_nstz abbreviationForDate:
- [NSDate dateWithTimeIntervalSince1970:seconds]]);
+ data.abbreviation = QCFString::toQString([m_nstz abbreviationForDate:date]);
+ [date release];
return data;
}
@@ -213,26 +212,46 @@ QTimeZonePrivate::Data QMacTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
{
QTimeZonePrivate::Data tran;
const NSTimeInterval seconds = afterMSecsSinceEpoch / 1000.0;
- NSDate *date = [NSDate dateWithTimeIntervalSince1970:seconds];
- const NSDate *next = [m_nstz nextDaylightSavingTimeTransitionAfterDate:date];
- const NSTimeInterval nextSecs = [next timeIntervalSince1970];
+ NSDate *nextDate = [NSDate dateWithTimeIntervalSince1970:seconds];
+ nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
+ const NSTimeInterval nextSecs = [nextDate timeIntervalSince1970];
+ if (nextDate == nil || nextSecs <= seconds) {
+ [nextDate release];
+ return invalidData();
+ }
tran.atMSecsSinceEpoch = nextSecs * 1000;
- tran.offsetFromUtc = [m_nstz secondsFromGMTForDate:
- [NSDate dateWithTimeIntervalSince1970:nextSecs]];
- tran.daylightTimeOffset = [m_nstz daylightSavingTimeOffsetForDate:
- [NSDate dateWithTimeIntervalSince1970:nextSecs]];
+ tran.offsetFromUtc = [m_nstz secondsFromGMTForDate:nextDate];
+ tran.daylightTimeOffset = [m_nstz daylightSavingTimeOffsetForDate:nextDate];
tran.standardTimeOffset = tran.offsetFromUtc - tran.daylightTimeOffset;
- tran.abbreviation = QCFString::toQString([m_nstz abbreviationForDate:date]);
- [next release];
- [date release];
+ tran.abbreviation = QCFString::toQString([m_nstz abbreviationForDate:nextDate]);
+ [nextDate release];
return tran;
}
QTimeZonePrivate::Data QMacTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
{
- // TODO No direct Mac API, so get all transitions since epoch and return the last one
- // Probably slow, need to optimize
- return transitions(0, beforeMSecsSinceEpoch - 1).last();
+ // No direct Mac API, so get all transitions since epoch and return the last one
+ QList<int> secsList;
+ if (beforeMSecsSinceEpoch > 0) {
+ const int endSecs = beforeMSecsSinceEpoch / 1000.0;
+ NSTimeInterval prevSecs = 0;
+ NSTimeInterval nextSecs = 0;
+ NSDate *nextDate = [NSDate dateWithTimeIntervalSince1970:nextSecs];
+ // If invalid may return a nil date or an Epoch date
+ nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
+ nextSecs = [nextDate timeIntervalSince1970];
+ while (nextDate != nil && nextSecs > prevSecs && nextSecs < endSecs) {
+ secsList.append(nextSecs);
+ prevSecs = nextSecs;
+ nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
+ nextSecs = [nextDate timeIntervalSince1970];
+ }
+ [nextDate release];
+ }
+ if (secsList.size() >= 1)
+ return data(qint64(secsList.last()) * 1000);
+ else
+ return invalidData();
}
QByteArray QMacTimeZonePrivate::systemTimeZoneId() const
diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h
index 9f99f49fcf..108aec2654 100644
--- a/src/corelib/tools/qtimezoneprivate_p.h
+++ b/src/corelib/tools/qtimezoneprivate_p.h
@@ -146,12 +146,12 @@ public:
static bool isValidId(const QByteArray &olsenId);
static QString isoOffsetFormat(int offsetFromUtc);
- static QByteArray olsenIdToWindowsId(const QByteArray &olsenId);
- static QByteArray windowsIdToDefaultOlsenId(const QByteArray &windowsId);
- static QByteArray windowsIdToDefaultOlsenId(const QByteArray &windowsId,
+ static QByteArray ianaIdToWindowsId(const QByteArray &ianaId);
+ static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId);
+ static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId,
QLocale::Country country);
- static QList<QByteArray> windowsIdToOlsenIds(const QByteArray &windowsId);
- static QList<QByteArray> windowsIdToOlsenIds(const QByteArray &windowsId,
+ static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId);
+ static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId,
QLocale::Country country);
protected:
@@ -309,6 +309,7 @@ private:
bool operator==(const QTzTransitionRule &other) { return (stdOffset == other.stdOffset
&& dstOffset == other.dstOffset && abbreviationIndex == other.abbreviationIndex); }
};
+ Data dataForTzTransition(QTzTransitionTime tran) const;
QList<QTzTransitionTime> m_tranTimes;
QList<QTzTransitionRule> m_tranRules;
QList<QByteArray> m_abbreviations;
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 4bf19178fa..1fb6bb1b5a 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -149,11 +149,13 @@ static QTzHeader parseTzHeader(QDataStream &ds, bool *ok)
if (memcmp(hdr.tzh_magic, TZ_MAGIC, 4) != 0 || ds.status() != QDataStream::Ok)
return hdr;
- // Parse Version, 1 byte, before 2005 was '\0', since 2005 a '2'
+ // Parse Version, 1 byte, before 2005 was '\0', since 2005 a '2', since 2013 a '3'
ds >> ch;
hdr.tzh_version = ch;
- if (ds.status() != QDataStream::Ok || (hdr.tzh_version != '2' && hdr.tzh_version != '\0'))
+ if (ds.status() != QDataStream::Ok
+ || (hdr.tzh_version != '2' && hdr.tzh_version != '\0' && hdr.tzh_version != '3')) {
return hdr;
+ }
// Parse reserved space, 15 bytes
ds.readRawData(hdr.tzh_reserved, 15);
@@ -238,30 +240,31 @@ static QList<QTzType> parseTzTypes(QDataStream &ds, int tzh_typecnt)
return typeList;
}
-static QMap<int, QByteArray> parseTzAbbreviations(QDataStream &ds, int tzh_charcnt)
+static QMap<int, QByteArray> parseTzAbbreviations(QDataStream &ds, int tzh_charcnt, QList<QTzType> typeList)
{
// Parse the abbreviation list which is tzh_charcnt long with '\0' separated strings. The
- // tz_abbrind index points to the first char of the abbreviation in the array, not the
- // occurrence in the list. By parsing char at a time we can track the char index and convert
- // to an occurrence index. By using a map with tz_abbrind as ordered key we get both index
+ // QTzType.tz_abbrind index points to the first char of the abbreviation in the array, not the
+ // occurrence in the list. It can also point to a partial string so we need to use the actual typeList
+ // index values when parsing. By using a map with tz_abbrind as ordered key we get both index
// methods in one data structure and can convert the types afterwards.
QMap<int, QByteArray> map;
quint8 ch;
- QByteArray abbrev;
- // Track the start position of each abbreviation
- int tz_abbrind = 0;
+ QByteArray input;
+ // First parse the full abbrev string
for (int i = 0; i < tzh_charcnt && ds.status() == QDataStream::Ok; ++i) {
ds >> ch;
- if (ds.status() == QDataStream::Ok) {
- if (ch == '\0') {
- // Have reached end of an abbreviation, so add to map
- map[tz_abbrind] = abbrev;
- tz_abbrind = i + 1;
- abbrev.clear();
- } else {
- abbrev.append((char)ch);
- }
- }
+ if (ds.status() == QDataStream::Ok)
+ input.append(char(ch));
+ else
+ return map;
+ }
+ // Then extract all the substrings pointed to by typeList
+ foreach (const QTzType type, typeList) {
+ QByteArray abbrev;
+ for (int i = type.tz_abbrind; input.at(i) != '\0'; ++i)
+ abbrev.append(input.at(i));
+ // Have reached end of an abbreviation, so add to map
+ map[type.tz_abbrind] = abbrev;
}
return map;
}
@@ -371,7 +374,7 @@ static QDate calculatePosixDate(const QByteArray dateRule, int year)
}
}
-static QTime parsePosixTime(const QByteArray timeRule)
+static QTime parsePosixTime(const QByteArray &timeRule)
{
// Format "HH:mm:ss", put check parts count just in case
QList<QByteArray> parts = timeRule.split(':');
@@ -385,7 +388,7 @@ static QTime parsePosixTime(const QByteArray timeRule)
return QTime(2, 0, 0);
}
-static int parsePosixOffset(const QByteArray timeRule)
+static int parsePosixOffset(const QByteArray &timeRule)
{
// Format "[+|-]hh[:mm[:ss]]"
QList<QByteArray> parts = timeRule.split(':');
@@ -399,7 +402,9 @@ static int parsePosixOffset(const QByteArray timeRule)
return 0;
}
-static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray &posixRule, int startYear, int endYear)
+static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray &posixRule,
+ int startYear, int endYear,
+ int lastTranMSecs)
{
QList<QTimeZonePrivate::Data> list;
@@ -443,11 +448,13 @@ static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray
// If only the name part then no transitions
if (parts.count() == 1) {
QTimeZonePrivate::Data data;
- data.atMSecsSinceEpoch = 0;
+ data.atMSecsSinceEpoch = lastTranMSecs;
data.offsetFromUtc = utcOffset;
data.standardTimeOffset = utcOffset;
data.daylightTimeOffset = 0;
data.abbreviation = stdName;
+ list << data;
+ return list;
}
// If not populated the total dst offset is 1 hour
@@ -572,7 +579,7 @@ void QTzTimeZonePrivate::init(const QByteArray &olsenId)
QList<QTzType> typeList = parseTzTypes(ds, hdr.tzh_typecnt);
if (ds.status() != QDataStream::Ok)
return;
- QMap<int, QByteArray> abbrevMap = parseTzAbbreviations(ds, hdr.tzh_charcnt);
+ QMap<int, QByteArray> abbrevMap = parseTzAbbreviations(ds, hdr.tzh_charcnt, typeList);
if (ds.status() != QDataStream::Ok)
return;
parseTzLeapSeconds(ds, hdr.tzh_leapcnt, false);
@@ -583,7 +590,7 @@ void QTzTimeZonePrivate::init(const QByteArray &olsenId)
return;
// If version 2 then parse the second block of data
- if (hdr.tzh_version == '2') {
+ if (hdr.tzh_version == '2' || hdr.tzh_version == '3') {
ok = false;
QTzHeader hdr2 = parseTzHeader(ds, &ok);
if (!ok || ds.status() != QDataStream::Ok)
@@ -594,7 +601,7 @@ void QTzTimeZonePrivate::init(const QByteArray &olsenId)
typeList = parseTzTypes(ds, hdr2.tzh_typecnt);
if (ds.status() != QDataStream::Ok)
return;
- abbrevMap = parseTzAbbreviations(ds, hdr2.tzh_charcnt);
+ abbrevMap = parseTzAbbreviations(ds, hdr2.tzh_charcnt, typeList);
if (ds.status() != QDataStream::Ok)
return;
parseTzLeapSeconds(ds, hdr2.tzh_leapcnt, true);
@@ -682,12 +689,14 @@ QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
if (!m_icu)
m_icu = new QIcuTimeZonePrivate(m_id);
// TODO small risk may not match if tran times differ due to outdated files
- return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
#else
Q_UNUSED(nameType)
Q_UNUSED(locale)
- return abbreviation(atMSecsSinceEpoch);
#endif // QT_USE_ICU
+ return abbreviation(atMSecsSinceEpoch);
}
QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
@@ -698,19 +707,59 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
if (!m_icu)
m_icu = new QIcuTimeZonePrivate(m_id);
// TODO small risk may not match if tran times differ due to outdated files
- return m_icu->displayName(timeType, nameType, locale);
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(timeType, nameType, locale);
#else
Q_UNUSED(timeType)
Q_UNUSED(nameType)
Q_UNUSED(locale)
- const int atMSecsSinceEpoch = QDateTime::currentMSecsSinceEpoch();
- QTimeZonePrivate::Data tran = data(atMSecsSinceEpoch);
- while ((timeType == QTimeZone::StandardTime && tran.daylightTimeOffset != 0)
- || (timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset == 0)) {
- tran = nextTransition(tran.atMSecsSinceEpoch);
- }
- return tran.abbreviation;
#endif // QT_USE_ICU
+ // If no ICU available then have to use abbreviations instead
+ // Abbreviations don't have GenericTime
+ if (timeType == QTimeZone::GenericTime)
+ timeType = QTimeZone::StandardTime;
+
+ // Get current tran, if valid and is what we want, then use it
+ const qint64 currentMSecs = QDateTime::currentMSecsSinceEpoch();
+ QTimeZonePrivate::Data tran = data(currentMSecs);
+ if (tran.atMSecsSinceEpoch != invalidMSecs()
+ && ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
+ || (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0))) {
+ return tran.abbreviation;
+ }
+
+ // Otherwise get next tran and if valid and is what we want, then use it
+ tran = nextTransition(currentMSecs);
+ if (tran.atMSecsSinceEpoch != invalidMSecs()
+ && ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
+ || (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0))) {
+ return tran.abbreviation;
+ }
+
+ // Otherwise get prev tran and if valid and is what we want, then use it
+ tran = previousTransition(currentMSecs);
+ if (tran.atMSecsSinceEpoch != invalidMSecs())
+ tran = previousTransition(tran.atMSecsSinceEpoch);
+ if (tran.atMSecsSinceEpoch != invalidMSecs()
+ && ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
+ || (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0))) {
+ return tran.abbreviation;
+ }
+
+ // Otherwise is strange sequence, so work backwards through trans looking for first match, if any
+ for (int i = m_tranTimes.size() - 1; i >= 0; --i) {
+ if (m_tranTimes.at(i).atMSecsSinceEpoch <= currentMSecs) {
+ tran = dataForTzTransition(m_tranTimes.at(i));
+ if ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
+ || (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0)) {
+ return tran.abbreviation;
+ }
+ }
+ }
+
+ // Otherwise if no match use current data
+ return data(currentMSecs).abbreviation;
}
QString QTzTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
@@ -749,35 +798,55 @@ bool QTzTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
return (daylightTimeOffset(atMSecsSinceEpoch) != 0);
}
+QTimeZonePrivate::Data QTzTimeZonePrivate::dataForTzTransition(QTzTransitionTime tran) const
+{
+ QTimeZonePrivate::Data data;
+ data.atMSecsSinceEpoch = tran.atMSecsSinceEpoch;
+ QTzTransitionRule rule = m_tranRules.at(tran.ruleIndex);
+ data.standardTimeOffset = rule.stdOffset;
+ data.daylightTimeOffset = rule.dstOffset;
+ data.offsetFromUtc = rule.stdOffset + rule.dstOffset;
+ data.abbreviation = QString::fromUtf8(m_abbreviations.at(rule.abbreviationIndex));
+ return data;
+}
+
QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
{
- QTimeZonePrivate::Data data = invalidData();
- int lastTran = m_tranTimes.size() - 1;
- int tran;
- for (tran = lastTran; tran > 0; --tran) {
- if (m_tranTimes.at(tran).atMSecsSinceEpoch <= forMSecsSinceEpoch)
- break;
- }
- // If after the last transition time then we need to use the posix rule if available
- if (tran >= lastTran && !m_posixRule.isEmpty()) {
- QDateTime dt = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch);
- int year = dt.date().year();
- QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, year + 1);
- for (int i = posixTrans.size() - 1; i > 0; --i) {
+ // If the required time is after the last transition and we have a POSIX rule then use it
+ if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch
+ &&!m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) {
+ const int year = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch, Qt::UTC).date().year();
+ const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0;
+ QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1,
+ year + 1, lastMSecs);
+ for (int i = posixTrans.size() - 1; i >= 0; --i) {
if (posixTrans.at(i).atMSecsSinceEpoch <= forMSecsSinceEpoch) {
+ QTimeZonePrivate::Data data;
data = posixTrans.at(i);
data.atMSecsSinceEpoch = forMSecsSinceEpoch;
return data;
}
}
}
- data.atMSecsSinceEpoch = forMSecsSinceEpoch;
- QTzTransitionRule rule = m_tranRules.at(m_tranTimes.at(tran).ruleIndex);
- data.standardTimeOffset = rule.stdOffset;
- data.daylightTimeOffset = rule.dstOffset;
- data.offsetFromUtc = rule.stdOffset + rule.dstOffset;
- data.abbreviation = QString::fromUtf8(m_abbreviations.at(rule.abbreviationIndex));
- return data;
+
+ // Otherwise if we can find a valid tran then use its rule
+ for (int i = m_tranTimes.size() - 1; i >= 0; --i) {
+ if (m_tranTimes.at(i).atMSecsSinceEpoch <= forMSecsSinceEpoch) {
+ Data data = dataForTzTransition(m_tranTimes.at(i));
+ data.atMSecsSinceEpoch = forMSecsSinceEpoch;
+ return data;
+ }
+ }
+
+ // Otherwise use the earliest transition we have
+ if (m_tranTimes.size() > 0) {
+ Data data = dataForTzTransition(m_tranTimes.at(0));
+ data.atMSecsSinceEpoch = forMSecsSinceEpoch;
+ return data;
+ }
+
+ // Otherwise we have no rules, so probably an invalid tz, so return invalid data
+ return invalidData();
}
bool QTzTimeZonePrivate::hasTransitions() const
@@ -787,60 +856,54 @@ bool QTzTimeZonePrivate::hasTransitions() const
QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
{
- int lastTran = m_tranTimes.size() - 1;
- int tran;
- for (tran = 0; tran < lastTran; ++tran) {
- if (m_tranTimes.at(tran).atMSecsSinceEpoch > afterMSecsSinceEpoch)
- break;
- }
- // If after the last transition time then we need to use the posix rule if available
- if (tran >= lastTran && !m_posixRule.isEmpty()) {
- QDateTime dt = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch);
- int year = dt.date().year();
- QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, year + 1);
- for (int i = 0; i < posixTrans.size() - 1; ++i) {
+ // If the required time is after the last transition and we have a POSIX rule then use it
+ if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch
+ &&!m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) {
+ const int year = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch, Qt::UTC).date().year();
+ const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0;
+ QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1,
+ year + 1, lastMSecs);
+ for (int i = 0; i < posixTrans.size(); ++i) {
if (posixTrans.at(i).atMSecsSinceEpoch > afterMSecsSinceEpoch)
return posixTrans.at(i);
}
}
- // Otherwise use the transition we found
- QTimeZonePrivate::Data data;
- data.atMSecsSinceEpoch = m_tranTimes.at(tran).atMSecsSinceEpoch;
- QTzTransitionRule rule = m_tranRules.at(m_tranTimes.at(tran).ruleIndex);
- data.standardTimeOffset = rule.stdOffset;
- data.daylightTimeOffset = rule.dstOffset;
- data.offsetFromUtc = rule.stdOffset + rule.dstOffset;
- data.abbreviation = QString::fromUtf8(m_abbreviations.at(rule.abbreviationIndex));
- return data;
+
+ // Otherwise if we can find a valid tran then use its rule
+ for (int i = 0; i < m_tranTimes.size(); ++i) {
+ if (m_tranTimes.at(i).atMSecsSinceEpoch > afterMSecsSinceEpoch) {
+ return dataForTzTransition(m_tranTimes.at(i));
+ }
+ }
+
+ // Otherwise we have no rule, or there is no next transition, so return invalid data
+ return invalidData();
}
QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
{
- int lastTran = m_tranTimes.size() - 1;
- int tran;
- for (tran = lastTran; tran > 0; --tran) {
- if (m_tranTimes.at(tran).atMSecsSinceEpoch < beforeMSecsSinceEpoch)
- break;
- }
- // If after the last transition time then we need to use the posix rule if available
- if (tran >= lastTran && !m_posixRule.isEmpty()) {
- QDateTime dt = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch);
- int year = dt.date().year();
- QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, year + 1);
- for (int i = posixTrans.size() - 1; i > 0; --i) {
+ // If the required time is after the last transition and we have a POSIX rule then use it
+ if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch
+ &&!m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) {
+ const int year = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch, Qt::UTC).date().year();
+ const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0;
+ QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1,
+ year + 1, lastMSecs);
+ for (int i = posixTrans.size() - 1; i >= 0; --i) {
if (posixTrans.at(i).atMSecsSinceEpoch < beforeMSecsSinceEpoch)
return posixTrans.at(i);
}
}
- // Otherwise use the transition we found
- QTimeZonePrivate::Data data;
- data.atMSecsSinceEpoch = m_tranTimes.at(tran).atMSecsSinceEpoch;
- QTzTransitionRule rule = m_tranRules.at(m_tranTimes.at(tran).ruleIndex);
- data.standardTimeOffset = rule.stdOffset;
- data.daylightTimeOffset = rule.dstOffset;
- data.offsetFromUtc = rule.stdOffset + rule.dstOffset;
- data.abbreviation = QString::fromUtf8(m_abbreviations.at(rule.abbreviationIndex));
- return data;
+
+ // Otherwise if we can find a valid tran then use its rule
+ for (int i = m_tranTimes.size() - 1; i >= 0; --i) {
+ if (m_tranTimes.at(i).atMSecsSinceEpoch < beforeMSecsSinceEpoch) {
+ return dataForTzTransition(m_tranTimes.at(i));
+ }
+ }
+
+ // Otherwise we have no rule, so return invalid data
+ return invalidData();
}
// TODO Could cache the value and monitor the required files for any changes
diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp
index c219a49e1e..04588b2ba8 100644
--- a/src/corelib/tools/qtimezoneprivate_win.cpp
+++ b/src/corelib/tools/qtimezoneprivate_win.cpp
@@ -106,14 +106,6 @@ static QDate msecsToDate(qint64 msecs)
return QDate::fromJulianDay(jd);
}
-static qint64 systemtimeToMsecs(const SYSTEMTIME &systemtime)
-{
- FILETIME utcFileTime;
- SystemTimeToFileTime(&systemtime, &utcFileTime);
- ULONGLONG utcNSecs = (((ULONGLONG) utcFileTime.dwHighDateTime) << 32) + utcFileTime.dwLowDateTime;
- return (utcNSecs - FILETIME_UNIX_EPOCH) / 10000;
-}
-
static bool equalSystemtime(const SYSTEMTIME &t1, const SYSTEMTIME &t2)
{
return (t1.wYear == t2.wYear
@@ -262,6 +254,10 @@ static QByteArray windowsSystemZoneId()
static QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year)
{
+ // If month is 0 then there is no date
+ if (rule.wMonth == 0)
+ return QDate();
+
SYSTEMTIME time = rule;
// If the year isn't set, then the rule date is relative
if (time.wYear == 0) {
@@ -277,9 +273,10 @@ static QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year)
while (date.month() != time.wMonth)
date = date.addDays(-7);
return date;
- } else {
- return QDate(time.wYear, time.wMonth, time.wDay);
}
+
+ // If the year is set then is an absolute date
+ return QDate(time.wYear, time.wMonth, time.wDay);
}
// Converts a date/time value into msecs
@@ -293,19 +290,25 @@ static void calculateTransitionsForYear(const QWinTimeZonePrivate::QWinTransitio
qint64 *stdMSecs, qint64 *dstMSecs)
{
// TODO Consider caching the calculated values
-
- // The local time in Daylight Time when switches to Standard TIme
+ // The local time in Daylight Time when switches to Standard Time
QDate standardDate = calculateTransitionLocalDate(rule.standardTimeRule, year);
QTime standardTime = QTime(rule.standardTimeRule.wHour, rule.standardTimeRule.wMinute,
rule.standardTimeRule.wSecond);
- // The local time in Standard Time when switches to Daylight TIme
+ if (standardDate.isValid() && standardTime.isValid()) {
+ *stdMSecs = timeToMSecs(standardDate, standardTime)
+ + ((rule.standardTimeBias + rule.daylightTimeBias) * 60000);
+ } else {
+ *stdMSecs = QTimeZonePrivate::invalidMSecs();
+ }
+
+ // The local time in Standard Time when switches to Daylight Time
QDate daylightDate = calculateTransitionLocalDate(rule.daylightTimeRule, year);
QTime daylightTime = QTime(rule.daylightTimeRule.wHour, rule.daylightTimeRule.wMinute,
rule.daylightTimeRule.wSecond);
-
- *stdMSecs = timeToMSecs(standardDate, standardTime)
- + ((rule.standardTimeBias + rule.daylightTimeBias) * 60000);
- *dstMSecs = timeToMSecs(daylightDate, daylightTime) + (rule.standardTimeBias * 60000);
+ if (daylightDate.isValid() && daylightTime.isValid())
+ *dstMSecs = timeToMSecs(daylightDate, daylightTime) + (rule.standardTimeBias * 60000);
+ else
+ *dstMSecs = QTimeZonePrivate::invalidMSecs();
}
static QLocale::Country userCountry()
@@ -359,7 +362,7 @@ void QWinTimeZonePrivate::init(const QByteArray &olsenId)
m_windowsId = windowsSystemZoneId();
m_id = systemTimeZoneId();
} else {
- m_windowsId = olsenIdToWindowsId(olsenId);
+ m_windowsId = ianaIdToWindowsId(olsenId);
m_id = olsenId;
}
@@ -473,15 +476,8 @@ bool QWinTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
{
- // Convert MSecs to year to get transitions for, but around 31 Dec/1 Jan may not be right year
- // So get the year after we think we want transitions for, to be safe
- QDate date = msecsToDate(forMSecsSinceEpoch);
- int year;
- int month;
- int day;
- date.getDate(&year, &month, &day);
- if ((month == 12 && day == 31) || (month == 1 && day == 1))
- ++year;
+ // Convert MSecs to year to get transitions for, assumes no transitions around 31 Dec/1 Jan
+ int year = msecsToDate(forMSecsSinceEpoch).year();
qint64 first;
qint64 second;
@@ -492,21 +488,26 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
do {
// Convert the transition rules into msecs for the year we want to try
rule = ruleForYear(year);
+ // If no transition rules to calculate then no DST, so just use rule for std
+ if (rule.standardTimeRule.wMonth == 0 && rule.daylightTimeRule.wMonth == 0)
+ break;
calculateTransitionsForYear(rule, year, &stdMSecs, &dstMSecs);
- first = qMin(stdMSecs, dstMSecs);
- second = qMax(stdMSecs, dstMSecs);
- if (forMSecsSinceEpoch >= second)
+ if (stdMSecs < dstMSecs) {
+ first = stdMSecs;
+ second = dstMSecs;
+ } else {
+ first = dstMSecs;
+ second = stdMSecs;
+ }
+ if (forMSecsSinceEpoch >= second && second != invalidMSecs())
next = second;
- else if (forMSecsSinceEpoch >= first)
+ else if (forMSecsSinceEpoch >= first && first != invalidMSecs())
next = first;
// If didn't fall in this year, try the previous
--year;
- } while (forMSecsSinceEpoch < first && year >= MIN_YEAR);
+ } while (next == maxMSecs() && year >= MIN_YEAR);
- if (next == dstMSecs)
- return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::DaylightTime);
- else
- return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::StandardTime);
+ return ruleToData(rule, forMSecsSinceEpoch, (next == dstMSecs) ? QTimeZone::DaylightTime : QTimeZone::StandardTime);
}
bool QWinTimeZonePrivate::hasTransitions() const
@@ -520,79 +521,105 @@ bool QWinTimeZonePrivate::hasTransitions() const
QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
{
- // Convert MSecs to year to get transitions for, but around 31 Dec/1 Jan may not be right year
- // Get the year before we think we want transitions for, to be safe
- QDate date = msecsToDate(afterMSecsSinceEpoch);
- int year;
- int month;
- int day;
- date.getDate(&year, &month, &day);
- if ((month == 12 && day == 31) || (month == 1 && day == 1))
- --year;
+ // Convert MSecs to year to get transitions for, assumes no transitions around 31 Dec/1 Jan
+ int year = msecsToDate(afterMSecsSinceEpoch).year();
+ QWinTransitionRule rule;
+ // If the required year falls after the last rule start year and the last rule has no
+ // valid future transition calculations then there is no next transition
+ if (year > m_tranRules.last().startYear) {
+ rule = ruleForYear(year);
+ // If the rules have either a fixed year, or no month, then no future trans
+ if (rule.standardTimeRule.wYear != 0 || rule.daylightTimeRule.wYear != 0
+ || rule.standardTimeRule.wMonth == 0 || rule.daylightTimeRule.wMonth == 0) {
+ return invalidData();
+ }
+ }
+
+ // Otherwise we have a valid rule for the required year that can be used
+ // to calculate this year or next
qint64 first;
qint64 second;
qint64 next = minMSecs();
qint64 stdMSecs;
qint64 dstMSecs;
- QWinTransitionRule rule;
do {
// Convert the transition rules into msecs for the year we want to try
rule = ruleForYear(year);
+ // If no transition rules to calculate then no next transition
+ if (rule.standardTimeRule.wMonth == 0 && rule.daylightTimeRule.wMonth == 0)
+ return invalidData();
calculateTransitionsForYear(rule, year, &stdMSecs, &dstMSecs);
// Find the first and second transition for the year
- first = qMin(stdMSecs, dstMSecs);
- second = qMax(stdMSecs, dstMSecs);
+ if (stdMSecs < dstMSecs) {
+ first = stdMSecs;
+ second = dstMSecs;
+ } else {
+ first = dstMSecs;
+ second = stdMSecs;
+ }
if (afterMSecsSinceEpoch < first)
next = first;
else if (afterMSecsSinceEpoch < second)
next = second;
// If didn't fall in this year, try the next
++year;
- } while (afterMSecsSinceEpoch >= second && year <= MAX_YEAR);
+ } while (next == minMSecs() && year <= MAX_YEAR);
- if (next == dstMSecs)
- return ruleToData(rule, next, QTimeZone::DaylightTime);
- else
- return ruleToData(rule, next, QTimeZone::StandardTime);
+ if (next == minMSecs() || next == invalidMSecs())
+ return invalidData();
+
+ return ruleToData(rule, next, (next == dstMSecs) ? QTimeZone::DaylightTime : QTimeZone::StandardTime);
}
QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
{
- // Convert MSecs to year to get transitions for, but around 31 Dec/1 Jan may not be right year
- // So get the year after we think we want transitions for, to be safe
- QDate date = msecsToDate(beforeMSecsSinceEpoch);
- int year;
- int month;
- int day;
- date.getDate(&year, &month, &day);
- if ((month == 12 && day == 31) || (month == 1 && day == 1))
- ++year;
+ // Convert MSecs to year to get transitions for, assumes no transitions around 31 Dec/1 Jan
+ int year = msecsToDate(beforeMSecsSinceEpoch).year();
+
+ QWinTransitionRule rule;
+ // If the required year falls before the first rule start year and the first rule has no
+ // valid transition calculations then there is no previous transition
+ if (year < m_tranRules.first().startYear) {
+ rule = ruleForYear(year);
+ // If the rules have either a fixed year, or no month, then no previous trans
+ if (rule.standardTimeRule.wYear != 0 || rule.daylightTimeRule.wYear != 0
+ || rule.standardTimeRule.wMonth == 0 || rule.daylightTimeRule.wMonth == 0) {
+ return invalidData();
+ }
+ }
qint64 first;
qint64 second;
qint64 next = maxMSecs();
qint64 stdMSecs;
qint64 dstMSecs;
- QWinTransitionRule rule;
do {
// Convert the transition rules into msecs for the year we want to try
rule = ruleForYear(year);
+ // If no transition rules to calculate then no previous transition
+ if (rule.standardTimeRule.wMonth == 0 && rule.daylightTimeRule.wMonth == 0)
+ return invalidData();
calculateTransitionsForYear(rule, year, &stdMSecs, &dstMSecs);
- first = qMin(stdMSecs, dstMSecs);
- second = qMax(stdMSecs, dstMSecs);
- if (beforeMSecsSinceEpoch > second)
+ if (stdMSecs < dstMSecs) {
+ first = stdMSecs;
+ second = dstMSecs;
+ } else {
+ first = dstMSecs;
+ second = stdMSecs;
+ }
+ if (beforeMSecsSinceEpoch > second && second != invalidMSecs())
next = second;
- else if (beforeMSecsSinceEpoch > first)
+ else if (beforeMSecsSinceEpoch > first && first != invalidMSecs())
next = first;
// If didn't fall in this year, try the previous
--year;
- } while (beforeMSecsSinceEpoch < first && year >= MIN_YEAR);
+ } while (next == maxMSecs() && year >= MIN_YEAR);
- if (next == dstMSecs)
- return ruleToData(rule, next, QTimeZone::DaylightTime);
- else
- return ruleToData(rule, next, QTimeZone::StandardTime);
+ if (next == maxMSecs())
+ return invalidData();
+
+ return ruleToData(rule, next, (next == dstMSecs) ? QTimeZone::DaylightTime : QTimeZone::StandardTime);
}
QByteArray QWinTimeZonePrivate::systemTimeZoneId() const
@@ -602,10 +629,10 @@ QByteArray QWinTimeZonePrivate::systemTimeZoneId() const
QByteArray olsenId;
// If we have a real country, then try get a specific match for that country
if (country != QLocale::AnyCountry)
- olsenId = windowsIdToDefaultOlsenId(windowsId, country);
+ olsenId = windowsIdToDefaultIanaId(windowsId, country);
// If we don't have a real country, or there wasn't a specific match, try the global default
if (olsenId.isEmpty()) {
- olsenId = windowsIdToDefaultOlsenId(windowsId);
+ olsenId = windowsIdToDefaultIanaId(windowsId);
// If no global default then probably an unknown Windows ID so return UTC
if (olsenId.isEmpty())
return QByteArrayLiteral("UTC");
@@ -617,7 +644,7 @@ QSet<QByteArray> QWinTimeZonePrivate::availableTimeZoneIds() const
{
QSet<QByteArray> set;
foreach (const QByteArray &winId, availableWindowsIds()) {
- foreach (const QByteArray &olsenId, windowsIdToOlsenIds(winId))
+ foreach (const QByteArray &olsenId, windowsIdToIanaIds(winId))
set << olsenId;
}
return set;
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
index b9281c6915..4beb0f939c 100644
--- a/src/corelib/tools/qvector.cpp
+++ b/src/corelib/tools/qvector.cpp
@@ -572,7 +572,7 @@
Provided for compatibility with QList.
- \sa remove(int), QList::removeAt(int)
+ \sa remove(), QList::removeAt()
*/
/*! \fn int QVector::length() const
@@ -597,7 +597,7 @@
Provided for compatibility with QList.
- \sa takeFirst(), takeLast(), QList::takeAt(int)
+ \sa takeFirst(), takeLast(), QList::takeAt()
*/
/*! \fn void QVector::removeFirst()
@@ -621,6 +621,7 @@
*/
/*! \fn T QVector::takeFirst()
+ \since 5.1
Removes the first item in the vector and returns it. This function
assumes the vector is not empty. To avoid failure, call isEmpty()
@@ -630,6 +631,7 @@
*/
/*! \fn T QVector::takeLast()
+ \since 5.1
Removes the last item in the list and returns it. This function
assumes the vector is not empty. To avoid failure, call isEmpty()
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 553797a22f..5de2364fe2 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -14,6 +14,7 @@ HEADERS += \
tools/qcommandlineoption.h \
tools/qcommandlineparser.h \
tools/qcollator.h \
+ tools/qcollator_p.h \
tools/qcontainerfwd.h \
tools/qcryptographichash.h \
tools/qdatetime.h \
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index 75ccea94e0..2a26c2ede4 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -41,13 +41,6 @@
#include "QtCore/qxmlstream.h"
-#if defined(QT_BUILD_XML_LIB) && defined(Q_OS_MAC64)
-// No need to define this in the 64-bit Mac libraries.
-// Since Qt 4.4 and previous weren't supported in 64-bit, there are
-// no QXmlStream* symbols to keep compatibility with
-# define QT_NO_XMLSTREAM
-#endif
-
#ifndef QT_NO_XMLSTREAM
#include "qxmlutils_p.h"