summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qcompilerdetection.h11
-rw-r--r--src/corelib/global/qglobal.cpp15
-rw-r--r--src/corelib/global/qglobal.h12
-rw-r--r--src/corelib/global/qlibraryinfo.cpp33
-rw-r--r--src/corelib/global/qlibraryinfo.h4
-rw-r--r--src/corelib/global/qnamespace.h6
-rw-r--r--src/corelib/global/qnamespace.qdoc22
-rw-r--r--src/corelib/global/qnumeric.cpp136
-rw-r--r--src/corelib/global/qnumeric.h3
-rw-r--r--src/corelib/io/io.pri6
-rw-r--r--src/corelib/io/qdatastream.cpp3
-rw-r--r--src/corelib/io/qdatastream.h5
-rw-r--r--src/corelib/io/qdir.cpp2
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp192
-rw-r--r--src/corelib/io/qfilesystementry.cpp6
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp4
-rw-r--r--src/corelib/io/qfilesystemiterator_win.cpp14
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h6
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp73
-rw-r--r--src/corelib/io/qlockfile_win.cpp14
-rw-r--r--src/corelib/io/qsettings.cpp67
-rw-r--r--src/corelib/io/qstandardpaths.cpp202
-rw-r--r--src/corelib/io/qstandardpaths_winrt.cpp127
-rw-r--r--src/corelib/io/qtemporaryfile.cpp15
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.cpp3
-rw-r--r--src/corelib/kernel/kernel.pri18
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp10
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib_p.h20
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h32
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp394
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt_p.h168
-rw-r--r--src/corelib/kernel/qfunctions_p.h2
-rw-r--r--src/corelib/kernel/qfunctions_winrt.cpp105
-rw-r--r--src/corelib/kernel/qfunctions_winrt.h122
-rw-r--r--src/corelib/kernel/qobject.cpp73
-rw-r--r--src/corelib/kernel/qobject.h46
-rw-r--r--src/corelib/kernel/qvariant.cpp2
-rw-r--r--src/corelib/kernel/qvariant_p.h2
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp4
-rw-r--r--src/corelib/plugin/qlibrary_win.cpp6
-rw-r--r--src/corelib/thread/qmutex_win.cpp9
-rw-r--r--src/corelib/thread/qthread.cpp2
-rw-r--r--src/corelib/thread/qthread_p.h9
-rw-r--r--src/corelib/thread/qthread_win.cpp154
-rw-r--r--src/corelib/thread/qthreadpool.cpp28
-rw-r--r--src/corelib/thread/qthreadpool_p.h3
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp11
-rw-r--r--src/corelib/tools/qalgorithms.h86
-rw-r--r--src/corelib/tools/qcollator_win.cpp24
-rw-r--r--src/corelib/tools/qdatetime.cpp3
-rw-r--r--src/corelib/tools/qlocale_win.cpp206
-rw-r--r--src/corelib/tools/qstring.cpp13
-rw-r--r--src/corelib/tools/qstring.h3
-rw-r--r--src/corelib/tools/qtimezone.cpp6
-rw-r--r--src/corelib/tools/tools.pri7
55 files changed, 2341 insertions, 208 deletions
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 44077132d4..2b957782e8 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -98,6 +98,7 @@
# define Q_UNREACHABLE_IMPL() __assume(0)
# define Q_NORETURN __declspec(noreturn)
# define Q_DECL_DEPRECATED __declspec(deprecated)
+# define Q_DECL_DEPRECATED_X(text) __declspec(deprecated(text))
# define Q_DECL_EXPORT __declspec(dllexport)
# define Q_DECL_IMPORT __declspec(dllimport)
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
@@ -152,6 +153,9 @@
# define Q_CC_INTEL
# define Q_ASSUME_IMPL(expr) __assume(expr)
# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
+# if __INTEL_COMPILER >= 1300
+# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text)))
+# endif
# elif defined(__clang__)
/* Clang also masquerades as GCC */
# define Q_CC_CLANG
@@ -173,6 +177,7 @@
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable()
# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
+# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text)))
# endif
# endif
@@ -528,6 +533,9 @@
# if !__has_feature(cxx_rtti)
# define QT_NO_RTTI
# endif
+# if __has_feature(attribute_deprecated_with_message)
+# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text)))
+# endif
/* C++11 features, see http://clang.llvm.org/cxx_status.html */
# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
@@ -861,6 +869,9 @@
#ifndef Q_DECL_VARIABLE_DEPRECATED
# define Q_DECL_VARIABLE_DEPRECATED Q_DECL_DEPRECATED
#endif
+#ifndef Q_DECL_DEPRECATED_X
+# define Q_DECL_DEPRECATED_X(text) Q_DECL_DEPRECATED
+#endif
#ifndef Q_DECL_EXPORT
# define Q_DECL_EXPORT
#endif
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 0c72bd7022..f72d27c2e5 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -2188,7 +2188,9 @@ QString qt_error_string(int errorCode)
s = QT_TRANSLATE_NOOP("QIODevice", "No space left on device");
break;
default: {
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN)
+ // Retrieve the system error message for the last-error code.
+# ifndef Q_OS_WINRT
wchar_t *string = 0;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
@@ -2199,6 +2201,17 @@ QString qt_error_string(int errorCode)
NULL);
ret = QString::fromWCharArray(string);
LocalFree((HLOCAL)string);
+# else // !Q_OS_WINRT
+ __declspec(thread) static wchar_t errorString[4096];
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ errorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ errorString,
+ ARRAYSIZE(errorString),
+ NULL);
+ ret = QString::fromWCharArray(errorString);
+# endif // Q_OS_WINRT
if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND)
ret = QString::fromLatin1("The specified module could not be found.");
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 3c3d35e373..da5f65fafb 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -45,11 +45,11 @@
#include <stddef.h>
-#define QT_VERSION_STR "5.2.1"
+#define QT_VERSION_STR "5.3.0"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x050201
+#define QT_VERSION 0x050300
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
@@ -191,7 +191,7 @@ typedef qint64 qlonglong;
typedef quint64 qulonglong;
#ifndef QT_POINTER_SIZE
-# if defined(Q_OS_WIN64)
+# if defined(Q_OS_WIN64) || (defined(Q_OS_WINRT) && defined(_M_X64))
# define QT_POINTER_SIZE 8
# elif defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
# define QT_POINTER_SIZE 4
@@ -221,11 +221,14 @@ typedef double qreal;
#if defined(QT_NO_DEPRECATED)
# undef QT_DEPRECATED
+# undef QT_DEPRECATED_X
# undef QT_DEPRECATED_VARIABLE
# undef QT_DEPRECATED_CONSTRUCTOR
#elif defined(QT_DEPRECATED_WARNINGS)
# undef QT_DEPRECATED
# define QT_DEPRECATED Q_DECL_DEPRECATED
+# undef QT_DEPRECATED_X
+# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text)
# undef QT_DEPRECATED_VARIABLE
# define QT_DEPRECATED_VARIABLE Q_DECL_VARIABLE_DEPRECATED
# undef QT_DEPRECATED_CONSTRUCTOR
@@ -233,6 +236,8 @@ typedef double qreal;
#else
# undef QT_DEPRECATED
# define QT_DEPRECATED
+# undef QT_DEPRECATED_X
+# define QT_DEPRECATED_X(text)
# undef QT_DEPRECATED_VARIABLE
# define QT_DEPRECATED_VARIABLE
# undef QT_DEPRECATED_CONSTRUCTOR
@@ -547,6 +552,7 @@ class QDataStream;
#if defined(Q_OS_WINRT)
# define QT_NO_PROCESS
+# define QT_NO_FILESYSTEMWATCHER
#endif
inline void qt_noop(void) {}
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 1c3b09f602..22a9980812 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qdir.h"
+#include "qstringlist.h"
#include "qfile.h"
#include "qsettings.h"
#include "qlibraryinfo.h"
@@ -113,6 +114,8 @@ public:
}
};
+static const char platformsSection[] = "Platforms";
+
QLibrarySettings::QLibrarySettings()
: settings(QLibraryInfoPrivate::findConfiguration())
{
@@ -132,7 +135,8 @@ QLibrarySettings::QLibrarySettings()
haveEffectivePaths = children.contains(QLatin1String("EffectivePaths"));
#endif
// Backwards compat: an existing but empty file is claimed to contain the Paths section.
- havePaths = !haveEffectivePaths || children.contains(QLatin1String("Paths"));
+ havePaths = (!haveEffectivePaths && !children.contains(QLatin1String(platformsSection)))
+ || children.contains(QLatin1String("Paths"));
#ifndef QT_BOOTSTRAPPED
if (!havePaths)
settings.reset(0);
@@ -466,6 +470,33 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
}
/*!
+ Returns additional arguments to the platform plugin matching
+ \a platformName which can be specified as a string list using
+ the key \c Arguments in a group called \c Platforms of the
+ \c qt.conf file.
+
+ sa {Using qt.conf}
+
+ \internal
+
+ \since 5.3
+*/
+
+QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
+{
+#ifndef QT_BOOTSTRAPPED
+ if (const QSettings *settings = QLibraryInfoPrivate::findConfiguration()) {
+ QString key = QLatin1String(platformsSection);
+ key += QLatin1Char('/');
+ key += platformName;
+ key += QLatin1String("Arguments");
+ return settings->value(key).toStringList();
+ }
+#endif // !QT_BOOTSTRAPPED
+ return QStringList();
+}
+
+/*!
\enum QLibraryInfo::LibraryLocation
\keyword library location
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index 17864b555b..54ef794d3e 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -47,6 +47,8 @@
QT_BEGIN_NAMESPACE
+class QStringList;
+
class Q_CORE_EXPORT QLibraryInfo
{
public:
@@ -96,6 +98,8 @@ public:
static QString rawLocation(LibraryLocation, PathGroup);
#endif
+ static QStringList platformPluginArguments(const QString &platformName);
+
private:
QLibraryInfo();
};
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 8a46f3a6ab..758f13596e 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1596,6 +1596,12 @@ public:
ScrollUpdate,
ScrollEnd
};
+
+ enum MouseEventSource {
+ MouseEventNotSynthesized,
+ MouseEventSynthesizedBySystem,
+ MouseEventSynthesizedByQt
+ };
}
#ifdef Q_MOC_RUN
;
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 90f38fd51c..e33fd085f2 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -2897,3 +2897,25 @@
\value ScrollEnd Scrolling has ended, but the scrolling distance
did not change anymore.
*/
+
+/*!
+ \enum Qt::MouseEventSource
+ \since 5.3
+
+ This enum describes the source of a mouse event and can be useful
+ to determine if the event is an artificial mouse event originating
+ from another device such as a touchscreen.
+
+ \value MouseEventNotSynthesized The most common value. On
+ platforms where such information is available this value indicates
+ that the event was generated in response to a genuine mouse event
+ in the system.
+
+ \value MouseEventSynthesizedBySystem Indicates that the mouse
+ event was synthesized from a touch event by the platform.
+
+ \value MouseEventSynthesizedByQt Indicates that the mouse event was
+ synthesized from an unhandled touch event by Qt.
+
+ \sa Qt::AA_SynthesizeMouseForUnhandledTouchEvents
+*/
diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp
index d09357c26c..7d8bd8c3c6 100644
--- a/src/corelib/global/qnumeric.cpp
+++ b/src/corelib/global/qnumeric.cpp
@@ -41,6 +41,7 @@
#include "qnumeric.h"
#include "qnumeric_p.h"
+#include <string.h>
QT_BEGIN_NAMESPACE
@@ -99,4 +100,139 @@ Q_CORE_EXPORT double qQNaN() { return qt_qnan(); }
Q_CORE_EXPORT double qInf() { return qt_inf(); }
+
+/*!
+ \internal
+ */
+static inline quint32 f2i(float f)
+{
+ quint32 i;
+ memcpy(&i, &f, sizeof(f));
+ return i;
+}
+
+/*!
+ Returns the number of representable floating-point numbers between \a a and \a b.
+
+ This function provides an alternative way of doing approximated comparisons of floating-point
+ numbers similar to qFuzzyCompare(). However, it returns the distance between two numbers, which
+ gives the caller a possibility to choose the accepted error. Errors are relative, so for
+ instance the distance between 1.0E-5 and 1.00001E-5 will give 110, while the distance between
+ 1.0E36 and 1.00001E36 will give 127.
+
+ This function is useful if a floating point comparison requires a certain precision.
+ Therefore, if \a a and \a b are equal it will return 0. The maximum value it will return for 32-bit
+ floating point numbers is 4,278,190,078. This is the distance between \c{-FLT_MAX} and
+ \c{+FLT_MAX}.
+
+ The function does not give meaningful results if any of the arguments are \c Infinite or \c NaN.
+ You can check for this by calling qIsFinite().
+
+ The return value can be considered as the "error", so if you for instance want to compare
+ two 32-bit floating point numbers and all you need is an approximated 24-bit precision, you can
+ use this function like this:
+
+ \code
+ if (qFloatDistance(a, b) < (1 << 7)) { // The last 7 bits are not
+ // significant
+ // precise enough
+ }
+ \endcode
+
+ \sa qFuzzyCompare()
+ \relates <QtGlobal>
+*/
+Q_CORE_EXPORT quint32 qFloatDistance(float a, float b)
+{
+ static const quint32 smallestPositiveFloatAsBits = 0x00000001; // denormalized, (SMALLEST), (1.4E-45)
+ /* Assumes:
+ * IEE754 format.
+ * Integers and floats have the same endian
+ */
+ Q_STATIC_ASSERT(sizeof(quint32) == sizeof(float));
+ Q_ASSERT(qIsFinite(a) && qIsFinite(b));
+ if (a == b)
+ return 0;
+ if ((a < 0) != (b < 0)) {
+ // if they have different signs
+ if (a < 0)
+ a = -a;
+ else /*if (b < 0)*/
+ b = -b;
+ return qFloatDistance(0.0F, a) + qFloatDistance(0.0F, b);
+ }
+ if (a < 0) {
+ a = -a;
+ b = -b;
+ }
+ // at this point a and b should not be negative
+
+ // 0 is special
+ if (!a)
+ return f2i(b) - smallestPositiveFloatAsBits + 1;
+ if (!b)
+ return f2i(a) - smallestPositiveFloatAsBits + 1;
+
+ // finally do the common integer subtraction
+ return a > b ? f2i(a) - f2i(b) : f2i(b) - f2i(a);
+}
+
+
+/*!
+ \internal
+ */
+static inline quint64 d2i(double d)
+{
+ quint64 i;
+ memcpy(&i, &d, sizeof(d));
+ return i;
+}
+
+/*!
+ Returns the number of representable floating-point numbers between \a a and \a b.
+
+ This function serves the same purpose as \c{qFloatDistance(float, float)}, but
+ returns the distance between two \c double numbers. Since the range is larger
+ than for two \c float numbers (\c{[-DBL_MAX,DBL_MAX]}), the return type is quint64.
+
+
+ \sa qFuzzyCompare()
+ \relates <QtGlobal>
+*/
+Q_CORE_EXPORT quint64 qFloatDistance(double a, double b)
+{
+ static const quint64 smallestPositiveFloatAsBits = 0x1; // denormalized, (SMALLEST)
+ /* Assumes:
+ * IEE754 format double precision
+ * Integers and floats have the same endian
+ */
+ Q_STATIC_ASSERT(sizeof(quint64) == sizeof(double));
+ Q_ASSERT(qIsFinite(a) && qIsFinite(b));
+ if (a == b)
+ return 0;
+ if ((a < 0) != (b < 0)) {
+ // if they have different signs
+ if (a < 0)
+ a = -a;
+ else /*if (b < 0)*/
+ b = -b;
+ return qFloatDistance(0.0, a) + qFloatDistance(0.0, b);
+ }
+ if (a < 0) {
+ a = -a;
+ b = -b;
+ }
+ // at this point a and b should not be negative
+
+ // 0 is special
+ if (!a)
+ return d2i(b) - smallestPositiveFloatAsBits + 1;
+ if (!b)
+ return d2i(a) - smallestPositiveFloatAsBits + 1;
+
+ // finally do the common integer subtraction
+ return a > b ? d2i(a) - d2i(b) : d2i(b) - d2i(a);
+}
+
+
QT_END_NAMESPACE
diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h
index 25db5443eb..633486dff1 100644
--- a/src/corelib/global/qnumeric.h
+++ b/src/corelib/global/qnumeric.h
@@ -57,6 +57,9 @@ Q_CORE_EXPORT double qSNaN();
Q_CORE_EXPORT double qQNaN();
Q_CORE_EXPORT double qInf();
+Q_CORE_EXPORT quint32 qFloatDistance(float a, float b);
+Q_CORE_EXPORT quint64 qFloatDistance(double a, double b);
+
#define Q_INFINITY (QT_PREPEND_NAMESPACE(qInf)())
#define Q_SNAN (QT_PREPEND_NAMESPACE(qSNaN)())
#define Q_QNAN (QT_PREPEND_NAMESPACE(qQNaN)())
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index f06bf61b09..0ec3d949b9 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -94,7 +94,6 @@ SOURCES += \
io/qloggingregistry.cpp
win32 {
- SOURCES += io/qsettings_win.cpp
SOURCES += io/qfsfileengine_win.cpp
SOURCES += io/qlockfile_win.cpp
@@ -102,11 +101,12 @@ win32 {
HEADERS += io/qfilesystemwatcher_win_p.h
SOURCES += io/qfilesystemengine_win.cpp
SOURCES += io/qfilesystemiterator_win.cpp
- SOURCES += io/qstandardpaths_win.cpp
!winrt {
+ SOURCES += io/qsettings_win.cpp
HEADERS += io/qwindowspipewriter_p.h
SOURCES += io/qwindowspipewriter.cpp
+ SOURCES += io/qstandardpaths_win.cpp
wince* {
SOURCES += io/qprocess_wince.cpp
@@ -119,6 +119,8 @@ win32 {
io/qwinoverlappedionotifier.cpp \
io/qwindowspipereader.cpp
}
+ } else {
+ SOURCES += io/qstandardpaths_winrt.cpp
}
} else:unix|integrity {
SOURCES += \
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index af5605f8c7..a6fbffee7e 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -251,7 +251,7 @@ QT_BEGIN_NAMESPACE
return retVal;
enum {
- DefaultStreamVersion = QDataStream::Qt_5_2
+ DefaultStreamVersion = QDataStream::Qt_5_3
};
/*!
@@ -541,6 +541,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_0 Version 13 (Qt 5.0)
\value Qt_5_1 Version 14 (Qt 5.1)
\value Qt_5_2 Version 15 (Qt 5.2)
+ \value Qt_5_3 Same as Qt_5_2
\sa setVersion(), version()
*/
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index f107e801b6..28f1d51a12 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -87,8 +87,9 @@ public:
Qt_4_9 = Qt_4_8,
Qt_5_0 = 13,
Qt_5_1 = 14,
- Qt_5_2 = 15
-#if QT_VERSION >= 0x050300
+ Qt_5_2 = 15,
+ Qt_5_3 = Qt_5_2
+#if QT_VERSION >= 0x050400
#error Add the datastream version for this Qt version
#endif
};
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index db27bed9d6..624f45caaf 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2144,7 +2144,7 @@ QString QDir::cleanPath(const QString &path)
name.replace(dir_separator, QLatin1Char('/'));
bool allowUncPaths = false;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) //allow unc paths
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) //allow unc paths
allowUncPaths = true;
#endif
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 257f18a6bb..dbc6d28846 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -63,13 +63,28 @@
# include <types.h>
#endif
#include <objbase.h>
-#include <shlobj.h>
+#ifndef Q_OS_WINRT
+# include <shlobj.h>
+# include <accctrl.h>
+#endif
#include <initguid.h>
-#include <accctrl.h>
#include <ctype.h>
#include <limits.h>
-#define SECURITY_WIN32
-#include <security.h>
+#ifndef Q_OS_WINRT
+# define SECURITY_WIN32
+# include <security.h>
+#else // !Q_OS_WINRT
+# include <wrl.h>
+# include <windows.foundation.h>
+# include <windows.storage.h>
+# include <Windows.ApplicationModel.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::ApplicationModel;
+#endif // Q_OS_WINRT
#ifndef SPI_GETPLATFORMTYPE
#define SPI_GETPLATFORMTYPE 257
@@ -141,7 +156,7 @@ QT_BEGIN_NAMESPACE
Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0;
-#if defined(Q_OS_WINCE)
+#if defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
static QString qfsPrivateCurrentDir = QLatin1String("");
// As none of the functions we try to resolve do exist on Windows CE
// we use QT_NO_LIBRARY to shorten everything up a little bit.
@@ -289,14 +304,14 @@ static bool resolveUNCLibs()
}
#endif
triedResolve = true;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
HINSTANCE hLib = QSystemLibrary::load(L"Netapi32");
if (hLib) {
ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum");
if (ptrNetShareEnum)
ptrNetApiBufferFree = (PtrNetApiBufferFree)GetProcAddress(hLib, "NetApiBufferFree");
}
-#endif
+#endif // !Q_OS_WINCE && !Q_OS_WINRT
}
return ptrNetShareEnum && ptrNetApiBufferFree;
}
@@ -304,7 +319,7 @@ static bool resolveUNCLibs()
static QString readSymLink(const QFileSystemEntry &link)
{
QString result;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
HANDLE handle = CreateFile((wchar_t*)link.nativeFilePath().utf16(),
FILE_READ_EA,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
@@ -347,11 +362,11 @@ static QString readSymLink(const QFileSystemEntry &link)
result.replace(0,matchVolName.matchedLength(), QString::fromWCharArray(buffer));
}
}
-#endif
+#endif // !Q_OS_WINCE && !Q_OS_WINRT
}
#else
Q_UNUSED(link);
-#endif // Q_OS_WINCE
+#endif // Q_OS_WINCE || Q_OS_WINRT
return result;
}
@@ -432,7 +447,11 @@ static inline bool getFindData(QString path, WIN32_FIND_DATA &findData)
// can't handle drives
if (!path.endsWith(QLatin1Char(':'))) {
+#ifndef Q_OS_WINRT
HANDLE hFind = ::FindFirstFile((wchar_t*)path.utf16(), &findData);
+#else
+ HANDLE hFind = ::FindFirstFileEx((const wchar_t*)path.utf16(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0);
+#endif
if (hFind != INVALID_HANDLE_VALUE) {
::FindClose(hFind);
return true;
@@ -506,7 +525,7 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path)
{
// can be //server or //server/share
QString absPath;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QVarLengthArray<wchar_t, MAX_PATH> buf(qMax(MAX_PATH, path.size() + 1));
wchar_t *fileName = 0;
DWORD retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName);
@@ -516,12 +535,17 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path)
}
if (retLen != 0)
absPath = QString::fromWCharArray(buf.data(), retLen);
-#else
+#elif !defined(Q_OS_WINCE)
+ if (QDir::isRelativePath(path))
+ absPath = QDir::toNativeSeparators(QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + path));
+ else
+ absPath = QDir::toNativeSeparators(QDir::cleanPath(path));
+#else // Q_OS_WINRT
if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\')))
absPath = QDir::toNativeSeparators(path);
else
absPath = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path));
-#endif
+#endif // Q_OS_WINCE
// This is really ugly, but GetFullPathName strips off whitespace at the end.
// If you for instance write ". " in the lineedit of QFileDialog,
// (which is an invalid filename) this function will strip the space off and viola,
@@ -548,9 +572,17 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
ret = entry.filePath();
#endif
} else {
+#ifndef Q_OS_WINRT
ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + entry.filePath());
+#else
+ // Some WinRT APIs do not support absolute paths (due to sandboxing).
+ // Thus the port uses the executable's directory as its root directory
+ // and treats paths relative to that as absolute paths.
+ ret = QDir::cleanPath(QDir::current().relativeFilePath(entry.filePath()));
+#endif
}
+#ifndef Q_OS_WINRT
// The path should be absolute at this point.
// From the docs :
// Absolute paths begin with the directory separator "/"
@@ -563,6 +595,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
// Force uppercase drive letters.
ret[0] = ret.at(0).toUpper();
}
+#endif // !Q_OS_WINRT
return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
}
@@ -590,18 +623,24 @@ typedef struct _FILE_ID_INFO {
static inline QByteArray fileId(HANDLE handle)
{
QByteArray result;
+#ifndef Q_OS_WINRT
BY_HANDLE_FILE_INFORMATION info;
if (GetFileInformationByHandle(handle, &info)) {
result = QByteArray::number(uint(info.nFileIndexLow), 16);
result += ':';
result += QByteArray::number(uint(info.nFileIndexHigh), 16);
}
+#else // !Q_OS_WINRT
+ Q_UNUSED(handle);
+ Q_UNIMPLEMENTED();
+#endif // Q_OS_WINRT
return result;
}
// File ID for Windows starting from version 8.
QByteArray fileIdWin8(HANDLE handle)
{
+#ifndef Q_OS_WINRT
typedef BOOL (WINAPI* GetFileInformationByHandleExType)(HANDLE, Q_FILE_INFO_BY_HANDLE_CLASS, void *, DWORD);
// Dynamically resolve GetFileInformationByHandleEx (Vista onwards).
@@ -621,6 +660,16 @@ QByteArray fileIdWin8(HANDLE handle)
result += QByteArray((char *)&infoEx.FileId, sizeof(infoEx.FileId)).toHex();
}
}
+#else // !Q_OS_WINRT
+ QByteArray result;
+ FILE_ID_INFO infoEx;
+ if (GetFileInformationByHandleEx(handle, FileIdInfo,
+ &infoEx, sizeof(FILE_ID_INFO))) {
+ result = QByteArray::number(infoEx.VolumeSerialNumber, 16);
+ result += ':';
+ result += QByteArray((char *)infoEx.FileId.Identifier, sizeof(infoEx.FileId.Identifier)).toHex();
+ }
+#endif // Q_OS_WINRT
return result;
}
#endif // !Q_OS_WINCE
@@ -631,8 +680,13 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry)
#ifndef Q_OS_WINCE
QByteArray result;
const HANDLE handle =
+#ifndef Q_OS_WINRT
CreateFile((wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+#else // !Q_OS_WINRT
+ CreateFile2((const wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ,
+ FILE_SHARE_READ, OPEN_EXISTING, NULL);
+#endif // Q_OS_WINRT
if (handle) {
result = QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS8 ?
fileIdWin8(handle) : fileId(handle);
@@ -810,7 +864,7 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa
{
bool entryExists = false;
DWORD fileAttrib = 0;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
if (fname.isDriveRoot()) {
// a valid drive ??
DWORD drivesBitmask = ::GetLogicalDrives();
@@ -851,7 +905,7 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa
fileAttrib = FILE_ATTRIBUTE_DIRECTORY;
entryExists = true;
}
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
}
#endif
if (entryExists)
@@ -894,12 +948,32 @@ bool QFileSystemEngine::fillMetaData(HANDLE fHandle, QFileSystemMetaData &data,
{
data.entryFlags &= ~what;
clearWinStatData(data);
+#ifndef Q_OS_WINRT
BY_HANDLE_FILE_INFORMATION fileInfo;
UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
if (GetFileInformationByHandle(fHandle , &fileInfo)) {
data.fillFromFindInfo(fileInfo);
}
SetErrorMode(oldmode);
+#else // !Q_OS_WINRT
+ FILE_BASIC_INFO fileBasicInfo;
+ if (GetFileInformationByHandleEx(fHandle, FileBasicInfo, &fileBasicInfo, sizeof(fileBasicInfo))) {
+ data.fillFromFileAttribute(fileBasicInfo.FileAttributes);
+ data.creationTime_.dwHighDateTime = fileBasicInfo.CreationTime.HighPart;
+ data.creationTime_.dwLowDateTime = fileBasicInfo.CreationTime.LowPart;
+ data.lastAccessTime_.dwHighDateTime = fileBasicInfo.LastAccessTime.HighPart;
+ data.lastAccessTime_.dwLowDateTime = fileBasicInfo.LastAccessTime.LowPart;
+ data.lastWriteTime_.dwHighDateTime = fileBasicInfo.LastWriteTime.HighPart;
+ data.lastWriteTime_.dwLowDateTime = fileBasicInfo.LastWriteTime.LowPart;
+ if (!(data.fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY)) {
+ FILE_STANDARD_INFO fileStandardInfo;
+ if (GetFileInformationByHandleEx(fHandle, FileStandardInfo, &fileStandardInfo, sizeof(fileStandardInfo)))
+ data.size_ = fileStandardInfo.EndOfFile.QuadPart;
+ } else
+ data.size_ = 0;
+ data.knownFlagsMask |= QFileSystemMetaData::Times | QFileSystemMetaData::SizeAttribute;
+ }
+#endif // Q_OS_WINRT
return data.hasFlags(what);
}
@@ -931,7 +1005,9 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
}
if (what & QFileSystemMetaData::WinStatFlags) {
+#ifndef Q_OS_WINRT
UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+#endif
clearWinStatData(data);
WIN32_FIND_DATA findData;
// The memory structure for WIN32_FIND_DATA is same as WIN32_FILE_ATTRIBUTE_DATA
@@ -943,11 +1019,15 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
} else {
if (!tryFindFallback(fname, data))
if (!tryDriveUNCFallback(fname, data)) {
+#ifndef Q_OS_WINRT
SetErrorMode(oldmode);
+#endif
return false;
}
}
+#ifndef Q_OS_WINRT
SetErrorMode(oldmode);
+#endif
}
if (what & QFileSystemMetaData::Permissions)
@@ -1006,7 +1086,14 @@ static bool isDirPath(const QString &dirPath, bool *existed)
if (path.length() == 2 && path.at(1) == QLatin1Char(':'))
path += QLatin1Char('\\');
+#ifndef Q_OS_WINRT
DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16());
+#else // Q_OS_WINRT
+ DWORD fileAttrib = INVALID_FILE_ATTRIBUTES;
+ WIN32_FILE_ATTRIBUTE_DATA data;
+ if (::GetFileAttributesEx((const wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), GetFileExInfoStandard, &data))
+ fileAttrib = data.dwFileAttributes;
+#endif // Q_OS_WINRT
if (fileAttrib == INVALID_FILE_ATTRIBUTES) {
int errorCode = GetLastError();
if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) {
@@ -1100,6 +1187,30 @@ QString QFileSystemEngine::rootPath()
{
#if defined(Q_OS_WINCE)
QString ret = QLatin1String("/");
+#elif defined(Q_OS_WINRT)
+ // We specify the package root as root directory
+ QString ret = QLatin1String("/");
+ // Get package location
+ ComPtr<IPackageStatics> statics;
+ if (FAILED(GetActivationFactory(HStringReference(RuntimeClass_Windows_ApplicationModel_Package).Get(), &statics)))
+ return ret;
+ ComPtr<IPackage> package;
+ if (FAILED(statics->get_Current(&package)))
+ return ret;
+ ComPtr<IStorageFolder> installedLocation;
+ if (FAILED(package->get_InstalledLocation(&installedLocation)))
+ return ret;
+
+ ComPtr<IStorageItem> item;
+ if (FAILED(installedLocation.As(&item)))
+ return ret;
+
+ HSTRING finalWinPath;
+ if (FAILED(item->get_Path(&finalWinPath)))
+ return ret;
+
+ ret = QDir::fromNativeSeparators(QString::fromWCharArray(WindowsGetStringRawBuffer(finalWinPath, nullptr)));
+
#else
QString ret = QString::fromLatin1(qgetenv("SystemDrive").constData());
if (ret.isEmpty())
@@ -1158,12 +1269,13 @@ QString QFileSystemEngine::homePath()
QString QFileSystemEngine::tempPath()
{
QString ret;
+#ifndef Q_OS_WINRT
wchar_t tempPath[MAX_PATH];
const DWORD len = GetTempPath(MAX_PATH, tempPath);
#ifdef Q_OS_WINCE
if (len)
ret = QString::fromWCharArray(tempPath, len);
-#else
+#else // Q_OS_WINCE
if (len) { // GetTempPath() can return short names, expand.
wchar_t longTempPath[MAX_PATH];
const DWORD longLen = GetLongPathName(tempPath, longTempPath, MAX_PATH);
@@ -1171,12 +1283,33 @@ QString QFileSystemEngine::tempPath()
QString::fromWCharArray(longTempPath, longLen) :
QString::fromWCharArray(tempPath, len);
}
-#endif
+#endif // !Q_OS_WINCE
if (!ret.isEmpty()) {
while (ret.endsWith(QLatin1Char('\\')))
ret.chop(1);
ret = QDir::fromNativeSeparators(ret);
}
+#else // !Q_OS_WINRT
+ // According to http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.temporaryfolder.aspx
+ // the API is not available on winphone which should cause one of the functions
+ // below to fail
+ ComPtr<IApplicationDataStatics> applicationDataStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
+ return ret;
+ ComPtr<IApplicationData> applicationData;
+ if (FAILED(applicationDataStatics->get_Current(&applicationData)))
+ return ret;
+ ComPtr<IStorageFolder> tempFolder;
+ if (FAILED(applicationData->get_TemporaryFolder(&tempFolder)))
+ return ret;
+ ComPtr<IStorageItem> tempFolderItem;
+ if (FAILED(tempFolder.As(&tempFolderItem)))
+ return ret;
+ HSTRING path;
+ if (FAILED(tempFolderItem->get_Path(&path)))
+ return ret;
+ ret = QDir::fromNativeSeparators(QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr)));
+#endif // Q_OS_WINRT
if (ret.isEmpty()) {
#if !defined(Q_OS_WINCE)
ret = QLatin1String("C:/tmp");
@@ -1195,7 +1328,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
if(!(meta.exists() && meta.isDirectory()))
return false;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
//TODO: this should really be using nativeFilePath(), but that returns a path in long format \\?\c:\foo
//which causes many problems later on when it's returned through currentPath()
return ::SetCurrentDirectory(reinterpret_cast<const wchar_t*>(QDir::toNativeSeparators(entry.filePath()).utf16())) != 0;
@@ -1208,7 +1341,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
QFileSystemEntry QFileSystemEngine::currentPath()
{
QString ret;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
DWORD size = 0;
wchar_t currentName[PATH_MAX];
size = ::GetCurrentDirectory(PATH_MAX, currentName);
@@ -1224,13 +1357,17 @@ QFileSystemEntry QFileSystemEngine::currentPath()
}
if (ret.length() >= 2 && ret[1] == QLatin1Char(':'))
ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
-#else
+#else // !Q_OS_WINCE && !Q_OS_WINRT
//TODO - a race condition exists when using currentPath / setCurrentPath from multiple threads
if (qfsPrivateCurrentDir.isEmpty())
+#ifndef Q_OS_WINRT
qfsPrivateCurrentDir = QCoreApplication::applicationDirPath();
+#else
+ qfsPrivateCurrentDir = QDir::rootPath();
+#endif
ret = qfsPrivateCurrentDir;
-#endif
+#endif // Q_OS_WINCE || Q_OS_WINRT
return QFileSystemEntry(ret, QFileSystemEntry::FromNativePath());
}
@@ -1248,8 +1385,16 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy
//static
bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
+#ifndef Q_OS_WINRT
bool ret = ::CopyFile((wchar_t*)source.nativeFilePath().utf16(),
(wchar_t*)target.nativeFilePath().utf16(), true) != 0;
+#else // !Q_OS_WINRT
+ COPYFILE2_EXTENDED_PARAMETERS copyParams = {
+ sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL
+ };
+ bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
+ (const wchar_t*)target.nativeFilePath().utf16(), &copyParams) != 0;
+#endif // Q_OS_WINRT
if(!ret)
error = QSystemError(::GetLastError(), QSystemError::NativeError);
return ret;
@@ -1258,8 +1403,13 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst
//static
bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
+#ifndef Q_OS_WINRT
bool ret = ::MoveFile((wchar_t*)source.nativeFilePath().utf16(),
(wchar_t*)target.nativeFilePath().utf16()) != 0;
+#else // !Q_OS_WINRT
+ bool ret = ::MoveFileEx((const wchar_t*)source.nativeFilePath().utf16(),
+ (const wchar_t*)target.nativeFilePath().utf16(), 0) != 0;
+#endif // Q_OS_WINRT
if(!ret)
error = QSystemError(::GetLastError(), QSystemError::NativeError);
return ret;
diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp
index 3934c6a673..42a724670e 100644
--- a/src/corelib/io/qfilesystementry.cpp
+++ b/src/corelib/io/qfilesystementry.cpp
@@ -170,6 +170,12 @@ void QFileSystemEntry::resolveNativeFilePath() const
#else
m_nativeFilePath = QFile::encodeName(QDir::toNativeSeparators(m_filePath));
#endif
+#ifdef Q_OS_WINRT
+ while (m_nativeFilePath.startsWith(QLatin1Char('\\')))
+ m_nativeFilePath.remove(0,1);
+ if (m_nativeFilePath.isEmpty())
+ m_nativeFilePath.append(QLatin1Char('.'));
+#endif
}
}
diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp
index bfedd3f70c..0b59aa169a 100644
--- a/src/corelib/io/qfilesystemiterator_unix.cpp
+++ b/src/corelib/io/qfilesystemiterator_unix.cpp
@@ -105,8 +105,8 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa
if (!dir)
return false;
-#if defined(Q_OS_QNX) && defined(__EXT_QNX__READDIR_R)
- lastError = _readdir_r(dir, mt_file.data(), &dirEntry, direntSize);
+#if defined(Q_OS_QNX) && defined(QT_EXT_QNX_READDIR_R)
+ lastError = QT_EXT_QNX_READDIR_R(dir, mt_file.data(), &dirEntry, direntSize);
if (lastError)
return false;
#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN)
diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp
index 90232f7cfc..dda96bd45a 100644
--- a/src/corelib/io/qfilesystemiterator_win.cpp
+++ b/src/corelib/io/qfilesystemiterator_win.cpp
@@ -39,10 +39,12 @@
**
****************************************************************************/
-#if _WIN32_WINNT < 0x0500
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
-#endif
+#if !defined(WINAPI_FAMILY)
+# if _WIN32_WINNT < 0x0500
+# undef _WIN32_WINNT
+# define _WIN32_WINNT 0x0500
+# endif // _WIN32_WINNT < 0x500
+#endif // !WINAPI_FAMILY
#include "qfilesystemiterator_p.h"
#include "qfilesystemengine_p.h"
@@ -73,6 +75,10 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi
if (!nativePath.endsWith(QLatin1Char('\\')))
nativePath.append(QLatin1Char('\\'));
nativePath.append(QLatin1Char('*'));
+#ifdef Q_OS_WINRT
+ if (nativePath.startsWith(QLatin1Char('\\')))
+ nativePath.remove(0, 1);
+#endif
if (!dirPath.endsWith(QLatin1Char('/')))
dirPath.append(QLatin1Char('/'));
if ((filters & (QDir::Dirs|QDir::Drives)) && (!(filters & (QDir::Files))))
diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h
index 1abc9b7ec4..de79ec32d3 100644
--- a/src/corelib/io/qfilesystemmetadata_p.h
+++ b/src/corelib/io/qfilesystemmetadata_p.h
@@ -219,7 +219,9 @@ public:
#if defined(Q_OS_WIN)
inline void fillFromFileAttribute(DWORD fileAttribute, bool isDriveRoot = false);
inline void fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType = false, bool isDriveRoot = false);
+# ifndef Q_OS_WINRT
inline void fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo);
+# endif
#endif
private:
friend class QFileSystemEngine;
@@ -340,6 +342,7 @@ inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, boo
}
}
+#ifndef Q_OS_WINRT
inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo)
{
fillFromFileAttribute(fileInfo.dwFileAttributes);
@@ -355,7 +358,8 @@ inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fi
}
knownFlagsMask |= Times | SizeAttribute;
}
-#endif
+#endif // !Q_OS_WINRT
+#endif // Q_OS_WIN
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 2b38019674..c974daab06 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -60,14 +60,18 @@
# include <types.h>
#endif
#include <objbase.h>
-#include <shlobj.h>
+#ifndef Q_OS_WINRT
+# include <shlobj.h>
+# include <accctrl.h>
+#endif
#include <initguid.h>
-#include <accctrl.h>
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
-#define SECURITY_WIN32
-#include <security.h>
+#ifndef Q_OS_WINRT
+# define SECURITY_WIN32
+# include <security.h>
+#endif
#ifndef PATH_MAX
#define PATH_MAX FILENAME_MAX
@@ -93,7 +97,7 @@ QString QFSFileEnginePrivate::longFileName(const QString &path)
return path;
QString absPath = QFileSystemEngine::nativeAbsoluteFilePath(path);
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QString prefix = QLatin1String("\\\\?\\");
if (isUncPath(absPath)) {
prefix.append(QLatin1String("UNC\\")); // "\\\\?\\UNC\\"
@@ -121,11 +125,12 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
if (openMode & QIODevice::WriteOnly)
accessRights |= GENERIC_WRITE;
- SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
// WriteOnly can create files, ReadOnly cannot.
DWORD creationDisp = (openMode & QIODevice::WriteOnly) ? OPEN_ALWAYS : OPEN_EXISTING;
// Create the file handle.
+#ifndef Q_OS_WINRT
+ SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
accessRights,
shareMode,
@@ -133,6 +138,13 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
creationDisp,
FILE_ATTRIBUTE_NORMAL,
NULL);
+#else // !Q_OS_WINRT
+ fileHandle = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(),
+ accessRights,
+ shareMode,
+ creationDisp,
+ NULL);
+#endif // Q_OS_WINRT
// Bail out on error.
if (fileHandle == INVALID_HANDLE_VALUE) {
@@ -473,7 +485,7 @@ int QFSFileEnginePrivate::nativeHandle() const
*/
bool QFSFileEnginePrivate::nativeIsSequential() const
{
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
HANDLE handle = fileHandle;
if (fh || fd != -1)
handle = (HANDLE)_get_osfhandle(fh ? QT_FILENO(fh) : fd);
@@ -577,7 +589,7 @@ bool QFSFileEngine::setCurrentPath(const QString &path)
QString QFSFileEngine::currentPath(const QString &fileName)
{
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QString ret;
//if filename is a drive: then get the pwd of that drive
if (fileName.length() >= 2 &&
@@ -596,10 +608,10 @@ QString QFSFileEngine::currentPath(const QString &fileName)
if (ret.length() >= 2 && ret[1] == QLatin1Char(':'))
ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
return ret;
-#else
+#else // !Q_OS_WINCE && !Q_OS_WINRT
Q_UNUSED(fileName);
return QFileSystemEngine::currentPath().filePath();
-#endif
+#endif // Q_OS_WINCE || Q_OS_WINRT
}
QString QFSFileEngine::homePath()
@@ -620,7 +632,7 @@ QString QFSFileEngine::tempPath()
QFileInfoList QFSFileEngine::drives()
{
QFileInfoList ret;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#if defined(Q_OS_WIN32)
quint32 driveBits = (quint32) GetLogicalDrives() & 0x3ffffff;
#endif
@@ -633,10 +645,10 @@ QFileInfoList QFSFileEngine::drives()
driveBits = driveBits >> 1;
}
return ret;
-#else
+#else // !Q_OS_WINCE && !Q_OS_WINRT
ret.append(QFileInfo(QLatin1String("/")));
return ret;
-#endif
+#endif // Q_OS_WINCE || Q_OS_WINRT
}
bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) const
@@ -661,7 +673,7 @@ bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) cons
bool QFSFileEngine::link(const QString &newName)
{
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#if !defined(QT_NO_LIBRARY)
bool ret = false;
@@ -707,7 +719,7 @@ bool QFSFileEngine::link(const QString &newName)
Q_UNUSED(newName);
return false;
#endif // QT_NO_LIBRARY
-#else
+#elif defined(Q_OS_WINCE)
QString linkName = newName;
linkName.replace(QLatin1Char('/'), QLatin1Char('\\'));
if (!linkName.endsWith(QLatin1String(".lnk")))
@@ -720,7 +732,11 @@ bool QFSFileEngine::link(const QString &newName)
if (!ret)
setError(QFile::RenameError, qt_error_string());
return ret;
-#endif // Q_OS_WINCE
+#else // Q_OS_WINCE
+ Q_UNUSED(newName);
+ Q_UNIMPLEMENTED();
+ return false;
+#endif // Q_OS_WINRT
}
/*!
@@ -937,6 +953,7 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const
uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
QFile::MemoryMapFlags flags)
{
+#ifndef Q_OS_WINPHONE
Q_Q(QFSFileEngine);
Q_UNUSED(flags);
if (openMode == QFile::NotOpen) {
@@ -980,7 +997,11 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
// first create the file mapping handle
DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY;
+#ifndef Q_OS_WINRT
mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0);
+#else
+ mapHandle = ::CreateFileMappingFromApp(handle, 0, protection, 0, 0);
+#endif
if (mapHandle == NULL) {
q->setError(QFile::PermissionsError, qt_error_string());
#ifdef Q_USE_DEPRECATED_MAP_API
@@ -998,15 +1019,23 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
DWORD offsetHi = offset >> 32;
DWORD offsetLo = offset & Q_UINT64_C(0xffffffff);
SYSTEM_INFO sysinfo;
+#ifndef Q_OS_WINRT
::GetSystemInfo(&sysinfo);
+#else
+ ::GetNativeSystemInfo(&sysinfo);
+#endif
DWORD mask = sysinfo.dwAllocationGranularity - 1;
DWORD extra = offset & mask;
if (extra)
offsetLo &= ~mask;
// attempt to create the map
+#ifndef Q_OS_WINRT
LPVOID mapAddress = ::MapViewOfFile(mapHandle, access,
offsetHi, offsetLo, size + extra);
+#else
+ LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access, offset, size);
+#endif
if (mapAddress) {
uchar *address = extra + static_cast<uchar*>(mapAddress);
maps[address] = extra;
@@ -1025,11 +1054,18 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
::CloseHandle(mapHandle);
mapHandle = NULL;
+#else // !Q_OS_WINPHONE
+ Q_UNUSED(offset);
+ Q_UNUSED(size);
+ Q_UNUSED(flags);
+ Q_UNIMPLEMENTED();
+#endif // Q_OS_WINPHONE
return 0;
}
bool QFSFileEnginePrivate::unmap(uchar *ptr)
{
+#ifndef Q_OS_WINPHONE
Q_Q(QFSFileEngine);
if (!maps.contains(ptr)) {
q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
@@ -1048,6 +1084,11 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
}
return true;
+#else // !Q_OS_WINPHONE
+ Q_UNUSED(ptr);
+ Q_UNIMPLEMENTED();
+ return false;
+#endif // Q_OS_WINPHONE
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp
index b5f6d9f3da..28f6b02a64 100644
--- a/src/corelib/io/qlockfile_win.cpp
+++ b/src/corelib/io/qlockfile_win.cpp
@@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE
QLockFile::LockError QLockFilePrivate::tryLock_sys()
{
- SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
const QFileSystemEntry fileEntry(fileName);
// When writing, allow others to read.
// When reading, QFile will allow others to read and write, all good.
@@ -60,6 +59,8 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
// but Windows doesn't allow recreating it while this handle is open anyway,
// so this would only create confusion (can't lock, but no lock file to read from).
const DWORD dwShareMode = FILE_SHARE_READ;
+#ifndef Q_OS_WINRT
+ SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
HANDLE fh = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
GENERIC_WRITE,
dwShareMode,
@@ -67,6 +68,13 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
CREATE_NEW, // error if already exists
FILE_ATTRIBUTE_NORMAL,
NULL);
+#else // !Q_OS_WINRT
+ HANDLE fh = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(),
+ GENERIC_WRITE,
+ dwShareMode,
+ CREATE_NEW, // error if already exists
+ NULL);
+#endif // Q_OS_WINRT
if (fh == INVALID_HANDLE_VALUE) {
const DWORD lastError = GetLastError();
switch (lastError) {
@@ -112,6 +120,9 @@ bool QLockFilePrivate::isApparentlyStale() const
if (!getLockInfo(&pid, &hostname, &appname))
return false;
+ // On WinRT there seems to be no way of obtaining information about other
+ // processes due to sandboxing
+#ifndef Q_OS_WINRT
HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!procHandle)
return true;
@@ -120,6 +131,7 @@ bool QLockFilePrivate::isApparentlyStale() const
::CloseHandle(procHandle);
if (dwR == WAIT_TIMEOUT)
return true;
+#endif // !Q_OS_WINRT
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
return staleLockTime > 0 && age > staleLockTime;
}
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 35b3ed4e3d..8b67fc1962 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -80,6 +80,16 @@
# include <qt_windows.h>
#endif
+#ifdef Q_OS_WINRT
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+#endif
+
#ifndef CSIDL_COMMON_APPDATA
#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
#endif
@@ -365,7 +375,7 @@ after_loop:
// see also qsettings_win.cpp and qsettings_mac.cpp
-#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
+#if defined(Q_OS_WINRT) || (!defined(Q_OS_WIN) && !defined(Q_OS_MAC))
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope,
const QString &organization, const QString &application)
{
@@ -373,7 +383,7 @@ QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::
}
#endif
-#if !defined(Q_OS_WIN)
+#if defined(Q_OS_WINRT) || !defined(Q_OS_WIN)
QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::Format format)
{
return new QConfFileSettingsPrivate(fileName, format);
@@ -1021,7 +1031,7 @@ void QConfFileSettingsPrivate::initAccess()
sync(); // loads the files the first time
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
static QString windowsConfigPath(int type)
{
QString result;
@@ -1063,7 +1073,40 @@ static QString windowsConfigPath(int type)
return result;
}
-#endif // Q_OS_WIN
+#elif defined(Q_OS_WINRT) // Q_OS_WIN && !Q_OS_WINRT
+static QString windowsConfigPath(int type)
+{
+ static QString result;
+ while (result.isEmpty()) {
+ ComPtr<IApplicationDataStatics> applicationDataStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
+ return result;
+ ComPtr<IApplicationData> applicationData;
+ if (FAILED(applicationDataStatics->get_Current(&applicationData)))
+ return result;
+ ComPtr<IStorageFolder> localFolder;
+ if (FAILED(applicationData->get_LocalFolder(&localFolder)))
+ return result;
+ ComPtr<IStorageItem> localFolderItem;
+ if (FAILED(localFolder.As(&localFolderItem)))
+ return result;
+ HSTRING path;
+ if (FAILED(localFolderItem->get_Path(&path)))
+ return result;
+ result = QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr));
+ }
+
+ switch (type) {
+ case CSIDL_COMMON_APPDATA:
+ return result + QLatin1String("\\qt-common");
+ case CSIDL_APPDATA:
+ return result + QLatin1String("\\qt-user");
+ default:
+ break;
+ }
+ return result;
+}
+#endif // Q_OS_WINRT
static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope)
{
@@ -1449,10 +1492,18 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QString writeSemName = QLatin1String("QSettingsWriteSem ");
writeSemName.append(file.fileName());
+#ifndef Q_OS_WINRT
writeSemaphore = CreateSemaphore(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()));
+#else
+ writeSemaphore = CreateSemaphoreEx(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()), 0, SEMAPHORE_ALL_ACCESS);
+#endif
if (writeSemaphore) {
+#ifndef Q_OS_WINRT
WaitForSingleObject(writeSemaphore, INFINITE);
+#else
+ WaitForSingleObjectEx(writeSemaphore, INFINITE, FALSE);
+#endif
} else {
setStatus(QSettings::AccessError);
return;
@@ -1465,11 +1516,19 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QString readSemName(QLatin1String("QSettingsReadSem "));
readSemName.append(file.fileName());
+#ifndef Q_OS_WINRT
readSemaphore = CreateSemaphore(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()));
+#else
+ readSemaphore = CreateSemaphoreEx(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()), 0, SEMAPHORE_ALL_ACCESS);
+#endif
if (readSemaphore) {
for (int i = 0; i < numReadLocks; ++i)
+#ifndef Q_OS_WINRT
WaitForSingleObject(readSemaphore, INFINITE);
+#else
+ WaitForSingleObjectEx(readSemaphore, INFINITE, FALSE);
+#endif
} else {
setStatus(QSettings::AccessError);
if (writeSemaphore != 0) {
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 2207b8c43e..1181d1b980 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -72,34 +72,198 @@ QT_BEGIN_NAMESPACE
methods such as QStandardPaths::writableLocation, QStandardPaths::standardLocations,
and QStandardPaths::displayName.
- \value DesktopLocation Returns the user's desktop directory.
- \value DocumentsLocation Returns the user's document.
- \value FontsLocation Returns the user's fonts.
- \value ApplicationsLocation Returns the user's applications.
- \value MusicLocation Returns the user's music.
- \value MoviesLocation Returns the user's movies.
- \value PicturesLocation Returns the user's pictures.
- \value TempLocation Returns the system's temporary directory.
- \value HomeLocation Returns the user's home directory.
+ Some of the values in this enum represent a user configuration. Such enum
+ values will return the same paths in different applications, so they could
+ be used to share data with other applications. Other values are specific to
+ this application. Each enum value in the table below describes whether it's
+ application-specific or generic.
+
+ Application-specific directories should be assumed to be unreachable by
+ other applications. Therefore, files placed there might not be readable by
+ other applications, even if run by the same user. On the other hand, generic
+ directories should be assumed to be accessible by all applications run by
+ this user, but should still be assumed to be unreachable by applications by
+ other users.
+
+ The only exception is QStandardPaths::TempLocation (which is the same as
+ QDir::tempPath()): the path returned may be application-specific, but files
+ stored there may be accessed by other applications run by the same user.
+
+ Data interchange with other users is out of the scope of QStandardPaths.
+
+ \value DesktopLocation Returns the user's desktop directory. This is a generic value.
+ On systems with no concept of a desktop, this is the same as
+ QStandardPaths::HomeLocation.
+ \value DocumentsLocation Returns the directory containing user document files.
+ This is a generic value. The returned path is never empty.
+ \value FontsLocation Returns the directory containing user's fonts. This is a generic value.
+ Note that installing fonts may require additional, platform-specific operations.
+ \value ApplicationsLocation Returns the directory containing the user applications
+ (either executables, application bundles, or shortcuts to them). This is a generic value.
+ Note that installing applications may require additional, platform-specific operations.
+ Files, folders or shortcuts in this directory are platform-specific.
+ \value MusicLocation Returns the directory containing the user's music or other audio files.
+ This is a generic value. If no directory specific for music files exists, a sensible
+ fallback for storing user documents is returned.
+ \value MoviesLocation Returns the directory containing the user's movies and videos.
+ This is a generic value. If no directory specific for movie files exists, a sensible
+ fallback for storing user documents is returned.
+ \value PicturesLocation Returns the directory containing the user's pictures or photos.
+ This is a generic value. If no directory specific for picture files exists, a sensible
+ fallback for storing user documents is returned.
+ \value TempLocation Returns a directory where temporary files can be stored. The returned value
+ might be application-specific, shared among other applications for this user, or even
+ system-wide. The returned path is never empty.
+ \value HomeLocation Returns the user's home directory (the same as QDir::homePath()). On Unix
+ systems, this is equal to the HOME environment variable. This value might be
+ generic or application-specific, but the returned path is never empty.
\value DataLocation Returns a directory location where persistent
- application data can be stored. QCoreApplication::organizationName
- and QCoreApplication::applicationName are appended to the directory location
- returned for GenericDataLocation.
+ application data can be stored. This is an application-specific directory. To obtain a
+ path to store data to be shared with other applications, use
+ QStandardPaths::GenericDataLocation. The returned path is never empty.
\value CacheLocation Returns a directory location where user-specific
- non-essential (cached) data should be written.
- \value GenericCacheLocation Returns a directory location where user-specific
- non-essential (cached) data, shared across applications, should be written.
+ non-essential (cached) data should be written. This is an application-specific directory.
+ The returned path is never empty.
+ \value GenericCacheLocation Returns a directory location where user-specific non-essential
+ (cached) data, shared across applications, should be written. This is a generic value.
+ Note that the returned path may be empty if the system has no concept of shared cache.
\value GenericDataLocation Returns a directory location where persistent
- data shared across applications can be stored.
+ data shared across applications can be stored. This is a generic value. The returned
+ path is never empty.
\value RuntimeLocation Returns a directory location where runtime communication
- files should be written. For instance unix local sockets.
+ files should be written, like Unix local sockets. This is a generic value.
+ The returned path may be empty on some systems.
\value ConfigLocation Returns a directory location where user-specific
- configuration files should be written.
+ configuration files should be written. This may be either a generic value
+ or application-specific, and the returned path is never empty.
+ \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.
- \value DownloadLocation Returns a directory for user's downloaded files.
+ The following table gives examples of paths on different operating systems.
+ The first path is the writable path (unless noted). Other, additional
+ paths, if any, represent non-writable locations.
+
+ \table
+ \header \li Path type \li OS X \li Windows
+ \row \li DesktopLocation
+ \li "~/Desktop"
+ \li "C:/Users/<USER>/Desktop"
+ \row \li DocumentsLocation
+ \li "~/Documents"
+ \li "C:/Users/<USER>/Documents"
+ \row \li FontsLocation
+ \li "/System/Library/Fonts" (not writable)
+ \li "C:/Windows/Fonts" (not writable)
+ \row \li ApplicationsLocation
+ \li "/Applications" (not writable)
+ \li "C:/Users/<USER>/AppData/Roaming/Microsoft/Windows/Start Menu/Programs"
+ \row \li MusicLocation
+ \li "~/Music"
+ \li "C:/Users/<USER>/Music"
+ \row \li MoviesLocation
+ \li "~/Movies"
+ \li "C:/Users/<USER>/Videos"
+ \row \li PicturesLocation
+ \li "~/Pictures"
+ \li "C:/Users/<USER>/Pictures"
+ \row \li TempLocation
+ \li randomly generated by the OS
+ \li "C:/Users/<USER>/AppData/Local/Temp"
+ \row \li HomeLocation
+ \li "~"
+ \li "C:/Users/<USER>"
+ \row \li DataLocation
+ \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>"
+ \row \li CacheLocation
+ \li "~/Library/Caches/<APPNAME>", "/Library/Caches/<APPNAME>"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>/cache"
+ \row \li GenericDataLocation
+ \li "~/Library/Application Support", "/Library/Application Support"
+ \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
+ \row \li RuntimeLocation
+ \li "~/Library/Application Support"
+ \li "C:/Users/<USER>"
+ \row \li ConfigLocation
+ \li "~/Library/Preferences"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>"
+ \row \li GenericConfigLocation
+ \li "~/Library/Preferences"
+ \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
+ \row \li DownloadLocation
+ \li "~/Documents"
+ \li "C:/Users/<USER>/Documents"
+ \row \li GenericCacheLocation
+ \li "~/Library/Caches", "/Library/Caches"
+ \li "C:/Users/<USER>/AppData/Local/cache"
+ \endtable
+
+ \table
+ \header \li Path type \li Blackberry \li Linux (including Android)
+ \row \li DesktopLocation
+ \li "<APPROOT>/data"
+ \li "~/Desktop"
+ \row \li DocumentsLocation
+ \li "<APPROOT>/shared/documents"
+ \li "~/Documents"
+ \row \li FontsLocation
+ \li "/base/usr/fonts" (not writable)
+ \li "~/.fonts"
+ \row \li ApplicationsLocation
+ \li not supported (directory not readable)
+ \li "~/.local/share/applications", "/usr/local/share/applications", "/usr/share/applications"
+ \row \li MusicLocation
+ \li "<APPROOT>/shared/music"
+ \li "~/Music"
+ \row \li MoviesLocation
+ \li "<APPROOT>/shared/videos"
+ \li "~/Videos"
+ \row \li PicturesLocation
+ \li "<APPROOT>/shared/photos"
+ \li "~/Pictures"
+ \row \li TempLocation
+ \li "/var/tmp"
+ \li "/tmp"
+ \row \li HomeLocation
+ \li "<APPROOT>/data"
+ \li "~"
+ \row \li DataLocation
+ \li "<APPROOT>/data"
+ \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
+ \row \li CacheLocation
+ \li "<APPROOT>/data/Cache"
+ \li "~/.cache/<APPNAME>"
+ \row \li GenericDataLocation
+ \li "<APPROOT>/shared/misc"
+ \li "~/.local/share", "/usr/local/share", "/usr/share"
+ \row \li RuntimeLocation
+ \li "/var/tmp"
+ \li "/run/user/<USER>"
+ \row \li ConfigLocation
+ \li "<APPROOT>/data/Settings"
+ \li "~/.config", "/etc/xdg"
+ \row \li GenericConfigLocation
+ \li "<APPROOT>/data/Settings"
+ \li "~/.config", "/etc/xdg"
+ \row \li DownloadLocation
+ \li "<APPROOT>/shared/downloads"
+ \li "~/Downloads"
+ \row \li GenericCacheLocation
+ \li "<APPROOT>/data/Cache" (there is no shared cache)
+ \li "~/.cache"
+ \endtable
+
+ In the table above, \c <APPNAME> is usually the organization name, the
+ application name, or both, or a unique name generated at packaging.
+ Similarly, <APPROOT> is the location where this application is installed
+ (often a sandbox).
+
+ The paths above should not be relied upon, as they may change according to
+ OS configuration, locale, or they may change in future Qt versions.
\sa writableLocation(), standardLocations(), displayName(), locate(), locateAll()
*/
diff --git a/src/corelib/io/qstandardpaths_winrt.cpp b/src/corelib/io/qstandardpaths_winrt.cpp
new file mode 100644
index 0000000000..9b6a088a30
--- /dev/null
+++ b/src/corelib/io/qstandardpaths_winrt.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qstandardpaths.h"
+
+#include <qdir.h>
+#include <private/qsystemlibrary_p.h>
+#include <qcoreapplication.h>
+#include <qstringlist.h>
+
+#include <qt_windows.h>
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.h>
+#include <Windows.ApplicationModel.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::ApplicationModel;
+
+#ifndef QT_NO_STANDARDPATHS
+
+QT_BEGIN_NAMESPACE
+
+static QString convertCharArray(const wchar_t *path)
+{
+ return QDir::fromNativeSeparators(QString::fromWCharArray(path));
+}
+
+QString QStandardPaths::writableLocation(StandardLocation type)
+{
+ QString result;
+
+ switch (type) {
+ case ConfigLocation: // same as DataLocation, on Windows
+ case DataLocation:
+ case GenericDataLocation: {
+ ComPtr<IApplicationDataStatics> applicationDataStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
+ break;
+ ComPtr<IApplicationData> applicationData;
+ if (FAILED(applicationDataStatics->get_Current(&applicationData)))
+ break;
+ ComPtr<IStorageFolder> settingsFolder;
+ if (FAILED(applicationData->get_LocalFolder(&settingsFolder)))
+ break;
+ ComPtr<IStorageItem> settingsFolderItem;
+ if (FAILED(settingsFolder.As(&settingsFolderItem)))
+ break;
+ HSTRING path;
+ if (FAILED(settingsFolderItem->get_Path(&path)))
+ break;
+ result = convertCharArray(WindowsGetStringRawBuffer(path, nullptr));
+ if (isTestModeEnabled())
+ result += QLatin1String("/qttest");
+ break;
+ }
+ case CacheLocation:
+ return writableLocation(DataLocation) + QLatin1String("/cache");
+
+ case GenericCacheLocation:
+ return writableLocation(GenericDataLocation) + QLatin1String("/cache");
+
+ case RuntimeLocation:
+ case HomeLocation:
+ result = QDir::homePath();
+ break;
+
+ case TempLocation:
+ result = QDir::tempPath();
+ break;
+ default:
+ Q_UNIMPLEMENTED();
+ }
+ return result;
+
+}
+
+QStringList QStandardPaths::standardLocations(StandardLocation type)
+{
+ return QStringList(writableLocation(type));
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STANDARDPATHS
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index b3cb4e43f8..b3a17eae7e 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -151,18 +151,27 @@ static bool createFileFromTemplate(NativeFileHandle &file,
for (;;) {
// Atomically create file and obtain handle
#if defined(Q_OS_WIN)
+# ifndef Q_OS_WINRT
file = CreateFile((const wchar_t *)path.constData(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
+# else // !Q_OS_WINRT
+ file = CreateFile2((const wchar_t *)path.constData(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_NEW,
+ NULL);
+# endif // Q_OS_WINRT
if (file != INVALID_HANDLE_VALUE)
return true;
DWORD err = GetLastError();
if (err == ERROR_ACCESS_DENIED) {
- DWORD attributes = GetFileAttributes((const wchar_t *)path.constData());
- if (attributes == INVALID_FILE_ATTRIBUTES) {
+ WIN32_FILE_ATTRIBUTE_DATA attributes;
+ if (!GetFileAttributesEx((const wchar_t *)path.constData(),
+ GetFileExInfoStandard, &attributes)
+ || attributes.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
// Potential write error (read-only parent directory, etc.).
error = QSystemError(err, QSystemError::NativeError);
return false;
@@ -336,7 +345,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
-#if !defined(Q_OS_WIN)
+#if !defined(Q_OS_WIN) || defined(Q_OS_WINRT)
d->closeFileHandle = true;
#endif
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp
index aff9939b87..883aa5b982 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.cpp
+++ b/src/corelib/itemmodels/qitemselectionmodel.cpp
@@ -1271,9 +1271,8 @@ void QItemSelectionModel::clearCurrentIndex()
*/
void QItemSelectionModel::reset()
{
- bool block = blockSignals(true);
+ const QSignalBlocker blocker(this);
clear();
- blockSignals(block);
}
/*!
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 7625a74381..4c43f292fb 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -68,16 +68,21 @@ SOURCES += \
win32 {
SOURCES += \
- kernel/qeventdispatcher_win.cpp \
kernel/qcoreapplication_win.cpp \
kernel/qwineventnotifier.cpp \
kernel/qsharedmemory_win.cpp \
kernel/qsystemsemaphore_win.cpp
HEADERS += \
- kernel/qeventdispatcher_win_p.h \
kernel/qwineventnotifier.h
-}
+ winrt {
+ SOURCES += kernel/qeventdispatcher_winrt.cpp
+ HEADERS += kernel/qeventdispatcher_winrt_p.h
+ } else {
+ SOURCES += kernel/qeventdispatcher_win.cpp
+ HEADERS += kernel/qeventdispatcher_win_p.h
+ }
+}
wince*: {
SOURCES += \
@@ -86,6 +91,13 @@ wince*: {
kernel/qfunctions_wince.h
}
+winrt {
+ SOURCES += \
+ kernel/qfunctions_winrt.cpp
+ HEADERS += \
+ kernel/qfunctions_winrt.h
+}
+
mac {
SOURCES += \
kernel/qcoreapplication_mac.cpp
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index e77d6894d0..e83a6e2ac4 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -85,7 +85,11 @@
# endif
#endif
#ifdef Q_OS_WIN
+# ifdef Q_OS_WINRT
+# include "qeventdispatcher_winrt_p.h"
+# else
# include "qeventdispatcher_win_p.h"
+# endif
#endif
#endif // QT_NO_QOBJECT
@@ -471,6 +475,8 @@ void QCoreApplicationPrivate::createEventDispatcher()
# endif
eventDispatcher = new QEventDispatcherUNIX(q);
# endif
+#elif defined(Q_OS_WINRT)
+ eventDispatcher = new QEventDispatcherWinRT(q);
#elif defined(Q_OS_WIN)
eventDispatcher = new QEventDispatcherWin32(q);
#else
@@ -518,6 +524,10 @@ void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
coreappdata()->app_libpaths = app_libpaths = new QStringList;
QString app_location = QCoreApplication::applicationFilePath();
app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
+#ifdef Q_OS_WINRT
+ if (app_location.isEmpty())
+ app_location.append(QLatin1Char('/'));
+#endif
app_location = QDir(app_location).canonicalPath();
if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
app_libpaths->append(app_location);
diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h
index 933faff5a5..a2e7b6b33e 100644
--- a/src/corelib/kernel/qeventdispatcher_glib_p.h
+++ b/src/corelib/kernel/qeventdispatcher_glib_p.h
@@ -77,19 +77,19 @@ public:
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
- void registerSocketNotifier(QSocketNotifier *socketNotifier);
- void unregisterSocketNotifier(QSocketNotifier *socketNotifier);
+ void registerSocketNotifier(QSocketNotifier *socketNotifier) Q_DECL_FINAL;
+ void unregisterSocketNotifier(QSocketNotifier *socketNotifier) Q_DECL_FINAL;
- void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
- bool unregisterTimer(int timerId);
- bool unregisterTimers(QObject *object);
- QList<TimerInfo> registeredTimers(QObject *object) const;
+ void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) Q_DECL_FINAL;
+ bool unregisterTimer(int timerId) Q_DECL_FINAL;
+ bool unregisterTimers(QObject *object) Q_DECL_FINAL;
+ QList<TimerInfo> registeredTimers(QObject *object) const Q_DECL_FINAL;
- int remainingTime(int timerId);
+ int remainingTime(int timerId) Q_DECL_FINAL;
- void wakeUp();
- void interrupt();
- void flush();
+ void wakeUp() Q_DECL_FINAL;
+ void interrupt() Q_DECL_FINAL;
+ void flush() Q_DECL_FINAL;
static bool versionSupported();
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index 5d69d5e396..242aa9e695 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -94,6 +94,12 @@ public:
class QEventDispatcherUNIXPrivate;
+#ifdef Q_OS_QNX
+# define FINAL_EXCEPT_BLACKBERRY
+#else
+# define FINAL_EXCEPT_BLACKBERRY Q_DECL_FINAL
+#endif
+
class Q_CORE_EXPORT QEventDispatcherUNIX : public QAbstractEventDispatcher
{
Q_OBJECT
@@ -106,18 +112,18 @@ public:
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
- void registerSocketNotifier(QSocketNotifier *notifier);
- void unregisterSocketNotifier(QSocketNotifier *notifier);
+ void registerSocketNotifier(QSocketNotifier *notifier) FINAL_EXCEPT_BLACKBERRY;
+ void unregisterSocketNotifier(QSocketNotifier *notifier) FINAL_EXCEPT_BLACKBERRY;
- void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
- bool unregisterTimer(int timerId);
- bool unregisterTimers(QObject *object);
- QList<TimerInfo> registeredTimers(QObject *object) const;
+ void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) Q_DECL_FINAL;
+ bool unregisterTimer(int timerId) Q_DECL_FINAL;
+ bool unregisterTimers(QObject *object) Q_DECL_FINAL;
+ QList<TimerInfo> registeredTimers(QObject *object) const Q_DECL_FINAL;
- int remainingTime(int timerId);
+ int remainingTime(int timerId) Q_DECL_FINAL;
- void wakeUp();
- void interrupt();
+ void wakeUp() FINAL_EXCEPT_BLACKBERRY;
+ void interrupt() Q_DECL_FINAL;
void flush();
protected:
@@ -130,7 +136,7 @@ protected:
virtual int select(int nfds,
fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- timespec *timeout);
+ timespec *timeout) Q_DECL_FINAL;
};
class Q_CORE_EXPORT QEventDispatcherUNIXPrivate : public QAbstractEventDispatcherPrivate
@@ -142,8 +148,8 @@ public:
~QEventDispatcherUNIXPrivate();
int doSelect(QEventLoop::ProcessEventsFlags flags, timespec *timeout);
- virtual int initThreadWakeUp();
- virtual int processThreadWakeUp(int nsel);
+ virtual int initThreadWakeUp() FINAL_EXCEPT_BLACKBERRY;
+ virtual int processThreadWakeUp(int nsel) FINAL_EXCEPT_BLACKBERRY;
bool mainThread;
@@ -165,6 +171,8 @@ public:
QAtomicInt interrupt; // bool
};
+#undef FINAL_EXCEPT_BLACKBERRY
+
QT_END_NAMESPACE
#endif // QEVENTDISPATCHER_UNIX_P_H
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
new file mode 100644
index 0000000000..daef8428e1
--- /dev/null
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -0,0 +1,394 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qeventdispatcher_winrt_p.h"
+
+#include "qelapsedtimer.h"
+#include "qcoreapplication.h"
+#include "qthread.h"
+
+#include <private/qcoreapplication_p.h>
+#include <private/qthread_p.h>
+
+#include <windows.foundation.h>
+#include <windows.system.threading.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::System::Threading;
+using namespace ABI::Windows::Foundation;
+
+QT_BEGIN_NAMESPACE
+
+QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
+ : QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
+{
+}
+
+QEventDispatcherWinRT::QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent)
+ : QAbstractEventDispatcher(dd, parent)
+{ }
+
+QEventDispatcherWinRT::~QEventDispatcherWinRT()
+{
+}
+
+bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ Q_UNUSED(flags);
+
+ // we are awake, broadcast it
+ emit awake();
+ QCoreApplicationPrivate::sendPostedEvents(0, 0, QThreadData::current());
+
+ return false;
+}
+
+bool QEventDispatcherWinRT::hasPendingEvents()
+{
+ return qGlobalPostedEventsCount();
+}
+
+void QEventDispatcherWinRT::registerSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+}
+void QEventDispatcherWinRT::unregisterSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+}
+
+void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object)
+{
+ Q_UNUSED(timerType);
+
+ if (timerId < 1 || interval < 0 || !object) {
+ qWarning("QEventDispatcherWinRT::registerTimer: invalid arguments");
+ return;
+ } else if (object->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QObject::startTimer: timers cannot be started from another thread");
+ return;
+ }
+
+ Q_D(QEventDispatcherWinRT);
+
+ WinRTTimerInfo *t = new WinRTTimerInfo();
+ t->dispatcher = this;
+ t->timerId = timerId;
+ t->interval = interval;
+ t->timeout = interval;
+ t->timerType = timerType;
+ t->obj = object;
+ t->inTimerEvent = false;
+
+ d->registerTimer(t);
+ d->timerVec.append(t); // store in timer vector
+ d->timerDict.insert(t->timerId, t); // store timers in dict
+}
+
+bool QEventDispatcherWinRT::unregisterTimer(int timerId)
+{
+ if (timerId < 1) {
+ qWarning("QEventDispatcherWinRT::unregisterTimer: invalid argument");
+ return false;
+ }
+ if (thread() != QThread::currentThread()) {
+ qWarning("QObject::killTimer: timers cannot be stopped from another thread");
+ return false;
+ }
+
+ Q_D(QEventDispatcherWinRT);
+ if (d->timerVec.isEmpty() || timerId <= 0)
+ return false;
+
+ WinRTTimerInfo *t = d->timerDict.value(timerId);
+ if (!t)
+ return false;
+
+ if (t->timer)
+ d->threadPoolTimerDict.remove(t->timer);
+ d->timerDict.remove(t->timerId);
+ d->timerVec.removeAll(t);
+ d->unregisterTimer(t);
+ return true;
+}
+
+bool QEventDispatcherWinRT::unregisterTimers(QObject *object)
+{
+ if (!object) {
+ qWarning("QEventDispatcherWinRT::unregisterTimers: invalid argument");
+ return false;
+ }
+ QThread *currentThread = QThread::currentThread();
+ if (object->thread() != thread() || thread() != currentThread) {
+ qWarning("QObject::killTimers: timers cannot be stopped from another thread");
+ return false;
+ }
+
+ Q_D(QEventDispatcherWinRT);
+ if (d->timerVec.isEmpty())
+ return false;
+ register WinRTTimerInfo *t;
+ for (int i = 0; i < d->timerVec.size(); i++) {
+ t = d->timerVec.at(i);
+ if (t && t->obj == object) { // object found
+ if (t->timer)
+ d->threadPoolTimerDict.remove(t->timer);
+ d->timerDict.remove(t->timerId);
+ d->timerVec.removeAt(i);
+ d->unregisterTimer(t);
+ --i;
+ }
+ }
+ return true;
+}
+
+QList<QAbstractEventDispatcher::TimerInfo> QEventDispatcherWinRT::registeredTimers(QObject *object) const
+{
+ if (!object) {
+ qWarning("QEventDispatcherWinRT:registeredTimers: invalid argument");
+ return QList<TimerInfo>();
+ }
+
+ Q_D(const QEventDispatcherWinRT);
+ QList<TimerInfo> list;
+ for (int i = 0; i < d->timerVec.size(); ++i) {
+ const WinRTTimerInfo *t = d->timerVec.at(i);
+ if (t && t->obj == object)
+ list << TimerInfo(t->timerId, t->interval, t->timerType);
+ }
+ return list;
+}
+
+bool QEventDispatcherWinRT::registerEventNotifier(QWinEventNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+ return false;
+}
+
+void QEventDispatcherWinRT::unregisterEventNotifier(QWinEventNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+}
+
+int QEventDispatcherWinRT::remainingTime(int timerId)
+{
+#ifndef QT_NO_DEBUG
+ if (timerId < 1) {
+ qWarning("QEventDispatcherWinRT::remainingTime: invalid argument");
+ return -1;
+ }
+#endif
+
+ Q_D(QEventDispatcherWinRT);
+
+ if (d->timerVec.isEmpty())
+ return -1;
+
+ quint64 currentTime = qt_msectime();
+
+ register WinRTTimerInfo *t;
+ for (int i = 0; i < d->timerVec.size(); i++) {
+ t = d->timerVec.at(i);
+ if (t && t->timerId == timerId) { // timer found
+ if (currentTime < t->timeout) {
+ // time to wait
+ return t->timeout - currentTime;
+ } else {
+ return 0;
+ }
+ }
+ }
+
+#ifndef QT_NO_DEBUG
+ qWarning("QEventDispatcherWinRT::remainingTime: timer id %d not found", timerId);
+#endif
+
+ return -1;
+}
+
+void QEventDispatcherWinRT::wakeUp()
+{
+ Q_D(QEventDispatcherWinRT);
+ if (d->wakeUps.testAndSetAcquire(0, 1)) {
+ // ###TODO: is there any thing to wake up?
+ }
+}
+
+void QEventDispatcherWinRT::interrupt()
+{
+ Q_D(QEventDispatcherWinRT);
+ d->interrupt = true;
+ wakeUp();
+}
+
+void QEventDispatcherWinRT::flush()
+{
+}
+
+void QEventDispatcherWinRT::startingUp()
+{
+}
+
+void QEventDispatcherWinRT::closingDown()
+{
+ Q_D(QEventDispatcherWinRT);
+
+ // clean up any timers
+ for (int i = 0; i < d->timerVec.count(); ++i)
+ d->unregisterTimer(d->timerVec.at(i));
+ d->timerVec.clear();
+ d->timerDict.clear();
+ d->threadPoolTimerDict.clear();
+}
+
+bool QEventDispatcherWinRT::event(QEvent *e)
+{
+ Q_D(QEventDispatcherWinRT);
+ if (e->type() == QEvent::ZeroTimerEvent) {
+ QZeroTimerEvent *zte = static_cast<QZeroTimerEvent*>(e);
+ WinRTTimerInfo *t = d->timerDict.value(zte->timerId());
+ if (t) {
+ t->inTimerEvent = true;
+
+ QTimerEvent te(zte->timerId());
+ QCoreApplication::sendEvent(t->obj, &te);
+
+ t = d->timerDict.value(zte->timerId());
+ if (t) {
+ if (t->interval == 0 && t->inTimerEvent) {
+ // post the next zero timer event as long as the timer was not restarted
+ QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId()));
+ }
+
+ t->inTimerEvent = false;
+ }
+ }
+ return true;
+ } else if (e->type() == QEvent::Timer) {
+ QTimerEvent *te = static_cast<QTimerEvent*>(e);
+ d->sendTimerEvent(te->timerId());
+ }
+ return QAbstractEventDispatcher::event(e);
+}
+
+QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate()
+ : interrupt(false)
+ , timerFactory(0)
+{
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Threading_ThreadPoolTimer).Get(), &timerFactory);
+ if (FAILED(hr))
+ qWarning("QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate: Could not obtain timer factory: %lx", hr);
+}
+
+QEventDispatcherWinRTPrivate::~QEventDispatcherWinRTPrivate()
+{
+ if (timerFactory)
+ timerFactory->Release();
+ CoUninitialize();
+}
+
+void QEventDispatcherWinRTPrivate::registerTimer(WinRTTimerInfo *t)
+{
+ Q_Q(QEventDispatcherWinRT);
+
+ int ok = 0;
+ uint interval = t->interval;
+ if (interval == 0u) {
+ // optimization for single-shot-zero-timer
+ QCoreApplication::postEvent(q, new QZeroTimerEvent(t->timerId));
+ ok = 1;
+ } else {
+ TimeSpan period;
+ period.Duration = interval * 10000; // TimeSpan is based on 100-nanosecond units
+ ok = SUCCEEDED(timerFactory->CreatePeriodicTimer(
+ Callback<ITimerElapsedHandler>(this, &QEventDispatcherWinRTPrivate::timerExpiredCallback).Get(), period, &t->timer));
+ if (ok)
+ threadPoolTimerDict.insert(t->timer, t);
+ }
+ t->timeout = qt_msectime() + interval;
+ if (ok == 0)
+ qErrnoWarning("QEventDispatcherWinRT::registerTimer: Failed to create a timer");
+}
+
+void QEventDispatcherWinRTPrivate::unregisterTimer(WinRTTimerInfo *t)
+{
+ if (t->timer) {
+ t->timer->Cancel();
+ t->timer->Release();
+ }
+ delete t;
+ t = 0;
+}
+
+void QEventDispatcherWinRTPrivate::sendTimerEvent(int timerId)
+{
+ WinRTTimerInfo *t = timerDict.value(timerId);
+ if (t && !t->inTimerEvent) {
+ // send event, but don't allow it to recurse
+ t->inTimerEvent = true;
+
+ QTimerEvent e(t->timerId);
+ QCoreApplication::sendEvent(t->obj, &e);
+
+ // timer could have been removed
+ t = timerDict.value(timerId);
+ if (t) {
+ t->inTimerEvent = false;
+ }
+ }
+}
+
+HRESULT QEventDispatcherWinRTPrivate::timerExpiredCallback(IThreadPoolTimer *source)
+{
+ register WinRTTimerInfo *t = threadPoolTimerDict.value(source);
+ if (t)
+ QCoreApplication::postEvent(t->dispatcher, new QTimerEvent(t->timerId));
+ else
+ qWarning("QEventDispatcherWinRT::timerExpiredCallback: Could not find timer %d in timer list", source);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h
new file mode 100644
index 0000000000..35b3faa771
--- /dev/null
+++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+
+#ifndef QEVENTDISPATCHER_WINRT_P_H
+#define QEVENTDISPATCHER_WINRT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qabstracteventdispatcher.h"
+#include "private/qabstracteventdispatcher_p.h"
+
+#include <qt_windows.h>
+#include <wrl.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace System {
+ namespace Threading {
+ struct IThreadPoolTimer;
+ struct IThreadPoolTimerStatics;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+int qt_msectime();
+
+class QEventDispatcherWinRTPrivate;
+
+class Q_CORE_EXPORT QEventDispatcherWinRT : public QAbstractEventDispatcher
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QEventDispatcherWinRT)
+
+public:
+ explicit QEventDispatcherWinRT(QObject *parent = 0);
+ ~QEventDispatcherWinRT();
+
+ bool processEvents(QEventLoop::ProcessEventsFlags flags);
+ bool hasPendingEvents();
+
+ void registerSocketNotifier(QSocketNotifier *notifier);
+ void unregisterSocketNotifier(QSocketNotifier *notifier);
+
+ void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
+ bool unregisterTimer(int timerId);
+ bool unregisterTimers(QObject *object);
+ QList<TimerInfo> registeredTimers(QObject *object) const;
+
+ int remainingTime(int timerId);
+
+ bool registerEventNotifier(QWinEventNotifier *notifier);
+ void unregisterEventNotifier(QWinEventNotifier *notifier);
+
+ void wakeUp();
+ void interrupt();
+ void flush();
+
+ void startingUp();
+ void closingDown();
+
+protected:
+ QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent = 0);
+
+
+ bool event(QEvent *);
+ int activateTimers();
+ int activateSocketNotifiers();
+};
+
+struct WinRTTimerInfo // internal timer info
+{
+ WinRTTimerInfo() : timer(0) {}
+
+ QObject *dispatcher;
+ int timerId;
+ int interval;
+ Qt::TimerType timerType;
+ quint64 timeout; // - when to actually fire
+ QObject *obj; // - object to receive events
+ bool inTimerEvent;
+ ABI::Windows::System::Threading::IThreadPoolTimer *timer;
+};
+
+class QZeroTimerEvent : public QTimerEvent
+{
+public:
+ explicit inline QZeroTimerEvent(int timerId)
+ : QTimerEvent(timerId)
+ { t = QEvent::ZeroTimerEvent; }
+};
+
+class Q_CORE_EXPORT QEventDispatcherWinRTPrivate : public QAbstractEventDispatcherPrivate
+{
+ Q_DECLARE_PUBLIC(QEventDispatcherWinRT)
+
+public:
+ QEventDispatcherWinRTPrivate();
+ ~QEventDispatcherWinRTPrivate();
+
+ QList<WinRTTimerInfo*> timerVec;
+ QHash<int, WinRTTimerInfo*> timerDict;
+ QHash<ABI::Windows::System::Threading::IThreadPoolTimer*, WinRTTimerInfo*> threadPoolTimerDict;
+
+ void registerTimer(WinRTTimerInfo *t);
+ void unregisterTimer(WinRTTimerInfo *t);
+ void sendTimerEvent(int timerId);
+ HRESULT timerExpiredCallback(ABI::Windows::System::Threading::IThreadPoolTimer *source);
+
+ QAtomicInt wakeUps;
+ bool interrupt;
+
+ ABI::Windows::System::Threading::IThreadPoolTimerStatics *timerFactory;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEVENTDISPATCHER_WINRT_P_H
diff --git a/src/corelib/kernel/qfunctions_p.h b/src/corelib/kernel/qfunctions_p.h
index 6e094f1ed3..e3014a0dcf 100644
--- a/src/corelib/kernel/qfunctions_p.h
+++ b/src/corelib/kernel/qfunctions_p.h
@@ -61,6 +61,8 @@
# include "QtCore/qfunctions_vxworks.h"
#elif defined(Q_OS_NACL)
# include "QtCore/qfunctions_nacl.h"
+#elif defined(Q_OS_WINRT)
+# include "QtCore/qfunctions_winrt.h"
#endif
#ifdef Q_CC_RVCT
diff --git a/src/corelib/kernel/qfunctions_winrt.cpp b/src/corelib/kernel/qfunctions_winrt.cpp
new file mode 100644
index 0000000000..1348af2acb
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_winrt.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+#ifdef Q_OS_WINRT
+
+#include "qfunctions_winrt.h"
+#include "qstring.h"
+#include "qbytearray.h"
+#include "qhash.h"
+
+QT_USE_NAMESPACE
+
+// Environment ------------------------------------------------------
+inline QHash<QByteArray, QByteArray> &qt_app_environment()
+{
+ static QHash<QByteArray, QByteArray> internalEnvironment;
+ return internalEnvironment;
+}
+
+errno_t qt_winrt_getenv_s(size_t* sizeNeeded, char* buffer, size_t bufferSize, const char* varName)
+{
+ if (!sizeNeeded)
+ return EINVAL;
+
+ if (!qt_app_environment().contains(varName)) {
+ if (buffer)
+ buffer[0] = '\0';
+ return ENOENT;
+ }
+
+ QByteArray value = qt_app_environment().value(varName);
+ if (!value.endsWith('\0')) // win32 guarantees terminated string
+ value.append('\0');
+
+ if (bufferSize < (size_t)value.size()) {
+ *sizeNeeded = value.size();
+ return ERANGE;
+ }
+
+ strcpy(buffer, value.constData());
+ return 0;
+}
+
+errno_t qt_winrt__putenv_s(const char* varName, const char* value)
+{
+ QByteArray input = value;
+ if (input.isEmpty()) {
+ if (qt_app_environment().contains(varName))
+ qt_app_environment().remove(varName);
+ } else {
+ // win32 on winrt guarantees terminated string
+ if (!input.endsWith('\0'))
+ input.append('\0');
+ qt_app_environment()[varName] = input;
+ }
+
+ return 0;
+}
+
+void qt_winrt_tzset()
+{
+}
+
+void qt_winrt__tzset()
+{
+}
+
+#endif // Q_OS_WINRT
diff --git a/src/corelib/kernel/qfunctions_winrt.h b/src/corelib/kernel/qfunctions_winrt.h
new file mode 100644
index 0000000000..fa2b2e12ff
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_winrt.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QFUNCTIONS_WINRT_H
+#define QFUNCTIONS_WINRT_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WINRT
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_BUILD_CORE_LIB
+#endif
+
+QT_END_NAMESPACE
+
+// Environment ------------------------------------------------------
+errno_t qt_winrt_getenv_s(size_t*, char*, size_t, const char*);
+errno_t qt_winrt__putenv_s(const char*, const char*);
+void qt_winrt_tzset();
+void qt_winrt__tzset();
+
+// As Windows Runtime lacks some standard functions used in Qt, these got
+// reimplemented. Other projects do this as well. Inline functions are used
+// that there is a central place to disable functions for newer versions if
+// they get available. There are no defines used anymore, because this
+// will break member functions of classes which are called like these
+// functions.
+// The other declarations available in this file are being used per
+// define inside qplatformdefs.h of the corresponding WinRT mkspec.
+
+#define generate_inline_return_func0(funcname, returntype) \
+ inline returntype funcname() \
+ { \
+ return qt_winrt_##funcname(); \
+ }
+#define generate_inline_return_func1(funcname, returntype, param1) \
+ inline returntype funcname(param1 p1) \
+ { \
+ return qt_winrt_##funcname(p1); \
+ }
+#define generate_inline_return_func2(funcname, returntype, param1, param2) \
+ inline returntype funcname(param1 p1, param2 p2) \
+ { \
+ return qt_winrt_##funcname(p1, p2); \
+ }
+#define generate_inline_return_func3(funcname, returntype, param1, param2, param3) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3); \
+ }
+#define generate_inline_return_func4(funcname, returntype, param1, param2, param3, param4) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4); \
+ }
+#define generate_inline_return_func5(funcname, returntype, param1, param2, param3, param4, param5) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4, p5); \
+ }
+#define generate_inline_return_func6(funcname, returntype, param1, param2, param3, param4, param5, param6) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4, p5, p6); \
+ }
+#define generate_inline_return_func7(funcname, returntype, param1, param2, param3, param4, param5, param6, param7) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4, p5, p6, p7); \
+ }
+
+typedef unsigned (__stdcall *StartAdressExFunc)(void *);
+typedef void(*StartAdressFunc)(void *);
+typedef int ( __cdecl *CompareFunc ) (const void *, const void *) ;
+
+generate_inline_return_func4(getenv_s, errno_t, size_t *, char *, size_t, const char *)
+generate_inline_return_func2(_putenv_s, errno_t, const char *, const char *)
+generate_inline_return_func0(tzset, void)
+generate_inline_return_func0(_tzset, void)
+
+#endif // Q_OS_WINRT
+#endif // QFUNCTIONS_WINRT_H
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index e02026ca4c..29c5a3dd24 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -485,6 +485,79 @@ void QMetaCallEvent::placeMetaCall(QObject *object)
}
/*!
+ \class QSignalBlocker
+ \brief Exception-safe wrapper around QObject::blockSignals()
+ \since 5.3
+ \ingroup objectmodel
+
+ \reentrant
+
+ QSignalBlocker can be used whereever you would otherwise use a
+ pair of calls to blockSignals(). It blocks signals in its
+ constructor and in the destructor it resets the state to what
+ it was before the constructor ran.
+
+ \code
+ {
+ const QSignalBlocker blocker(someQObject);
+ // no signals here
+ }
+ \endcode
+ is thus equivalent to
+ \code
+ const bool wasBlocked = someQObject->blockSignals(true);
+ // no signals here
+ someQObject->blockSignals(false);
+ \endcode
+
+ except the code using QSignalBlocker is safe in the face of
+ exceptions.
+
+ \sa QMutexLocker, QEventLoopLocker
+*/
+
+/*!
+ \fn QSignalBlocker::QSignalBlocker(QObject *object)
+
+ Constructor. Calls \a{object}->blockSignals(true).
+*/
+
+/*!
+ \fn QSignalBlocker::QSignalBlocker(QObject &object)
+ \overload
+
+ Calls \a{object}.blockSignals(true).
+*/
+
+/*!
+ \fn QSignalBlocker::~QSignalBlocker()
+
+ Destructor. Restores the QObject::signalsBlocked() state to what it
+ was before the constructor ran, unless unblock() has been called
+ without a following reblock(), in which case it does nothing.
+*/
+
+/*!
+ \fn void QSignalBlocker::reblock()
+
+ Re-blocks signals after a previous unblock().
+
+ The numbers of reblock() and unblock() calls are not counted, so
+ every reblock() undoes any number of unblock() calls.
+*/
+
+/*!
+ \fn void QSignalBlocker::unblock()
+
+ Temporarily restores the QObject::signalsBlocked() state to what
+ it was before this QSignaBlocker's constructor ran. To undo, use
+ reblock().
+
+ The numbers of reblock() and unblock() calls are not counted, so
+ every unblock() undoes any number of reblock() calls.
+*/
+
+/*!
\class QObject
\inmodule QtCore
\brief The QObject class is the base class of all Qt objects.
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index e2000afc82..f9239bf575 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -549,6 +549,52 @@ template <class T> inline const char * qobject_interface_iid()
Q_CORE_EXPORT QDebug operator<<(QDebug, const QObject *);
#endif
+class Q_CORE_EXPORT QSignalBlocker
+{
+public:
+ inline explicit QSignalBlocker(QObject *o);
+ inline explicit QSignalBlocker(QObject &o);
+ inline ~QSignalBlocker();
+
+ inline void reblock();
+ inline void unblock();
+private:
+ Q_DISABLE_COPY(QSignalBlocker)
+ QObject * const m_o;
+ bool m_blocked;
+ bool m_inhibited;
+};
+
+QSignalBlocker::QSignalBlocker(QObject *o)
+ : m_o(o),
+ m_blocked(o && o->blockSignals(true)),
+ m_inhibited(false)
+{}
+
+QSignalBlocker::QSignalBlocker(QObject &o)
+ : m_o(&o),
+ m_blocked(o.blockSignals(true)),
+ m_inhibited(false)
+{}
+
+QSignalBlocker::~QSignalBlocker()
+{
+ if (m_o && !m_inhibited)
+ m_o->blockSignals(m_blocked);
+}
+
+void QSignalBlocker::reblock()
+{
+ if (m_o) m_o->blockSignals(true);
+ m_inhibited = false;
+}
+
+void QSignalBlocker::unblock()
+{
+ if (m_o) m_o->blockSignals(m_blocked);
+ m_inhibited = true;
+}
+
namespace QtPrivate {
inline QObject & deref_for_methodcall(QObject &o) { return o; }
inline QObject & deref_for_methodcall(QObject *o) { return *o; }
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 69cfa7888f..91ccf3996e 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -868,7 +868,7 @@ static void customConstruct(QVariant::Private *d, const void *copy)
// this logic should match with QVariantIntegrator::CanUseInternalSpace
if (size <= sizeof(QVariant::Private::Data)
- && (type.flags() & QMetaType::MovableType)) {
+ && (type.flags() & (QMetaType::MovableType | QMetaType::IsEnumeration))) {
type.construct(&d->data.ptr, copy);
d->is_shared = false;
} else {
diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h
index 4ec049e20d..b523d19187 100644
--- a/src/corelib/kernel/qvariant_p.h
+++ b/src/corelib/kernel/qvariant_p.h
@@ -67,7 +67,7 @@ template<typename T>
struct QVariantIntegrator
{
static const bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data)
- && (!QTypeInfo<T>::isStatic);
+ && ((!QTypeInfo<T>::isStatic) || Q_IS_ENUM(T));
};
Q_STATIC_ASSERT(QVariantIntegrator<double>::CanUseInternalSpace);
Q_STATIC_ASSERT(QVariantIntegrator<long int>::CanUseInternalSpace);
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index eab5a37645..c694237dc3 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -41,7 +41,11 @@
#include "qwineventnotifier.h"
+#ifdef Q_OS_WINRT
+#include "qeventdispatcher_winrt_p.h"
+#else
#include "qeventdispatcher_win_p.h"
+#endif
#include "qcoreapplication.h"
#include <private/qthread_p.h>
diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp
index 928f2c5eb1..b9494a3041 100644
--- a/src/corelib/plugin/qlibrary_win.cpp
+++ b/src/corelib/plugin/qlibrary_win.cpp
@@ -107,12 +107,16 @@ bool QLibraryPrivate::load_sys()
attempts.append(QFileInfo(fileName).absoluteFilePath());
#endif
}
+#ifdef Q_OS_WINRT
+ if (fileName.startsWith(QLatin1Char('/')))
+ attempts.prepend(QDir::rootPath() + fileName);
+#endif
Q_FOREACH (const QString &attempt, attempts) {
#ifndef Q_OS_WINRT
pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(attempt).utf16());
#else // Q_OS_WINRT
- QString path = QDir::toNativeSeparators(QDir::current().relativeFilePath(fileName));
+ QString path = QDir::toNativeSeparators(QDir::current().relativeFilePath(attempt));
pHnd = LoadPackagedLibrary((LPCWSTR)path.utf16(), 0);
if (pHnd)
qualifiedFileName = attempt;
diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp
index 14b7f34008..a8cdf85fb6 100644
--- a/src/corelib/thread/qmutex_win.cpp
+++ b/src/corelib/thread/qmutex_win.cpp
@@ -48,7 +48,12 @@ QT_BEGIN_NAMESPACE
QMutexPrivate::QMutexPrivate()
{
+#ifndef Q_OS_WINRT
event = CreateEvent(0, FALSE, FALSE, 0);
+#else
+ event = CreateEventEx(0, NULL, 0, EVENT_ALL_ACCESS);
+#endif
+
if (!event)
qWarning("QMutexData::QMutexData: Cannot create event");
}
@@ -58,7 +63,11 @@ QMutexPrivate::~QMutexPrivate()
bool QMutexPrivate::wait(int timeout)
{
+#ifndef Q_OS_WINRT
return (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0);
+#else
+ return (WaitForSingleObjectEx(event, timeout < 0 ? INFINITE : timeout, FALSE) == WAIT_OBJECT_0);
+#endif
}
void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 50ccca9eda..adad4b81a1 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -154,7 +154,9 @@ QThreadPrivate::QThreadPrivate(QThreadData *d)
thread_id = 0;
#elif defined (Q_OS_WIN)
handle = 0;
+# ifndef Q_OS_WINRT
id = 0;
+# endif
waiters = 0;
#endif
#if defined (Q_OS_WIN)
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 8429e41433..c9b98ac5c0 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -66,6 +66,10 @@
#include <algorithm>
+#ifdef Q_OS_WINRT
+#include <thread>
+#endif
+
QT_BEGIN_NAMESPACE
class QAbstractEventDispatcher;
@@ -173,8 +177,13 @@ public:
static unsigned int __stdcall start(void *);
static void finish(void *, bool lockAnyway=true);
+# ifndef Q_OS_WINRT
Qt::HANDLE handle;
unsigned int id;
+# else
+ std::thread *handle;
+ std::thread::id id;
+# endif
int waiters;
bool terminationEnabled, terminatePending;
# endif
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 9d90583a28..903e72c151 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
//#define WINVER 0x0500
-#if _WIN32_WINNT < 0x0400
+#if (_WIN32_WINNT < 0x0400) && !defined(Q_OS_WINRT)
#define _WIN32_WINNT 0x0400
#endif
@@ -54,10 +54,17 @@
#include <qpointer.h>
#include <private/qcoreapplication_p.h>
+#ifdef Q_OS_WINRT
+#include "private/qeventdispatcher_winrt_p.h"
+#else
#include <private/qeventdispatcher_win_p.h>
+#endif
#include <qt_windows.h>
+#ifdef Q_OS_WINRT
+#include <thread>
+#endif
#ifndef Q_OS_WINCE
#ifndef _MT
@@ -71,6 +78,7 @@
#ifndef QT_NO_THREAD
QT_BEGIN_NAMESPACE
+#ifndef Q_OS_WINRT
void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread);
DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID);
@@ -92,6 +100,38 @@ static void qt_free_tls()
}
}
Q_DESTRUCTOR_FUNCTION(qt_free_tls)
+#else // !Q_OS_WINRT
+
+__declspec(thread) static QThreadData* qt_current_thread_data_tls_index = 0;
+void qt_create_tls()
+{
+}
+
+static void qt_free_tls()
+{
+ if (qt_current_thread_data_tls_index) {
+ qt_current_thread_data_tls_index->deref();
+ qt_current_thread_data_tls_index = 0;
+ }
+}
+
+QThreadData* TlsGetValue(QThreadData*& tls)
+{
+ Q_ASSERT(tls == qt_current_thread_data_tls_index);
+ return tls;
+}
+
+void TlsSetValue(QThreadData*& tls, QThreadData* data)
+{
+ Q_ASSERT(tls == qt_current_thread_data_tls_index);
+ if (tls)
+ tls->deref();
+ tls = data;
+ if (tls)
+ tls->ref();
+}
+Q_DESTRUCTOR_FUNCTION(qt_free_tls)
+#endif // Q_OS_WINRT
/*
QThreadData
@@ -124,6 +164,9 @@ QThreadData *QThreadData::current()
if (!QCoreApplicationPrivate::theMainThread) {
QCoreApplicationPrivate::theMainThread = threadData->thread;
+#ifndef Q_OS_WINRT
+ // TODO: is there a way to reflect the branch's behavior using
+ // WinRT API?
} else {
HANDLE realHandle = INVALID_HANDLE_VALUE;
#if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
@@ -138,6 +181,7 @@ QThreadData *QThreadData::current()
realHandle = reinterpret_cast<HANDLE>(GetCurrentThreadId());
#endif
qt_watch_adopted_thread(realHandle, threadData->thread);
+#endif // !Q_OS_WINRT
}
}
return threadData;
@@ -145,10 +189,16 @@ QThreadData *QThreadData::current()
void QAdoptedThread::init()
{
+#ifndef Q_OS_WINRT
d_func()->handle = GetCurrentThread();
d_func()->id = GetCurrentThreadId();
+#else
+ d_func()->handle = nullptr;
+ d_func()->id = std::this_thread::get_id();
+#endif
}
+#ifndef Q_OS_WINRT
static QVector<HANDLE> qt_adopted_thread_handles;
static QVector<QThread *> qt_adopted_qthreads;
static QMutex qt_adopted_thread_watcher_mutex;
@@ -297,6 +347,7 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
}
}
#endif // !QT_NO_DEBUG && Q_CC_MSVC && !Q_OS_WINCE
+#endif // !Q_OS_WINRT
/**************************************************************************
** QThreadPrivate
@@ -306,7 +357,11 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
void QThreadPrivate::createEventDispatcher(QThreadData *data)
{
+#ifdef Q_OS_WINRT
+ QEventDispatcherWinRT *theEventDispatcher = new QEventDispatcherWinRT;
+#else
QEventDispatcherWin32 *theEventDispatcher = new QEventDispatcherWin32;
+#endif
data->eventDispatcher.storeRelease(theEventDispatcher);
theEventDispatcher->startingUp();
}
@@ -334,7 +389,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
else
createEventDispatcher(data);
-#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE)
+#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
// sets the name of the current thread.
QByteArray objectName = thr->objectName().toLocal8Bit();
qt_set_thread_name((HANDLE)-1,
@@ -380,11 +435,20 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway)
d->interruptionRequested = false;
if (!d->waiters) {
+#ifndef Q_OS_WINRT
CloseHandle(d->handle);
+#else
+ CloseHandle(d->handle->native_handle());
+ delete d->handle;
+#endif
d->handle = 0;
}
+#ifndef Q_OS_WINRT
d->id = 0;
+#else
+ d->id = std::thread::id();
+#endif
}
@@ -400,10 +464,15 @@ Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
int QThread::idealThreadCount() Q_DECL_NOTHROW
{
SYSTEM_INFO sysinfo;
+#ifndef Q_OS_WINRT
GetSystemInfo(&sysinfo);
+#else
+ GetNativeSystemInfo(&sysinfo);
+#endif
return sysinfo.dwNumberOfProcessors;
}
+#ifndef Q_OS_WINRT
void QThread::yieldCurrentThread()
{
#ifndef Q_OS_WINCE
@@ -427,7 +496,28 @@ void QThread::usleep(unsigned long usecs)
{
::Sleep((usecs / 1000) + 1);
}
+#else // !Q_OS_WINRT
+
+void QThread::yieldCurrentThread()
+{
+ std::this_thread::yield();
+}
+void QThread::sleep(unsigned long secs)
+{
+ std::this_thread::sleep_for(std::chrono::seconds(secs));
+}
+
+void QThread::msleep(unsigned long msecs)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(msecs));
+}
+
+void QThread::usleep(unsigned long usecs)
+{
+ std::this_thread::sleep_for(std::chrono::microseconds(usecs));
+}
+#endif // Q_OS_WINRT
void QThread::start(Priority priority)
{
@@ -449,6 +539,7 @@ void QThread::start(Priority priority)
d->returnCode = 0;
d->interruptionRequested = false;
+#ifndef Q_OS_WINRT
/*
NOTE: we create the thread in the suspended state, set the
priority and then resume the thread.
@@ -513,6 +604,23 @@ void QThread::start(Priority priority)
if (ResumeThread(d->handle) == (DWORD) -1) {
qErrnoWarning("QThread::start: Failed to resume new thread");
}
+#else // !Q_OS_WINRT
+ d->handle = new std::thread(QThreadPrivate::start, this);
+
+ if (!d->handle) {
+ qErrnoWarning(errno, "QThread::start: Failed to create thread");
+ d->running = false;
+ d->finished = true;
+ return;
+ }
+
+ d->id = d->handle->get_id();
+
+ if (priority != NormalPriority || priority != InheritPriority) {
+ qWarning("QThread::start: Failed to set thread priority (not implemented)");
+ d->priority = NormalPriority;
+ }
+#endif // Q_OS_WINRT
}
void QThread::terminate()
@@ -525,7 +633,14 @@ void QThread::terminate()
d->terminatePending = true;
return;
}
+
+#ifndef Q_OS_WINRT
TerminateThread(d->handle, 0);
+#else // !Q_OS_WINRT
+ qWarning("QThread::terminate: Terminate is not supported on WinRT");
+ CloseHandle(d->handle->native_handle());
+ d->handle = 0;
+#endif // Q_OS_WINRT
QThreadPrivate::finish(this, false);
}
@@ -534,7 +649,11 @@ bool QThread::wait(unsigned long time)
Q_D(QThread);
QMutexLocker locker(&d->mutex);
+#ifndef Q_OS_WINRT
if (d->id == GetCurrentThreadId()) {
+#else
+ if (d->id == std::this_thread::get_id()) {
+#endif
qWarning("QThread::wait: Thread tried to wait on itself");
return false;
}
@@ -545,6 +664,7 @@ bool QThread::wait(unsigned long time)
locker.mutex()->unlock();
bool ret = false;
+#ifndef Q_OS_WINRT
switch (WaitForSingleObject(d->handle, time)) {
case WAIT_OBJECT_0:
ret = true;
@@ -557,6 +677,23 @@ bool QThread::wait(unsigned long time)
default:
break;
}
+#else // !Q_OS_WINRT
+ if (d->handle->joinable()) {
+ switch (WaitForSingleObjectEx(d->handle->native_handle(), time, FALSE)) {
+ case WAIT_OBJECT_0:
+ ret = true;
+ d->handle->join();
+ break;
+ case WAIT_FAILED:
+ qErrnoWarning("QThread::wait: WaitForSingleObjectEx() failed");
+ break;
+ case WAIT_ABANDONED:
+ case WAIT_TIMEOUT:
+ default:
+ break;
+ }
+ }
+#endif // Q_OS_WINRT
locker.mutex()->lock();
--d->waiters;
@@ -568,7 +705,11 @@ bool QThread::wait(unsigned long time)
}
if (d->finished && !d->waiters) {
+#ifndef Q_OS_WINRT
CloseHandle(d->handle);
+#else
+ delete d->handle;
+#endif
d->handle = 0;
}
@@ -586,13 +727,16 @@ void QThread::setTerminationEnabled(bool enabled)
if (enabled && d->terminatePending) {
QThreadPrivate::finish(thr, false);
locker.unlock(); // don't leave the mutex locked!
+#ifndef Q_OS_WINRT
_endthreadex(0);
+#endif
}
}
// Caller must hold the mutex
void QThreadPrivate::setPriority(QThread::Priority threadPriority)
{
+#ifndef Q_OS_WINRT
// copied from start() with a few modifications:
int prio;
@@ -635,6 +779,12 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
if (!SetThreadPriority(handle, prio)) {
qErrnoWarning("QThread::setPriority: Failed to set thread priority");
}
+#else // !Q_OS_WINRT
+ if (priority != threadPriority) {
+ qWarning("QThread::setPriority: Failed to set thread priority (not implemented)");
+ return;
+ }
+#endif // Q_OS_WINRT
}
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index fb1d1ee7cc..269f561a91 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -61,6 +61,7 @@ public:
void run();
void registerThreadInactive();
+ QWaitCondition runnableReady;
QThreadPoolPrivate *manager;
QRunnable *runnable;
};
@@ -128,14 +129,13 @@ void QThreadPoolThread::run()
// if too many threads are active, expire this thread
bool expired = manager->tooManyThreadsActive();
if (!expired) {
- ++manager->waitingThreads;
+ manager->waitingThreads.enqueue(this);
registerThreadInactive();
// wait for work, exiting after the expiry timeout is reached
- expired = !manager->runnableReady.wait(locker.mutex(), manager->expiryTimeout);
+ runnableReady.wait(locker.mutex(), manager->expiryTimeout);
++manager->activeThreads;
-
- if (expired)
- --manager->waitingThreads;
+ if (manager->waitingThreads.removeOne(this))
+ expired = true;
}
if (expired) {
manager->expiredThreads.enqueue(this);
@@ -160,7 +160,6 @@ QThreadPoolPrivate:: QThreadPoolPrivate()
expiryTimeout(30000),
maxThreadCount(qAbs(QThread::idealThreadCount())),
reservedThreads(0),
- waitingThreads(0),
activeThreads(0)
{ }
@@ -176,11 +175,10 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task)
if (activeThreadCount() >= maxThreadCount)
return false;
- if (waitingThreads > 0) {
+ if (waitingThreads.count() > 0) {
// recycle an available thread
- --waitingThreads;
enqueueTask(task);
- runnableReady.wakeOne();
+ waitingThreads.takeFirst()->runnableReady.wakeOne();
return true;
}
@@ -225,7 +223,7 @@ int QThreadPoolPrivate::activeThreadCount() const
{
return (allThreads.count()
- expiredThreads.count()
- - waitingThreads
+ - waitingThreads.count()
+ reservedThreads);
}
@@ -266,7 +264,6 @@ void QThreadPoolPrivate::reset()
{
QMutexLocker locker(&mutex);
isExiting = true;
- runnableReady.wakeAll();
while (!allThreads.empty()) {
// move the contents of the set out so that we can iterate without the lock
@@ -275,6 +272,7 @@ void QThreadPoolPrivate::reset()
locker.unlock();
foreach (QThreadPoolThread *thread, allThreadsCopy) {
+ thread->runnableReady.wakeAll();
thread->wait();
delete thread;
}
@@ -283,7 +281,7 @@ void QThreadPoolPrivate::reset()
// repeat until all newly arrived threads have also completed
}
- waitingThreads = 0;
+ waitingThreads.clear();
expiredThreads.clear();
isExiting = false;
@@ -459,10 +457,8 @@ void QThreadPool::start(QRunnable *runnable, int priority)
if (!d->tryStart(runnable)) {
d->enqueueTask(runnable, priority);
- if (d->waitingThreads > 0) {
- --d->waitingThreads;
- d->runnableReady.wakeOne();
- }
+ if (!d->waitingThreads.isEmpty())
+ d->waitingThreads.takeFirst()->runnableReady.wakeOne();
}
}
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h
index ba77f7e57c..bd5f546fdb 100644
--- a/src/corelib/thread/qthreadpool_p.h
+++ b/src/corelib/thread/qthreadpool_p.h
@@ -87,8 +87,8 @@ public:
void stealRunnable(QRunnable *);
mutable QMutex mutex;
- QWaitCondition runnableReady;
QSet<QThreadPoolThread *> allThreads;
+ QQueue<QThreadPoolThread *> waitingThreads;
QQueue<QThreadPoolThread *> expiredThreads;
QList<QPair<QRunnable *, int> > queue;
QWaitCondition noActiveThreads;
@@ -97,7 +97,6 @@ public:
int expiryTimeout;
int maxThreadCount;
int reservedThreads;
- int waitingThreads;
int activeThreads;
};
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index 1cb1f82b03..f09667a364 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -64,7 +64,11 @@ class QWaitConditionEvent
public:
inline QWaitConditionEvent() : priority(0), wokenUp(false)
{
+#ifndef Q_OS_WINRT
event = CreateEvent(NULL, TRUE, FALSE, NULL);
+#else
+ event = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
+#endif
}
inline ~QWaitConditionEvent() { CloseHandle(event); }
int priority;
@@ -91,7 +95,9 @@ QWaitConditionEvent *QWaitConditionPrivate::pre()
mtx.lock();
QWaitConditionEvent *wce =
freeQueue.isEmpty() ? new QWaitConditionEvent : freeQueue.takeFirst();
+#ifndef Q_OS_WINRT
wce->priority = GetThreadPriority(GetCurrentThread());
+#endif
wce->wokenUp = false;
// insert 'wce' into the queue (sorted by priority)
@@ -111,7 +117,12 @@ bool QWaitConditionPrivate::wait(QWaitConditionEvent *wce, unsigned long time)
{
// wait for the event
bool ret = false;
+#ifndef Q_OS_WINRT
switch (WaitForSingleObject(wce->event, time)) {
+#else
+ switch (WaitForSingleObjectEx(wce->event, time, FALSE)) {
+#endif
+
default: break;
case WAIT_OBJECT_0:
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index c6eede05cb..f75f33f25c 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -55,28 +55,28 @@ namespace QAlgorithmsPrivate {
#if QT_DEPRECATED_SINCE(5, 2)
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
+QT_DEPRECATED_X("Use std::sort") Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
+QT_DEPRECATED_X("Use std::sort") inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
+QT_DEPRECATED_X("Use std::stable_sort") Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
+QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
#endif // QT_DEPRECATED_SINCE(5, 2)
}
#if QT_DEPRECATED_SINCE(5, 2)
template <typename InputIterator, typename OutputIterator>
-QT_DEPRECATED inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
+QT_DEPRECATED_X("Use std::copy") inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
{
while (begin != end)
*dest++ = *begin++;
@@ -84,7 +84,7 @@ QT_DEPRECATED inline OutputIterator qCopy(InputIterator begin, InputIterator end
}
template <typename BiIterator1, typename BiIterator2>
-QT_DEPRECATED inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
+QT_DEPRECATED_X("Use std::copy_backward") inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
{
while (begin != end)
*--dest = *--end;
@@ -92,7 +92,7 @@ QT_DEPRECATED inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 en
}
template <typename InputIterator1, typename InputIterator2>
-QT_DEPRECATED inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
+QT_DEPRECATED_X("Use std::equal") inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
{
for (; first1 != last1; ++first1, ++first2)
if (!(*first1 == *first2))
@@ -101,20 +101,20 @@ QT_DEPRECATED inline bool qEqual(InputIterator1 first1, InputIterator1 last1, In
}
template <typename ForwardIterator, typename T>
-QT_DEPRECATED inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
+QT_DEPRECATED_X("Use std::fill") inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
{
for (; first != last; ++first)
*first = val;
}
template <typename Container, typename T>
-QT_DEPRECATED inline void qFill(Container &container, const T &val)
+QT_DEPRECATED_X("Use std::fill") inline void qFill(Container &container, const T &val)
{
qFill(container.begin(), container.end(), val);
}
template <typename InputIterator, typename T>
-QT_DEPRECATED inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
+QT_DEPRECATED_X("Use std::find") inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
{
while (first != last && !(*first == val))
++first;
@@ -122,13 +122,13 @@ QT_DEPRECATED inline InputIterator qFind(InputIterator first, InputIterator last
}
template <typename Container, typename T>
-QT_DEPRECATED inline typename Container::const_iterator qFind(const Container &container, const T &val)
+QT_DEPRECATED_X("Use std::find") inline typename Container::const_iterator qFind(const Container &container, const T &val)
{
return qFind(container.constBegin(), container.constEnd(), val);
}
template <typename InputIterator, typename T, typename Size>
-QT_DEPRECATED inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
+QT_DEPRECATED_X("Use std::count") inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
{
for (; first != last; ++first)
if (*first == value)
@@ -136,7 +136,7 @@ QT_DEPRECATED inline void qCount(InputIterator first, InputIterator last, const
}
template <typename Container, typename T, typename Size>
-QT_DEPRECATED inline void qCount(const Container &container, const T &value, Size &n)
+QT_DEPRECATED_X("Use std::count") inline void qCount(const Container &container, const T &value, Size &n)
{
qCount(container.constBegin(), container.constEnd(), value, n);
}
@@ -153,7 +153,7 @@ LessThan qGreater()
}
#else
template <typename T>
-class QT_DEPRECATED qLess
+class QT_DEPRECATED_X("Use std::less") qLess
{
public:
inline bool operator()(const T &t1, const T &t2) const
@@ -163,7 +163,7 @@ public:
};
template <typename T>
-class QT_DEPRECATED qGreater
+class QT_DEPRECATED_X("Use std::greater") qGreater
{
public:
inline bool operator()(const T &t1, const T &t2) const
@@ -174,21 +174,21 @@ public:
#endif
template <typename RandomAccessIterator>
-QT_DEPRECATED inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
+QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
{
if (start != end)
QAlgorithmsPrivate::qSortHelper(start, end, *start);
}
template <typename RandomAccessIterator, typename LessThan>
-QT_DEPRECATED inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
+QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
{
if (start != end)
QAlgorithmsPrivate::qSortHelper(start, end, *start, lessThan);
}
template<typename Container>
-QT_DEPRECATED inline void qSort(Container &c)
+QT_DEPRECATED_X("Use std::sort") inline void qSort(Container &c)
{
#ifdef Q_CC_BOR
// Work around Borland 5.5 optimizer bug
@@ -199,21 +199,21 @@ QT_DEPRECATED inline void qSort(Container &c)
}
template <typename RandomAccessIterator>
-QT_DEPRECATED inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
+QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
{
if (start != end)
QAlgorithmsPrivate::qStableSortHelper(start, end, *start);
}
template <typename RandomAccessIterator, typename LessThan>
-QT_DEPRECATED inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
+QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
{
if (start != end)
QAlgorithmsPrivate::qStableSortHelper(start, end, *start, lessThan);
}
template<typename Container>
-QT_DEPRECATED inline void qStableSort(Container &c)
+QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(Container &c)
{
#ifdef Q_CC_BOR
// Work around Borland 5.5 optimizer bug
@@ -224,7 +224,7 @@ QT_DEPRECATED inline void qStableSort(Container &c)
}
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate to keep existing code
// compiling. We have to allow using *begin and value with different types,
@@ -247,19 +247,19 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccess
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qLowerBoundHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
+QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qLowerBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate.
RandomAccessIterator middle;
@@ -280,19 +280,19 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccess
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qUpperBoundHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
+QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qUpperBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate.
RandomAccessIterator it = qLowerBound(begin, end, value);
@@ -304,13 +304,13 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccess
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qBinaryFindHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
+QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qBinaryFindHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
@@ -340,7 +340,7 @@ namespace QAlgorithmsPrivate {
#if QT_DEPRECATED_SINCE(5, 2)
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
+QT_DEPRECATED_X("Use std::sort") Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
{
top:
int span = int(end - start);
@@ -393,13 +393,13 @@ top:
}
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
+QT_DEPRECATED_X("Use std::sort") inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
{
qSortHelper(begin, end, dummy, qLess<T>());
}
template <typename RandomAccessIterator>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
+QT_DEPRECATED_X("Use std::reverse") Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
{
--end;
while (begin < end)
@@ -407,7 +407,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, Ran
}
template <typename RandomAccessIterator>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
+QT_DEPRECATED_X("Use std::rotate") Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
{
qReverse(begin, middle);
qReverse(middle, end);
@@ -415,7 +415,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, Rand
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
+QT_DEPRECATED_X("Use std::merge") Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
{
const int len1 = pivot - begin;
const int len2 = end - pivot;
@@ -450,7 +450,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, Rando
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
+QT_DEPRECATED_X("Use std::stable_sort") Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
{
const int span = end - begin;
if (span < 2)
@@ -463,13 +463,13 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator b
}
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
+QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
{
qStableSortHelper(begin, end, dummy, qLess<T>());
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator middle;
int n = int(end - begin);
@@ -490,7 +490,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(Random
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator middle;
int n = end - begin;
@@ -510,7 +510,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(Random
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator it = qLowerBoundHelper(begin, end, value, lessThan);
diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp
index 8e59000946..9a672a0505 100644
--- a/src/corelib/tools/qcollator_win.cpp
+++ b/src/corelib/tools/qcollator_win.cpp
@@ -125,9 +125,15 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con
// comparing strings, the value 2 can be subtracted from a nonzero return value. Then, the
// meaning of <0, ==0, and >0 is consistent with the C runtime.
+#ifndef Q_OS_WINRT
return CompareString(LOCALE_USER_DEFAULT, d->collator,
reinterpret_cast<const wchar_t*>(s1), len1,
reinterpret_cast<const wchar_t*>(s2), len2) - 2;
+#else // !Q_OS_WINRT
+ return CompareStringEx(LOCALE_NAME_USER_DEFAULT, d->collator,
+ reinterpret_cast<LPCWSTR>(s1), len1,
+ reinterpret_cast<LPCWSTR>(s2), len2, NULL, NULL, 0) - 2;
+#endif // Q_OS_WINRT
}
int QCollator::compare(const QString &str1, const QString &str2) const
@@ -142,13 +148,31 @@ int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
QCollatorSortKey QCollator::sortKey(const QString &string) const
{
+#ifndef Q_OS_WINRT
int size = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | d->collator,
reinterpret_cast<const wchar_t*>(string.constData()), string.size(),
0, 0);
+#elif defined(Q_OS_WINPHONE)
+ int size = 0;
+ Q_UNIMPLEMENTED();
+#else // Q_OS_WINPHONE
+ int size = LCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_SORTKEY | d->collator,
+ reinterpret_cast<LPCWSTR>(string.constData()), string.size(),
+ 0, 0, NULL, NULL, 0);
+#endif // !Q_OS_WINPHONE
QString ret(size, Qt::Uninitialized);
+#ifndef Q_OS_WINRT
int finalSize = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | d->collator,
reinterpret_cast<const wchar_t*>(string.constData()), string.size(),
reinterpret_cast<wchar_t*>(ret.data()), ret.size());
+#elif defined(Q_OS_WINPHONE)
+ int finalSize = 0;
+#else // Q_OS_WINPHONE
+ int finalSize = LCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_SORTKEY | d->collator,
+ reinterpret_cast<LPCWSTR>(string.constData()), string.size(),
+ reinterpret_cast<LPWSTR>(ret.data()), ret.size(),
+ NULL, NULL, 0);
+#endif // !Q_OS_WINPHONE
if (finalSize == 0) {
qWarning() << "there were problems when generating the ::sortKey by LCMapStringW with error:" << GetLastError();
}
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 42721c018f..a95c7f53f7 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -61,6 +61,9 @@
# ifdef Q_OS_WINCE
# include "qfunctions_wince.h"
# endif
+# ifdef Q_OS_WINRT
+# include "qfunctions_winrt.h"
+# endif
#endif
#if defined(Q_OS_MAC)
diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp
index 0730002ca3..bbc208e673 100644
--- a/src/corelib/tools/qlocale_win.cpp
+++ b/src/corelib/tools/qlocale_win.cpp
@@ -55,12 +55,32 @@
# include <time.h>
#endif
+#ifdef Q_OS_WINRT
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.foundation.collections.h>
+#ifndef Q_OS_WINPHONE
+#include <windows.globalization.h>
+#endif
+#endif // Q_OS_WINRT
+
QT_BEGIN_NAMESPACE
+#ifndef Q_OS_WINRT
static QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT);
static const char *winLangCodeToIsoName(int code);
static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT);
static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT);
+#else // !Q_OS_WINRT
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+
+static QByteArray getWinLocaleName(LPWSTR id = LOCALE_NAME_USER_DEFAULT);
+static const char *winLangCodeToIsoName(int code);
+static QString winIso639LangName(LPWSTR id = LOCALE_NAME_USER_DEFAULT);
+static QString winIso3116CtryName(LPWSTR id = LOCALE_NAME_USER_DEFAULT);
+#endif // Q_OS_WINRT
#ifndef QT_NO_SYSTEMLOCALE
@@ -121,14 +141,23 @@ private:
};
// cached values:
+#ifndef Q_OS_WINRT
LCID lcid;
+#else
+ WCHAR lcName[LOCALE_NAME_MAX_LENGTH];
+#endif
SubstitutionType substitutionType;
QChar zero;
+ int getLocaleInfo(LCTYPE type, LPWSTR data, int size);
QString getLocaleInfo(LCTYPE type, int maxlen = 0);
int getLocaleInfo_int(LCTYPE type, int maxlen = 0);
QChar getLocaleInfo_qchar(LCTYPE type);
+ int getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size);
+ int getDateFormat(DWORD flags, const SYSTEMTIME * date, LPCWSTR format, LPWSTR data, int size);
+ int getTimeFormat(DWORD flags, const SYSTEMTIME *date, LPCWSTR format, LPWSTR data, int size);
+
SubstitutionType substitution();
QString &substituteDigits(QString &string);
@@ -140,20 +169,60 @@ Q_GLOBAL_STATIC(QSystemLocalePrivate, systemLocalePrivate)
QSystemLocalePrivate::QSystemLocalePrivate()
: substitutionType(SUnknown)
{
+#ifndef Q_OS_WINRT
lcid = GetUserDefaultLCID();
+#else
+ GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH);
+#endif
+}
+
+inline int QSystemLocalePrivate::getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size)
+{
+#ifndef Q_OS_WINRT
+ return GetCurrencyFormat(lcid, flags, value, format, data, size);
+#else
+ return GetCurrencyFormatEx(lcName, flags, value, format, data, size);
+#endif
+}
+
+inline int QSystemLocalePrivate::getDateFormat(DWORD flags, const SYSTEMTIME * date, LPCWSTR format, LPWSTR data, int size)
+{
+#ifndef Q_OS_WINRT
+ return GetDateFormat(lcid, flags, date, format, data, size);
+#else
+ return GetDateFormatEx(lcName, flags, date, format, data, size, NULL);
+#endif
+}
+
+inline int QSystemLocalePrivate::getTimeFormat(DWORD flags, const SYSTEMTIME *date, LPCWSTR format, LPWSTR data, int size)
+{
+#ifndef Q_OS_WINRT
+ return GetTimeFormat(lcid, flags, date, format, data, size);
+#else
+ return GetTimeFormatEx(lcName, flags, date, format, data, size);
+#endif
+}
+
+inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int size)
+{
+#ifndef Q_OS_WINRT
+ return GetLocaleInfo(lcid, type, data, size);
+#else
+ return GetLocaleInfoEx(lcName, type, data, size);
+#endif
}
QString QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen)
{
QVarLengthArray<wchar_t, 64> buf(maxlen ? maxlen : 64);
- if (!GetLocaleInfo(lcid, type, buf.data(), buf.size()))
+ if (!getLocaleInfo(type, buf.data(), buf.size()))
return QString();
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- int cnt = GetLocaleInfo(lcid, type, 0, 0);
+ int cnt = getLocaleInfo(type, 0, 0);
if (cnt == 0)
return QString();
buf.resize(cnt);
- if (!GetLocaleInfo(lcid, type, buf.data(), buf.size()))
+ if (!getLocaleInfo(type, buf.data(), buf.size()))
return QString();
}
return QString::fromWCharArray(buf.data());
@@ -177,7 +246,7 @@ QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution()
{
if (substitutionType == SUnknown) {
wchar_t buf[8];
- if (!GetLocaleInfo(lcid, LOCALE_IDIGITSUBSTITUTION, buf, 8)) {
+ if (!getLocaleInfo(LOCALE_IDIGITSUBSTITUTION, buf, 8)) {
substitutionType = QSystemLocalePrivate::SNever;
return substitutionType;
}
@@ -189,7 +258,7 @@ QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution()
substitutionType = QSystemLocalePrivate::SAlways;
else {
wchar_t digits[11];
- if (!GetLocaleInfo(lcid, LOCALE_SNATIVEDIGITS, digits, 11)) {
+ if (!getLocaleInfo(LOCALE_SNATIVEDIGITS, digits, 11)) {
substitutionType = QSystemLocalePrivate::SNever;
return substitutionType;
}
@@ -332,7 +401,7 @@ QVariant QSystemLocalePrivate::toString(const QDate &date, QLocale::FormatType t
DWORD flags = (type == QLocale::LongFormat ? DATE_LONGDATE : DATE_SHORTDATE);
wchar_t buf[255];
- if (GetDateFormat(lcid, flags, &st, NULL, buf, 255)) {
+ if (getDateFormat(flags, &st, NULL, buf, 255)) {
QString format = QString::fromWCharArray(buf);
if (substitution() == SAlways)
substituteDigits(format);
@@ -353,7 +422,7 @@ QVariant QSystemLocalePrivate::toString(const QTime &time, QLocale::FormatType)
DWORD flags = 0;
wchar_t buf[255];
- if (GetTimeFormat(lcid, flags, &st, NULL, buf, 255)) {
+ if (getTimeFormat(flags, &st, NULL, buf, 255)) {
QString format = QString::fromWCharArray(buf);
if (substitution() == SAlways)
substituteDigits(format);
@@ -371,7 +440,7 @@ QVariant QSystemLocalePrivate::measurementSystem()
{
wchar_t output[2];
- if (GetLocaleInfo(lcid, LOCALE_IMEASURE, output, 2)) {
+ if (getLocaleInfo(LOCALE_IMEASURE, output, 2)) {
QString iMeasure = QString::fromWCharArray(output);
if (iMeasure == QLatin1String("1")) {
return QLocale::ImperialSystem;
@@ -385,7 +454,7 @@ QVariant QSystemLocalePrivate::amText()
{
wchar_t output[15]; // maximum length including terminating zero character for Win2003+
- if (GetLocaleInfo(lcid, LOCALE_S1159, output, 15)) {
+ if (getLocaleInfo(LOCALE_S1159, output, 15)) {
return QString::fromWCharArray(output);
}
@@ -396,7 +465,7 @@ QVariant QSystemLocalePrivate::pmText()
{
wchar_t output[15]; // maximum length including terminating zero character for Win2003+
- if (GetLocaleInfo(lcid, LOCALE_S2359, output, 15)) {
+ if (getLocaleInfo(LOCALE_S2359, output, 15)) {
return QString::fromWCharArray(output);
}
@@ -407,7 +476,7 @@ QVariant QSystemLocalePrivate::firstDayOfWeek()
{
wchar_t output[4]; // maximum length including terminating zero character for Win2003+
- if (GetLocaleInfo(lcid, LOCALE_IFIRSTDAYOFWEEK, output, 4))
+ if (getLocaleInfo(LOCALE_IFIRSTDAYOFWEEK, output, 4))
return QString::fromWCharArray(output).toUInt()+1;
return 1;
@@ -418,20 +487,20 @@ QVariant QSystemLocalePrivate::currencySymbol(QLocale::CurrencySymbolFormat form
wchar_t buf[13];
switch (format) {
case QLocale::CurrencySymbol:
- if (GetLocaleInfo(lcid, LOCALE_SCURRENCY, buf, 13))
+ if (getLocaleInfo(LOCALE_SCURRENCY, buf, 13))
return QString::fromWCharArray(buf);
break;
case QLocale::CurrencyIsoCode:
- if (GetLocaleInfo(lcid, LOCALE_SINTLSYMBOL, buf, 9))
+ if (getLocaleInfo(LOCALE_SINTLSYMBOL, buf, 9))
return QString::fromWCharArray(buf);
break;
case QLocale::CurrencyDisplayName: {
QVarLengthArray<wchar_t, 64> buf(64);
- if (!GetLocaleInfo(lcid, LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) {
+ if (!getLocaleInfo(LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) {
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break;
buf.resize(255); // should be large enough, right?
- if (!GetLocaleInfo(lcid, LOCALE_SNATIVECURRNAME, buf.data(), buf.size()))
+ if (!getLocaleInfo(LOCALE_SNATIVECURRNAME, buf.data(), buf.size()))
break;
}
return QString::fromWCharArray(buf.data());
@@ -478,14 +547,14 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS
CURRENCYFMT format;
CURRENCYFMT *pformat = NULL;
if (!arg.symbol.isEmpty()) {
- format.NumDigits = getLocaleInfo_int(lcid, LOCALE_ICURRDIGITS);
- format.LeadingZero = getLocaleInfo_int(lcid, LOCALE_ILZERO);
- decimalSep = getLocaleInfo(lcid, LOCALE_SMONDECIMALSEP);
+ format.NumDigits = getLocaleInfo_int(LOCALE_ICURRDIGITS);
+ format.LeadingZero = getLocaleInfo_int(LOCALE_ILZERO);
+ decimalSep = getLocaleInfo(LOCALE_SMONDECIMALSEP);
format.lpDecimalSep = (wchar_t *)decimalSep.utf16();
- thousandSep = getLocaleInfo(lcid, LOCALE_SMONTHOUSANDSEP);
+ thousandSep = getLocaleInfo(LOCALE_SMONTHOUSANDSEP);
format.lpThousandSep = (wchar_t *)thousandSep.utf16();
- format.NegativeOrder = getLocaleInfo_int(lcid, LOCALE_INEGCURR);
- format.PositiveOrder = getLocaleInfo_int(lcid, LOCALE_ICURRENCY);
+ format.NegativeOrder = getLocaleInfo_int(LOCALE_INEGCURR);
+ format.PositiveOrder = getLocaleInfo_int(LOCALE_ICURRENCY);
format.lpCurrencySymbol = (wchar_t *)arg.symbol.utf16();
// grouping is complicated and ugly:
@@ -494,7 +563,7 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS
// int(30) == "123456,789.00" == string("3;0;0")
// int(32) == "12,34,56,789.00" == string("3;2;0")
// int(320)== "1234,56,789.00" == string("3;2")
- QString groupingStr = getLocaleInfo(lcid, LOCALE_SMONGROUPING);
+ QString groupingStr = getLocaleInfo(LOCALE_SMONGROUPING);
format.Grouping = groupingStr.remove(QLatin1Char(';')).toInt();
if (format.Grouping % 10 == 0) // magic
format.Grouping /= 10;
@@ -503,13 +572,13 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS
pformat = &format;
}
- int ret = ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()),
+ int ret = getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(value.utf16()),
pformat, out.data(), out.size());
if (ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- ret = ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()),
+ ret = getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(value.utf16()),
pformat, out.data(), 0);
out.resize(ret);
- ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()),
+ getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(value.utf16()),
pformat, out.data(), out.size());
}
@@ -528,11 +597,13 @@ QVariant QSystemLocalePrivate::uiLanguages()
PWSTR pwszLanguagesBuffer,
PULONG pcchLanguagesBuffer);
static GetUserPreferredUILanguagesFunc GetUserPreferredUILanguages_ptr = 0;
+#ifndef Q_OS_WINRT
if (!GetUserPreferredUILanguages_ptr) {
QSystemLibrary lib(QLatin1String("kernel32"));
if (lib.load())
GetUserPreferredUILanguages_ptr = (GetUserPreferredUILanguagesFunc)lib.resolve("GetUserPreferredUILanguages");
}
+#endif // !Q_OS_WINRT
if (GetUserPreferredUILanguages_ptr) {
unsigned long cnt = 0;
QVarLengthArray<wchar_t, 64> buf(64);
@@ -560,8 +631,39 @@ QVariant QSystemLocalePrivate::uiLanguages()
}
}
+#ifndef Q_OS_WINRT
// old Windows before Vista
return QStringList(QString::fromLatin1(winLangCodeToIsoName(GetUserDefaultUILanguage())));
+#else // !Q_OS_WINRT
+ QStringList result;
+#ifndef Q_OS_WINPHONE
+ ComPtr<ABI::Windows::Globalization::IApplicationLanguagesStatics> appLanguagesStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Globalization_ApplicationLanguages).Get(), &appLanguagesStatics))) {
+ qWarning("Could not obtain ApplicationLanguagesStatic");
+ return QStringList();
+ }
+
+ ComPtr<ABI::Windows::Foundation::Collections::IVectorView<HSTRING> > languageList;
+ appLanguagesStatics->get_ManifestLanguages(&languageList);
+
+ if (!languageList)
+ return QStringList();
+
+ unsigned int size;
+ languageList->get_Size(&size);
+ for (unsigned int i = 0; i < size; ++i) {
+ HSTRING language;
+ languageList->GetAt(i, &language);
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(language, &length);
+ result << QString::fromWCharArray(rawString, length);
+ }
+#else // !Q_OS_WINPHONE
+ result << QString::fromWCharArray(lcName);
+#endif // Q_OS_WINPHONE
+
+ return result;
+#endif // Q_OS_WINRT
}
QVariant QSystemLocalePrivate::nativeLanguageName()
@@ -581,7 +683,11 @@ QVariant QSystemLocalePrivate::nativeCountryName()
void QSystemLocalePrivate::update()
{
+#ifndef Q_OS_WINRT
lcid = GetUserDefaultLCID();
+#else
+ GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH);
+#endif
substitutionType = SUnknown;
zero = QChar();
}
@@ -895,7 +1001,11 @@ static const char *winLangCodeToIsoName(int code)
}
+#ifndef Q_OS_WINRT
static QString winIso639LangName(LCID id)
+#else
+static QString winIso639LangName(LPWSTR id)
+#endif
{
QString result;
@@ -903,7 +1013,11 @@ static QString winIso639LangName(LCID id)
// the language code
QString lang_code;
wchar_t out[256];
- if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255)) // ### shouldn't use them according to msdn
+#ifndef Q_OS_WINRT
+ if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255))
+#else
+ if (GetLocaleInfoEx(id, LOCALE_ILANGUAGE, out, 255))
+#endif
lang_code = QString::fromWCharArray(out);
if (!lang_code.isEmpty()) {
@@ -926,27 +1040,47 @@ static QString winIso639LangName(LCID id)
return result;
// not one of the problematic languages - do the usual lookup
- if (GetLocaleInfo(id, LOCALE_SISO639LANGNAME , out, 255))
+#ifndef Q_OS_WINRT
+ if (GetLocaleInfo(id, LOCALE_SISO639LANGNAME, out, 255))
+#else
+ if (GetLocaleInfoEx(id, LOCALE_SISO639LANGNAME, out, 255))
+#endif
result = QString::fromWCharArray(out);
return result;
}
+#ifndef Q_OS_WINRT
static QString winIso3116CtryName(LCID id)
+#else
+static QString winIso3116CtryName(LPWSTR id)
+#endif
{
QString result;
wchar_t out[256];
+#ifndef Q_OS_WINRT
if (GetLocaleInfo(id, LOCALE_SISO3166CTRYNAME, out, 255))
+#else
+ if (GetLocaleInfoEx(id, LOCALE_SISO3166CTRYNAME, out, 255))
+#endif
result = QString::fromWCharArray(out);
return result;
}
+#ifndef Q_OS_WINRT
static QByteArray getWinLocaleName(LCID id)
+#else
+static QByteArray getWinLocaleName(LPWSTR id)
+#endif
{
QByteArray result;
+#ifndef Q_OS_WINRT
if (id == LOCALE_USER_DEFAULT) {
+#else
+ if (QString::fromWCharArray(id) == QString::fromWCharArray(LOCALE_NAME_USER_DEFAULT)) {
+#endif
static QByteArray langEnvVar = qgetenv("LANG");
result = langEnvVar;
QString lang, script, cntry;
@@ -964,9 +1098,17 @@ static QByteArray getWinLocaleName(LCID id)
#if defined(Q_OS_WINCE)
result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID());
-#else
+#else // !Q_OS_WINCE
+# ifndef Q_OS_WINRT
if (id == LOCALE_USER_DEFAULT)
id = GetUserDefaultLCID();
+# else // !Q_OS_WINRT
+ WCHAR lcName[LOCALE_NAME_MAX_LENGTH];
+ if (QString::fromWCharArray(id) == QString::fromWCharArray(LOCALE_NAME_USER_DEFAULT)) {
+ GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH);
+ id = lcName;
+ }
+# endif // Q_OS_WINRT
QString resultuage = winIso639LangName(id);
QString country = winIso3116CtryName(id);
result = resultuage.toLatin1();
@@ -974,14 +1116,20 @@ static QByteArray getWinLocaleName(LCID id)
result += '_';
result += country.toLatin1();
}
-#endif
+#endif // !Q_OS_WINCE
return result;
}
Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id)
{
+#ifndef Q_OS_WINRT
return QLocale(QString::fromLatin1(getWinLocaleName(id)));
+#else // !Q_OS_WINRT
+ WCHAR name[LOCALE_NAME_MAX_LENGTH];
+ LCIDToLocaleName(id, name, LOCALE_NAME_MAX_LENGTH, 0);
+ return QLocale(QString::fromLatin1(getWinLocaleName(name)));
+#endif // Q_OS_WINRT
}
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 3976f2cb6f..77d002e4d5 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -3158,6 +3158,15 @@ int QString::count(const QStringRef &str, Qt::CaseSensitivity cs) const
\sa indexOf(), count()
*/
+/*! \fn bool QString::contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \since 5.3
+
+ \overload contains()
+
+ Returns \c true if this string contains an occurrence of the latin-1 string
+ \a str; otherwise returns \c false.
+*/
+
/*! \fn bool QString::contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\overload contains()
@@ -5109,7 +5118,11 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
return ucstrcmp(data1, length1, data2, length2);
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+#ifndef Q_OS_WINRT
int res = CompareString(GetUserDefaultLCID(), 0, (wchar_t*)data1, length1, (wchar_t*)data2, length2);
+#else
+ int res = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, (LPCWSTR)data1, length1, (LPCWSTR)data2, length2, NULL, NULL, 0);
+#endif
switch (res) {
case CSTR_LESS_THAN:
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 3140af084b..798ff2f3e0 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -332,6 +332,7 @@ public:
inline bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline bool contains(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@@ -985,6 +986,8 @@ inline bool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
inline bool QString::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
+inline bool QString::contains(QLatin1String s, Qt::CaseSensitivity cs) const
+{ return indexOf(s, 0, cs) != -1; }
inline bool QString::contains(QChar c, Qt::CaseSensitivity cs) const
{ return indexOf(c, 0, cs) != -1; }
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index 5fec06b30a..24c20b46c7 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -65,7 +65,8 @@ static QTimeZonePrivate *newBackendTimeZone()
return new QMacTimeZonePrivate();
#elif defined Q_OS_UNIX
return new QTzTimeZonePrivate();
-#elif defined Q_OS_WIN
+ // Registry based timezone backend not available on WinRT
+#elif defined Q_OS_WIN && !defined Q_OS_WINRT
return new QWinTimeZonePrivate();
#elif defined QT_USE_ICU
return new QIcuTimeZonePrivate();
@@ -89,7 +90,8 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &olsenId)
return new QMacTimeZonePrivate(olsenId);
#elif defined Q_OS_UNIX
return new QTzTimeZonePrivate(olsenId);
-#elif defined Q_OS_WIN
+ // Registry based timezone backend not available on WinRT
+#elif defined Q_OS_WIN && !defined Q_OS_WINRT
return new QWinTimeZonePrivate(olsenId);
#elif defined QT_USE_ICU
return new QIcuTimeZonePrivate(olsenId);
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index e4a7b02aee..5de2364fe2 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -125,8 +125,11 @@ else:blackberry {
HEADERS += tools/qlocale_blackberry.h
}
else:unix:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_tz.cpp
-else:win32:SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp tools/qtimezoneprivate_win.cpp
-else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp
+else:win32 {
+ SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp
+ !winrt: SOURCES += tools/qtimezoneprivate_win.cpp
+ winphone: LIBS_PRIVATE += -lWindowsPhoneGlobalizationUtil
+} else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp
else:SOURCES += tools/qelapsedtimer_generic.cpp
contains(QT_CONFIG, zlib) {