Merge remote-tracking branch 'origin/release' into stable
Change-Id: I83ff8f4d7dffd7385013a1bd8a1732a89ee20d56
This commit is contained in:
commit
3061dc4abd
6
config.tests/.qmake.conf
Normal file
6
config.tests/.qmake.conf
Normal file
@ -0,0 +1,6 @@
|
||||
mingw {
|
||||
TMPPATH = $$(INCLUDE)
|
||||
QMAKE_INCDIR_POST += $$split(TMPPATH, $$QMAKE_DIRLIST_SEP)
|
||||
TMPPATH = $$(LIB)
|
||||
QMAKE_LIBDIR_POST += $$split(TMPPATH, $$QMAKE_DIRLIST_SEP)
|
||||
}
|
50
config.tests/unix/pps/pps.cpp
Normal file
50
config.tests/unix/pps/pps.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the config.tests of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/pps.h>
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
pps_decoder_t decoder;
|
||||
|
||||
pps_decoder_initialize(&decoder, NULL);
|
||||
return 0;
|
||||
}
|
3
config.tests/unix/pps/pps.pro
Normal file
3
config.tests/unix/pps/pps.pro
Normal file
@ -0,0 +1,3 @@
|
||||
SOURCES = pps.cpp
|
||||
CONFIG -= qt
|
||||
LIBS += -lpps
|
35
configure
vendored
35
configure
vendored
@ -629,6 +629,7 @@ CFG_JAVASCRIPTCORE_JIT=auto
|
||||
CFG_PKGCONFIG=auto
|
||||
CFG_STACK_PROTECTOR_STRONG=auto
|
||||
CFG_SLOG2=auto
|
||||
CFG_PPS=auto
|
||||
CFG_SYSTEM_PROXIES=no
|
||||
|
||||
# Target architecture
|
||||
@ -1769,6 +1770,13 @@ while [ "$#" -gt 0 ]; do
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
pps)
|
||||
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
||||
CFG_PPS="$VAL"
|
||||
else
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
gtkstyle)
|
||||
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
||||
CFG_QGTKSTYLE="$VAL"
|
||||
@ -1918,7 +1926,11 @@ while [ "$#" -gt 0 ]; do
|
||||
break
|
||||
fi
|
||||
done
|
||||
[ "$found" = yes ] || ERROR=yes
|
||||
if [ "$found" != "yes" ]; then
|
||||
echo "$CURRENT_OPT: unknown argument"
|
||||
ERROR=yes
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$VAR" = "sql" ]; then
|
||||
# set the CFG_SQL_driver
|
||||
@ -1942,9 +1954,6 @@ while [ "$#" -gt 0 ]; do
|
||||
QMakeVar del "${IN_VAR}s" "$VAL"
|
||||
QMakeVar del "${PLUG_VAR}s" "$VAL"
|
||||
fi
|
||||
if [ "$ERROR" = "yes" ]; then
|
||||
echo "$CURRENT_OPT: unknown argument"
|
||||
fi
|
||||
;;
|
||||
v|verbose)
|
||||
if [ "$VAL" = "yes" ]; then
|
||||
@ -2455,6 +2464,9 @@ QNX/Blackberry options:
|
||||
-no-slog2 .......... Do not compile with slog2 support.
|
||||
-slog2 ............. Compile with slog2 support.
|
||||
|
||||
-no-pps ............ Do not compile with pps support.
|
||||
-pps ............... Compile with pps support.
|
||||
|
||||
MacOS/iOS options:
|
||||
|
||||
-Fstring ........... Add an explicit framework path.
|
||||
@ -3318,7 +3330,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then
|
||||
CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples tests"
|
||||
CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store
|
||||
CFG_CXX11="no" # C++11 support disabled for now
|
||||
CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtgraphicaleffects qtlocation qtmacextras qtmultimedia qtquickcontrols qtserialport qttools qtwebkit qtwebkit-examples"
|
||||
CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtlocation qtmacextras qtserialport qttools qtwebkit qtwebkit-examples"
|
||||
|
||||
# If the user passes -sdk on the command line we build a SDK-specific Qt build.
|
||||
# Otherwise we build a joined simulator and device build, which is the default.
|
||||
@ -4344,6 +4356,15 @@ if [ "$XPLATFORM_QNX" = "yes" ]; then
|
||||
CFG_SLOG2=no
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CFG_PPS" != "no" ]; then
|
||||
if compileTest unix/pps "pps"; then
|
||||
CFG_PPS=yes
|
||||
QMAKE_CONFIG="$QMAKE_CONFIG qqnx_pps"
|
||||
else
|
||||
CFG_PPS=no
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CFG_ZLIB" = "auto" ]; then
|
||||
@ -6684,8 +6705,10 @@ if [ "$CFG_XCB" != "no" ]; then
|
||||
report_support " XVideo ............." "$CFG_XVIDEO"
|
||||
fi
|
||||
report_support " Session management ....." "$CFG_SM"
|
||||
[ "$XPLATFORM_QNX" = "yes" ] && \
|
||||
if [ "$XPLATFORM_QNX" = "yes" ]; then
|
||||
report_support " SLOG2 .................." "$CFG_SLOG2"
|
||||
report_support " PPS ...................." "$CFG_PPS"
|
||||
fi
|
||||
report_support " SQL drivers:"
|
||||
report_support " DB2 .................." "$CFG_SQL_db2" plugin "plugin" yes "built into QtSql"
|
||||
report_support " InterBase ............" "$CFG_SQL_ibase" plugin "plugin" yes "built into QtSql"
|
||||
|
572
dist/changes-5.2.0
vendored
572
dist/changes-5.2.0
vendored
@ -16,56 +16,69 @@ Each of these identifiers can be entered in the bug tracker to obtain more
|
||||
information about a particular change.
|
||||
|
||||
****************************************************************************
|
||||
* Architecture Specific Changes *
|
||||
* Important Behavior Changes *
|
||||
****************************************************************************
|
||||
|
||||
Qt is now compiled with qreal typedef'ed to double on all platforms. qreal
|
||||
was a float on ARM chipsets before. This guarantees more consistent behavior
|
||||
between all platforms Qt supports, but is binary incompatible to Qt 5.1
|
||||
on ARM. The old behavior can be restored by passing -qreal float to
|
||||
configure.
|
||||
- Qt is now compiled with qreal typedef'ed to double on all
|
||||
platforms. qreal was a float on ARM chipsets before. This guarantees more
|
||||
consistent behavior between all platforms Qt supports, but is binary
|
||||
incompatible to Qt 5.1 on ARM. The old behavior can be restored by
|
||||
passing -qreal float to configure.
|
||||
- The supported date range in QDateTime has been reduced to about +/- 292
|
||||
million years, the range supported by the number of msecs since the Unix
|
||||
epoch of 1 Jan 1970 as stored in a qint64, and as able to be used in the
|
||||
setMSecsSinceEpoch() and toMSecsSinceEpoch() methods.
|
||||
|
||||
- QUrl and QUrlQuery:
|
||||
* [QTBUG-31660] QUrl no longer considers all delimiter characters
|
||||
equivalent to their percent-encoded forms. Now, both classes always
|
||||
keep all delimiters exactly as they were in the original URL text.
|
||||
* [QTBUG-31660] QUrl no longer decodes %7B and %7D to "{" and "}" in the
|
||||
output of toString()
|
||||
* QUrl no longer supports QUrl::FullyDecoded mode in authority() and
|
||||
userInfo(), nor QUrl::DecodedMode in setAuthority() and setUserInfo().
|
||||
* [QTBUG-31945] QUrl no longer decodes %23 found in the fragment to "#"
|
||||
in the output of toString(QUrl::FullyEncoded) or toEncoded()
|
||||
* QUrl now defaults to decoded mode in the getters and setters for
|
||||
userName, password, host, topLevelDomain, path and fileName. This
|
||||
means a '%' in one of those fields is now returned (or set) as '%'
|
||||
rather than "%25". In the unlikely case where the former behavior was
|
||||
expected, pass PrettyDecoded to the getter and TolerantMode to the
|
||||
setter.
|
||||
* QUrl now normalizes the path given in setPath, removing ./ and ../ and
|
||||
duplicate slashes.
|
||||
|
||||
****************************************************************************
|
||||
* Library *
|
||||
****************************************************************************
|
||||
|
||||
|
||||
QtWidgets
|
||||
---------
|
||||
|
||||
- QAbstractScrollArea now has a SizeAdjustPolicy. If it is set to AdjustToContents
|
||||
it will make use of the protected viewportSizeHint() virtual function. This
|
||||
function returns a suggested size based on contents. Note that although the
|
||||
viewportSizeHint() virtual function was reserved in 5.0, user code was not
|
||||
supposed to be overriding it (as the function was private and undocumented).
|
||||
Code that was overriding viewportSizeHint() needs to be recompiled against 5.2
|
||||
for this feature to work correctly.
|
||||
|
||||
- QTreeView now has setTreePosition to allow the treestructure to show data from other
|
||||
columns than logicalindex zero.
|
||||
|
||||
- [QTBUG-4206] QTableView resizeToContents will now adjust to actual contents
|
||||
and not just visible area. QHeaderView::setAutoResizePrecision() has been
|
||||
introduced to control how precise the autoResize should be.
|
||||
|
||||
- QFileDialog::setDefaultSuffix() removes leading dot characters.
|
||||
|
||||
- [QTBUG-34132] QFileDialog does not instantiate widgets if a native dialog
|
||||
will be used instead. Therefore some accessors which previously returned
|
||||
unused objects will now return null. As before, you can set the
|
||||
DontUseNativeDialog option to ensure that widgets will be created and used instead.
|
||||
|
||||
- QSizePolicy got a retainSizeWhenHidden attribute.
|
||||
|
||||
- [QTBUG-31602] QSpinBox size calculation will now be fixed when stylesheets are
|
||||
used.
|
||||
|
||||
QtCore
|
||||
------
|
||||
- [QTBUG-30250] QTime, QDateTime:
|
||||
When calling QTime::toString(Qt::TextDate) and QTime::toString(Qt::ISODate),
|
||||
milliseconds are now included in the returned string. This also applies to
|
||||
QDateTime::toString(Qt::TextDate) and QDateTime::toString(ISODate).
|
||||
|
||||
- Added QCollator, a class to collate Unicode strings.
|
||||
- Added QCommandLineParser, a class to parse command lines.
|
||||
- Added QFileSelector, a class to select platform-specific file assets.
|
||||
- Added QLoggingCategory and related functions for logging
|
||||
- [QTBUG-23946] Fixed a bug that prevented Qt from being built in a
|
||||
namespace on Mac OS X.
|
||||
- Updated the locale database to CLDR 23.1
|
||||
- Added support for ARMv8 64-bit mode.
|
||||
|
||||
- Metatype system (QMetaType & QVariant):
|
||||
* Qt now handles metatypes automatically for std::vector, std::list,
|
||||
std::pair and std::map
|
||||
* The metatype system now supports registering explicit conversion
|
||||
functions via QMetaType::registerConverter
|
||||
* The metatype system now supports iteration over a container type via
|
||||
QSequentialIterable and QAssociativeIterable
|
||||
* Registering the same type name twice will now print only a warning (as
|
||||
opposed to aborting the execution of the program)
|
||||
|
||||
- Qt Containers:
|
||||
* In debug mode, the Qt containers will now verify whether the iterators
|
||||
passed to most mutating functions belong to the iterator in question.
|
||||
* Fixed a number of bugs that would modify shared containers when calling
|
||||
erase(), under corner-case conditions.
|
||||
|
||||
- QtAlgorithms
|
||||
With STL no longer being optional for building and using Qt, a number of parts
|
||||
@ -96,85 +109,458 @@ QtCore
|
||||
- qLess (std::less)
|
||||
- qGreater (std::greater)
|
||||
|
||||
- QByteArray:
|
||||
* Added QByteArray::Base64Url and QByteArray::OmitTrailingEquals flags
|
||||
for QByteArray::toBase64 and fromBase64.
|
||||
* [QTBUG-34694] Fixed a bug that would cause QByteArray to overflow some
|
||||
size calculations.
|
||||
|
||||
- QCoreApplication:
|
||||
* [QTBUG-15379][QTBUG-30628] Fixed a bug that caused Qt to mis-parse a
|
||||
command-line argument like -DKEY=\"VALUE\" on Windows.
|
||||
|
||||
- QDateTime:
|
||||
* [QTBUG-26161][QTBUG-29666] Fully implement support for Qt::TimeSpec of
|
||||
Qt::OffsetFromUTC, added new methods for offsetFromUTC(),
|
||||
toTimeSpec(), and toOffsetFromUTC().
|
||||
* Added convenience methods for fromMSecsSinceEpoch() and fromTime_t()
|
||||
to take time spec to be used in returned datetime.
|
||||
* Add method timeZoneAbbreviation() to return effective time zone
|
||||
abbreviation.
|
||||
* The debug datastream is now an ISO-like format instead of Qt::TextDate
|
||||
* The Standard Time to Daylight Time transition for Qt::LocalTime is now
|
||||
handled correctly. Any date set in the "missing" hour is now
|
||||
considered invalid. All date math results that fall into the missing
|
||||
hour will be automatically adjusted to a valid time in the following
|
||||
hour.
|
||||
* Added new method isDaylightTime() to return if the datetime is in
|
||||
Daylight Time or not.
|
||||
* Added support for a new Qt::TimeZone spec to be used with QTimeZone to
|
||||
define times in a specific time zone.
|
||||
* Added Qt::RFC2822Date format that can be passed to QDateTime and
|
||||
QLocale formatters and parsers.
|
||||
* Fixed a bug that caused QDate::toString() to return empty for dates
|
||||
with years beyond 9999.
|
||||
|
||||
- QFileSystemWatcher:
|
||||
* [QTBUG-33211] Fixed a bug that caused QFileSystemWatcher to emit change
|
||||
notifications with the wrong path on Linux.
|
||||
|
||||
- QJson:
|
||||
* [QTBUG-33229] The Writer and the Parser now fully accept non-character
|
||||
unicode points.
|
||||
* The Writer will no longer write inf, -inf and nan for infinites and NaN
|
||||
values, which resulted in parsing back as strings. Instead, it will now
|
||||
output null.
|
||||
* The Writer now emits numeric values with full numeric precision. This
|
||||
also allows QJson to support integer values with no loss of precision
|
||||
up to 2^53.
|
||||
|
||||
- QJsonValue:
|
||||
* Added QJsonValue::toInt(). QJsonValue can store 32-bit signed integers
|
||||
with no loss of precision.
|
||||
|
||||
- QObject:
|
||||
* New-style signal connections to functors, lambdas, and static functions
|
||||
now works with a receiver object. The connection will be removed when
|
||||
the either the sender or receiver objects are destroyed.
|
||||
|
||||
- QPluginLoader:
|
||||
* QPluginLoader will no longer load the plugins on Mac OS X and iOS
|
||||
systems when scanning for valid plugins.
|
||||
* Added QPluginLoader::staticPlugins(), which returns the list of
|
||||
built-in plugins (linked to the executable and any loaded libraries).
|
||||
|
||||
- QProcess:
|
||||
* [QTBUG-32958] Fixed a bug that would cause QProcess to crash if
|
||||
waitForStarted() were called after an unsuccessful start()
|
||||
* Added QProcess::nullDevice(), which returns the platform's "blackhole"
|
||||
device (/dev/null on Unix, NUL on Windows). This can be used with
|
||||
QProcess::setStandardOutputFile.
|
||||
* Added enum values QProcess::ForwardedOutputChannel and
|
||||
QProcess::ForwardedErrorChannel, which allow for more fine-grained
|
||||
control over which channel is forwarded and which one is captured.
|
||||
* Added QProcess::ForwardedInputChannel, which allows for stdin to be
|
||||
forwarded to this process's input.
|
||||
* [QTBUG-32979] On Unix, QProcess now correctly forwards the siginfo_t
|
||||
and context parameters of the signal handler to the previous handler.
|
||||
|
||||
- QScopedPointer:
|
||||
* Added QScopedPointerDeleteLater, a new class that can be used as the
|
||||
second template to QScopedPointer and will call deleteLater() on the
|
||||
pointer when it goes out of scope.
|
||||
|
||||
- QSocketNotifier:
|
||||
* Fixed a bug that caused socket notifiers not to be re-enabled after
|
||||
they had been activated on BlackBerry.
|
||||
|
||||
- QStandardPaths:
|
||||
* QStandardPaths::enableTestMode is deprecated and is replaced by
|
||||
QStandardPaths::setTestModeEnabled.
|
||||
* Added QStandardPaths::GenericConfigLocation, which refers to a location
|
||||
where applications can store config files to be shared with other
|
||||
applications.
|
||||
|
||||
- QThread:
|
||||
* Added an advisory interrupt mechanism (QThread::requestInterruption and
|
||||
QThread::isInterruptionRequested).
|
||||
|
||||
- QThreadPool:
|
||||
* Added method clear() to remove any queued QRunnables.
|
||||
* Fixed a number of race conditions.
|
||||
|
||||
- QTime:
|
||||
* [QTBUG-30250] When calling QTime::toString(Qt::TextDate) and
|
||||
QTime::toString(Qt::ISODate), milliseconds are now included in
|
||||
the returned string. This also applies to
|
||||
QDateTime::toString(Qt::TextDate) and
|
||||
QDateTime::toString(ISODate).
|
||||
* Added new methods fromMSecsSinceStartOfDay() to create a new QTime
|
||||
from an msecs value, and msecsSinceStartOfDay() to return the QTime as
|
||||
the number of msecs since the start of the day.
|
||||
|
||||
- QTimeZone:
|
||||
* Added new QTimeZone class to support time tone calculations using the
|
||||
host platform time zone database and the Olsen time zone ID's.
|
||||
|
||||
- QUrl:
|
||||
* [QTBUG-33229] QUrl now fully accepts non-character unicode points;
|
||||
they are encoded as percent characters; they can also be pretty
|
||||
decoded
|
||||
* Added QUrl::RemoveFilename flag which can be passed to path(),
|
||||
authority() and toString() and will cause the filename part of the path
|
||||
(the contents after the last '/') to be removed.
|
||||
* Added QUrl::fileName(), which returns just the filename part of the
|
||||
path.
|
||||
* Added QUrl::NormalizePathSegments flag, which will cause QUrl to
|
||||
remove "/./" or "/../" sequences as much as possible. It will not
|
||||
remove "/../" from the beginning of the path.
|
||||
* Added QUrl::adjusted(), which returns a new QUrl with certain parts of
|
||||
the original URL removed or normalized.
|
||||
* Added QUrl::matches(), which can be used to compare parts of two URLs
|
||||
or to compare two URLs after normalization.
|
||||
|
||||
- QUtf8:
|
||||
* [QTBUG-33229] UTF-8 now accepts non-character unicode points; these
|
||||
are not replaced by the replacement character anymore
|
||||
|
||||
- QVariant:
|
||||
* Fixed QVariant::canConvert with longlong
|
||||
* Variant containing enum types can now be converted to integer
|
||||
* [QTBUG-33981] Fixed a bug that would cause QPolygonF to be saved or
|
||||
loaded incorrectly in QDataStream.
|
||||
|
||||
QtDBus
|
||||
------
|
||||
|
||||
- Improved error handling so as to give more feedback to the developer when
|
||||
certain marshalling or demarshalling actions fail.
|
||||
- [QTBUG-27809] Fixed some race conditions related to delivering method
|
||||
reply deliveries.
|
||||
- Fixed a bug that made non-slot invokables not get listed in the
|
||||
auto-generated introspections.
|
||||
|
||||
QtDeclarative
|
||||
-------------
|
||||
|
||||
- ColorDialog:
|
||||
* Added currentColor property.
|
||||
|
||||
- [QTBUG-32928] ShortcutOverride events now work for QQuickItem
|
||||
subclasses
|
||||
|
||||
QtGui
|
||||
-----
|
||||
- [QTBUG-28228] Session Management:
|
||||
The new QPlatformSessionManager class brings back the session management
|
||||
functionality. It allows the implementation of platform specific behavior
|
||||
related to session management. For platform that don't support this
|
||||
feature the default behavior has not changed.
|
||||
Both X11 and Windows session management are supported.
|
||||
|
||||
- Accessibility classes are now public allowing accessibility
|
||||
information for custom widgets/QQuickItems
|
||||
|
||||
- Session Management:
|
||||
* [QTBUG-28228] The new QPlatformSessionManager class brings back
|
||||
the session management functionality. It allows the
|
||||
implementation of platform specific behavior related to session
|
||||
management. For platform that don't support this feature the
|
||||
default behavior has not changed. Both X11 and Windows session
|
||||
management are supported.
|
||||
|
||||
- QPolygonF:
|
||||
* When a QVariant holds a QPolygonF() then it will be correctly seen as
|
||||
a null QVariant.
|
||||
|
||||
- [QTBUG-27349] Reintroduced command line argument for positioning
|
||||
windows (-geometry on X11, -qwindowgeometry on other platforms)
|
||||
|
||||
QtNetwork
|
||||
---------
|
||||
|
||||
- API was added to store and resume TLS session tickets.
|
||||
- API was added to store and resume TLS session tickets.
|
||||
- The minimum support openssl version has been increased to openssl
|
||||
1.0. The code to support older versions has not been removed, but is no
|
||||
longer supported.
|
||||
- An off-by-one error in NTLM proxy authentication has been fixed.
|
||||
- Various improvements to reduce the memory used by qtnetwork have been
|
||||
made.
|
||||
- Improved support for HTTP proxy authentication.
|
||||
- Support for preconnecting to servers before making HTTP and HTTPS
|
||||
connections. This allows for much reduced latency when the hosts to be
|
||||
connected to are known.
|
||||
|
||||
- The minimum support openssl version has been increased to openssl 1.0. The
|
||||
code to support older versions has not been removed, but is no longer
|
||||
supported.
|
||||
QtPrintSupport
|
||||
--------------
|
||||
|
||||
- An off-by-one error in NTLM proxy authentication has been fixed.
|
||||
|
||||
- Various improvements to reduce the memory used by qtnetwork have been made.
|
||||
|
||||
- Improved support for HTTP proxy authentication.
|
||||
|
||||
- Support for preconnecting to servers before making HTTP and HTTPS
|
||||
connections. This allows for much reduced latency when the hosts to be
|
||||
connected to are known.
|
||||
- QPrintDialog:
|
||||
* Added support for setting CUPS job options in the print dialog.
|
||||
* Added support for setting CUPS Banner pages in the print dialog.
|
||||
* Added support for setting CUPS Page Set (even/odd pages only) in the
|
||||
print dialog.
|
||||
* Added support for setting CUPS Pages Per Sheet and Pages Per Sheet
|
||||
Layout options
|
||||
* Added CUPS server-side print range support for apps that can't support
|
||||
print range option themselves
|
||||
|
||||
QtSql
|
||||
-----
|
||||
|
||||
Changes in Qt 5.1.0 (missing from released changelog dist/changes-5.1.0)
|
||||
- [QTBUG-28088] Remove dependency of DB driver headers on qsqlcachedresult_p.h.
|
||||
- Deprecate QSqlError setters.
|
||||
The constructor is sufficient, since it has a parameter for each member variable.
|
||||
- Rename the SQL driver header files to _p.h (make private)
|
||||
The drivers were never public API. They were exposed by mistake in
|
||||
public headers. What's more, they have #include'd a private header
|
||||
(qsqlcachedresult_p.h) since at least Qt 4.5.1. That means no one used
|
||||
those headers in Qt 4 (private headers weren't installed then) and
|
||||
it's unlikely anyone did in 5.0.
|
||||
- ODBC: Implemented lastInsertId() for some ODBC compatible databases.
|
||||
- PSQL: Make lastInsertID work for tables without OIDs.
|
||||
- [QTBUG-14904] SQLITE: Fix for Sql query aliases with dots
|
||||
- [QTBUG-2192] ODBC: fix loss of milliseconds when binding QDateTime
|
||||
- [QTBUG-30076] PSQL: escape backslashes only when server requires it
|
||||
IMPORTANT: Applications that implemented their own workarounds must be
|
||||
updated to avoid misbehavior and SQL injection vulnerabilities.
|
||||
- [QTBUG-10569] ODBC: fixed QODBCResult::exec() return value for DELETE
|
||||
operations when no rows are affected.
|
||||
- ODBC: Fixed loss of column metadata on SQL_NO_DATA.
|
||||
- QSqlTableModel: expose methods for getting primary values.
|
||||
- ODBC: Fixed possible cause of spurious errors (commit af35ee291a1bbbc8)
|
||||
- [QTBUG-28088] Remove dependency of DB driver headers on qsqlcachedresult_p.h.
|
||||
- Deprecate QSqlError setters. The constructor is sufficient, since it has
|
||||
a parameter for each member variable.
|
||||
- Rename the SQL driver header files to _p.h (make private)
|
||||
The drivers were never public API. They were exposed by mistake in
|
||||
public headers. What's more, they have #include'd a private header
|
||||
(qsqlcachedresult_p.h) since at least Qt 4.5.1. That means no one used
|
||||
those headers in Qt 4 (private headers weren't installed then) and
|
||||
it's unlikely anyone did in 5.0.
|
||||
- ODBC: Implemented lastInsertId() for some ODBC compatible databases.
|
||||
- PSQL: Make lastInsertID work for tables without OIDs.
|
||||
- [QTBUG-14904] SQLITE: Fix for Sql query aliases with dots
|
||||
- [QTBUG-2192] ODBC: fix loss of milliseconds when binding QDateTime
|
||||
- [QTBUG-30076] PSQL: escape backslashes only when server requires it
|
||||
IMPORTANT: Applications that implemented their own workarounds must be
|
||||
updated to avoid misbehavior and SQL injection vulnerabilities.
|
||||
- [QTBUG-10569] ODBC: fixed QODBCResult::exec() return value for DELETE
|
||||
operations when no rows are affected.
|
||||
- ODBC: Fixed loss of column metadata on SQL_NO_DATA.
|
||||
- QSqlTableModel: expose methods for getting primary values.
|
||||
- ODBC: Fixed possible cause of spurious errors (commit af35ee291a1bbbc8)
|
||||
|
||||
Changes in Qt 5.2.0
|
||||
- [QTBUG-29261] IBASE: Construct a valid QTime when creating timestamps for iBase SQL driver.
|
||||
- [QTBUG-33389] PSQL: Format QDateTime following ISO8601.
|
||||
- Add QSQLITE_OPEN_URI option to QSQLITE driver
|
||||
- [QTBUG-29261] IBASE: Construct a valid QTime when creating timestamps for
|
||||
iBase SQL driver.
|
||||
- [QTBUG-33389] PSQL: Format QDateTime following ISO8601.
|
||||
- Add QSQLITE_OPEN_URI option to QSQLITE driver
|
||||
|
||||
QtWidgets
|
||||
---------
|
||||
|
||||
- [QTBUG-30255] Fixed a bug where spans across empty cells in a grid
|
||||
layout got broken.
|
||||
- [QTBUG-32788] Properly handles Qt::WidgetWithChildrenShortcut
|
||||
shortcuts in MDI subwindows now.
|
||||
- [QTBUG-33078] QWidget::setWindowOpacity() now works when called
|
||||
before QWidget::show().
|
||||
- [QTBUG-33247] Changed accessible trees and tables to always expose
|
||||
hidden headers, instead of only exposing the visible headers.
|
||||
- [QTBUG-34007] Fixed a crash in tablet support.
|
||||
- Fixed a bug where the maximum size hint of a layout with spans was
|
||||
wrong.
|
||||
- Item delegates now cycle through all three states of tri-state
|
||||
checkboxes, the same way QCheckBox itself does.
|
||||
|
||||
- QAbstractItemView:
|
||||
* [QTBUG-7232] In ItemViews scrollbars will now by default only
|
||||
scroll 1 pixel when scrollMode is set to scrollPerPixel. That is
|
||||
it will (when scrollMode is scrollPerPixel) do what is stated in
|
||||
the documentation, and no longer automatically adjust the
|
||||
scrollbar's singleStep. The user can now control that value.
|
||||
|
||||
- QAbstractScrollArea:
|
||||
* QAbstractScrollArea now has a SizeAdjustPolicy. If it is set to
|
||||
AdjustToContents it will make use of the protected viewportSizeHint()
|
||||
virtual function. This function returns a suggested size based on
|
||||
contents. Note that although the viewportSizeHint() virtual function
|
||||
was reserved in 5.0, user code was not supposed to be overriding it
|
||||
(as the function was private and undocumented). Code that was
|
||||
overriding viewportSizeHint() needs to be recompiled against 5.2 for
|
||||
this feature to work correctly.
|
||||
|
||||
- QColorDialog:
|
||||
* Added a web color QLineEdit.
|
||||
* [QTBUG-14332] Added a screen color picker button.
|
||||
* [QTBUG-31998] Does no longer create widgets when using the
|
||||
platform dialog.
|
||||
|
||||
- QComboBox:
|
||||
* Added currentData() convenience function which allows to retrieve
|
||||
the user data set for the current item.
|
||||
|
||||
- QCompleter:
|
||||
* [QTBUG-3414] Added filterMode property.
|
||||
|
||||
- QDesktopWidget:
|
||||
* [QTBUG-32567] Fixed emission of workAreaResized() signal.
|
||||
|
||||
- QDialogButtonBox:
|
||||
* Added a (StandardButtons,QWidget*) constructor.
|
||||
|
||||
- QDockWidget:
|
||||
* [QTBUG-31044] The position of a dock widget is now kept when
|
||||
undocking.
|
||||
* [QTBUG-32260] Fixed a bug where visibilityChanged was signaled
|
||||
wrongly in certain multi-screen setups.
|
||||
|
||||
- QFileDialog:
|
||||
* setDefaultSuffix() now removes leading dot characters.
|
||||
* Introduced DontUseCustomDirectoryIcons. This improves the file
|
||||
dialog performance under Windows for the case where there are
|
||||
lots of folders. Went from taking 60 seconds to 2 seconds, on a
|
||||
SDCard with 10k folders.
|
||||
* Added setMimeTypeFilters() for mimetype-based filtering, as an
|
||||
alternative to pattern matching.
|
||||
* Fixed removing of directories containing hidden or system files.
|
||||
* Added QUrl-based API for remote files.
|
||||
* [QTBUG-13182] Improved performance on Windows by
|
||||
+ not resolving NTFS symlinks (15x speedup on pessimistic
|
||||
workloads) and
|
||||
+ using extensions over calling GetFileAttributesEx() in certain
|
||||
cases.
|
||||
* [QTBUG-29403] Fixed potential crash in destructor of
|
||||
~QFileInfoGather in threaded applications.
|
||||
* [QTBUG-34132] QFileDialog does no longer instantiate widgets if a
|
||||
native dialog will be used instead. Therefore some accessors
|
||||
which previously returned unused objects will now return null.
|
||||
As before, you can set the DontUseNativeDialog option to ensure
|
||||
that widgets will be created and used instead.
|
||||
* [QTBUG-33039] Does no longer create widgets when using the
|
||||
platform dialog.
|
||||
|
||||
- QFontDialog:
|
||||
* Now has finer-grained control over the types of fonts listed,
|
||||
similar to what QFontComboBox already had.
|
||||
|
||||
- QGraphicsView etc
|
||||
* Fixed a crash in QGraphicsProxyWidget.
|
||||
* [QTBUG-8061] Allow handling of mouseDoubleClickEvent in
|
||||
QGraphicsItems.
|
||||
* [QTBUG-19036] Make QGraphicsScene::items(QPointF) work using
|
||||
Qt::{Contains,Intersets}ItemBoundingRect with items that contain
|
||||
the point in the bounding rectangle, but not their (custom)
|
||||
shape.
|
||||
|
||||
- QHeaderView:
|
||||
* [QTBUG-4346] A maximumSize for sections has been introduced. The
|
||||
maximum section size is by default the largest possible section
|
||||
size which in Qt 5.2 has been limited to 1048575 pixels.
|
||||
|
||||
- QInputDialog:
|
||||
* Added getMultiLineText static method.
|
||||
|
||||
- QLineEdit:
|
||||
* Keep placeholderText visible when focused, until text is added.
|
||||
* Context-menu actions now have icons.
|
||||
* Made it possible to add side widgets.
|
||||
* Made it possible to add a clear button commonly used for item
|
||||
view filtering as a side widget
|
||||
|
||||
- QListView:
|
||||
* [QTBUG-1180] Dragging an item outside the QListView in icon mode
|
||||
no longer loses the icon. Also fixed a bug where under certain
|
||||
conditions code overriding QAbstractItemView::viewOptions() would
|
||||
not be called.
|
||||
|
||||
- QMenuBar:
|
||||
* [QTBUG-32807] Menus now close again on second click.
|
||||
|
||||
- QMessageBox:
|
||||
* May use native message boxes on some platforms now.
|
||||
* [QTBUG-6731] It is now possible to select some or all text from a
|
||||
QMessageBox and copy it to the clipboard.
|
||||
|
||||
- QSizePolicy:
|
||||
* Added a retainSizeWhenHidden attribute.
|
||||
|
||||
- QSpinBox:
|
||||
* Values can now be displayed in different bases
|
||||
(cf. displayIntegerBase property)
|
||||
* [QTBUG-31602] Size calculation will now be fixed when stylesheets
|
||||
are used.
|
||||
|
||||
- QSplitter:
|
||||
* Now gets the default value of opaqueResize property from (new)
|
||||
QStyle::SH_Splitter_OpaqueResize styleHint.
|
||||
|
||||
- QSystemTrayIcon:
|
||||
* [QTBUG-31762] Fixed position of system tray icon on Linux/X11
|
||||
(except Unity).
|
||||
* [QTBUG-33461] Increased the maximum length of a system tray
|
||||
tooltip on Windows to what it was in Qt 4.
|
||||
|
||||
- QTableView:
|
||||
* [QTBUG-4206] resizeToContents will now adjust to actual contents
|
||||
and not just visible area. QHeaderView::setAutoResizePrecision()
|
||||
has been introduced to control how precise the autoResize should
|
||||
be.
|
||||
|
||||
- QTextEdit:
|
||||
* Added placeholderText akin to QLineEdit.
|
||||
* Context-menu actions now have icons.
|
||||
|
||||
- QTreeView:
|
||||
* QTreeView now has setTreePosition to allow the treestructure to
|
||||
show data from other columns than logicalindex zero.
|
||||
|
||||
- QWindowContainer:
|
||||
* [QTBUG-32177] Sets active window correctly now.
|
||||
|
||||
- QWizard:
|
||||
* [QTBUG-29924] Gave all buttons an objectName().
|
||||
|
||||
****************************************************************************
|
||||
* Platform Specific Changes *
|
||||
****************************************************************************
|
||||
|
||||
|
||||
Qt for Windows
|
||||
--------------
|
||||
- QCoreApplication::arguments() changed the handling of single quotes, double quotes
|
||||
and the backslash character, in order to match what argv[] contains.
|
||||
In particular, single quotes are no longer removed from the argument string.
|
||||
(QTBUG-15379, QTBUG-30628)
|
||||
Android
|
||||
-------
|
||||
|
||||
Qt for Android
|
||||
--------------
|
||||
- Project structure and deployment has changed with the introduction of
|
||||
androiddeployqt. Source and build files are no longer mixed, and the
|
||||
build files for the APK package should not be touched. Customizing
|
||||
the build files is possible. Read the documentation for androiddeployqt
|
||||
for more information.
|
||||
|
||||
- Status bar visibility is now controlled by Qt, so the window state will
|
||||
override settings in the AndroidManifest.xml. The default is still to
|
||||
show the status bar (QWindow::showMaximized()). Use
|
||||
QWindow::showFullScreen() to hide it.
|
||||
- Implemented support for accessibility on Android.
|
||||
|
||||
OS X
|
||||
----
|
||||
|
||||
- Qt for OS X is now identified by the macro Q_OS_OSX. This complements the
|
||||
existing Q_OS_DARWIN macro (which identifies the open source kernel and
|
||||
could identify non-Apple products) and Q_OS_MAC, which is defined for
|
||||
both OS X and iOS. The old macro Q_OS_MACX is now deprecated.
|
||||
- Qt no longer complains about new versions of OS X that haven't been
|
||||
released yet. This will allow Qt 5.2 and future versions to build on
|
||||
future versions yet to be released. Note that those versions are not
|
||||
supported until official announcement by the Qt Project.
|
||||
- Added a number of functions to QtCore to convert to and from
|
||||
CFString/NSString and QString, CFURL/NSURL and QUrl.
|
||||
|
||||
Windows
|
||||
-------
|
||||
|
||||
- [QTBUG-33409][QTBUG-8764][QTBUG-10032] Fixed virtual key mapping on
|
||||
Windows.
|
||||
- QCoreApplication::arguments() changed the handling of single quotes, double quotes
|
||||
and the backslash character, in order to match what argv[] contains.
|
||||
In particular, single quotes are no longer removed from the argument string.
|
||||
(QTBUG-15379, QTBUG-30628)
|
||||
|
||||
X11
|
||||
---
|
||||
|
||||
- [QTBUG-31762] Fix position of system tray icon (except Unity)
|
||||
- [QTBUG-27349] Reintroduced command line argument for positioning
|
||||
windows (-geometry)
|
||||
|
@ -125,8 +125,11 @@ manifestmeta.android.names = "QtQuick/Qt Quick Demo - Maroon*" \
|
||||
"QtLinguist/Arrow Pad Example" \
|
||||
"QtGui/Raster Window Example" \
|
||||
"QtGui/Analog Clock Window Example" \
|
||||
"QtMultimediaWidgets/Video Widget Example" \
|
||||
"QtMultimediaWidgets/Media Player Example" \
|
||||
"QtAndroidExtras/Qt Notifier" \
|
||||
"QtMultimedia/QML Video Shader Effects Example" \
|
||||
"QtMultimedia/QML Video Example" \
|
||||
"QtMultimedia/QML Camera Example" \
|
||||
"QtMultimedia/Audio Output Example" \
|
||||
"QtSVG/Text Object Example" \
|
||||
"QtQML/Qt Quick Examples - XMLHttpRequest" \
|
||||
"QtQuick/Qt Quick Particles Examples - *" \
|
||||
@ -138,6 +141,9 @@ manifestmeta.android.names = "QtQuick/Qt Quick Demo - Maroon*" \
|
||||
"QtQuick/Qt Quick Examples - Animation" \
|
||||
"QtQuick/Qt Quick Examples - Shader Effects" \
|
||||
"QtQuick/Qt Quick Examples - Canvas" \
|
||||
"QtQuick/Qt Quick Examples - MouseArea" \
|
||||
"QtQuick/Qt Quick Examples - Positioners" \
|
||||
"QtQuick/Qt Quick Examples - Right to Left" \
|
||||
"QtWidgets/Interview" \
|
||||
"QtWidgets/Spreadsheet" \
|
||||
"QtWidgets/Pixelator Example" \
|
||||
@ -164,7 +170,6 @@ manifestmeta.android.names = "QtQuick/Qt Quick Demo - Maroon*" \
|
||||
"QtQML/Extending QML - Methods Example" \
|
||||
"QtQML/Extending QML - Signal Support Example" \
|
||||
"QtQML/Extending QML - Attached Properties Example" \
|
||||
"QtQuick/Qt Quick Examples - Window and Screen" \
|
||||
"QtWidgets/Address Book Example"
|
||||
|
||||
manifestmeta.android.tags = android
|
||||
|
@ -4,7 +4,6 @@ QMAKE_PLATFORM = android
|
||||
QMAKE_COMPILER = gcc
|
||||
|
||||
CONFIG += android_install unversioned_soname android_deployment_settings
|
||||
DEFINES += QT_NO_PRINTER QT_NO_PRINTDIALOG
|
||||
|
||||
include(../common/linux.conf)
|
||||
include(../common/gcc-base-unix.conf)
|
||||
|
@ -43,6 +43,9 @@
|
||||
#include "option.h"
|
||||
#include "cachekeys.h"
|
||||
#include "meta.h"
|
||||
|
||||
#include <ioutils.h>
|
||||
|
||||
#include <qdir.h>
|
||||
#include <qfile.h>
|
||||
#include <qtextstream.h>
|
||||
@ -52,6 +55,7 @@
|
||||
#include <qbuffer.h>
|
||||
#include <qsettings.h>
|
||||
#include <qdatetime.h>
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
@ -92,7 +96,7 @@ bool MakefileGenerator::canExecute(const QStringList &cmdline, int *a) const
|
||||
|
||||
QString MakefileGenerator::mkdir_p_asstring(const QString &dir, bool escape) const
|
||||
{
|
||||
QString edir = escape ? escapeFilePath(dir) : dir;
|
||||
QString edir = escape ? escapeFilePath(Option::fixPathToTargetOS(dir, false, false)) : dir;
|
||||
return "@" + makedir.arg(edir);
|
||||
}
|
||||
|
||||
@ -3345,11 +3349,17 @@ QString MakefileGenerator::installMetaFile(const ProKey &replace_rule, const QSt
|
||||
const ProString match = project->first(ProKey(replace_rules.at(r) + ".match")),
|
||||
replace = project->first(ProKey(replace_rules.at(r) + ".replace"));
|
||||
if (!match.isEmpty() /*&& match != replace*/)
|
||||
ret += " -e \"s," + match + "," + replace + ",g\"";
|
||||
ret += " -e " + shellQuote("s," + match + "," + replace + ",g");
|
||||
}
|
||||
ret += " \"" + src + "\" >\"" + dst + "\"";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString MakefileGenerator::shellQuote(const QString &str)
|
||||
{
|
||||
return isWindowsShell() ? QMakeInternal::IoUtils::shellQuoteWin(str)
|
||||
: QMakeInternal::IoUtils::shellQuoteUnix(str);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -271,6 +271,7 @@ public:
|
||||
virtual bool mergeBuildProject(MakefileGenerator * /*other*/) { return false; }
|
||||
virtual bool openOutput(QFile &, const QString &build) const;
|
||||
bool isWindowsShell() const { return Option::dir_sep == QLatin1String("\\"); }
|
||||
QString shellQuote(const QString &str);
|
||||
};
|
||||
|
||||
inline void MakefileGenerator::setNoIO(bool o)
|
||||
|
@ -502,7 +502,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
incr_lflags += var("QMAKE_LFLAGS_RELEASE");
|
||||
t << incr_target_dir << ": $(INCREMENTAL_OBJECTS)\n\t";
|
||||
if(!destdir.isEmpty())
|
||||
t << mkdir_p_asstring(destdir) << "\n\t";
|
||||
t << mkdir_p_asstring(destdir, false) << "\n\t";
|
||||
t << "$(LINK) " << incr_lflags << " " << var("QMAKE_LINK_O_FLAG") << incr_target_dir <<
|
||||
" $(INCREMENTAL_OBJECTS)\n";
|
||||
//communicated below
|
||||
@ -528,7 +528,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
<< " " << var("POST_TARGETDEPS");
|
||||
}
|
||||
if(!destdir.isEmpty())
|
||||
t << "\n\t" << mkdir_p_asstring(destdir);
|
||||
t << "\n\t" << mkdir_p_asstring(destdir, false);
|
||||
if(!project->isEmpty("QMAKE_PRE_LINK"))
|
||||
t << "\n\t" << var("QMAKE_PRE_LINK");
|
||||
|
||||
@ -685,7 +685,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
|
||||
if(!project->first("QMAKE_PKGINFO").isEmpty()) {
|
||||
ProString pkginfo = escapeFilePath(project->first("QMAKE_PKGINFO"));
|
||||
QString destdir = escapeFilePath(project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents");
|
||||
QString destdir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents";
|
||||
t << pkginfo << ": \n\t";
|
||||
if(!destdir.isEmpty())
|
||||
t << mkdir_p_asstring(destdir) << "\n\t";
|
||||
@ -697,7 +697,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
if(!project->first("QMAKE_BUNDLE_RESOURCE_FILE").isEmpty()) {
|
||||
ProString resources = escapeFilePath(project->first("QMAKE_BUNDLE_RESOURCE_FILE"));
|
||||
bundledFiles << resources;
|
||||
QString destdir = escapeFilePath(project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents/Resources");
|
||||
QString destdir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents/Resources";
|
||||
t << resources << ": \n\t";
|
||||
t << mkdir_p_asstring(destdir) << "\n\t";
|
||||
t << "@touch " << resources << "\n\t\n";
|
||||
@ -710,7 +710,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
QString destdir = info_plist_out.section(Option::dir_sep, 0, -2);
|
||||
t << info_plist_out << ": \n\t";
|
||||
if(!destdir.isEmpty())
|
||||
t << mkdir_p_asstring(destdir) << "\n\t";
|
||||
t << mkdir_p_asstring(destdir, false) << "\n\t";
|
||||
ProStringList commonSedArgs;
|
||||
if (!project->values("VERSION").isEmpty())
|
||||
commonSedArgs << "-e \"s,@SHORT_VERSION@," << project->first("VER_MAJ") << "." << project->first("VER_MIN") << ",g\" ";
|
||||
|
@ -235,8 +235,10 @@ QString NmakeMakefileGenerator::defaultInstall(const QString &t)
|
||||
if(targetdir.right(1) != Option::dir_sep)
|
||||
targetdir += Option::dir_sep;
|
||||
|
||||
if(t == "target" && project->first("TEMPLATE") == "lib") {
|
||||
if(project->isActiveConfig("shared") && project->isActiveConfig("debug")) {
|
||||
if (project->isActiveConfig("debug")) {
|
||||
if (t == "dlltarget"
|
||||
|| (project->first("TEMPLATE") == "lib"
|
||||
&& project->isActiveConfig("shared"))) {
|
||||
QString pdb_target = getPdbTarget();
|
||||
pdb_target.remove('"');
|
||||
QString src_targ = (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + pdb_target;
|
||||
|
@ -106,7 +106,7 @@ static int doSed(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
if (phase == 1
|
||||
&& (c == QLatin1Char('+') || c == QLatin1Char('?')
|
||||
&& (c == QLatin1Char('+') || c == QLatin1Char('?') || c == QLatin1Char('|')
|
||||
|| c == QLatin1Char('{') || c == QLatin1Char('}')
|
||||
|| c == QLatin1Char('(') || c == QLatin1Char(')'))) {
|
||||
// translate sed rx to QRegExp
|
||||
@ -133,6 +133,7 @@ static int doSed(int argc, char **argv)
|
||||
SedSubst subst;
|
||||
subst.from = QRegExp(phases.at(0));
|
||||
subst.to = phases.at(1);
|
||||
subst.to.replace("\\\\", "\\"); // QString::replace(rx, sub) groks \1, but not \\.
|
||||
substs << subst;
|
||||
}
|
||||
} else if (argv[i][0] == '-' && argv[i][1] != 0) {
|
||||
|
4
src/3rdparty/xcb/include/xcb/xkb.h
vendored
4
src/3rdparty/xcb/include/xcb/xkb.h
vendored
@ -114,8 +114,8 @@ typedef enum xcb_xkb_control_t {
|
||||
XCB_XKB_CONTROL_GROUPS_WRAP = 134217728,
|
||||
XCB_XKB_CONTROL_INTERNAL_MODS = 268435456,
|
||||
XCB_XKB_CONTROL_IGNORE_LOCK_MODS = 536870912,
|
||||
XCB_XKB_CONTROL_PER_KEY_REPEAT = 1073741824,
|
||||
XCB_XKB_CONTROL_CONTROLS_ENABLED = 2147483648
|
||||
XCB_XKB_CONTROL_PER_KEY_REPEAT = 1073741824u,
|
||||
XCB_XKB_CONTROL_CONTROLS_ENABLED = 2147483648u
|
||||
} xcb_xkb_control_t;
|
||||
|
||||
typedef enum xcb_xkb_axfb_opt_t {
|
||||
|
15
src/3rdparty/xcb/libxcb/fix_compiler_warning_on_32bit_systems.patch
vendored
Normal file
15
src/3rdparty/xcb/libxcb/fix_compiler_warning_on_32bit_systems.patch
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
diff --git a/src/3rdparty/xcb/include/xcb/xkb.h b/src/3rdparty/xcb/include/xcb/xkb.h
|
||||
index 44b0a8d..0180ec8 100644
|
||||
--- a/src/3rdparty/xcb/include/xcb/xkb.h
|
||||
+++ b/src/3rdparty/xcb/include/xcb/xkb.h
|
||||
@@ -114,8 +114,8 @@ typedef enum xcb_xkb_control_t {
|
||||
XCB_XKB_CONTROL_GROUPS_WRAP = 134217728,
|
||||
XCB_XKB_CONTROL_INTERNAL_MODS = 268435456,
|
||||
XCB_XKB_CONTROL_IGNORE_LOCK_MODS = 536870912,
|
||||
- XCB_XKB_CONTROL_PER_KEY_REPEAT = 1073741824,
|
||||
- XCB_XKB_CONTROL_CONTROLS_ENABLED = 2147483648
|
||||
+ XCB_XKB_CONTROL_PER_KEY_REPEAT = 1073741824u,
|
||||
+ XCB_XKB_CONTROL_CONTROLS_ENABLED = 2147483648u
|
||||
} xcb_xkb_control_t;
|
||||
|
||||
typedef enum xcb_xkb_axfb_opt_t {
|
@ -735,6 +735,20 @@
|
||||
# define Q_COMPILER_CLASS_ENUM
|
||||
# define Q_COMPILER_ATOMICS
|
||||
# endif /* VC 11 */
|
||||
# if _MSC_VER >= 1800
|
||||
/* C++11 features in VC12 = VC2013 */
|
||||
# define Q_COMPILER_DEFAULT_MEMBERS
|
||||
# define Q_COMPILER_DELETE_MEMBERS
|
||||
# define Q_COMPILER_DELEGATING_CONSTRUCTORS
|
||||
# define Q_COMPILER_EXPLICIT_CONVERSIONS
|
||||
# define Q_COMPILER_NONSTATIC_MEMBER_INIT
|
||||
# define Q_COMPILER_INITIALIZER_LISTS
|
||||
// implemented in principle, but has a bug that makes it unusable: http://connect.microsoft.com/VisualStudio/feedback/details/802058/c-11-unified-initialization-fails-with-c-style-arrays
|
||||
// #define Q_COMPILER_UNIFORM_INIT
|
||||
# define Q_COMPILER_RAW_STRINGS
|
||||
# define Q_COMPILER_TEMPLATE_ALIAS
|
||||
# define Q_COMPILER_VARIADIC_TEMPLATES
|
||||
# endif /* VC 12 */
|
||||
#endif /* Q_CC_MSVC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -985,8 +985,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
|
||||
/*!
|
||||
\fn QSysInfo::MacVersion QSysInfo::macVersion()
|
||||
|
||||
Returns the version of Mac OS X on which the application is run (Mac OS X
|
||||
Only).
|
||||
Returns the version of Darwin (OS X or iOS) on which the application is run.
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -1056,7 +1055,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
|
||||
\enum QSysInfo::MacVersion
|
||||
|
||||
This enum provides symbolic names for the various versions of the
|
||||
OS X operating system. On OS X, the
|
||||
Darwin operating system, covering both OS X and iOS. The
|
||||
QSysInfo::MacintoshVersion variable gives the version of the
|
||||
system on which the application is run.
|
||||
|
||||
@ -1084,6 +1083,15 @@ bool qSharedBuild() Q_DECL_NOTHROW
|
||||
\value MV_MOUNTAINLION Apple codename for MV_10_8
|
||||
\value MV_MAVERICKS Apple codename for MV_10_9
|
||||
|
||||
\value MV_IOS iOS (any)
|
||||
\value MV_IOS_4_3 iOS 4.3
|
||||
\value MV_IOS_5_0 iOS 5.0
|
||||
\value MV_IOS_5_1 iOS 5.1
|
||||
\value MV_IOS_6_0 iOS 6.0
|
||||
\value MV_IOS_6_1 iOS 6.1
|
||||
\value MV_IOS_7_0 iOS 7.0
|
||||
\value MV_IOS_7_1 iOS 7.1
|
||||
|
||||
\sa WinVersion
|
||||
*/
|
||||
|
||||
@ -1706,13 +1714,15 @@ static const unsigned int qt_one = 1;
|
||||
const int QSysInfo::ByteOrder = ((*((unsigned char *) &qt_one) == 0) ? BigEndian : LittleEndian);
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MACX)
|
||||
#if defined(Q_OS_MAC)
|
||||
|
||||
QT_BEGIN_INCLUDE_NAMESPACE
|
||||
#include "private/qcore_mac_p.h"
|
||||
#include "qnamespace.h"
|
||||
QT_END_INCLUDE_NAMESPACE
|
||||
|
||||
#if defined(Q_OS_OSX)
|
||||
|
||||
Q_CORE_EXPORT OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref)
|
||||
{
|
||||
return FSPathMakeRef(reinterpret_cast<const UInt8 *>(file.toUtf8().constData()), fsref, 0);
|
||||
@ -1728,17 +1738,17 @@ Q_CORE_EXPORT void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding e
|
||||
Q_CORE_EXPORT QString qt_mac_from_pascal_string(const Str255 pstr) {
|
||||
return QCFString(CFStringCreateWithPascalString(0, pstr, CFStringGetSystemEncoding()));
|
||||
}
|
||||
#endif // defined(Q_OS_MACX)
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
#endif // defined(Q_OS_OSX)
|
||||
|
||||
QSysInfo::MacVersion QSysInfo::macVersion()
|
||||
{
|
||||
#ifdef Q_OS_MACX
|
||||
#if defined(Q_OS_OSX)
|
||||
SInt32 gestalt_version;
|
||||
if (Gestalt(gestaltSystemVersion, &gestalt_version) == noErr) {
|
||||
return QSysInfo::MacVersion(((gestalt_version & 0x00F0) >> 4) + 2);
|
||||
}
|
||||
#elif defined(Q_OS_IOS)
|
||||
return qt_ios_version(); // qtcore_mac_objc.mm
|
||||
#endif
|
||||
return QSysInfo::MV_Unknown;
|
||||
}
|
||||
|
@ -520,6 +520,16 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max
|
||||
# define QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, ios) \
|
||||
(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && osx != __MAC_NA && __MAC_OS_X_VERSION_MIN_REQUIRED < osx) || \
|
||||
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MIN_REQUIRED < ios)
|
||||
|
||||
# define QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(ios) \
|
||||
QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, ios)
|
||||
# define QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(osx) \
|
||||
QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, __IPHONE_NA)
|
||||
|
||||
# define QT_IOS_DEPLOYMENT_TARGET_BELOW(ios) \
|
||||
QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_NA, ios)
|
||||
# define QT_OSX_DEPLOYMENT_TARGET_BELOW(osx) \
|
||||
QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, __IPHONE_NA)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -120,6 +120,7 @@ public:
|
||||
|
||||
#endif
|
||||
#ifdef Q_OS_MAC
|
||||
# define Q_MV_IOS(major, minor) (QSysInfo::MV_IOS | major << 4 | minor)
|
||||
enum MacVersion {
|
||||
MV_Unknown = 0x0000,
|
||||
|
||||
@ -146,7 +147,17 @@ public:
|
||||
MV_SNOWLEOPARD = MV_10_6,
|
||||
MV_LION = MV_10_7,
|
||||
MV_MOUNTAINLION = MV_10_8,
|
||||
MV_MAVERICKS = MV_10_9
|
||||
MV_MAVERICKS = MV_10_9,
|
||||
|
||||
/* iOS */
|
||||
MV_IOS = 1 << 8,
|
||||
MV_IOS_4_3 = Q_MV_IOS(4, 3),
|
||||
MV_IOS_5_0 = Q_MV_IOS(5, 0),
|
||||
MV_IOS_5_1 = Q_MV_IOS(5, 1),
|
||||
MV_IOS_6_0 = Q_MV_IOS(6, 0),
|
||||
MV_IOS_6_1 = Q_MV_IOS(6, 1),
|
||||
MV_IOS_7_0 = Q_MV_IOS(7, 0),
|
||||
MV_IOS_7_1 = Q_MV_IOS(7, 1)
|
||||
};
|
||||
static const MacVersion MacintoshVersion;
|
||||
static MacVersion macVersion();
|
||||
|
@ -359,6 +359,8 @@ QStringList QFileSelectorPrivate::platformSelectors()
|
||||
ret << QStringLiteral("android");
|
||||
# elif defined(Q_OS_BLACKBERRY)
|
||||
ret << QStringLiteral("blackberry");
|
||||
# elif defined(Q_OS_QNX)
|
||||
ret << QStringLiteral("qnx");
|
||||
# elif defined(Q_OS_IOS)
|
||||
ret << QStringLiteral("ios");
|
||||
# elif defined(Q_OS_LINUX)
|
||||
|
@ -98,6 +98,9 @@ mac:!nacl {
|
||||
kernel/qcore_mac.cpp
|
||||
OBJECTIVE_SOURCES += \
|
||||
kernel/qcore_mac_objc.mm
|
||||
|
||||
# We need UIKit for UIDevice
|
||||
ios: LIBS_PRIVATE += -framework UIKit
|
||||
}
|
||||
|
||||
nacl {
|
||||
|
@ -41,6 +41,10 @@
|
||||
|
||||
#include <private/qcore_mac_p.h>
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
NSString *QCFString::toNSString(const QString &string)
|
||||
@ -54,5 +58,31 @@ QString QCFString::toQString(const NSString *nsstr)
|
||||
return toQString(reinterpret_cast<CFStringRef>(nsstr));
|
||||
}
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
QSysInfo::MacVersion qt_ios_version()
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
int major = 0, minor = 0;
|
||||
NSArray *components = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
|
||||
switch ([components count]) {
|
||||
case 3:
|
||||
// We don't care about the patch version
|
||||
case 2:
|
||||
minor = [[components objectAtIndex:1] intValue];
|
||||
// fall through
|
||||
case 1:
|
||||
major = [[components objectAtIndex:0] intValue];
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
return QSysInfo::MacVersion(Q_MV_IOS(major, minor));
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -143,6 +143,10 @@ private:
|
||||
QString string;
|
||||
};
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
QSysInfo::MacVersion qt_ios_version();
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QCORE_MAC_P_H
|
||||
|
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -177,6 +178,7 @@ private:
|
||||
|
||||
|
||||
void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
|
||||
void (*QAbstractDeclarativeData::destroyed_qml1)(QAbstractDeclarativeData *, QObject *) = 0;
|
||||
void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
|
||||
void (*QAbstractDeclarativeData::signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **) = 0;
|
||||
int (*QAbstractDeclarativeData::receivers)(QAbstractDeclarativeData *, const QObject *, int) = 0;
|
||||
@ -805,8 +807,12 @@ QObject::~QObject()
|
||||
}
|
||||
}
|
||||
|
||||
if (d->declarativeData)
|
||||
QAbstractDeclarativeData::destroyed(d->declarativeData, this);
|
||||
if (d->declarativeData) {
|
||||
if (QAbstractDeclarativeData::destroyed)
|
||||
QAbstractDeclarativeData::destroyed(d->declarativeData, this);
|
||||
if (QAbstractDeclarativeData::destroyed_qml1)
|
||||
QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
|
||||
}
|
||||
|
||||
// set ref to zero to indicate that this object has been deleted
|
||||
if (d->currentSender != 0)
|
||||
@ -847,9 +853,9 @@ QObject::~QObject()
|
||||
|
||||
// The destroy operation must happen outside the lock
|
||||
if (c->isSlotObject) {
|
||||
c->isSlotObject = false;
|
||||
locker.unlock();
|
||||
c->slotObj->destroyIfLastRef();
|
||||
c->isSlotObject = false;
|
||||
locker.relock();
|
||||
}
|
||||
c->deref();
|
||||
@ -864,15 +870,29 @@ QObject::~QObject()
|
||||
d->connectionLists = 0;
|
||||
}
|
||||
|
||||
// disconnect all senders
|
||||
/* Disconnect all senders:
|
||||
* This loop basically just does
|
||||
* for (node = d->senders; node; node = node->next) { ... }
|
||||
*
|
||||
* We need to temporarily unlock the receiver mutex to destroy the functors or to lock the
|
||||
* sender's mutex. And when the mutex is released, node->next might be destroyed by another
|
||||
* thread. That's why we set node->prev to &node, that way, if node is destroyed, node will
|
||||
* be updated.
|
||||
*/
|
||||
QObjectPrivate::Connection *node = d->senders;
|
||||
while (node) {
|
||||
QObject *sender = node->sender;
|
||||
// Send disconnectNotify before removing the connection from sender's connection list.
|
||||
// This ensures any eventual destructor of sender will block on getting receiver's lock
|
||||
// and not finish until we release it.
|
||||
sender->disconnectNotify(QMetaObjectPrivate::signal(sender->metaObject(), node->signal_index));
|
||||
QMutex *m = signalSlotLock(sender);
|
||||
node->prev = &node;
|
||||
bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
|
||||
//the node has maybe been removed while the mutex was unlocked in relock?
|
||||
if (!node || node->sender != sender) {
|
||||
// We hold the wrong mutex
|
||||
Q_ASSERT(needToUnlock);
|
||||
m->unlock();
|
||||
continue;
|
||||
}
|
||||
@ -881,8 +901,6 @@ QObject::~QObject()
|
||||
if (senderLists)
|
||||
senderLists->dirty = true;
|
||||
|
||||
int signal_index = node->signal_index;
|
||||
|
||||
QtPrivate::QSlotObjectBase *slotObj = Q_NULLPTR;
|
||||
if (node->isSlotObject) {
|
||||
slotObj = node->slotObj;
|
||||
@ -894,12 +912,12 @@ QObject::~QObject()
|
||||
m->unlock();
|
||||
|
||||
if (slotObj) {
|
||||
if (node)
|
||||
node->prev = &node;
|
||||
locker.unlock();
|
||||
slotObj->destroyIfLastRef();
|
||||
locker.relock();
|
||||
}
|
||||
|
||||
sender->disconnectNotify(QMetaObjectPrivate::signal(sender->metaObject(), signal_index));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1858,7 +1876,7 @@ void QObjectPrivate::setParent_helper(QObject *o)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isDeletingChildren && declarativeData)
|
||||
if (!isDeletingChildren && declarativeData && QAbstractDeclarativeData::parentChanged)
|
||||
QAbstractDeclarativeData::parentChanged(declarativeData, q, o);
|
||||
}
|
||||
|
||||
@ -3163,7 +3181,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
|
||||
&& (slot == 0 || (c->isSlotObject && c->slotObj->compare(slot)))))) {
|
||||
bool needToUnlock = false;
|
||||
QMutex *receiverMutex = 0;
|
||||
if (!receiver) {
|
||||
if (c->receiver) {
|
||||
receiverMutex = signalSlotLock(c->receiver);
|
||||
// need to relock this receiver and sender in the correct order
|
||||
needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex);
|
||||
@ -3180,9 +3198,9 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
|
||||
c->receiver = 0;
|
||||
|
||||
if (c->isSlotObject) {
|
||||
c->isSlotObject = false;
|
||||
senderMutex->unlock();
|
||||
c->slotObj->destroyIfLastRef();
|
||||
c->isSlotObject = false;
|
||||
senderMutex->lock();
|
||||
}
|
||||
|
||||
@ -3211,8 +3229,7 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender,
|
||||
QObject *s = const_cast<QObject *>(sender);
|
||||
|
||||
QMutex *senderMutex = signalSlotLock(sender);
|
||||
QMutex *receiverMutex = receiver ? signalSlotLock(receiver) : 0;
|
||||
QOrderedMutexLocker locker(senderMutex, receiverMutex);
|
||||
QMutexLocker locker(senderMutex);
|
||||
|
||||
QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
|
||||
if (!connectionLists)
|
||||
|
@ -99,6 +99,8 @@ namespace QtPrivate {
|
||||
|
||||
template <typename ArgList, bool Declared = TypesAreDeclaredMetaType<ArgList>::Value > struct ConnectionTypes
|
||||
{ static const int *types() { return 0; } };
|
||||
template <> struct ConnectionTypes<List<>, true>
|
||||
{ static const int *types() { return 0; } };
|
||||
template <typename... Args> struct ConnectionTypes<List<Args...>, true>
|
||||
{ static const int *types() { static const int t[sizeof...(Args) + 1] = { (QtPrivate::QMetaTypeIdHelper<Args>::qt_metatype_id())..., 0 }; return t; } };
|
||||
#endif
|
||||
|
@ -90,6 +90,7 @@ class Q_CORE_EXPORT QAbstractDeclarativeData
|
||||
{
|
||||
public:
|
||||
static void (*destroyed)(QAbstractDeclarativeData *, QObject *);
|
||||
static void (*destroyed_qml1)(QAbstractDeclarativeData *, QObject *);
|
||||
static void (*parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *);
|
||||
static void (*signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **);
|
||||
static int (*receivers)(QAbstractDeclarativeData *, const QObject *, int);
|
||||
|
@ -105,7 +105,7 @@ public:
|
||||
QTimeZoneSingleton() : backend(newBackendTimeZone()) {}
|
||||
|
||||
// The backend_tz is the tz to use in static methods such as availableTimeZoneIds() and
|
||||
// isTimeZoneIdAvailable() and to create named Olsen time zones. This is usually the host
|
||||
// isTimeZoneIdAvailable() and to create named IANA time zones. This is usually the host
|
||||
// system, but may be different if the host resources are insufficient or if
|
||||
// QT_NO_SYSTEMLOCALE is set. A simple UTC backend is used if no alternative is available.
|
||||
QSharedDataPointer<QTimeZonePrivate> backend;
|
||||
@ -135,18 +135,21 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
|
||||
|
||||
\section1
|
||||
|
||||
\section2 Olsen Time Zone IDs
|
||||
\section2 IANA Time Zone IDs
|
||||
|
||||
QTimeZone uses the Olsen time zone IDs as defined in the IANA Time Zone
|
||||
QTimeZone uses the IANA time zone IDs as defined in the IANA Time Zone
|
||||
Database (http://www.iana.org/time-zones). This is to ensure a standard ID
|
||||
across all supported platforms. Most platforms support the Olsen IDs
|
||||
across all supported platforms. Most platforms support the IANA IDs
|
||||
and the IANA Database natively, but for Windows a mapping is required to
|
||||
the native IDs. See below for more details.
|
||||
|
||||
The Olsen IDs can and do change on a regular basis, and can vary depending
|
||||
The IANA IDs can and do change on a regular basis, and can vary depending
|
||||
on how recently the host system data was updated. As such you cannot rely
|
||||
on any given ID existing on any host system. You must use
|
||||
availableTimeZoneIds() to determine what Olsen IDs are available.
|
||||
availableTimeZoneIds() to determine what IANA IDs are available.
|
||||
|
||||
The IANA IDs and database are also know as the Olson IDs and database,
|
||||
named after their creator.
|
||||
|
||||
\section2 UTC Offset Time Zones
|
||||
|
||||
@ -165,7 +168,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
|
||||
the current year.
|
||||
|
||||
QTimeZone uses a conversion table derived form the Unicode CLDR data to map
|
||||
between Olsen IDs and Windows IDs. Depending on your version of Windows
|
||||
between IANA IDs and Windows IDs. Depending on your version of Windows
|
||||
and Qt, this table may not be able to provide a valid conversion, in which
|
||||
"UTC" will be returned.
|
||||
|
||||
@ -180,7 +183,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
|
||||
If you require a QDateTime that uses the current system time zone at any
|
||||
given moment then you should use a Qt::TimeSpec of Qt::LocalTime.
|
||||
|
||||
The method systemTimeZoneId() returns the current system Olsen time zone
|
||||
The method systemTimeZoneId() returns the current system IANA time zone
|
||||
ID which on OSX and Linux will always be correct. On Windows this ID is
|
||||
translated from the the Windows system ID using an internal translation
|
||||
table and the user's selected country. As a consequence there is a small
|
||||
@ -323,7 +326,7 @@ QTimeZone::QTimeZone()
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates an instance of the requested time zone \a olsenId.
|
||||
Creates an instance of the requested time zone \a ianaId.
|
||||
|
||||
The ID must be one of the available system IDs otherwise an invalid
|
||||
time zone will be returned.
|
||||
@ -331,14 +334,14 @@ QTimeZone::QTimeZone()
|
||||
\sa availableTimeZoneIds()
|
||||
*/
|
||||
|
||||
QTimeZone::QTimeZone(const QByteArray &olsenId)
|
||||
QTimeZone::QTimeZone(const QByteArray &ianaId)
|
||||
{
|
||||
// Try and see if it's a valid UTC offset ID, just as quick to try create as look-up
|
||||
d = new QUtcTimeZonePrivate(olsenId);
|
||||
d = new QUtcTimeZonePrivate(ianaId);
|
||||
// If not a valid UTC offset ID then try create it with the system backend
|
||||
// Relies on backend not creating valid tz with invalid name
|
||||
if (!d->isValid())
|
||||
d = newBackendTimeZone(olsenId);
|
||||
d = newBackendTimeZone(ianaId);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -359,14 +362,14 @@ QTimeZone::QTimeZone(int offsetSeconds)
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a custom time zone with an ID of \a olsenId and an offset from UTC
|
||||
Creates a custom time zone with an ID of \a ianaId and an offset from UTC
|
||||
of \a offsetSeconds. The \a name will be the name used by displayName()
|
||||
for the LongName, the \a abbreviation will be used by displayName() for the
|
||||
ShortName and by abbreviation(), and the optional \a country will be used
|
||||
by country(). The \a comment is an optional note that may be displayed in
|
||||
a GUI to assist users in selecting a time zone.
|
||||
|
||||
The \a olsenId must not be one of the available system IDs returned by
|
||||
The \a ianaId must not be one of the available system IDs returned by
|
||||
availableTimeZoneIds(). The \a offsetSeconds from UTC must be in the range
|
||||
-14 hours to +14 hours.
|
||||
|
||||
@ -374,12 +377,12 @@ QTimeZone::QTimeZone(int offsetSeconds)
|
||||
default value of QLocale::AnyCountry.
|
||||
*/
|
||||
|
||||
QTimeZone::QTimeZone(const QByteArray &olsenId, int offsetSeconds, const QString &name,
|
||||
QTimeZone::QTimeZone(const QByteArray &ianaId, int offsetSeconds, const QString &name,
|
||||
const QString &abbreviation, QLocale::Country country, const QString &comment)
|
||||
{
|
||||
// olsenId must be a valid ID and must not clash with the standard system names
|
||||
if (QTimeZonePrivate::isValidId(olsenId) && !availableTimeZoneIds().contains(olsenId))
|
||||
d = new QUtcTimeZonePrivate(olsenId, offsetSeconds, name, abbreviation, country, comment);
|
||||
// ianaId must be a valid ID and must not clash with the standard system names
|
||||
if (QTimeZonePrivate::isValidId(ianaId) && !availableTimeZoneIds().contains(ianaId))
|
||||
d = new QUtcTimeZonePrivate(ianaId, offsetSeconds, name, abbreviation, country, comment);
|
||||
else
|
||||
d = 0;
|
||||
}
|
||||
@ -473,10 +476,10 @@ bool QTimeZone::isValid() const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the Olsen ID for the time zone.
|
||||
Returns the IANA ID for the time zone.
|
||||
|
||||
Olsen IDs are used on all platforms. On Windows these are translated
|
||||
from the Windows ID into the closest Olsen ID for the time zone and country.
|
||||
IANA IDs are used on all platforms. On Windows these are translated
|
||||
from the Windows ID into the closest IANA ID for the time zone and country.
|
||||
*/
|
||||
|
||||
QByteArray QTimeZone::id() const
|
||||
@ -705,6 +708,9 @@ bool QTimeZone::hasTransitions() const
|
||||
This is most useful when you have a Transition time and wish to find the
|
||||
Transition after it.
|
||||
|
||||
If there is no transition after the given \a afterDateTime then an invalid
|
||||
OffsetData will be returned with an invalid QDateTime.
|
||||
|
||||
The given \a afterDateTime is exclusive.
|
||||
|
||||
\sa hasTransitions(), previousTransition(), transitions()
|
||||
@ -723,6 +729,9 @@ QTimeZone::OffsetData QTimeZone::nextTransition(const QDateTime &afterDateTime)
|
||||
This is most useful when you have a Transition time and wish to find the
|
||||
Transition before it.
|
||||
|
||||
If there is no transition before the given \a beforeDateTime then an invalid
|
||||
OffsetData will be returned with an invalid QDateTime.
|
||||
|
||||
The given \a beforeDateTime is exclusive.
|
||||
|
||||
\sa hasTransitions(), nextTransition(), transitions()
|
||||
@ -760,7 +769,7 @@ QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime,
|
||||
// Static methods
|
||||
|
||||
/*!
|
||||
Returns the current system time zone Olsen ID.
|
||||
Returns the current system time zone IANA ID.
|
||||
|
||||
On Windows this ID is translated from the the Windows ID using an internal
|
||||
translation table and the user's selected country. As a consequence there
|
||||
@ -774,20 +783,20 @@ QByteArray QTimeZone::systemTimeZoneId()
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c true if a given time zone \a olsenId is available on this system.
|
||||
Returns \c true if a given time zone \a ianaId is available on this system.
|
||||
|
||||
\sa availableTimeZoneIds()
|
||||
*/
|
||||
|
||||
bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &olsenId)
|
||||
bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &ianaId)
|
||||
{
|
||||
// isValidId is not strictly required, but faster to weed out invalid
|
||||
// IDs as availableTimeZoneIds() may be slow
|
||||
return (QTimeZonePrivate::isValidId(olsenId) && (availableTimeZoneIds().contains(olsenId)));
|
||||
return (QTimeZonePrivate::isValidId(ianaId) && (availableTimeZoneIds().contains(ianaId)));
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a list of all available Olsen time zone IDs on this system.
|
||||
Returns a list of all available IANA time zone IDs on this system.
|
||||
|
||||
\sa isTimeZoneIdAvailable()
|
||||
*/
|
||||
@ -802,7 +811,7 @@ QList<QByteArray> QTimeZone::availableTimeZoneIds()
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a list of all available Olsen time zone IDs for a given \a country.
|
||||
Returns a list of all available IANA time zone IDs for a given \a country.
|
||||
|
||||
As a special case, a \a country of Qt::AnyCountry returns those time zones
|
||||
that do not have any country related to them, such as UTC. If you require
|
||||
@ -822,7 +831,7 @@ QList<QByteArray> QTimeZone::availableTimeZoneIds(QLocale::Country country)
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a list of all available Olsen time zone IDs with a given standard
|
||||
Returns a list of all available IANA time zone IDs with a given standard
|
||||
time offset of \a offsetSeconds.
|
||||
|
||||
\sa isTimeZoneIdAvailable()
|
||||
@ -838,79 +847,79 @@ QList<QByteArray> QTimeZone::availableTimeZoneIds(int offsetSeconds)
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the Windows ID equivalent to the given \a olsenId.
|
||||
Returns the Windows ID equivalent to the given \a ianaId.
|
||||
|
||||
\sa windowsIdToDefaultOlsenId(), windowsIdToOlsenIds()
|
||||
\sa windowsIdToDefaultIanaId(), windowsIdToIanaIds()
|
||||
*/
|
||||
|
||||
QByteArray QTimeZone::olsenIdToWindowsId(const QByteArray &olsenId)
|
||||
QByteArray QTimeZone::ianaIdToWindowsId(const QByteArray &ianaId)
|
||||
{
|
||||
return QTimeZonePrivate::olsenIdToWindowsId(olsenId);
|
||||
return QTimeZonePrivate::ianaIdToWindowsId(ianaId);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the default Olsen ID for a given \a windowsId.
|
||||
Returns the default IANA ID for a given \a windowsId.
|
||||
|
||||
Because a Windows ID can cover several Olsen IDs in several different
|
||||
countries, this function returns the most frequently used Olsen ID with no
|
||||
Because a Windows ID can cover several IANA IDs in several different
|
||||
countries, this function returns the most frequently used IANA ID with no
|
||||
regard for the country and should thus be used with care. It is usually
|
||||
best to request the default for a specific country.
|
||||
|
||||
\sa olsenIdToWindowsId(), windowsIdToOlsenIds()
|
||||
\sa ianaIdToWindowsId(), windowsIdToIanaIds()
|
||||
*/
|
||||
|
||||
QByteArray QTimeZone::windowsIdToDefaultOlsenId(const QByteArray &windowsId)
|
||||
QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId)
|
||||
{
|
||||
return QTimeZonePrivate::windowsIdToDefaultOlsenId(windowsId);
|
||||
return QTimeZonePrivate::windowsIdToDefaultIanaId(windowsId);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the default Olsen ID for a given \a windowsId and \a country.
|
||||
Returns the default IANA ID for a given \a windowsId and \a country.
|
||||
|
||||
Because a Windows ID can cover several Olsen IDs within a given country,
|
||||
the most frequently used Olsen ID in that country is returned.
|
||||
Because a Windows ID can cover several IANA IDs within a given country,
|
||||
the most frequently used IANA ID in that country is returned.
|
||||
|
||||
As a special case, QLocale::AnyCountry returns the default of those Olsen IDs
|
||||
As a special case, QLocale::AnyCountry returns the default of those IANA IDs
|
||||
that do not have any specific country.
|
||||
|
||||
\sa olsenIdToWindowsId(), windowsIdToOlsenIds()
|
||||
\sa ianaIdToWindowsId(), windowsIdToIanaIds()
|
||||
*/
|
||||
|
||||
QByteArray QTimeZone::windowsIdToDefaultOlsenId(const QByteArray &windowsId,
|
||||
QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId,
|
||||
QLocale::Country country)
|
||||
{
|
||||
return QTimeZonePrivate::windowsIdToDefaultOlsenId(windowsId, country);
|
||||
return QTimeZonePrivate::windowsIdToDefaultIanaId(windowsId, country);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns all the Olsen IDs for a given \a windowsId.
|
||||
Returns all the IANA IDs for a given \a windowsId.
|
||||
|
||||
The returned list is sorted alphabetically.
|
||||
|
||||
\sa olsenIdToWindowsId(), windowsIdToDefaultOlsenId()
|
||||
\sa ianaIdToWindowsId(), windowsIdToDefaultIanaId()
|
||||
*/
|
||||
|
||||
QList<QByteArray> QTimeZone::windowsIdToOlsenIds(const QByteArray &windowsId)
|
||||
QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId)
|
||||
{
|
||||
return QTimeZonePrivate::windowsIdToOlsenIds(windowsId);
|
||||
return QTimeZonePrivate::windowsIdToIanaIds(windowsId);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns all the Olsen IDs for a given \a windowsId and \a country.
|
||||
Returns all the IANA IDs for a given \a windowsId and \a country.
|
||||
|
||||
As a special case QLocale::AnyCountry returns those Olsen IDs that do
|
||||
As a special case QLocale::AnyCountry returns those IANA IDs that do
|
||||
not have any specific country.
|
||||
|
||||
The returned list is in order of frequency of usage, i.e. larger zones
|
||||
within a country are listed first.
|
||||
|
||||
\sa olsenIdToWindowsId(), windowsIdToDefaultOlsenId()
|
||||
\sa ianaIdToWindowsId(), windowsIdToDefaultIanaId()
|
||||
*/
|
||||
|
||||
QList<QByteArray> QTimeZone::windowsIdToOlsenIds(const QByteArray &windowsId,
|
||||
QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
|
||||
QLocale::Country country)
|
||||
{
|
||||
return QTimeZonePrivate::windowsIdToOlsenIds(windowsId, country);
|
||||
return QTimeZonePrivate::windowsIdToIanaIds(windowsId, country);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
typedef QVector<OffsetData> OffsetDataList;
|
||||
|
||||
QTimeZone();
|
||||
explicit QTimeZone(const QByteArray &olsenId);
|
||||
explicit QTimeZone(const QByteArray &ianaId);
|
||||
explicit QTimeZone(int offsetSeconds);
|
||||
/*implicit*/ QTimeZone(const QByteArray &zoneId, int offsetSeconds, const QString &name,
|
||||
const QString &abbreviation, QLocale::Country country = QLocale::AnyCountry,
|
||||
@ -126,18 +126,18 @@ public:
|
||||
|
||||
static QByteArray systemTimeZoneId();
|
||||
|
||||
static bool isTimeZoneIdAvailable(const QByteArray &olsenId);
|
||||
static bool isTimeZoneIdAvailable(const QByteArray &ianaId);
|
||||
|
||||
static QList<QByteArray> availableTimeZoneIds();
|
||||
static QList<QByteArray> availableTimeZoneIds(QLocale::Country country);
|
||||
static QList<QByteArray> availableTimeZoneIds(int offsetSeconds);
|
||||
|
||||
static QByteArray olsenIdToWindowsId(const QByteArray &olsenId);
|
||||
static QByteArray windowsIdToDefaultOlsenId(const QByteArray &windowsId);
|
||||
static QByteArray windowsIdToDefaultOlsenId(const QByteArray &windowsId,
|
||||
static QByteArray ianaIdToWindowsId(const QByteArray &ianaId);
|
||||
static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId);
|
||||
static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId,
|
||||
QLocale::Country country);
|
||||
static QList<QByteArray> windowsIdToOlsenIds(const QByteArray &windowsId);
|
||||
static QList<QByteArray> windowsIdToOlsenIds(const QByteArray &windowsId,
|
||||
static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId);
|
||||
static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId,
|
||||
QLocale::Country country);
|
||||
|
||||
private:
|
||||
|
@ -264,7 +264,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs)
|
||||
// If the local msecs is less than the real local time of the transition
|
||||
// then get the previous transition to use instead
|
||||
if (forLocalMSecs < tran.atMSecsSinceEpoch + (tran.offsetFromUtc * 1000)) {
|
||||
while (forLocalMSecs < tran.atMSecsSinceEpoch + (tran.offsetFromUtc * 1000)) {
|
||||
while (tran.atMSecsSinceEpoch != invalidMSecs()
|
||||
&& forLocalMSecs < tran.atMSecsSinceEpoch + (tran.offsetFromUtc * 1000)) {
|
||||
nextTran = tran;
|
||||
tran = previousTransition(tran.atMSecsSinceEpoch);
|
||||
}
|
||||
@ -272,7 +273,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs)
|
||||
// The zone msecs is after the transition, so check it is before the next tran
|
||||
// If not try use the next transition instead
|
||||
nextTran = nextTransition(tran.atMSecsSinceEpoch);
|
||||
while (forLocalMSecs >= nextTran.atMSecsSinceEpoch + (nextTran.offsetFromUtc * 1000)) {
|
||||
while (nextTran.atMSecsSinceEpoch != invalidMSecs()
|
||||
&& forLocalMSecs >= nextTran.atMSecsSinceEpoch + (nextTran.offsetFromUtc * 1000)) {
|
||||
tran = nextTran;
|
||||
nextTran = nextTransition(tran.atMSecsSinceEpoch);
|
||||
}
|
||||
@ -292,7 +294,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs)
|
||||
// then use the prev tran as we default to the FirstOccurrence
|
||||
// TODO Check if faster to just always get prev tran, or if faster using 6 hour check.
|
||||
Data dstTran = previousTransition(tran.atMSecsSinceEpoch);
|
||||
if (dstTran.daylightTimeOffset > 0 && diffPrevTran < (dstTran.daylightTimeOffset * 1000))
|
||||
if (dstTran.atMSecsSinceEpoch != invalidMSecs()
|
||||
&& dstTran.daylightTimeOffset > 0 && diffPrevTran < (dstTran.daylightTimeOffset * 1000))
|
||||
tran = dstTran;
|
||||
} else if (diffNextTran >= 0 && diffNextTran <= (nextTran.daylightTimeOffset * 1000)) {
|
||||
// If time falls within last hour of standard time then is actually the missing hour
|
||||
@ -328,10 +331,11 @@ QTimeZonePrivate::DataList QTimeZonePrivate::transitions(qint64 fromMSecsSinceEp
|
||||
qint64 toMSecsSinceEpoch) const
|
||||
{
|
||||
DataList list;
|
||||
if (toMSecsSinceEpoch > fromMSecsSinceEpoch) {
|
||||
if (toMSecsSinceEpoch >= fromMSecsSinceEpoch) {
|
||||
// fromMSecsSinceEpoch is inclusive but nextTransitionTime() is exclusive so go back 1 msec
|
||||
Data next = nextTransition(fromMSecsSinceEpoch - 1);
|
||||
while (next.atMSecsSinceEpoch <= toMSecsSinceEpoch) {
|
||||
while (next.atMSecsSinceEpoch != invalidMSecs()
|
||||
&& next.atMSecsSinceEpoch <= toMSecsSinceEpoch) {
|
||||
list.append(next);
|
||||
next = nextTransition(next.atMSecsSinceEpoch);
|
||||
}
|
||||
@ -477,7 +481,7 @@ QString QTimeZonePrivate::isoOffsetFormat(int offsetFromUtc)
|
||||
.arg(qAbs(mins) % 60, 2, 10, QLatin1Char('0'));
|
||||
}
|
||||
|
||||
QByteArray QTimeZonePrivate::olsenIdToWindowsId(const QByteArray &id)
|
||||
QByteArray QTimeZonePrivate::ianaIdToWindowsId(const QByteArray &id)
|
||||
{
|
||||
for (int i = 0; i < zoneDataTableSize; ++i) {
|
||||
const QZoneData *data = zoneData(i);
|
||||
@ -487,7 +491,7 @@ QByteArray QTimeZonePrivate::olsenIdToWindowsId(const QByteArray &id)
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray QTimeZonePrivate::windowsIdToDefaultOlsenId(const QByteArray &windowsId)
|
||||
QByteArray QTimeZonePrivate::windowsIdToDefaultIanaId(const QByteArray &windowsId)
|
||||
{
|
||||
const quint16 windowsIdKey = toWindowsIdKey(windowsId);
|
||||
for (int i = 0; i < windowsDataTableSize; ++i) {
|
||||
@ -498,17 +502,17 @@ QByteArray QTimeZonePrivate::windowsIdToDefaultOlsenId(const QByteArray &windows
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray QTimeZonePrivate::windowsIdToDefaultOlsenId(const QByteArray &windowsId,
|
||||
QByteArray QTimeZonePrivate::windowsIdToDefaultIanaId(const QByteArray &windowsId,
|
||||
QLocale::Country country)
|
||||
{
|
||||
const QList<QByteArray> list = windowsIdToOlsenIds(windowsId, country);
|
||||
const QList<QByteArray> list = windowsIdToIanaIds(windowsId, country);
|
||||
if (list.count() > 0)
|
||||
return list.first();
|
||||
else
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QList<QByteArray> QTimeZonePrivate::windowsIdToOlsenIds(const QByteArray &windowsId)
|
||||
QList<QByteArray> QTimeZonePrivate::windowsIdToIanaIds(const QByteArray &windowsId)
|
||||
{
|
||||
const quint16 windowsIdKey = toWindowsIdKey(windowsId);
|
||||
QList<QByteArray> list;
|
||||
@ -524,7 +528,7 @@ QList<QByteArray> QTimeZonePrivate::windowsIdToOlsenIds(const QByteArray &window
|
||||
return list;
|
||||
}
|
||||
|
||||
QList<QByteArray> QTimeZonePrivate::windowsIdToOlsenIds(const QByteArray &windowsId,
|
||||
QList<QByteArray> QTimeZonePrivate::windowsIdToIanaIds(const QByteArray &windowsId,
|
||||
QLocale::Country country)
|
||||
{
|
||||
const quint16 windowsIdKey = toWindowsIdKey(windowsId);
|
||||
|
@ -146,12 +146,12 @@ public:
|
||||
static bool isValidId(const QByteArray &olsenId);
|
||||
static QString isoOffsetFormat(int offsetFromUtc);
|
||||
|
||||
static QByteArray olsenIdToWindowsId(const QByteArray &olsenId);
|
||||
static QByteArray windowsIdToDefaultOlsenId(const QByteArray &windowsId);
|
||||
static QByteArray windowsIdToDefaultOlsenId(const QByteArray &windowsId,
|
||||
static QByteArray ianaIdToWindowsId(const QByteArray &ianaId);
|
||||
static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId);
|
||||
static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId,
|
||||
QLocale::Country country);
|
||||
static QList<QByteArray> windowsIdToOlsenIds(const QByteArray &windowsId);
|
||||
static QList<QByteArray> windowsIdToOlsenIds(const QByteArray &windowsId,
|
||||
static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId);
|
||||
static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId,
|
||||
QLocale::Country country);
|
||||
|
||||
protected:
|
||||
@ -309,6 +309,7 @@ private:
|
||||
bool operator==(const QTzTransitionRule &other) { return (stdOffset == other.stdOffset
|
||||
&& dstOffset == other.dstOffset && abbreviationIndex == other.abbreviationIndex); }
|
||||
};
|
||||
Data dataForTzTransition(QTzTransitionTime tran) const;
|
||||
QList<QTzTransitionTime> m_tranTimes;
|
||||
QList<QTzTransitionRule> m_tranRules;
|
||||
QList<QByteArray> m_abbreviations;
|
||||
|
@ -149,11 +149,13 @@ static QTzHeader parseTzHeader(QDataStream &ds, bool *ok)
|
||||
if (memcmp(hdr.tzh_magic, TZ_MAGIC, 4) != 0 || ds.status() != QDataStream::Ok)
|
||||
return hdr;
|
||||
|
||||
// Parse Version, 1 byte, before 2005 was '\0', since 2005 a '2'
|
||||
// Parse Version, 1 byte, before 2005 was '\0', since 2005 a '2', since 2013 a '3'
|
||||
ds >> ch;
|
||||
hdr.tzh_version = ch;
|
||||
if (ds.status() != QDataStream::Ok || (hdr.tzh_version != '2' && hdr.tzh_version != '\0'))
|
||||
if (ds.status() != QDataStream::Ok
|
||||
|| (hdr.tzh_version != '2' && hdr.tzh_version != '\0' && hdr.tzh_version != '3')) {
|
||||
return hdr;
|
||||
}
|
||||
|
||||
// Parse reserved space, 15 bytes
|
||||
ds.readRawData(hdr.tzh_reserved, 15);
|
||||
@ -238,30 +240,31 @@ static QList<QTzType> parseTzTypes(QDataStream &ds, int tzh_typecnt)
|
||||
return typeList;
|
||||
}
|
||||
|
||||
static QMap<int, QByteArray> parseTzAbbreviations(QDataStream &ds, int tzh_charcnt)
|
||||
static QMap<int, QByteArray> parseTzAbbreviations(QDataStream &ds, int tzh_charcnt, QList<QTzType> typeList)
|
||||
{
|
||||
// Parse the abbreviation list which is tzh_charcnt long with '\0' separated strings. The
|
||||
// tz_abbrind index points to the first char of the abbreviation in the array, not the
|
||||
// occurrence in the list. By parsing char at a time we can track the char index and convert
|
||||
// to an occurrence index. By using a map with tz_abbrind as ordered key we get both index
|
||||
// QTzType.tz_abbrind index points to the first char of the abbreviation in the array, not the
|
||||
// occurrence in the list. It can also point to a partial string so we need to use the actual typeList
|
||||
// index values when parsing. By using a map with tz_abbrind as ordered key we get both index
|
||||
// methods in one data structure and can convert the types afterwards.
|
||||
QMap<int, QByteArray> map;
|
||||
quint8 ch;
|
||||
QByteArray abbrev;
|
||||
// Track the start position of each abbreviation
|
||||
int tz_abbrind = 0;
|
||||
QByteArray input;
|
||||
// First parse the full abbrev string
|
||||
for (int i = 0; i < tzh_charcnt && ds.status() == QDataStream::Ok; ++i) {
|
||||
ds >> ch;
|
||||
if (ds.status() == QDataStream::Ok) {
|
||||
if (ch == '\0') {
|
||||
// Have reached end of an abbreviation, so add to map
|
||||
map[tz_abbrind] = abbrev;
|
||||
tz_abbrind = i + 1;
|
||||
abbrev.clear();
|
||||
} else {
|
||||
abbrev.append((char)ch);
|
||||
}
|
||||
}
|
||||
if (ds.status() == QDataStream::Ok)
|
||||
input.append(char(ch));
|
||||
else
|
||||
return map;
|
||||
}
|
||||
// Then extract all the substrings pointed to by typeList
|
||||
foreach (const QTzType type, typeList) {
|
||||
QByteArray abbrev;
|
||||
for (int i = type.tz_abbrind; input.at(i) != '\0'; ++i)
|
||||
abbrev.append(input.at(i));
|
||||
// Have reached end of an abbreviation, so add to map
|
||||
map[type.tz_abbrind] = abbrev;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@ -371,7 +374,7 @@ static QDate calculatePosixDate(const QByteArray dateRule, int year)
|
||||
}
|
||||
}
|
||||
|
||||
static QTime parsePosixTime(const QByteArray timeRule)
|
||||
static QTime parsePosixTime(const QByteArray &timeRule)
|
||||
{
|
||||
// Format "HH:mm:ss", put check parts count just in case
|
||||
QList<QByteArray> parts = timeRule.split(':');
|
||||
@ -385,7 +388,7 @@ static QTime parsePosixTime(const QByteArray timeRule)
|
||||
return QTime(2, 0, 0);
|
||||
}
|
||||
|
||||
static int parsePosixOffset(const QByteArray timeRule)
|
||||
static int parsePosixOffset(const QByteArray &timeRule)
|
||||
{
|
||||
// Format "[+|-]hh[:mm[:ss]]"
|
||||
QList<QByteArray> parts = timeRule.split(':');
|
||||
@ -399,7 +402,9 @@ static int parsePosixOffset(const QByteArray timeRule)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray &posixRule, int startYear, int endYear)
|
||||
static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray &posixRule,
|
||||
int startYear, int endYear,
|
||||
int lastTranMSecs)
|
||||
{
|
||||
QList<QTimeZonePrivate::Data> list;
|
||||
|
||||
@ -443,11 +448,13 @@ static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray
|
||||
// If only the name part then no transitions
|
||||
if (parts.count() == 1) {
|
||||
QTimeZonePrivate::Data data;
|
||||
data.atMSecsSinceEpoch = 0;
|
||||
data.atMSecsSinceEpoch = lastTranMSecs;
|
||||
data.offsetFromUtc = utcOffset;
|
||||
data.standardTimeOffset = utcOffset;
|
||||
data.daylightTimeOffset = 0;
|
||||
data.abbreviation = stdName;
|
||||
list << data;
|
||||
return list;
|
||||
}
|
||||
|
||||
// If not populated the total dst offset is 1 hour
|
||||
@ -572,7 +579,7 @@ void QTzTimeZonePrivate::init(const QByteArray &olsenId)
|
||||
QList<QTzType> typeList = parseTzTypes(ds, hdr.tzh_typecnt);
|
||||
if (ds.status() != QDataStream::Ok)
|
||||
return;
|
||||
QMap<int, QByteArray> abbrevMap = parseTzAbbreviations(ds, hdr.tzh_charcnt);
|
||||
QMap<int, QByteArray> abbrevMap = parseTzAbbreviations(ds, hdr.tzh_charcnt, typeList);
|
||||
if (ds.status() != QDataStream::Ok)
|
||||
return;
|
||||
parseTzLeapSeconds(ds, hdr.tzh_leapcnt, false);
|
||||
@ -583,7 +590,7 @@ void QTzTimeZonePrivate::init(const QByteArray &olsenId)
|
||||
return;
|
||||
|
||||
// If version 2 then parse the second block of data
|
||||
if (hdr.tzh_version == '2') {
|
||||
if (hdr.tzh_version == '2' || hdr.tzh_version == '3') {
|
||||
ok = false;
|
||||
QTzHeader hdr2 = parseTzHeader(ds, &ok);
|
||||
if (!ok || ds.status() != QDataStream::Ok)
|
||||
@ -594,7 +601,7 @@ void QTzTimeZonePrivate::init(const QByteArray &olsenId)
|
||||
typeList = parseTzTypes(ds, hdr2.tzh_typecnt);
|
||||
if (ds.status() != QDataStream::Ok)
|
||||
return;
|
||||
abbrevMap = parseTzAbbreviations(ds, hdr2.tzh_charcnt);
|
||||
abbrevMap = parseTzAbbreviations(ds, hdr2.tzh_charcnt, typeList);
|
||||
if (ds.status() != QDataStream::Ok)
|
||||
return;
|
||||
parseTzLeapSeconds(ds, hdr2.tzh_leapcnt, true);
|
||||
@ -682,12 +689,14 @@ QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
|
||||
if (!m_icu)
|
||||
m_icu = new QIcuTimeZonePrivate(m_id);
|
||||
// TODO small risk may not match if tran times differ due to outdated files
|
||||
return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
|
||||
// TODO Some valid TZ names are not valid ICU names, use translation table?
|
||||
if (m_icu->isValid())
|
||||
return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
|
||||
#else
|
||||
Q_UNUSED(nameType)
|
||||
Q_UNUSED(locale)
|
||||
return abbreviation(atMSecsSinceEpoch);
|
||||
#endif // QT_USE_ICU
|
||||
return abbreviation(atMSecsSinceEpoch);
|
||||
}
|
||||
|
||||
QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
|
||||
@ -698,19 +707,59 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
|
||||
if (!m_icu)
|
||||
m_icu = new QIcuTimeZonePrivate(m_id);
|
||||
// TODO small risk may not match if tran times differ due to outdated files
|
||||
return m_icu->displayName(timeType, nameType, locale);
|
||||
// TODO Some valid TZ names are not valid ICU names, use translation table?
|
||||
if (m_icu->isValid())
|
||||
return m_icu->displayName(timeType, nameType, locale);
|
||||
#else
|
||||
Q_UNUSED(timeType)
|
||||
Q_UNUSED(nameType)
|
||||
Q_UNUSED(locale)
|
||||
const int atMSecsSinceEpoch = QDateTime::currentMSecsSinceEpoch();
|
||||
QTimeZonePrivate::Data tran = data(atMSecsSinceEpoch);
|
||||
while ((timeType == QTimeZone::StandardTime && tran.daylightTimeOffset != 0)
|
||||
|| (timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset == 0)) {
|
||||
tran = nextTransition(tran.atMSecsSinceEpoch);
|
||||
}
|
||||
return tran.abbreviation;
|
||||
#endif // QT_USE_ICU
|
||||
// If no ICU available then have to use abbreviations instead
|
||||
// Abbreviations don't have GenericTime
|
||||
if (timeType == QTimeZone::GenericTime)
|
||||
timeType = QTimeZone::StandardTime;
|
||||
|
||||
// Get current tran, if valid and is what we want, then use it
|
||||
const qint64 currentMSecs = QDateTime::currentMSecsSinceEpoch();
|
||||
QTimeZonePrivate::Data tran = data(currentMSecs);
|
||||
if (tran.atMSecsSinceEpoch != invalidMSecs()
|
||||
&& ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
|
||||
|| (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0))) {
|
||||
return tran.abbreviation;
|
||||
}
|
||||
|
||||
// Otherwise get next tran and if valid and is what we want, then use it
|
||||
tran = nextTransition(currentMSecs);
|
||||
if (tran.atMSecsSinceEpoch != invalidMSecs()
|
||||
&& ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
|
||||
|| (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0))) {
|
||||
return tran.abbreviation;
|
||||
}
|
||||
|
||||
// Otherwise get prev tran and if valid and is what we want, then use it
|
||||
tran = previousTransition(currentMSecs);
|
||||
if (tran.atMSecsSinceEpoch != invalidMSecs())
|
||||
tran = previousTransition(tran.atMSecsSinceEpoch);
|
||||
if (tran.atMSecsSinceEpoch != invalidMSecs()
|
||||
&& ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
|
||||
|| (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0))) {
|
||||
return tran.abbreviation;
|
||||
}
|
||||
|
||||
// Otherwise is strange sequence, so work backwards through trans looking for first match, if any
|
||||
for (int i = m_tranTimes.size() - 1; i >= 0; --i) {
|
||||
if (m_tranTimes.at(i).atMSecsSinceEpoch <= currentMSecs) {
|
||||
tran = dataForTzTransition(m_tranTimes.at(i));
|
||||
if ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
|
||||
|| (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0)) {
|
||||
return tran.abbreviation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise if no match use current data
|
||||
return data(currentMSecs).abbreviation;
|
||||
}
|
||||
|
||||
QString QTzTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
|
||||
@ -749,35 +798,55 @@ bool QTzTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
|
||||
return (daylightTimeOffset(atMSecsSinceEpoch) != 0);
|
||||
}
|
||||
|
||||
QTimeZonePrivate::Data QTzTimeZonePrivate::dataForTzTransition(QTzTransitionTime tran) const
|
||||
{
|
||||
QTimeZonePrivate::Data data;
|
||||
data.atMSecsSinceEpoch = tran.atMSecsSinceEpoch;
|
||||
QTzTransitionRule rule = m_tranRules.at(tran.ruleIndex);
|
||||
data.standardTimeOffset = rule.stdOffset;
|
||||
data.daylightTimeOffset = rule.dstOffset;
|
||||
data.offsetFromUtc = rule.stdOffset + rule.dstOffset;
|
||||
data.abbreviation = QString::fromUtf8(m_abbreviations.at(rule.abbreviationIndex));
|
||||
return data;
|
||||
}
|
||||
|
||||
QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
|
||||
{
|
||||
QTimeZonePrivate::Data data = invalidData();
|
||||
int lastTran = m_tranTimes.size() - 1;
|
||||
int tran;
|
||||
for (tran = lastTran; tran > 0; --tran) {
|
||||
if (m_tranTimes.at(tran).atMSecsSinceEpoch <= forMSecsSinceEpoch)
|
||||
break;
|
||||
}
|
||||
// If after the last transition time then we need to use the posix rule if available
|
||||
if (tran >= lastTran && !m_posixRule.isEmpty()) {
|
||||
QDateTime dt = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch);
|
||||
int year = dt.date().year();
|
||||
QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, year + 1);
|
||||
for (int i = posixTrans.size() - 1; i > 0; --i) {
|
||||
// If the required time is after the last transition and we have a POSIX rule then use it
|
||||
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch
|
||||
&&!m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) {
|
||||
const int year = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch, Qt::UTC).date().year();
|
||||
const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0;
|
||||
QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1,
|
||||
year + 1, lastMSecs);
|
||||
for (int i = posixTrans.size() - 1; i >= 0; --i) {
|
||||
if (posixTrans.at(i).atMSecsSinceEpoch <= forMSecsSinceEpoch) {
|
||||
QTimeZonePrivate::Data data;
|
||||
data = posixTrans.at(i);
|
||||
data.atMSecsSinceEpoch = forMSecsSinceEpoch;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
data.atMSecsSinceEpoch = forMSecsSinceEpoch;
|
||||
QTzTransitionRule rule = m_tranRules.at(m_tranTimes.at(tran).ruleIndex);
|
||||
data.standardTimeOffset = rule.stdOffset;
|
||||
data.daylightTimeOffset = rule.dstOffset;
|
||||
data.offsetFromUtc = rule.stdOffset + rule.dstOffset;
|
||||
data.abbreviation = QString::fromUtf8(m_abbreviations.at(rule.abbreviationIndex));
|
||||
return data;
|
||||
|
||||
// Otherwise if we can find a valid tran then use its rule
|
||||
for (int i = m_tranTimes.size() - 1; i >= 0; --i) {
|
||||
if (m_tranTimes.at(i).atMSecsSinceEpoch <= forMSecsSinceEpoch) {
|
||||
Data data = dataForTzTransition(m_tranTimes.at(i));
|
||||
data.atMSecsSinceEpoch = forMSecsSinceEpoch;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise use the earliest transition we have
|
||||
if (m_tranTimes.size() > 0) {
|
||||
Data data = dataForTzTransition(m_tranTimes.at(0));
|
||||
data.atMSecsSinceEpoch = forMSecsSinceEpoch;
|
||||
return data;
|
||||
}
|
||||
|
||||
// Otherwise we have no rules, so probably an invalid tz, so return invalid data
|
||||
return invalidData();
|
||||
}
|
||||
|
||||
bool QTzTimeZonePrivate::hasTransitions() const
|
||||
@ -787,60 +856,54 @@ bool QTzTimeZonePrivate::hasTransitions() const
|
||||
|
||||
QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
|
||||
{
|
||||
int lastTran = m_tranTimes.size() - 1;
|
||||
int tran;
|
||||
for (tran = 0; tran < lastTran; ++tran) {
|
||||
if (m_tranTimes.at(tran).atMSecsSinceEpoch > afterMSecsSinceEpoch)
|
||||
break;
|
||||
}
|
||||
// If after the last transition time then we need to use the posix rule if available
|
||||
if (tran >= lastTran && !m_posixRule.isEmpty()) {
|
||||
QDateTime dt = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch);
|
||||
int year = dt.date().year();
|
||||
QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, year + 1);
|
||||
for (int i = 0; i < posixTrans.size() - 1; ++i) {
|
||||
// If the required time is after the last transition and we have a POSIX rule then use it
|
||||
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch
|
||||
&&!m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) {
|
||||
const int year = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch, Qt::UTC).date().year();
|
||||
const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0;
|
||||
QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1,
|
||||
year + 1, lastMSecs);
|
||||
for (int i = 0; i < posixTrans.size(); ++i) {
|
||||
if (posixTrans.at(i).atMSecsSinceEpoch > afterMSecsSinceEpoch)
|
||||
return posixTrans.at(i);
|
||||
}
|
||||
}
|
||||
// Otherwise use the transition we found
|
||||
QTimeZonePrivate::Data data;
|
||||
data.atMSecsSinceEpoch = m_tranTimes.at(tran).atMSecsSinceEpoch;
|
||||
QTzTransitionRule rule = m_tranRules.at(m_tranTimes.at(tran).ruleIndex);
|
||||
data.standardTimeOffset = rule.stdOffset;
|
||||
data.daylightTimeOffset = rule.dstOffset;
|
||||
data.offsetFromUtc = rule.stdOffset + rule.dstOffset;
|
||||
data.abbreviation = QString::fromUtf8(m_abbreviations.at(rule.abbreviationIndex));
|
||||
return data;
|
||||
|
||||
// Otherwise if we can find a valid tran then use its rule
|
||||
for (int i = 0; i < m_tranTimes.size(); ++i) {
|
||||
if (m_tranTimes.at(i).atMSecsSinceEpoch > afterMSecsSinceEpoch) {
|
||||
return dataForTzTransition(m_tranTimes.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise we have no rule, or there is no next transition, so return invalid data
|
||||
return invalidData();
|
||||
}
|
||||
|
||||
QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
|
||||
{
|
||||
int lastTran = m_tranTimes.size() - 1;
|
||||
int tran;
|
||||
for (tran = lastTran; tran > 0; --tran) {
|
||||
if (m_tranTimes.at(tran).atMSecsSinceEpoch < beforeMSecsSinceEpoch)
|
||||
break;
|
||||
}
|
||||
// If after the last transition time then we need to use the posix rule if available
|
||||
if (tran >= lastTran && !m_posixRule.isEmpty()) {
|
||||
QDateTime dt = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch);
|
||||
int year = dt.date().year();
|
||||
QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, year + 1);
|
||||
for (int i = posixTrans.size() - 1; i > 0; --i) {
|
||||
// If the required time is after the last transition and we have a POSIX rule then use it
|
||||
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch
|
||||
&&!m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) {
|
||||
const int year = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch, Qt::UTC).date().year();
|
||||
const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0;
|
||||
QList<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1,
|
||||
year + 1, lastMSecs);
|
||||
for (int i = posixTrans.size() - 1; i >= 0; --i) {
|
||||
if (posixTrans.at(i).atMSecsSinceEpoch < beforeMSecsSinceEpoch)
|
||||
return posixTrans.at(i);
|
||||
}
|
||||
}
|
||||
// Otherwise use the transition we found
|
||||
QTimeZonePrivate::Data data;
|
||||
data.atMSecsSinceEpoch = m_tranTimes.at(tran).atMSecsSinceEpoch;
|
||||
QTzTransitionRule rule = m_tranRules.at(m_tranTimes.at(tran).ruleIndex);
|
||||
data.standardTimeOffset = rule.stdOffset;
|
||||
data.daylightTimeOffset = rule.dstOffset;
|
||||
data.offsetFromUtc = rule.stdOffset + rule.dstOffset;
|
||||
data.abbreviation = QString::fromUtf8(m_abbreviations.at(rule.abbreviationIndex));
|
||||
return data;
|
||||
|
||||
// Otherwise if we can find a valid tran then use its rule
|
||||
for (int i = m_tranTimes.size() - 1; i >= 0; --i) {
|
||||
if (m_tranTimes.at(i).atMSecsSinceEpoch < beforeMSecsSinceEpoch) {
|
||||
return dataForTzTransition(m_tranTimes.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise we have no rule, so return invalid data
|
||||
return invalidData();
|
||||
}
|
||||
|
||||
// TODO Could cache the value and monitor the required files for any changes
|
||||
|
@ -305,7 +305,7 @@ static void calculateTransitionsForYear(const QWinTimeZonePrivate::QWinTransitio
|
||||
QDate daylightDate = calculateTransitionLocalDate(rule.daylightTimeRule, year);
|
||||
QTime daylightTime = QTime(rule.daylightTimeRule.wHour, rule.daylightTimeRule.wMinute,
|
||||
rule.daylightTimeRule.wSecond);
|
||||
if (standardDate.isValid() && standardTime.isValid())
|
||||
if (daylightDate.isValid() && daylightTime.isValid())
|
||||
*dstMSecs = timeToMSecs(daylightDate, daylightTime) + (rule.standardTimeBias * 60000);
|
||||
else
|
||||
*dstMSecs = QTimeZonePrivate::invalidMSecs();
|
||||
@ -362,7 +362,7 @@ void QWinTimeZonePrivate::init(const QByteArray &olsenId)
|
||||
m_windowsId = windowsSystemZoneId();
|
||||
m_id = systemTimeZoneId();
|
||||
} else {
|
||||
m_windowsId = olsenIdToWindowsId(olsenId);
|
||||
m_windowsId = ianaIdToWindowsId(olsenId);
|
||||
m_id = olsenId;
|
||||
}
|
||||
|
||||
@ -488,6 +488,9 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
|
||||
do {
|
||||
// Convert the transition rules into msecs for the year we want to try
|
||||
rule = ruleForYear(year);
|
||||
// If no transition rules to calculate then no DST, so just use rule for std
|
||||
if (rule.standardTimeRule.wMonth == 0 && rule.daylightTimeRule.wMonth == 0)
|
||||
break;
|
||||
calculateTransitionsForYear(rule, year, &stdMSecs, &dstMSecs);
|
||||
if (stdMSecs < dstMSecs) {
|
||||
first = stdMSecs;
|
||||
@ -543,6 +546,9 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
|
||||
do {
|
||||
// Convert the transition rules into msecs for the year we want to try
|
||||
rule = ruleForYear(year);
|
||||
// If no transition rules to calculate then no next transition
|
||||
if (rule.standardTimeRule.wMonth == 0 && rule.daylightTimeRule.wMonth == 0)
|
||||
return invalidData();
|
||||
calculateTransitionsForYear(rule, year, &stdMSecs, &dstMSecs);
|
||||
// Find the first and second transition for the year
|
||||
if (stdMSecs < dstMSecs) {
|
||||
@ -591,6 +597,9 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
|
||||
do {
|
||||
// Convert the transition rules into msecs for the year we want to try
|
||||
rule = ruleForYear(year);
|
||||
// If no transition rules to calculate then no previous transition
|
||||
if (rule.standardTimeRule.wMonth == 0 && rule.daylightTimeRule.wMonth == 0)
|
||||
return invalidData();
|
||||
calculateTransitionsForYear(rule, year, &stdMSecs, &dstMSecs);
|
||||
if (stdMSecs < dstMSecs) {
|
||||
first = stdMSecs;
|
||||
@ -620,10 +629,10 @@ QByteArray QWinTimeZonePrivate::systemTimeZoneId() const
|
||||
QByteArray olsenId;
|
||||
// If we have a real country, then try get a specific match for that country
|
||||
if (country != QLocale::AnyCountry)
|
||||
olsenId = windowsIdToDefaultOlsenId(windowsId, country);
|
||||
olsenId = windowsIdToDefaultIanaId(windowsId, country);
|
||||
// If we don't have a real country, or there wasn't a specific match, try the global default
|
||||
if (olsenId.isEmpty()) {
|
||||
olsenId = windowsIdToDefaultOlsenId(windowsId);
|
||||
olsenId = windowsIdToDefaultIanaId(windowsId);
|
||||
// If no global default then probably an unknown Windows ID so return UTC
|
||||
if (olsenId.isEmpty())
|
||||
return QByteArrayLiteral("UTC");
|
||||
@ -635,7 +644,7 @@ QSet<QByteArray> QWinTimeZonePrivate::availableTimeZoneIds() const
|
||||
{
|
||||
QSet<QByteArray> set;
|
||||
foreach (const QByteArray &winId, availableWindowsIds()) {
|
||||
foreach (const QByteArray &olsenId, windowsIdToOlsenIds(winId))
|
||||
foreach (const QByteArray &olsenId, windowsIdToIanaIds(winId))
|
||||
set << olsenId;
|
||||
}
|
||||
return set;
|
||||
|
@ -364,6 +364,20 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::WindowState QPlatformIntegration::defaultWindowState(Qt::WindowFlags flags) const
|
||||
{
|
||||
// Leave popup-windows as is
|
||||
if (flags & Qt::Popup & ~Qt::Window)
|
||||
return Qt::WindowNoState;
|
||||
|
||||
if (styleHint(QPlatformIntegration::ShowIsFullScreen).toBool())
|
||||
return Qt::WindowFullScreen;
|
||||
else if (styleHint(QPlatformIntegration::ShowIsMaximized).toBool())
|
||||
return Qt::WindowMaximized;
|
||||
|
||||
return Qt::WindowNoState;
|
||||
}
|
||||
|
||||
Qt::KeyboardModifiers QPlatformIntegration::queryKeyboardModifiers() const
|
||||
{
|
||||
return QGuiApplication::keyboardModifiers();
|
||||
|
@ -152,6 +152,7 @@ public:
|
||||
};
|
||||
|
||||
virtual QVariant styleHint(StyleHint hint) const;
|
||||
virtual Qt::WindowState defaultWindowState(Qt::WindowFlags) const;
|
||||
|
||||
virtual Qt::KeyboardModifiers queryKeyboardModifiers() const;
|
||||
virtual QList<int> possibleKeys(const QKeyEvent *) const;
|
||||
|
@ -176,6 +176,9 @@ int QStyleHints::cursorFlashTime() const
|
||||
Returns \c true if the platform defaults to windows being fullscreen,
|
||||
otherwise \c false.
|
||||
|
||||
\note The platform may still choose to show certain windows non-fullscreen,
|
||||
such as popups or dialogs. This method only returns the default behavior.
|
||||
|
||||
\sa QWindow::show()
|
||||
*/
|
||||
bool QStyleHints::showIsFullScreen() const
|
||||
|
@ -1651,18 +1651,17 @@ QObject *QWindow::focusObject() const
|
||||
/*!
|
||||
Shows the window.
|
||||
|
||||
This equivalent to calling showFullScreen() or showNormal(), depending
|
||||
on whether the platform defaults to windows being fullscreen or not, and
|
||||
whether the window is a popup.
|
||||
This is equivalent to calling showFullScreen(), showMaximized(), or showNormal(),
|
||||
depending on the platform's default behavior for the window type and flags.
|
||||
|
||||
\sa showFullScreen(), showNormal(), hide(), QStyleHints::showIsFullScreen(), flags()
|
||||
\sa showFullScreen(), showMaximized(), showNormal(), hide(), QStyleHints::showIsFullScreen(), flags()
|
||||
*/
|
||||
void QWindow::show()
|
||||
{
|
||||
bool isPopup = d_func()->windowFlags & Qt::Popup & ~Qt::Window;
|
||||
if (!isPopup && qApp->styleHints()->showIsFullScreen())
|
||||
Qt::WindowState defaultState = QGuiApplicationPrivate::platformIntegration()->defaultWindowState(d_func()->windowFlags);
|
||||
if (defaultState == Qt::WindowFullScreen)
|
||||
showFullScreen();
|
||||
else if (!isPopup && !(d_func()->windowFlags & Qt::Dialog & ~Qt::Window) && QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ShowIsMaximized).toBool())
|
||||
else if (defaultState == Qt::WindowMaximized)
|
||||
showMaximized();
|
||||
else
|
||||
showNormal();
|
||||
|
@ -146,17 +146,16 @@ static inline uint line_emulation(uint emulation)
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
static bool qt_painter_thread_test(int devType, const char *what, bool extraCondition = false)
|
||||
static bool qt_painter_thread_test(int devType, const char *what)
|
||||
{
|
||||
switch (devType) {
|
||||
case QInternal::Image:
|
||||
case QInternal::Printer:
|
||||
case QInternal::Picture:
|
||||
// can be drawn onto these devices safely from any thread
|
||||
if (extraCondition)
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
if (!extraCondition && QThread::currentThread() != qApp->thread()) {
|
||||
if (QThread::currentThread() != qApp->thread()) {
|
||||
qWarning("QPainter: It is not safe to use %s outside the GUI thread", what);
|
||||
return false;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
@ -691,7 +692,7 @@ static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state
|
||||
{
|
||||
m_activityActive = (state == Qt::ApplicationActive);
|
||||
|
||||
if (!m_androidPlatformIntegration)
|
||||
if (!m_androidPlatformIntegration || !QGuiApplicationPrivate::platformIntegration())
|
||||
return;
|
||||
|
||||
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state));
|
||||
|
@ -242,6 +242,15 @@ QVariant QAndroidPlatformIntegration::styleHint(StyleHint hint) const
|
||||
}
|
||||
}
|
||||
|
||||
Qt::WindowState QAndroidPlatformIntegration::defaultWindowState(Qt::WindowFlags flags) const
|
||||
{
|
||||
// Don't maximize dialogs on Android
|
||||
if (flags & Qt::Dialog & ~Qt::Window)
|
||||
return Qt::WindowNoState;
|
||||
|
||||
return QPlatformIntegration::defaultWindowState(flags);
|
||||
}
|
||||
|
||||
static const QLatin1String androidThemeName("android");
|
||||
QStringList QAndroidPlatformIntegration::themeNames() const
|
||||
{
|
||||
|
@ -121,6 +121,7 @@ public:
|
||||
#endif
|
||||
|
||||
QVariant styleHint(StyleHint hint) const;
|
||||
Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const Q_DECL_OVERRIDE;
|
||||
|
||||
QStringList themeNames() const;
|
||||
QPlatformTheme *createPlatformTheme(const QString &name) const;
|
||||
|
@ -125,7 +125,7 @@ const QFont *QAndroidPlatformTheme::font(Font type) const
|
||||
return &(it.value());
|
||||
|
||||
// default in case the style has not set a font
|
||||
static QFont systemFont("Roboto", 12.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi
|
||||
static QFont systemFont("Roboto", 14.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi
|
||||
if (type == QPlatformTheme::SystemFont)
|
||||
return &systemFont;
|
||||
return 0;
|
||||
|
@ -175,6 +175,7 @@ void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)
|
||||
if (newParentWindow == NULL) {
|
||||
m_window = NULL;
|
||||
} else {
|
||||
newParentWindow->create();
|
||||
m_window = static_cast<QCocoaWindow*>(newParentWindow->handle());
|
||||
m_window->setMenubar(this);
|
||||
}
|
||||
|
@ -465,8 +465,10 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
|
||||
{
|
||||
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
|
||||
NSInteger styleMask = NSBorderlessWindowMask;
|
||||
if (flags & Qt::FramelessWindowHint)
|
||||
return styleMask;
|
||||
if ((type & Qt::Popup) == Qt::Popup) {
|
||||
if (!windowIsPopupType(type) && !(flags & Qt::FramelessWindowHint))
|
||||
if (!windowIsPopupType(type))
|
||||
styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask |
|
||||
NSMiniaturizableWindowMask | NSTitledWindowMask);
|
||||
} else {
|
||||
@ -485,7 +487,7 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
|
||||
} else {
|
||||
styleMask = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask;
|
||||
}
|
||||
} else if (!(flags & Qt::FramelessWindowHint)) {
|
||||
} else {
|
||||
if (flags & Qt::WindowMaximizeButtonHint)
|
||||
styleMask |= NSResizableWindowMask;
|
||||
if (flags & Qt::WindowTitleHint)
|
||||
|
@ -58,6 +58,25 @@
|
||||
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
|
||||
self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease];
|
||||
|
||||
#if QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_7_0)
|
||||
QSysInfo::MacVersion iosVersion = QSysInfo::MacintoshVersion;
|
||||
|
||||
// We prefer to keep the root viewcontroller in fullscreen layout, so that
|
||||
// we don't have to compensate for the viewcontroller position. This also
|
||||
// gives us the same behavior on iOS 5/6 as on iOS 7, where full screen layout
|
||||
// is the only way.
|
||||
if (iosVersion < QSysInfo::MV_IOS_7_0)
|
||||
self.window.rootViewController.wantsFullScreenLayout = YES;
|
||||
|
||||
// Use translucent statusbar by default on iOS6 iPhones (unless the user changed
|
||||
// the default in the Info.plist), so that windows placed under the stausbar are
|
||||
// still visible, just like on iOS7.
|
||||
if (iosVersion >= QSysInfo::MV_IOS_6_0 && iosVersion < QSysInfo::MV_IOS_7_0
|
||||
&& [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone
|
||||
&& [UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleDefault)
|
||||
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent];
|
||||
#endif
|
||||
|
||||
self.window.hidden = NO;
|
||||
|
||||
return YES;
|
||||
|
@ -56,6 +56,9 @@ QIOSBackingStore::QIOSBackingStore(QWindow *window)
|
||||
fmt.setDepthBufferSize(16);
|
||||
fmt.setStencilBufferSize(8);
|
||||
|
||||
// Needed to prevent QOpenGLContext::makeCurrent() from failing
|
||||
window->setSurfaceType(QSurface::OpenGLSurface);
|
||||
|
||||
m_context->setFormat(fmt);
|
||||
m_context->setScreen(window->screen());
|
||||
m_context->create();
|
||||
@ -69,9 +72,6 @@ QIOSBackingStore::~QIOSBackingStore()
|
||||
|
||||
void QIOSBackingStore::beginPaint(const QRegion &)
|
||||
{
|
||||
// Needed to prevent QOpenGLContext::makeCurrent() from failing
|
||||
window()->setSurfaceType(QSurface::OpenGLSurface);
|
||||
|
||||
m_context->makeCurrent(window());
|
||||
|
||||
QIOSWindow *iosWindow = static_cast<QIOSWindow *>(window()->handle());
|
||||
@ -102,6 +102,8 @@ void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin
|
||||
// the child window overlaps a sibling window that's draws using a separate QOpenGLContext.
|
||||
return;
|
||||
}
|
||||
|
||||
m_context->makeCurrent(window);
|
||||
m_context->swapBuffers(window);
|
||||
}
|
||||
|
||||
@ -115,7 +117,7 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents)
|
||||
// backing store and always keep the paint device's size in sync with the
|
||||
// window size in beginPaint().
|
||||
|
||||
if (size != window()->size())
|
||||
if (size != window()->size() && !window()->inherits("QWidgetWindow"))
|
||||
qWarning() << "QIOSBackingStore needs to have the same size as its window";
|
||||
}
|
||||
|
||||
|
@ -53,10 +53,11 @@ class QPlatformScreen;
|
||||
|
||||
bool isQtApplication();
|
||||
|
||||
CGRect toCGRect(const QRect &rect);
|
||||
QRect fromCGRect(const CGRect &rect);
|
||||
CGPoint toCGPoint(const QPoint &point);
|
||||
QPoint fromCGPoint(const CGPoint &point);
|
||||
CGRect toCGRect(const QRectF &rect);
|
||||
QRectF fromCGRect(const CGRect &rect);
|
||||
CGPoint toCGPoint(const QPointF &point);
|
||||
QPointF fromCGPoint(const CGPoint &point);
|
||||
|
||||
Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation);
|
||||
UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation);
|
||||
QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen);
|
||||
|
@ -58,24 +58,24 @@ bool isQtApplication()
|
||||
return isQt;
|
||||
}
|
||||
|
||||
CGRect toCGRect(const QRect &rect)
|
||||
CGRect toCGRect(const QRectF &rect)
|
||||
{
|
||||
return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
|
||||
}
|
||||
|
||||
QRect fromCGRect(const CGRect &rect)
|
||||
QRectF fromCGRect(const CGRect &rect)
|
||||
{
|
||||
return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
|
||||
return QRectF(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
|
||||
}
|
||||
|
||||
CGPoint toCGPoint(const QPoint &point)
|
||||
CGPoint toCGPoint(const QPointF &point)
|
||||
{
|
||||
return CGPointMake(point.x(), point.y());
|
||||
}
|
||||
|
||||
QPoint fromCGPoint(const CGPoint &point)
|
||||
QPointF fromCGPoint(const CGPoint &point)
|
||||
{
|
||||
return QPoint(point.x, point.y);
|
||||
return QPointF(point.x, point.y);
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation)
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
#include <UIKit/UIKit.h>
|
||||
|
||||
#include <QtGui/qtransform.h>
|
||||
#include <qpa/qplatforminputcontext.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -60,13 +61,17 @@ public:
|
||||
void showInputPanel();
|
||||
void hideInputPanel();
|
||||
bool isInputPanelVisible() const;
|
||||
void setFocusObject(QObject *object);
|
||||
|
||||
void focusViewChanged(UIView *view);
|
||||
void focusWindowChanged(QWindow *focusWindow);
|
||||
void scrollRootView();
|
||||
|
||||
private:
|
||||
QIOSKeyboardListener *m_keyboardListener;
|
||||
UIView *m_focusView;
|
||||
UIView<UIKeyInput> *m_focusView;
|
||||
QTransform m_inputItemTransform;
|
||||
bool m_hasPendingHideRequest;
|
||||
bool m_inSetFocusObject;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -48,7 +48,12 @@
|
||||
@public
|
||||
QIOSInputContext *m_context;
|
||||
BOOL m_keyboardVisible;
|
||||
BOOL m_keyboardVisibleAndDocked;
|
||||
QRectF m_keyboardRect;
|
||||
QRectF m_keyboardEndRect;
|
||||
NSTimeInterval m_duration;
|
||||
UIViewAnimationCurve m_curve;
|
||||
UIViewController *m_viewController;
|
||||
}
|
||||
@end
|
||||
|
||||
@ -60,8 +65,30 @@
|
||||
if (self) {
|
||||
m_context = context;
|
||||
m_keyboardVisible = NO;
|
||||
// After the keyboard became undockable (iOS5), UIKeyboardWillShow/UIKeyboardWillHide
|
||||
// no longer works for all cases. So listen to keyboard frame changes instead:
|
||||
m_keyboardVisibleAndDocked = NO;
|
||||
m_duration = 0;
|
||||
m_curve = UIViewAnimationCurveEaseOut;
|
||||
m_viewController = 0;
|
||||
|
||||
if (isQtApplication()) {
|
||||
// Get the root view controller that is on the same screen as the keyboard:
|
||||
for (UIWindow *uiWindow in [[UIApplication sharedApplication] windows]) {
|
||||
if (uiWindow.screen == [UIScreen mainScreen]) {
|
||||
m_viewController = [uiWindow.rootViewController retain];
|
||||
break;
|
||||
}
|
||||
}
|
||||
Q_ASSERT(m_viewController);
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(keyboardWillShow:)
|
||||
name:@"UIKeyboardWillShowNotification" object:nil];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(keyboardWillHide:)
|
||||
name:@"UIKeyboardWillHideNotification" object:nil];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(keyboardDidChangeFrame:)
|
||||
@ -72,25 +99,68 @@
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[m_viewController release];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
removeObserver:self
|
||||
name:@"UIKeyboardWillShowNotification" object:nil];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
removeObserver:self
|
||||
name:@"UIKeyboardWillHideNotification" object:nil];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
removeObserver:self
|
||||
name:@"UIKeyboardDidChangeFrameNotification" object:nil];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (QRectF) getKeyboardRect:(NSNotification *)notification
|
||||
{
|
||||
// For Qt applications we rotate the keyboard rect to align with the screen
|
||||
// orientation (which is the interface orientation of the root view controller).
|
||||
// For hybrid apps we follow native behavior, and return the rect unmodified:
|
||||
CGRect keyboardFrame = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
||||
if (isQtApplication()) {
|
||||
UIView *view = m_viewController.view;
|
||||
return fromCGRect(CGRectOffset([view convertRect:keyboardFrame fromView:view.window], 0, -view.bounds.origin.y));
|
||||
} else {
|
||||
return fromCGRect(keyboardFrame);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) keyboardDidChangeFrame:(NSNotification *)notification
|
||||
{
|
||||
CGRect frame;
|
||||
[[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame];
|
||||
|
||||
m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame), QGuiApplication::primaryScreen()->handle());
|
||||
m_keyboardRect = [self getKeyboardRect:notification];
|
||||
m_context->emitKeyboardRectChanged();
|
||||
|
||||
BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds);
|
||||
BOOL visible = m_keyboardRect.intersects(fromCGRect([UIScreen mainScreen].bounds));
|
||||
if (m_keyboardVisible != visible) {
|
||||
m_keyboardVisible = visible;
|
||||
m_context->emitInputPanelVisibleChanged();
|
||||
}
|
||||
|
||||
// If the keyboard was visible and docked from before, this is just a geometry
|
||||
// change (normally caused by an orientation change). In that case, update scroll:
|
||||
if (m_keyboardVisibleAndDocked)
|
||||
m_context->scrollRootView();
|
||||
}
|
||||
|
||||
- (void) keyboardWillShow:(NSNotification *)notification
|
||||
{
|
||||
// Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked.
|
||||
m_keyboardVisibleAndDocked = YES;
|
||||
m_keyboardEndRect = [self getKeyboardRect:notification];
|
||||
if (!m_duration) {
|
||||
m_duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
|
||||
m_curve = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16;
|
||||
}
|
||||
m_context->scrollRootView();
|
||||
}
|
||||
|
||||
- (void) keyboardWillHide:(NSNotification *)notification
|
||||
{
|
||||
// Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked.
|
||||
m_keyboardVisibleAndDocked = NO;
|
||||
m_keyboardEndRect = [self getKeyboardRect:notification];
|
||||
m_context->scrollRootView();
|
||||
}
|
||||
|
||||
@end
|
||||
@ -100,7 +170,11 @@ QIOSInputContext::QIOSInputContext()
|
||||
, m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this])
|
||||
, m_focusView(0)
|
||||
, m_hasPendingHideRequest(false)
|
||||
, m_inSetFocusObject(false)
|
||||
{
|
||||
if (isQtApplication())
|
||||
connect(qGuiApp->inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QIOSInputContext::scrollRootView);
|
||||
connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSInputContext::focusWindowChanged);
|
||||
}
|
||||
|
||||
QIOSInputContext::~QIOSInputContext()
|
||||
@ -142,10 +216,76 @@ bool QIOSInputContext::isInputPanelVisible() const
|
||||
return m_keyboardListener->m_keyboardVisible;
|
||||
}
|
||||
|
||||
void QIOSInputContext::focusViewChanged(UIView *view)
|
||||
void QIOSInputContext::setFocusObject(QObject *)
|
||||
{
|
||||
m_inputItemTransform = qApp->inputMethod()->inputItemTransform();
|
||||
|
||||
if (!m_focusView || !m_focusView.isFirstResponder)
|
||||
return;
|
||||
|
||||
// Since m_focusView is the first responder, it means that the keyboard is open and we
|
||||
// should update keyboard layout. But there seem to be no way to tell it to reread the
|
||||
// UITextInputTraits from m_focusView. To work around that, we quickly resign first
|
||||
// responder status just to reassign it again. To not remove the focusObject in the same
|
||||
// go, we need to call the super implementation of resignFirstResponder. Since the call
|
||||
// will cause a 'keyboardWillHide' notification to be sendt, we also block scrollRootView
|
||||
// to avoid artifacts:
|
||||
m_inSetFocusObject = true;
|
||||
SEL sel = @selector(resignFirstResponder);
|
||||
[[m_focusView superclass] instanceMethodForSelector:sel](m_focusView, sel);
|
||||
m_inSetFocusObject = false;
|
||||
[m_focusView becomeFirstResponder];
|
||||
}
|
||||
|
||||
void QIOSInputContext::focusWindowChanged(QWindow *focusWindow)
|
||||
{
|
||||
UIView<UIKeyInput> *view = reinterpret_cast<UIView<UIKeyInput> *>(focusWindow->handle()->winId());
|
||||
if ([m_focusView isFirstResponder])
|
||||
[view becomeFirstResponder];
|
||||
[m_focusView release];
|
||||
m_focusView = [view retain];
|
||||
}
|
||||
|
||||
void QIOSInputContext::scrollRootView()
|
||||
{
|
||||
// Scroll the root view (screen) if:
|
||||
// - our backend controls the root view controller on the main screen (no hybrid app)
|
||||
// - the focus object is on the same screen as the keyboard.
|
||||
// - the first responder is a QUIView, and not some other foreign UIView.
|
||||
// - the keyboard is docked. Otherwise the user can move the keyboard instead.
|
||||
// - the inputItem has not been moved/scrolled
|
||||
if (!isQtApplication() || !m_focusView || m_inSetFocusObject)
|
||||
return;
|
||||
|
||||
if (m_inputItemTransform != qApp->inputMethod()->inputItemTransform()) {
|
||||
// The inputItem has moved since the last scroll update. To avoid competing
|
||||
// with the application where the cursor/inputItem should be, we bail:
|
||||
return;
|
||||
}
|
||||
|
||||
UIView *view = m_keyboardListener->m_viewController.view;
|
||||
qreal scrollTo = 0;
|
||||
|
||||
if (m_focusView.isFirstResponder
|
||||
&& m_keyboardListener->m_keyboardVisibleAndDocked
|
||||
&& m_focusView.window == view.window) {
|
||||
QRectF cursorRect = qGuiApp->inputMethod()->cursorRectangle();
|
||||
cursorRect.translate(qGuiApp->focusWindow()->geometry().topLeft());
|
||||
qreal keyboardY = m_keyboardListener->m_keyboardEndRect.y();
|
||||
int statusBarY = qGuiApp->primaryScreen()->availableGeometry().y();
|
||||
const int margin = 20;
|
||||
|
||||
if (cursorRect.bottomLeft().y() > keyboardY - margin)
|
||||
scrollTo = qMin(view.bounds.size.height - keyboardY, cursorRect.y() - statusBarY - margin);
|
||||
}
|
||||
|
||||
if (scrollTo != view.bounds.origin.y) {
|
||||
// Scroll the view the same way a UIScrollView works: by changing bounds.origin:
|
||||
CGRect newBounds = view.bounds;
|
||||
newBounds.origin.y = scrollTo;
|
||||
[UIView animateWithDuration:m_keyboardListener->m_duration delay:0
|
||||
options:m_keyboardListener->m_curve
|
||||
animations:^{ view.bounds = newBounds; }
|
||||
completion:0];
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ QPlatformServices *QIOSIntegration::services() const
|
||||
QVariant QIOSIntegration::styleHint(StyleHint hint) const
|
||||
{
|
||||
switch (hint) {
|
||||
case ShowIsFullScreen:
|
||||
case ShowIsMaximized:
|
||||
return true;
|
||||
case SetFocusOnTouchRelease:
|
||||
return true;
|
||||
|
@ -50,8 +50,10 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIOSScreen : public QPlatformScreen
|
||||
class QIOSScreen : public QObject, public QPlatformScreen
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QIOSScreen(unsigned int screenIndex);
|
||||
~QIOSScreen();
|
||||
@ -73,6 +75,10 @@ public:
|
||||
UIScreen *uiScreen() const;
|
||||
|
||||
void updateProperties();
|
||||
void layoutWindows();
|
||||
|
||||
public slots:
|
||||
void updateStatusBarVisibility();
|
||||
|
||||
private:
|
||||
UIScreen *m_uiScreen;
|
||||
|
@ -139,6 +139,8 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex)
|
||||
m_unscaledDpi = 163; // Regular iPhone DPI
|
||||
}
|
||||
|
||||
connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSScreen::updateStatusBarVisibility);
|
||||
|
||||
updateProperties();
|
||||
}
|
||||
|
||||
@ -156,7 +158,7 @@ void QIOSScreen::updateProperties()
|
||||
}
|
||||
|
||||
bool inPortrait = UIInterfaceOrientationIsPortrait(uiWindow.rootViewController.interfaceOrientation);
|
||||
QRect geometry = inPortrait ? fromCGRect(m_uiScreen.bounds)
|
||||
QRect geometry = inPortrait ? fromCGRect(m_uiScreen.bounds).toRect()
|
||||
: QRect(m_uiScreen.bounds.origin.x, m_uiScreen.bounds.origin.y,
|
||||
m_uiScreen.bounds.size.height, m_uiScreen.bounds.size.width);
|
||||
|
||||
@ -182,7 +184,66 @@ void QIOSScreen::updateProperties()
|
||||
}
|
||||
|
||||
if (screen())
|
||||
resizeMaximizedWindows();
|
||||
layoutWindows();
|
||||
}
|
||||
|
||||
void QIOSScreen::updateStatusBarVisibility()
|
||||
{
|
||||
QWindow *focusWindow = QGuiApplication::focusWindow();
|
||||
|
||||
// If we don't have a focus window we leave the status
|
||||
// bar as is, so that the user can activate a new window
|
||||
// with the same window state without the status bar jumping
|
||||
// back and forth.
|
||||
if (!focusWindow)
|
||||
return;
|
||||
|
||||
UIView *view = reinterpret_cast<UIView *>(focusWindow->handle()->winId());
|
||||
#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_7_0)
|
||||
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_7_0) {
|
||||
[view.viewController setNeedsStatusBarAppearanceUpdate];
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
bool wasHidden = [UIApplication sharedApplication].statusBarHidden;
|
||||
QIOSViewController *viewController = static_cast<QIOSViewController *>(view.viewController);
|
||||
[[UIApplication sharedApplication]
|
||||
setStatusBarHidden:[viewController prefersStatusBarHidden]
|
||||
withAnimation:UIStatusBarAnimationNone];
|
||||
|
||||
if ([UIApplication sharedApplication].statusBarHidden != wasHidden)
|
||||
updateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
void QIOSScreen::layoutWindows()
|
||||
{
|
||||
QList<QWindow*> windows = QGuiApplication::topLevelWindows();
|
||||
|
||||
const QRect oldGeometry = screen()->geometry();
|
||||
const QRect oldAvailableGeometry = screen()->availableGeometry();
|
||||
const QRect newGeometry = geometry();
|
||||
const QRect newAvailableGeometry = availableGeometry();
|
||||
|
||||
for (int i = 0; i < windows.size(); ++i) {
|
||||
QWindow *window = windows.at(i);
|
||||
|
||||
if (platformScreenForWindow(window) != this)
|
||||
continue;
|
||||
|
||||
QIOSWindow *platformWindow = static_cast<QIOSWindow *>(window->handle());
|
||||
if (!platformWindow)
|
||||
continue;
|
||||
|
||||
// FIXME: Handle more complex cases of no-state and/or child windows when rotating
|
||||
|
||||
if (window->windowState() & Qt::WindowFullScreen
|
||||
|| (window->windowState() & Qt::WindowNoState && window->geometry() == oldGeometry))
|
||||
platformWindow->applyGeometry(newGeometry);
|
||||
else if (window->windowState() & Qt::WindowMaximized
|
||||
|| (window->windowState() & Qt::WindowNoState && window->geometry() == oldAvailableGeometry))
|
||||
platformWindow->applyGeometry(newAvailableGeometry);
|
||||
}
|
||||
}
|
||||
|
||||
QRect QIOSScreen::geometry() const
|
||||
@ -247,4 +308,6 @@ UIScreen *QIOSScreen::uiScreen() const
|
||||
return m_uiScreen;
|
||||
}
|
||||
|
||||
#include "moc_qiosscreen.cpp"
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -42,5 +42,6 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface QIOSViewController : UIViewController
|
||||
- (BOOL)prefersStatusBarHidden;
|
||||
@end
|
||||
|
||||
|
@ -42,9 +42,11 @@
|
||||
#import "qiosviewcontroller.h"
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QScreen>
|
||||
#include "qiosscreen.h"
|
||||
#include "qiosglobal.h"
|
||||
#include "qioswindow.h"
|
||||
|
||||
@implementation QIOSViewController
|
||||
|
||||
@ -55,12 +57,22 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_6_0)
|
||||
-(NSUInteger)supportedInterfaceOrientations
|
||||
{
|
||||
// We need to tell iOS that we support all orientations in order to set
|
||||
// status bar orientation when application content orientation changes.
|
||||
return UIInterfaceOrientationMaskAll;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_6_0)
|
||||
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
Q_UNUSED(interfaceOrientation);
|
||||
return YES;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
|
||||
{
|
||||
@ -74,5 +86,28 @@
|
||||
qiosScreen->updateProperties();
|
||||
}
|
||||
|
||||
#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_7_0)
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
// Since we don't place anything behind the status bare by default, we
|
||||
// end up with a black area, so we have to enable the white text mode
|
||||
// of the iOS7 statusbar.
|
||||
return UIStatusBarStyleLightContent;
|
||||
|
||||
// FIXME: Try to detect the content underneath the statusbar and choose
|
||||
// an appropriate style, and/or expose Qt APIs to control the style.
|
||||
}
|
||||
#endif
|
||||
|
||||
- (BOOL)prefersStatusBarHidden
|
||||
{
|
||||
QWindow *focusWindow = QGuiApplication::focusWindow();
|
||||
if (!focusWindow)
|
||||
return [UIApplication sharedApplication].statusBarHidden;
|
||||
|
||||
QIOSWindow *topLevel = static_cast<QIOSWindow *>(focusWindow->handle())->topLevelWindow();
|
||||
return topLevel->window()->windowState() == Qt::WindowFullScreen;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
@ -85,7 +85,11 @@ public:
|
||||
|
||||
WId winId() const { return WId(m_view); };
|
||||
|
||||
QIOSWindow *topLevelWindow() const;
|
||||
|
||||
private:
|
||||
void applyGeometry(const QRect &rect);
|
||||
|
||||
QUIView *m_view;
|
||||
|
||||
QRect m_normalGeometry;
|
||||
@ -97,6 +101,8 @@ private:
|
||||
|
||||
inline Qt::WindowType windowType() { return static_cast<Qt::WindowType>(int(window()->flags() & Qt::WindowType_Mask)); }
|
||||
inline bool windowIsPopup() { return windowType() & Qt::Popup & ~Qt::Window; }
|
||||
|
||||
friend class QIOSScreen;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -105,18 +105,10 @@
|
||||
CAEAGLLayer *eaglLayer = static_cast<CAEAGLLayer *>(self.layer);
|
||||
eaglLayer.opaque = TRUE;
|
||||
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking,
|
||||
[NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,
|
||||
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
|
||||
|
||||
// Set up text input
|
||||
autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
enablesReturnKeyAutomatically = NO;
|
||||
keyboardAppearance = UIKeyboardAppearanceDefault;
|
||||
keyboardType = UIKeyboardTypeDefault;
|
||||
returnKeyType = UIReturnKeyDone;
|
||||
secureTextEntry = NO;
|
||||
m_nextTouchId = 0;
|
||||
[self updateTextInputTraits];
|
||||
|
||||
if (isQtApplication())
|
||||
self.hidden = YES;
|
||||
@ -153,6 +145,15 @@
|
||||
self.clipsToBounds = NO;
|
||||
}
|
||||
|
||||
- (void)setNeedsDisplay
|
||||
{
|
||||
[super setNeedsDisplay];
|
||||
|
||||
// We didn't implement drawRect: so we have to manually
|
||||
// mark the layer as needing display.
|
||||
[self.layer setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
// This method is the de facto way to know that view has been resized,
|
||||
@ -165,15 +166,53 @@
|
||||
qWarning() << m_qioswindow->window()
|
||||
<< "is backed by a UIView that has a transform set. This is not supported.";
|
||||
|
||||
QRect geometry = fromCGRect(self.frame);
|
||||
m_qioswindow->QPlatformWindow::setGeometry(geometry);
|
||||
QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry);
|
||||
QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), QRect(QPoint(), geometry.size()));
|
||||
// The original geometry requested by setGeometry() might be different
|
||||
// from what we end up with after applying window constraints.
|
||||
QRect requestedGeometry = m_qioswindow->geometry();
|
||||
|
||||
// If we have a new size here we need to resize the FBO's corresponding buffers,
|
||||
// but we defer that to when the application calls makeCurrent.
|
||||
QRect actualGeometry;
|
||||
if (m_qioswindow->window()->isTopLevel()) {
|
||||
UIWindow *uiWindow = self.window;
|
||||
UIView *rootView = uiWindow.rootViewController.view;
|
||||
CGRect rootViewPositionInRelationToRootViewController =
|
||||
[rootView convertRect:uiWindow.bounds fromView:uiWindow];
|
||||
|
||||
[super layoutSubviews];
|
||||
actualGeometry = fromCGRect(CGRectOffset([self.superview convertRect:self.frame toView:rootView],
|
||||
-rootViewPositionInRelationToRootViewController.origin.x,
|
||||
-rootViewPositionInRelationToRootViewController.origin.y
|
||||
+ rootView.bounds.origin.y)).toRect();
|
||||
} else {
|
||||
actualGeometry = fromCGRect(self.frame).toRect();
|
||||
}
|
||||
|
||||
// Persist the actual/new geometry so that QWindow::geometry() can
|
||||
// be queried on the resize event.
|
||||
m_qioswindow->QPlatformWindow::setGeometry(actualGeometry);
|
||||
|
||||
QRect previousGeometry = requestedGeometry != actualGeometry ?
|
||||
requestedGeometry : qt_window_private(m_qioswindow->window())->geometry;
|
||||
|
||||
QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), actualGeometry, previousGeometry);
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
|
||||
if (actualGeometry.size() != previousGeometry.size()) {
|
||||
// Trigger expose event on resize
|
||||
[self setNeedsDisplay];
|
||||
|
||||
// A new size means we also need to resize the FBO's corresponding buffers,
|
||||
// but we defer that to when the application calls makeCurrent.
|
||||
}
|
||||
}
|
||||
|
||||
- (void)displayLayer:(CALayer *)layer
|
||||
{
|
||||
QRect geometry = fromCGRect(layer.frame).toRect();
|
||||
Q_ASSERT(m_qioswindow->geometry() == geometry);
|
||||
Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible());
|
||||
|
||||
QRegion region = self.hidden ? QRegion() : QRect(QPoint(), geometry.size());
|
||||
QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region);
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
}
|
||||
|
||||
- (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state
|
||||
@ -195,7 +234,7 @@
|
||||
} else {
|
||||
touchPoint.state = state;
|
||||
touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0;
|
||||
QPoint touchPos = fromCGPoint([uiTouch locationInView:rootView]);
|
||||
QPoint touchPos = fromCGPoint([uiTouch locationInView:rootView]).toPoint();
|
||||
touchPoint.area = QRectF(touchPos, QSize(0, 0));
|
||||
touchPoint.normalPosition = QPointF(touchPos.x() / rootViewSize.width, touchPos.y() / rootViewSize.height);
|
||||
}
|
||||
@ -296,6 +335,7 @@
|
||||
// user cannot type. And since the keyboard will open when a view becomes
|
||||
// the first responder, it's now a good time to inform QPA that the QWindow
|
||||
// this view backs became active:
|
||||
[self updateTextInputTraits];
|
||||
QWindowSystemInterface::handleWindowActivated(m_qioswindow->window());
|
||||
return [super becomeFirstResponder];
|
||||
}
|
||||
@ -318,8 +358,11 @@
|
||||
{
|
||||
QString string = QString::fromUtf8([text UTF8String]);
|
||||
int key = 0;
|
||||
if ([text isEqualToString:@"\n"])
|
||||
if ([text isEqualToString:@"\n"]) {
|
||||
key = (int)Qt::Key_Return;
|
||||
if (self.returnKeyType == UIReturnKeyDone)
|
||||
[self resignFirstResponder];
|
||||
}
|
||||
|
||||
// Send key event to window system interface
|
||||
QWindowSystemInterface::handleKeyEvent(
|
||||
@ -337,6 +380,47 @@
|
||||
0, QEvent::KeyRelease, (int)Qt::Key_Backspace, Qt::NoModifier);
|
||||
}
|
||||
|
||||
- (void)updateTextInputTraits
|
||||
{
|
||||
// Ask the current focus object what kind of input it
|
||||
// expects, and configure the keyboard appropriately:
|
||||
QObject *focusObject = QGuiApplication::focusObject();
|
||||
if (!focusObject)
|
||||
return;
|
||||
QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints);
|
||||
if (!QCoreApplication::sendEvent(focusObject, &queryEvent))
|
||||
return;
|
||||
if (!queryEvent.value(Qt::ImEnabled).toBool())
|
||||
return;
|
||||
|
||||
Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryEvent.value(Qt::ImHints).toUInt());
|
||||
|
||||
self.returnKeyType = (hints & Qt::ImhMultiLine) ? UIReturnKeyDefault : UIReturnKeyDone;
|
||||
self.secureTextEntry = BOOL(hints & Qt::ImhHiddenText);
|
||||
self.autocorrectionType = (hints & Qt::ImhNoPredictiveText) ?
|
||||
UITextAutocorrectionTypeNo : UITextAutocorrectionTypeDefault;
|
||||
|
||||
if (hints & Qt::ImhUppercaseOnly)
|
||||
self.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
|
||||
else if (hints & Qt::ImhNoAutoUppercase)
|
||||
self.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
else
|
||||
self.autocapitalizationType = UITextAutocapitalizationTypeSentences;
|
||||
|
||||
if (hints & Qt::ImhUrlCharactersOnly)
|
||||
self.keyboardType = UIKeyboardTypeURL;
|
||||
else if (hints & Qt::ImhEmailCharactersOnly)
|
||||
self.keyboardType = UIKeyboardTypeEmailAddress;
|
||||
else if (hints & Qt::ImhDigitsOnly)
|
||||
self.keyboardType = UIKeyboardTypeNumberPad;
|
||||
else if (hints & Qt::ImhFormattedNumbersOnly)
|
||||
self.keyboardType = UIKeyboardTypeDecimalPad;
|
||||
else if (hints & Qt::ImhDialableCharactersOnly)
|
||||
self.keyboardType = UIKeyboardTypeNumberPad;
|
||||
else
|
||||
self.keyboardType = UIKeyboardTypeDefault;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIView (QIOS)
|
||||
@ -393,8 +477,8 @@ bool QIOSWindow::blockedByModal()
|
||||
|
||||
void QIOSWindow::setVisible(bool visible)
|
||||
{
|
||||
QPlatformWindow::setVisible(visible);
|
||||
m_view.hidden = !visible;
|
||||
[m_view setNeedsDisplay];
|
||||
|
||||
if (!isQtApplication())
|
||||
return;
|
||||
@ -412,6 +496,10 @@ void QIOSWindow::setVisible(bool visible)
|
||||
|
||||
if (visible) {
|
||||
requestActivateWindow();
|
||||
|
||||
if (window()->isTopLevel())
|
||||
static_cast<QIOSScreen *>(screen())->updateStatusBarVisibility();
|
||||
|
||||
} else {
|
||||
// Activate top-most visible QWindow:
|
||||
NSArray *subviews = m_view.viewController.view.subviews;
|
||||
@ -429,40 +517,90 @@ void QIOSWindow::setVisible(bool visible)
|
||||
|
||||
void QIOSWindow::setGeometry(const QRect &rect)
|
||||
{
|
||||
// If the window is in fullscreen, just bookkeep the requested
|
||||
// geometry in case the window goes into Qt::WindowNoState later:
|
||||
m_normalGeometry = rect;
|
||||
if (window()->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen))
|
||||
return;
|
||||
|
||||
// Since we don't support transformations on the UIView, we can set the frame
|
||||
// directly and let UIKit deal with translating that into bounds and center.
|
||||
// Changing the size of the view will end up in a call to -[QUIView layoutSubviews]
|
||||
// which will update QWindowSystemInterface with the new size.
|
||||
m_view.frame = toCGRect(rect);
|
||||
if (window()->windowState() != Qt::WindowNoState) {
|
||||
QPlatformWindow::setGeometry(rect);
|
||||
|
||||
// The layout will realize the requested geometry was not applied, and
|
||||
// send geometry-change events that match the actual geometry.
|
||||
[m_view setNeedsLayout];
|
||||
|
||||
if (window()->inherits("QWidgetWindow")) {
|
||||
// QWidget wrongly assumes that setGeometry resets the window
|
||||
// state back to Qt::NoWindowState, so we need to inform it that
|
||||
// that his is not the case by re-issuing the current window state.
|
||||
QWindowSystemInterface::handleWindowStateChanged(window(), window()->windowState());
|
||||
|
||||
// It also needs to be told immediately that the geometry it requested
|
||||
// did not apply, otherwise it will continue on as if it did, instead
|
||||
// of waiting for a resize event.
|
||||
[m_view layoutIfNeeded];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
applyGeometry(rect);
|
||||
}
|
||||
|
||||
void QIOSWindow::applyGeometry(const QRect &rect)
|
||||
{
|
||||
// Geometry changes are asynchronous, but QWindow::geometry() is
|
||||
// expected to report back the 'requested geometry' until we get
|
||||
// a callback with the updated geometry from the window system.
|
||||
// The baseclass takes care of persisting this for us.
|
||||
QPlatformWindow::setGeometry(rect);
|
||||
|
||||
if (window()->isTopLevel()) {
|
||||
// The QWindow is in QScreen coordinates, which maps to a possibly rotated root-view-controller.
|
||||
// Since the root-view-controller might be translated in relation to the UIWindow, we need to
|
||||
// check specifically for that and compensate. Also check if the root view has been scrolled
|
||||
// as a result of the keyboard being open.
|
||||
UIWindow *uiWindow = m_view.window;
|
||||
UIView *rootView = uiWindow.rootViewController.view;
|
||||
CGRect rootViewPositionInRelationToRootViewController =
|
||||
[rootView convertRect:uiWindow.bounds fromView:uiWindow];
|
||||
|
||||
m_view.frame = CGRectOffset([m_view.superview convertRect:toCGRect(rect) fromView:rootView],
|
||||
rootViewPositionInRelationToRootViewController.origin.x,
|
||||
rootViewPositionInRelationToRootViewController.origin.y
|
||||
+ rootView.bounds.origin.y);
|
||||
} else {
|
||||
// Easy, in parent's coordinates
|
||||
m_view.frame = toCGRect(rect);
|
||||
}
|
||||
|
||||
// iOS will automatically trigger -[layoutSubviews:] for resize,
|
||||
// but not for move, so we force it just in case.
|
||||
[m_view setNeedsLayout];
|
||||
|
||||
if (window()->inherits("QWidgetWindow"))
|
||||
[m_view layoutIfNeeded];
|
||||
}
|
||||
|
||||
void QIOSWindow::setWindowState(Qt::WindowState state)
|
||||
{
|
||||
// FIXME: Figure out where or how we should disable/enable the statusbar.
|
||||
// Perhaps setting QWindow to maximized should also mean that we'll show
|
||||
// the statusbar, and vice versa for fullscreen?
|
||||
// Update the QWindow representation straight away, so that
|
||||
// we can update the statusbar visibility based on the new
|
||||
// state before applying geometry changes.
|
||||
qt_window_private(window())->windowState = state;
|
||||
|
||||
if (state != Qt::WindowNoState)
|
||||
m_normalGeometry = geometry();
|
||||
if (window()->isTopLevel() && window()->isVisible() && window()->isActive())
|
||||
static_cast<QIOSScreen *>(screen())->updateStatusBarVisibility();
|
||||
|
||||
switch (state) {
|
||||
case Qt::WindowNoState:
|
||||
setGeometry(m_normalGeometry);
|
||||
applyGeometry(m_normalGeometry);
|
||||
break;
|
||||
case Qt::WindowMaximized:
|
||||
setGeometry(screen()->availableGeometry());
|
||||
applyGeometry(screen()->availableGeometry());
|
||||
break;
|
||||
case Qt::WindowFullScreen:
|
||||
setGeometry(screen()->geometry());
|
||||
applyGeometry(screen()->geometry());
|
||||
break;
|
||||
case Qt::WindowMinimized:
|
||||
setGeometry(QRect());
|
||||
applyGeometry(QRect());
|
||||
break;
|
||||
case Qt::WindowActive:
|
||||
Q_UNREACHABLE();
|
||||
@ -486,6 +624,23 @@ void QIOSWindow::setParent(const QPlatformWindow *parentWindow)
|
||||
}
|
||||
}
|
||||
|
||||
QIOSWindow *QIOSWindow::topLevelWindow() const
|
||||
{
|
||||
QWindow *window = this->window();
|
||||
while (window) {
|
||||
QWindow *parent = window->parent();
|
||||
if (!parent)
|
||||
parent = window->transientParent();
|
||||
|
||||
if (!parent)
|
||||
break;
|
||||
|
||||
window = parent;
|
||||
}
|
||||
|
||||
return static_cast<QIOSWindow *>(window->handle());
|
||||
}
|
||||
|
||||
void QIOSWindow::requestActivateWindow()
|
||||
{
|
||||
// Note that several windows can be active at the same time if they exist in the same
|
||||
@ -499,8 +654,6 @@ void QIOSWindow::requestActivateWindow()
|
||||
if (window()->isTopLevel())
|
||||
raise();
|
||||
|
||||
QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
|
||||
static_cast<QIOSInputContext *>(context)->focusViewChanged(m_view);
|
||||
QWindowSystemInterface::handleWindowActivated(window());
|
||||
}
|
||||
|
||||
|
@ -2,9 +2,6 @@ TARGET = qqnx
|
||||
|
||||
QT += platformsupport-private core-private gui-private
|
||||
|
||||
# The PPS based platform integration is currently used for both BB10 and plain QNX
|
||||
CONFIG += qqnx_pps
|
||||
|
||||
# Uncomment this to build with support for IMF once it becomes available in the BBNDK
|
||||
#CONFIG += qqnx_imf
|
||||
|
||||
@ -132,7 +129,8 @@ CONFIG(qqnx_pps) {
|
||||
qqnxclipboard.h \
|
||||
qqnxbuttoneventnotifier.h
|
||||
|
||||
LIBS += -lpps -lclipboard
|
||||
LIBS += -lpps
|
||||
!contains(DEFINES, QT_NO_CLIPBOARD): LIBS += -lclipboard
|
||||
|
||||
CONFIG(qqnx_imf) {
|
||||
DEFINES += QQNX_IMF
|
||||
|
@ -58,12 +58,13 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow) :
|
||||
QQnxWindow(window, context, needRootWindow),
|
||||
m_requestedBufferSize(window->geometry().size()),
|
||||
m_platformOpenGLContext(0),
|
||||
m_newSurfaceRequested(true),
|
||||
m_eglSurface(EGL_NO_SURFACE)
|
||||
{
|
||||
initWindow();
|
||||
m_requestedBufferSize = screen()->rootWindow() == this ?
|
||||
screen()->geometry().size() : window->geometry().size();
|
||||
}
|
||||
|
||||
QQnxEglWindow::~QQnxEglWindow()
|
||||
@ -145,6 +146,9 @@ EGLSurface QQnxEglWindow::getSurface()
|
||||
|
||||
void QQnxEglWindow::setGeometry(const QRect &rect)
|
||||
{
|
||||
//If this is the root window, it has to be shown fullscreen
|
||||
const QRect &newGeometry = screen()->rootWindow() == this ? screen()->geometry() : rect;
|
||||
|
||||
//We need to request that the GL context updates
|
||||
// the EGLsurface on which it is rendering.
|
||||
{
|
||||
@ -152,11 +156,11 @@ void QQnxEglWindow::setGeometry(const QRect &rect)
|
||||
// setting m_requestedBufferSize and therefore extended the scope to include
|
||||
// that test.
|
||||
const QMutexLocker locker(&m_mutex);
|
||||
m_requestedBufferSize = rect.size();
|
||||
if (m_platformOpenGLContext != 0 && bufferSize() != rect.size())
|
||||
m_requestedBufferSize = newGeometry.size();
|
||||
if (m_platformOpenGLContext != 0 && bufferSize() != newGeometry.size())
|
||||
m_newSurfaceRequested.testAndSetRelease(false, true);
|
||||
}
|
||||
QQnxWindow::setGeometry(rect);
|
||||
QQnxWindow::setGeometry(newGeometry);
|
||||
}
|
||||
|
||||
QSize QQnxEglWindow::requestedBufferSize() const
|
||||
|
@ -136,7 +136,7 @@ void QQnxWindow::setGeometry(const QRect &rect)
|
||||
|
||||
// Calling flushWindowSystemEvents() here would flush input events which
|
||||
// could result in re-entering QQnxWindow::setGeometry() again.
|
||||
QWindowSystemInterface::setSynchronousWindowsSystemEvents(true); //This does not work
|
||||
QWindowSystemInterface::setSynchronousWindowsSystemEvents(true);
|
||||
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
|
||||
QWindowSystemInterface::handleExposeEvent(window(), newGeometry);
|
||||
QWindowSystemInterface::setSynchronousWindowsSystemEvents(false);
|
||||
@ -608,13 +608,15 @@ void QQnxWindow::initWindow()
|
||||
setWindowState(window()->windowState());
|
||||
if (window()->parent() && window()->parent()->handle())
|
||||
setParent(window()->parent()->handle());
|
||||
setGeometryHelper(window()->geometry());
|
||||
|
||||
if (screen()->rootWindow() == this) {
|
||||
setGeometry(screen()->geometry());
|
||||
setGeometryHelper(screen()->geometry());
|
||||
QWindowSystemInterface::handleGeometryChange(window(), screen()->geometry());
|
||||
} else {
|
||||
setGeometryHelper(window()->geometry());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QQnxWindow::createWindowGroup()
|
||||
{
|
||||
// Generate a random window group name
|
||||
|
@ -86,6 +86,10 @@ QWindowsKeyMapper::~QWindowsKeyMapper()
|
||||
#define VK_OEM_3 0xC0
|
||||
#endif
|
||||
|
||||
// We not only need the scancode itself but also the extended bit of key messages. Thus we need
|
||||
// the additional bit when masking the scancode.
|
||||
enum { scancodeBitmask = 0x1ff };
|
||||
|
||||
// Key recorder ------------------------------------------------------------------------[ start ] --
|
||||
struct KeyRecord {
|
||||
KeyRecord(int c, int a, int s, const QString &t) : code(c), ascii(a), state(s), text(t) {}
|
||||
@ -567,7 +571,7 @@ void QWindowsKeyMapper::updateKeyMap(const MSG &msg)
|
||||
{
|
||||
unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
|
||||
GetKeyboardState(kbdBuffer);
|
||||
const quint32 scancode = (msg.lParam >> 16) & 0xff;
|
||||
const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask;
|
||||
updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam);
|
||||
}
|
||||
|
||||
@ -754,7 +758,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
|
||||
{
|
||||
const int msgType = msg.message;
|
||||
|
||||
const quint32 scancode = (msg.lParam >> 16) & 0xff;
|
||||
const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask;
|
||||
const quint32 vk_key = msg.wParam;
|
||||
quint32 nModifiers = 0;
|
||||
|
||||
|
@ -415,12 +415,17 @@ bool QGLXContext::m_supportsThreading = true;
|
||||
// If this list grows to any significant size, change it a
|
||||
// proper string table and make the implementation below use
|
||||
// binary search.
|
||||
static const char *qglx_threadedgl_blacklist[] = {
|
||||
static const char *qglx_threadedgl_blacklist_renderer[] = {
|
||||
"Chromium", // QTBUG-32225 (initialization fails)
|
||||
"Mesa DRI Intel(R) Sandybridge Mobile", // QTBUG-34492 (flickering in fullscreen)
|
||||
0
|
||||
};
|
||||
|
||||
static const char *qglx_threadedgl_blacklist_vendor[] = {
|
||||
"nouveau", // QTCREATORBUG-10875 (crash in creator)
|
||||
0
|
||||
};
|
||||
|
||||
void QGLXContext::queryDummyContext()
|
||||
{
|
||||
if (m_queriedDummyContext)
|
||||
@ -437,8 +442,8 @@ void QGLXContext::queryDummyContext()
|
||||
oldSurface = oldContext->surface();
|
||||
|
||||
QScopedPointer<QSurface> surface;
|
||||
const char *vendor = glXGetClientString(glXGetCurrentDisplay(), GLX_VENDOR);
|
||||
if (vendor && !strcmp(vendor, "ATI")) {
|
||||
const char *glxvendor = glXGetClientString(glXGetCurrentDisplay(), GLX_VENDOR);
|
||||
if (glxvendor && !strcmp(glxvendor, "ATI")) {
|
||||
QWindow *window = new QWindow;
|
||||
window->resize(64, 64);
|
||||
window->setSurfaceType(QSurface::OpenGLSurface);
|
||||
@ -454,11 +459,19 @@ void QGLXContext::queryDummyContext()
|
||||
context.create();
|
||||
context.makeCurrent(surface.data());
|
||||
|
||||
const char *renderer = (const char *) glGetString(GL_RENDERER);
|
||||
|
||||
m_supportsThreading = true;
|
||||
for (int i = 0; qglx_threadedgl_blacklist[i]; ++i) {
|
||||
if (strstr(renderer, qglx_threadedgl_blacklist[i]) != 0) {
|
||||
|
||||
const char *renderer = (const char *) glGetString(GL_RENDERER);
|
||||
for (int i = 0; qglx_threadedgl_blacklist_renderer[i]; ++i) {
|
||||
if (strstr(renderer, qglx_threadedgl_blacklist_renderer[i]) != 0) {
|
||||
m_supportsThreading = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char *vendor = (const char *) glGetString(GL_VENDOR);
|
||||
for (int i = 0; qglx_threadedgl_blacklist_vendor[i]; ++i) {
|
||||
if (strstr(vendor, qglx_threadedgl_blacklist_vendor[i]) != 0) {
|
||||
m_supportsThreading = false;
|
||||
break;
|
||||
}
|
||||
|
@ -1749,10 +1749,26 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode)
|
||||
// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
|
||||
// - "pad0" became "extension"
|
||||
// - "pad1" and "pad" became "pad0"
|
||||
// New and old version of this struct share the following fields:
|
||||
// NOTE: API might change again in the next release of xcb in which case this comment will
|
||||
// need to be updated to reflect the reality.
|
||||
typedef struct qt_xcb_ge_event_t {
|
||||
uint8_t response_type;
|
||||
uint8_t extension;
|
||||
uint16_t sequence;
|
||||
uint32_t length;
|
||||
uint16_t event_type;
|
||||
} qt_xcb_ge_event_t;
|
||||
|
||||
bool QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *ev, int opCode)
|
||||
{
|
||||
// xGenericEvent has "extension" on the second byte, xcb_ge_event_t has "pad0".
|
||||
if (event->pad0 == opCode) {
|
||||
qt_xcb_ge_event_t *event = (qt_xcb_ge_event_t *)ev;
|
||||
// xGenericEvent has "extension" on the second byte, the same is true for xcb_ge_event_t starting from
|
||||
// the xcb version 1.9.3, prior to that it was called "pad0".
|
||||
if (event->extension == opCode) {
|
||||
// xcb event structs contain stuff that wasn't on the wire, the full_sequence field
|
||||
// adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes.
|
||||
// Move this data back to have the same layout in memory as it was on the wire
|
||||
|
@ -6999,23 +6999,23 @@ void QWidget::setUpdatesEnabled(bool enable)
|
||||
}
|
||||
|
||||
/*!
|
||||
Shows the widget and its child widgets. This function is
|
||||
equivalent to setVisible(true) in the normal case, and equivalent
|
||||
to showFullScreen() if the QStyleHints::showIsFullScreen() hint
|
||||
is true and the window is not a popup.
|
||||
Shows the widget and its child widgets.
|
||||
|
||||
\sa raise(), showEvent(), hide(), setVisible(), showMinimized(), showMaximized(),
|
||||
showNormal(), isVisible(), windowFlags()
|
||||
This is equivalent to calling showFullScreen(), showMaximized(), or setVisible(true),
|
||||
depending on the platform's default behavior for the window flags.
|
||||
|
||||
\sa raise(), showEvent(), hide(), setVisible(), showMinimized(), showMaximized(),
|
||||
showNormal(), isVisible(), windowFlags(), flags()
|
||||
*/
|
||||
void QWidget::show()
|
||||
{
|
||||
bool isPopup = data->window_flags & Qt::Popup & ~Qt::Window;
|
||||
if (isWindow() && !isPopup && qApp->styleHints()->showIsFullScreen())
|
||||
Qt::WindowState defaultState = QGuiApplicationPrivate::platformIntegration()->defaultWindowState(data->window_flags);
|
||||
if (defaultState == Qt::WindowFullScreen)
|
||||
showFullScreen();
|
||||
else if (isWindow() && !(data->window_flags & Qt::Dialog & ~Qt::Window) && !isPopup && QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ShowIsMaximized).toBool())
|
||||
else if (defaultState == Qt::WindowMaximized)
|
||||
showMaximized();
|
||||
else
|
||||
setVisible(true);
|
||||
setVisible(true); // FIXME: Why not showNormal(), like QWindow::show()?
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
@ -510,9 +510,9 @@ void QWidgetPrivate::show_sys()
|
||||
|
||||
QWindow *window = q->windowHandle();
|
||||
|
||||
q->setAttribute(Qt::WA_Mapped);
|
||||
if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
|
||||
invalidateBuffer(q->rect());
|
||||
q->setAttribute(Qt::WA_Mapped);
|
||||
if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
|
||||
// add our window to the modal window list
|
||||
QGuiApplicationPrivate::showModalWindow(window);
|
||||
|
@ -715,10 +715,6 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event
|
||||
break;
|
||||
}
|
||||
|
||||
// Note that widgetState == m_widget->data->window_state when triggered by QWidget::setWindowState().
|
||||
if (!(widgetState & Qt::WindowMinimized))
|
||||
m_widget->setAttribute(Qt::WA_Mapped);
|
||||
|
||||
// Sent event if the state changed (that is, it is not triggered by
|
||||
// QWidget::setWindowState(), which also sends an event to the widget).
|
||||
if (widgetState != int(m_widget->data->window_state)) {
|
||||
|
@ -1834,14 +1834,6 @@ QSize QMenu::sizeHint() const
|
||||
void QMenu::popup(const QPoint &p, QAction *atAction)
|
||||
{
|
||||
Q_D(QMenu);
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
if (!d->platformMenu.isNull() && !testAttribute(Qt::WA_SetStyle)) {
|
||||
d->platformMenu->showPopup(window()->windowHandle(), p, 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (d->scroll) { // reset scroll state from last popup
|
||||
if (d->scroll->scrollOffset)
|
||||
d->itemsDirty = 1; // sizeHint will be incorrect if there is previous scroll
|
||||
|
@ -2903,6 +2903,12 @@ void tst_QDateTime::timeZones() const
|
||||
// - Test 03:00:00 = 1 hour after tran
|
||||
hourAfterStd = QDateTime(QDate(2013, 10, 27), QTime(3, 0, 0), cet);
|
||||
QCOMPARE(hourAfterStd.toMSecsSinceEpoch(), dstToStdMSecs + 3600000);
|
||||
|
||||
// Test Time Zone that has transitions but no future transitions afer a given date
|
||||
QTimeZone sgt("Asia/Singapore");
|
||||
QDateTime future(QDate(2015, 1, 1), QTime(0, 0, 0), sgt);
|
||||
QVERIFY(future.isValid());
|
||||
QCOMPARE(future.offsetFromUtc(), 28800);
|
||||
}
|
||||
|
||||
void tst_QDateTime::invalid() const
|
||||
|
@ -57,6 +57,7 @@ private slots:
|
||||
void nullTest();
|
||||
void dataStreamTest();
|
||||
void availableTimeZoneIds();
|
||||
void stressTest();
|
||||
void windowsId();
|
||||
// Backend tests
|
||||
void utcTest();
|
||||
@ -75,7 +76,7 @@ private:
|
||||
|
||||
tst_QTimeZone::tst_QTimeZone()
|
||||
{
|
||||
// Set to true to print debug output
|
||||
// Set to true to print debug output, test Display Names and run long stress tests
|
||||
debug = false;
|
||||
}
|
||||
|
||||
@ -367,11 +368,59 @@ void tst_QTimeZone::availableTimeZoneIds()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QTimeZone::stressTest()
|
||||
{
|
||||
QList<QByteArray> idList = QTimeZone::availableTimeZoneIds();
|
||||
foreach (const QByteArray &id, idList) {
|
||||
QTimeZone testZone = QTimeZone(id);
|
||||
QCOMPARE(testZone.isValid(), true);
|
||||
QCOMPARE(testZone.id(), id);
|
||||
QDateTime testDate = QDateTime(QDate(2015, 1, 1), QTime(0, 0, 0), Qt::UTC);
|
||||
testZone.country();
|
||||
testZone.comment();
|
||||
testZone.displayName(testDate);
|
||||
testZone.displayName(QTimeZone::DaylightTime);
|
||||
testZone.displayName(QTimeZone::StandardTime);
|
||||
testZone.abbreviation(testDate);
|
||||
testZone.offsetFromUtc(testDate);
|
||||
testZone.standardTimeOffset(testDate);
|
||||
testZone.daylightTimeOffset(testDate);
|
||||
testZone.hasDaylightTime();
|
||||
testZone.isDaylightTime(testDate);
|
||||
testZone.offsetData(testDate);
|
||||
testZone.hasTransitions();
|
||||
testZone.nextTransition(testDate);
|
||||
testZone.previousTransition(testDate);
|
||||
// Dates known to be outside possible tz file pre-calculated rules range
|
||||
QDateTime lowDate1 = QDateTime(QDate(1800, 1, 1), QTime(0, 0, 0), Qt::UTC);
|
||||
QDateTime lowDate2 = QDateTime(QDate(1800, 6, 1), QTime(0, 0, 0), Qt::UTC);
|
||||
QDateTime highDate1 = QDateTime(QDate(2200, 1, 1), QTime(0, 0, 0), Qt::UTC);
|
||||
QDateTime highDate2 = QDateTime(QDate(2200, 6, 1), QTime(0, 0, 0), Qt::UTC);
|
||||
testZone.nextTransition(lowDate1);
|
||||
testZone.nextTransition(lowDate2);
|
||||
testZone.previousTransition(lowDate2);
|
||||
testZone.previousTransition(lowDate2);
|
||||
testZone.nextTransition(highDate1);
|
||||
testZone.nextTransition(highDate2);
|
||||
testZone.previousTransition(highDate1);
|
||||
testZone.previousTransition(highDate2);
|
||||
if (debug) {
|
||||
// This could take a long time, depending on platform and database
|
||||
qDebug() << "Stress test calculating transistions for" << testZone.id();
|
||||
testZone.transitions(lowDate1, highDate1);
|
||||
}
|
||||
testDate.setTimeZone(testZone);
|
||||
testDate.isValid();
|
||||
testDate.offsetFromUtc();
|
||||
testDate.timeZoneAbbreviation();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QTimeZone::windowsId()
|
||||
{
|
||||
/*
|
||||
Current Windows zones for "Central Standard Time":
|
||||
Region Olsen Id(s)
|
||||
Region IANA Id(s)
|
||||
Default "America/Chicago"
|
||||
Canada "America/Winnipeg America/Rainy_River America/Rankin_Inlet America/Resolute"
|
||||
Mexico "America/Matamoros"
|
||||
@ -380,24 +429,24 @@ void tst_QTimeZone::windowsId()
|
||||
"America/North_Dakota/New_Salem"
|
||||
AnyCountry "CST6CDT"
|
||||
*/
|
||||
QCOMPARE(QTimeZone::olsenIdToWindowsId("America/Chicago"),
|
||||
QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Chicago"),
|
||||
QByteArray("Central Standard Time"));
|
||||
QCOMPARE(QTimeZone::olsenIdToWindowsId("America/Resolute"),
|
||||
QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Resolute"),
|
||||
QByteArray("Central Standard Time"));
|
||||
|
||||
// Partials shouldn't match
|
||||
QCOMPARE(QTimeZone::olsenIdToWindowsId("America/Chi"), QByteArray());
|
||||
QCOMPARE(QTimeZone::olsenIdToWindowsId("InvalidZone"), QByteArray());
|
||||
QCOMPARE(QTimeZone::olsenIdToWindowsId(QByteArray()), QByteArray());
|
||||
QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Chi"), QByteArray());
|
||||
QCOMPARE(QTimeZone::ianaIdToWindowsId("InvalidZone"), QByteArray());
|
||||
QCOMPARE(QTimeZone::ianaIdToWindowsId(QByteArray()), QByteArray());
|
||||
|
||||
// Check default value
|
||||
QCOMPARE(QTimeZone::windowsIdToDefaultOlsenId("Central Standard Time"),
|
||||
QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time"),
|
||||
QByteArray("America/Chicago"));
|
||||
QCOMPARE(QTimeZone::windowsIdToDefaultOlsenId("Central Standard Time", QLocale::Canada),
|
||||
QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time", QLocale::Canada),
|
||||
QByteArray("America/Winnipeg"));
|
||||
QCOMPARE(QTimeZone::windowsIdToDefaultOlsenId("Central Standard Time", QLocale::AnyCountry),
|
||||
QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time", QLocale::AnyCountry),
|
||||
QByteArray("CST6CDT"));
|
||||
QCOMPARE(QTimeZone::windowsIdToDefaultOlsenId(QByteArray()), QByteArray());
|
||||
QCOMPARE(QTimeZone::windowsIdToDefaultIanaId(QByteArray()), QByteArray());
|
||||
|
||||
// No country is sorted list of all zones
|
||||
QList<QByteArray> list;
|
||||
@ -406,39 +455,39 @@ void tst_QTimeZone::windowsId()
|
||||
<< "America/North_Dakota/Center" << "America/North_Dakota/New_Salem"
|
||||
<< "America/Rainy_River" << "America/Rankin_Inlet" << "America/Resolute"
|
||||
<< "America/Winnipeg" << "CST6CDT";
|
||||
QCOMPARE(QTimeZone::windowsIdToOlsenIds("Central Standard Time"), list);
|
||||
QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time"), list);
|
||||
|
||||
// Check country with no match returns empty list
|
||||
list.clear();
|
||||
QCOMPARE(QTimeZone::windowsIdToOlsenIds("Central Standard Time", QLocale::NewZealand),
|
||||
QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::NewZealand),
|
||||
list);
|
||||
|
||||
// Check valid country returns list in preference order
|
||||
list.clear();
|
||||
list << "America/Winnipeg" << "America/Rainy_River" << "America/Rankin_Inlet"
|
||||
<< "America/Resolute";
|
||||
QCOMPARE(QTimeZone::windowsIdToOlsenIds("Central Standard Time", QLocale::Canada), list);
|
||||
QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::Canada), list);
|
||||
|
||||
list.clear();
|
||||
list << "America/Matamoros";
|
||||
QCOMPARE(QTimeZone::windowsIdToOlsenIds("Central Standard Time", QLocale::Mexico), list);
|
||||
QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::Mexico), list);
|
||||
|
||||
list.clear();
|
||||
list << "America/Chicago" << "America/Indiana/Knox" << "America/Indiana/Tell_City"
|
||||
<< "America/Menominee" << "America/North_Dakota/Beulah" << "America/North_Dakota/Center"
|
||||
<< "America/North_Dakota/New_Salem";
|
||||
QCOMPARE(QTimeZone::windowsIdToOlsenIds("Central Standard Time", QLocale::UnitedStates),
|
||||
QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::UnitedStates),
|
||||
list);
|
||||
|
||||
list.clear();
|
||||
list << "CST6CDT";
|
||||
QCOMPARE(QTimeZone::windowsIdToOlsenIds("Central Standard Time", QLocale::AnyCountry),
|
||||
QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::AnyCountry),
|
||||
list);
|
||||
|
||||
// Check no windowsId return empty
|
||||
list.clear();
|
||||
QCOMPARE(QTimeZone::windowsIdToOlsenIds(QByteArray()), list);
|
||||
QCOMPARE(QTimeZone::windowsIdToOlsenIds(QByteArray(), QLocale::AnyCountry), list);
|
||||
QCOMPARE(QTimeZone::windowsIdToIanaIds(QByteArray()), list);
|
||||
QCOMPARE(QTimeZone::windowsIdToIanaIds(QByteArray(), QLocale::AnyCountry), list);
|
||||
}
|
||||
|
||||
void tst_QTimeZone::utcTest()
|
||||
@ -639,10 +688,11 @@ void tst_QTimeZone::tzTest()
|
||||
QCOMPARE(dat.standardTimeOffset, 3600);
|
||||
QCOMPARE(dat.daylightTimeOffset, 0);
|
||||
|
||||
// Test previous to low value is invalid
|
||||
dat = tzp.previousTransition(-9999999999999);
|
||||
QCOMPARE(dat.atMSecsSinceEpoch, (qint64)-2422054408000);
|
||||
QCOMPARE(dat.standardTimeOffset, 3600);
|
||||
QCOMPARE(dat.daylightTimeOffset, 0);
|
||||
QCOMPARE(dat.atMSecsSinceEpoch, std::numeric_limits<qint64>::min());
|
||||
QCOMPARE(dat.standardTimeOffset, std::numeric_limits<int>::min());
|
||||
QCOMPARE(dat.daylightTimeOffset, std::numeric_limits<int>::min());
|
||||
|
||||
dat = tzp.nextTransition(-9999999999999);
|
||||
QCOMPARE(dat.atMSecsSinceEpoch, (qint64)-2422054408000);
|
||||
|
@ -47,6 +47,12 @@
|
||||
enum { OneMinute = 60 * 1000,
|
||||
TwoMinutes = OneMinute * 2 };
|
||||
|
||||
|
||||
struct Functor
|
||||
{
|
||||
void operator()() const {};
|
||||
};
|
||||
|
||||
class tst_QObjectRace: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -122,11 +128,7 @@ signals:
|
||||
private slots:
|
||||
void checkStopWatch()
|
||||
{
|
||||
#if defined(Q_OS_WINCE) || defined(Q_OS_VXWORKS)
|
||||
if (stopWatch.elapsed() >= OneMinute / 2)
|
||||
#else
|
||||
if (stopWatch.elapsed() >= OneMinute)
|
||||
#endif
|
||||
if (stopWatch.elapsed() >= 5000)
|
||||
quit();
|
||||
|
||||
QObject o;
|
||||
@ -188,16 +190,34 @@ class MyObject : public QObject
|
||||
void signal7();
|
||||
};
|
||||
|
||||
namespace {
|
||||
const char *_slots[] = { SLOT(slot1()) , SLOT(slot2()) , SLOT(slot3()),
|
||||
SLOT(slot4()) , SLOT(slot5()) , SLOT(slot6()),
|
||||
SLOT(slot7()) };
|
||||
|
||||
const char *_signals[] = { SIGNAL(signal1()), SIGNAL(signal2()), SIGNAL(signal3()),
|
||||
SIGNAL(signal4()), SIGNAL(signal5()), SIGNAL(signal6()),
|
||||
SIGNAL(signal7()) };
|
||||
|
||||
typedef void (MyObject::*PMFType)();
|
||||
const PMFType _slotsPMF[] = { &MyObject::slot1, &MyObject::slot2, &MyObject::slot3,
|
||||
&MyObject::slot4, &MyObject::slot5, &MyObject::slot6,
|
||||
&MyObject::slot7 };
|
||||
|
||||
const PMFType _signalsPMF[] = { &MyObject::signal1, &MyObject::signal2, &MyObject::signal3,
|
||||
&MyObject::signal4, &MyObject::signal5, &MyObject::signal6,
|
||||
&MyObject::signal7 };
|
||||
|
||||
}
|
||||
|
||||
class DestroyThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
QObject **objects;
|
||||
MyObject **objects;
|
||||
int number;
|
||||
|
||||
public:
|
||||
void setObjects(QObject **o, int n)
|
||||
void setObjects(MyObject **o, int n)
|
||||
{
|
||||
objects = o;
|
||||
number = n;
|
||||
@ -206,8 +226,29 @@ public:
|
||||
}
|
||||
|
||||
void run() {
|
||||
for(int i = 0; i < number; i++)
|
||||
for (int i = number-1; i >= 0; --i) {
|
||||
/* Do some more connection and disconnection between object in this thread that have not been destroyed yet */
|
||||
|
||||
const int nAlive = i+1;
|
||||
connect (objects[((i+1)*31) % nAlive], _signals[(12*i)%7], objects[((i+2)*37) % nAlive], _slots[(15*i+2)%7] );
|
||||
disconnect(objects[((i+1)*31) % nAlive], _signals[(12*i)%7], objects[((i+2)*37) % nAlive], _slots[(15*i+2)%7] );
|
||||
|
||||
connect (objects[((i+4)*41) % nAlive], _signalsPMF[(18*i)%7], objects[((i+5)*43) % nAlive], _slotsPMF[(19*i+2)%7] );
|
||||
disconnect(objects[((i+4)*41) % nAlive], _signalsPMF[(18*i)%7], objects[((i+5)*43) % nAlive], _slotsPMF[(19*i+2)%7] );
|
||||
|
||||
QMetaObject::Connection c = connect(objects[((i+5)*43) % nAlive], _signalsPMF[(9*i+1)%7], Functor());
|
||||
disconnect(c);
|
||||
|
||||
disconnect(objects[i], _signalsPMF[(10*i+5)%7], 0, 0);
|
||||
disconnect(objects[i], _signals[(11*i+6)%7], 0, 0);
|
||||
|
||||
disconnect(objects[i], 0, objects[(i*17+6) % nAlive], 0);
|
||||
if (i%4 == 1) {
|
||||
disconnect(objects[i], 0, 0, 0);
|
||||
}
|
||||
|
||||
delete objects[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -216,27 +257,24 @@ public:
|
||||
|
||||
void tst_QObjectRace::destroyRace()
|
||||
{
|
||||
enum { ThreadCount = 10, ObjectCountPerThread = 733,
|
||||
enum { ThreadCount = 10, ObjectCountPerThread = 2777,
|
||||
ObjectCount = ThreadCount * ObjectCountPerThread };
|
||||
|
||||
const char *_slots[] = { SLOT(slot1()) , SLOT(slot2()) , SLOT(slot3()),
|
||||
SLOT(slot4()) , SLOT(slot5()) , SLOT(slot6()),
|
||||
SLOT(slot7()) };
|
||||
|
||||
const char *_signals[] = { SIGNAL(signal1()), SIGNAL(signal2()), SIGNAL(signal3()),
|
||||
SIGNAL(signal4()), SIGNAL(signal5()), SIGNAL(signal6()),
|
||||
SIGNAL(signal7()) };
|
||||
|
||||
QObject *objects[ObjectCount];
|
||||
MyObject *objects[ObjectCount];
|
||||
for (int i = 0; i < ObjectCount; ++i)
|
||||
objects[i] = new MyObject;
|
||||
|
||||
|
||||
for (int i = 0; i < ObjectCount * 11; ++i) {
|
||||
for (int i = 0; i < ObjectCount * 17; ++i) {
|
||||
connect(objects[(i*13) % ObjectCount], _signals[(2*i)%7],
|
||||
objects[((i+2)*17) % ObjectCount], _slots[(3*i+2)%7] );
|
||||
connect(objects[((i+6)*23) % ObjectCount], _signals[(5*i+4)%7],
|
||||
objects[((i+8)*41) % ObjectCount], _slots[(i+6)%7] );
|
||||
|
||||
connect(objects[(i*67) % ObjectCount], _signalsPMF[(2*i)%7],
|
||||
objects[((i+1)*71) % ObjectCount], _slotsPMF[(3*i+2)%7] );
|
||||
connect(objects[((i+3)*73) % ObjectCount], _signalsPMF[(5*i+4)%7],
|
||||
objects[((i+5)*79) % ObjectCount], Functor() );
|
||||
}
|
||||
|
||||
DestroyThread *threads[ThreadCount];
|
||||
|
@ -212,7 +212,14 @@ void tst_QFileSystemModel::rootPath()
|
||||
QString oldRootPath = model->rootPath();
|
||||
const QStringList documentPaths = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
|
||||
QVERIFY(!documentPaths.isEmpty());
|
||||
const QString documentPath = documentPaths.front();
|
||||
QString documentPath = documentPaths.front();
|
||||
// In particular on Linux, ~/Documents (the first
|
||||
// DocumentsLocation) may not exist, so choose ~ in that case:
|
||||
if (!QFile::exists(documentPath)) {
|
||||
documentPath = QDir::homePath();
|
||||
qWarning("%s: first documentPath \"%s\" does not exist. Using ~ (\"%s\") instead.",
|
||||
Q_FUNC_INFO, qPrintable(documentPaths.front()), qPrintable(documentPath));
|
||||
}
|
||||
root = model->setRootPath(documentPath);
|
||||
|
||||
QTRY_VERIFY(model->rowCount(root) >= 0);
|
||||
|
@ -4072,6 +4072,7 @@ void tst_QGraphicsScene::isActive()
|
||||
|
||||
|
||||
{
|
||||
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
QWidget toplevel2;
|
||||
QHBoxLayout *layout = new QHBoxLayout;
|
||||
toplevel2.setLayout(layout);
|
||||
@ -4085,12 +4086,13 @@ void tst_QGraphicsScene::isActive()
|
||||
QVERIFY(!scene1.hasFocus());
|
||||
QVERIFY(!scene2.hasFocus());
|
||||
|
||||
toplevel2.move(availableGeometry.topLeft() + QPoint(50, 50));
|
||||
toplevel2.show();
|
||||
QApplication::setActiveWindow(&toplevel2);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&toplevel2));
|
||||
QCOMPARE(QApplication::activeWindow(), &toplevel2);
|
||||
|
||||
QVERIFY(scene1.isActive());
|
||||
QTRY_VERIFY(scene1.isActive());
|
||||
QVERIFY(!scene2.isActive());
|
||||
QVERIFY(scene1.hasFocus());
|
||||
QVERIFY(!scene2.hasFocus());
|
||||
@ -4133,6 +4135,7 @@ void tst_QGraphicsScene::isActive()
|
||||
QVERIFY(!scene2.hasFocus());
|
||||
|
||||
QGraphicsView topLevelView;
|
||||
topLevelView.move(availableGeometry.topLeft() + QPoint(500, 50));
|
||||
topLevelView.show();
|
||||
QApplication::setActiveWindow(&topLevelView);
|
||||
topLevelView.setFocus();
|
||||
|
@ -4687,13 +4687,17 @@ public:
|
||||
|
||||
void tst_QGraphicsView::hoverLeave()
|
||||
{
|
||||
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
view.resize(160, 160);
|
||||
view.move(availableGeometry.center() - QPoint(80, 80));
|
||||
GraphicsItemWithHover *item = new GraphicsItemWithHover;
|
||||
scene.addItem(item);
|
||||
|
||||
// move the cursor out of the way
|
||||
QCursor::setPos(1,1);
|
||||
const QPoint outOfWindow = view.geometry().topRight() + QPoint(50, 0);
|
||||
QCursor::setPos(outOfWindow);
|
||||
|
||||
view.show();
|
||||
qApp->setActiveWindow(&view);
|
||||
@ -4701,16 +4705,14 @@ void tst_QGraphicsView::hoverLeave()
|
||||
|
||||
QPoint pos = view.viewport()->mapToGlobal(view.mapFromScene(item->mapToScene(10, 10)));
|
||||
QCursor::setPos(pos);
|
||||
QTest::qWait(200);
|
||||
QVERIFY(item->receivedEnterEvent);
|
||||
QTRY_VERIFY(item->receivedEnterEvent);
|
||||
QCOMPARE(item->enterWidget, view.viewport());
|
||||
|
||||
QCursor::setPos(1,1);
|
||||
QTest::qWait(200);
|
||||
QCursor::setPos(outOfWindow);
|
||||
#ifdef Q_OS_MAC
|
||||
QEXPECT_FAIL("", "QTBUG-26274 - behaviour regression", Abort);
|
||||
#endif
|
||||
QVERIFY(item->receivedLeaveEvent);
|
||||
QTRY_VERIFY(item->receivedLeaveEvent);
|
||||
QCOMPARE(item->leaveWidget, view.viewport());
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include <qwidgetaction.h>
|
||||
#include <qcommonstyle.h>
|
||||
#include <qstylefactory.h>
|
||||
#include <qscreen.h>
|
||||
|
||||
#include "../../../qtest-config.h"
|
||||
|
||||
@ -1780,8 +1781,11 @@ void tst_QGraphicsWidget::verifyFocusChain()
|
||||
|
||||
void tst_QGraphicsWidget::updateFocusChainWhenChildDie()
|
||||
{
|
||||
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
view.resize(200, 150);
|
||||
view.move(availableGeometry.topLeft() + QPoint(50, 50));
|
||||
view.show();
|
||||
QApplication::setActiveWindow(&view);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&view));
|
||||
@ -1801,6 +1805,9 @@ void tst_QGraphicsWidget::updateFocusChainWhenChildDie()
|
||||
QVERIFY(w1_1->hasFocus());
|
||||
QWidget myWidget(0);
|
||||
QLineEdit edit(&myWidget);
|
||||
(new QHBoxLayout(&myWidget))->addWidget(&edit);
|
||||
edit.setMinimumWidth(160); // Windows
|
||||
myWidget.move(availableGeometry.topLeft() + QPoint(350, 50));
|
||||
myWidget.show();
|
||||
edit.setFocus();
|
||||
QTRY_VERIFY(edit.hasFocus());
|
||||
@ -1809,8 +1816,9 @@ void tst_QGraphicsWidget::updateFocusChainWhenChildDie()
|
||||
w->setParentItem(parent);
|
||||
//We don't crash perfect
|
||||
QVERIFY(w);
|
||||
QTest::mouseMove(view.viewport());
|
||||
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0);
|
||||
const QPoint center(view.viewport()->width() / 2, view.viewport()->height() / 2);
|
||||
QTest::mouseMove(view.viewport(), center);
|
||||
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, center);
|
||||
#ifdef Q_OS_MAC
|
||||
QEXPECT_FAIL("", "QTBUG-23699", Continue);
|
||||
#endif
|
||||
|
@ -7192,10 +7192,6 @@ void tst_QWidget::hideOpaqueChildWhileHidden()
|
||||
#if !defined(Q_OS_WINCE)
|
||||
void tst_QWidget::updateWhileMinimized()
|
||||
{
|
||||
#ifdef Q_OS_UNIX
|
||||
if (qgetenv("XDG_CURRENT_DESKTOP").contains("Unity"))
|
||||
QSKIP("This test fails on Unity."); // Minimized windows are not unmapped for some reason.
|
||||
#endif // Q_OS_UNIX
|
||||
UpdateWidget widget;
|
||||
// Filter out activation change and focus events to avoid update() calls in QWidget.
|
||||
widget.updateOnActivationChangeAndFocusIn = false;
|
||||
|
@ -91,8 +91,6 @@ private slots:
|
||||
void tst_showWithoutActivating();
|
||||
void tst_paintEventOnSecondShow();
|
||||
|
||||
void obscuredNativeMapped();
|
||||
|
||||
#ifndef QT_NO_DRAGANDDROP
|
||||
void tst_dnd();
|
||||
#endif
|
||||
@ -370,32 +368,6 @@ void tst_QWidget_window::tst_paintEventOnSecondShow()
|
||||
QTRY_VERIFY(w.paintEventReceived);
|
||||
}
|
||||
|
||||
// QTBUG-33520, a toplevel fully obscured by native children should still receive Qt::WA_Mapped
|
||||
void tst_QWidget_window::obscuredNativeMapped()
|
||||
{
|
||||
enum { size = 200 };
|
||||
|
||||
QWidget topLevel;
|
||||
topLevel.setWindowFlags(Qt::FramelessWindowHint);
|
||||
QWidget *child = new QWidget(&topLevel);
|
||||
child->resize(size, size);
|
||||
topLevel.resize(size, size);
|
||||
topLevel.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(size /2 , size / 2));
|
||||
child->winId();
|
||||
topLevel.show();
|
||||
QTRY_VERIFY(topLevel.testAttribute(Qt::WA_Mapped));
|
||||
#if defined(Q_OS_MAC)
|
||||
QSKIP("This test fails on Mac."); // Minimized windows are not unmapped for some reason.
|
||||
#elif defined(Q_OS_UNIX)
|
||||
if (qgetenv("XDG_CURRENT_DESKTOP").contains("Unity"))
|
||||
QSKIP("This test fails on Unity."); // Minimized windows are not unmapped for some reason.
|
||||
#endif // Q_OS_UNIX
|
||||
topLevel.setWindowState(Qt::WindowMinimized);
|
||||
QTRY_VERIFY(!topLevel.testAttribute(Qt::WA_Mapped));
|
||||
topLevel.setWindowState(Qt::WindowNoState);
|
||||
QTRY_VERIFY(topLevel.testAttribute(Qt::WA_Mapped));
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DRAGANDDROP
|
||||
|
||||
/* DnD test for QWidgetWindow (handleDrag*Event() functions).
|
||||
|
@ -194,6 +194,7 @@ Configure::Configure(int& argc, char** argv)
|
||||
dictionary[ "QT_CUPS" ] = "auto";
|
||||
dictionary[ "CFG_GCC_SYSROOT" ] = "yes";
|
||||
dictionary[ "SLOG2" ] = "no";
|
||||
dictionary[ "PPS" ] = "no";
|
||||
dictionary[ "SYSTEM_PROXIES" ] = "no";
|
||||
dictionary[ "WERROR" ] = "auto";
|
||||
dictionary[ "QREAL" ] = "double";
|
||||
@ -879,6 +880,10 @@ void Configure::parseCmdLine()
|
||||
dictionary[ "SLOG2" ] = "no";
|
||||
} else if (configCmdLine.at(i) == "-slog2") {
|
||||
dictionary[ "SLOG2" ] = "yes";
|
||||
} else if (configCmdLine.at(i) == "-no-pps") {
|
||||
dictionary[ "PPS" ] = "no";
|
||||
} else if (configCmdLine.at(i) == "-pps") {
|
||||
dictionary[ "PPS" ] = "yes";
|
||||
} else if (configCmdLine.at(i) == "-no-system-proxies") {
|
||||
dictionary[ "SYSTEM_PROXIES" ] = "no";
|
||||
} else if (configCmdLine.at(i) == "-system-proxies") {
|
||||
@ -1648,6 +1653,7 @@ void Configure::applySpecSpecifics()
|
||||
} else if ((platform() == QNX) || (platform() == BLACKBERRY)) {
|
||||
dictionary["STACK_PROTECTOR_STRONG"] = "auto";
|
||||
dictionary["SLOG2"] = "auto";
|
||||
dictionary["PPS"] = "auto";
|
||||
dictionary["QT_XKBCOMMON"] = "no";
|
||||
dictionary[ "ANGLE" ] = "no";
|
||||
dictionary[ "FONT_CONFIG" ] = "auto";
|
||||
@ -1864,6 +1870,9 @@ bool Configure::displayHelp()
|
||||
if ((platform() == QNX) || (platform() == BLACKBERRY)) {
|
||||
desc("SLOG2", "yes", "-slog2", "Compile with slog2 support.");
|
||||
desc("SLOG2", "no", "-no-slog2", "Do not compile with slog2 support.");
|
||||
|
||||
desc("PPS", "yes", "-pps", "Compile with PPS support.");
|
||||
desc("PPS", "no", "-no-pps", "Do not compile with PPS support.");
|
||||
}
|
||||
|
||||
desc("ANGLE", "yes", "-angle", "Use the ANGLE implementation of OpenGL ES 2.0.");
|
||||
@ -2203,6 +2212,8 @@ bool Configure::checkAvailability(const QString &part)
|
||||
available = (platform() == QNX || platform() == BLACKBERRY) && compilerSupportsFlag("qcc -fstack-protector-strong");
|
||||
} else if (part == "SLOG2") {
|
||||
available = tryCompileProject("unix/slog2");
|
||||
} else if (part == "PPS") {
|
||||
available = (platform() == QNX || platform() == BLACKBERRY) && tryCompileProject("unix/pps");
|
||||
} else if (part == "NEON") {
|
||||
available = (dictionary["QT_ARCH"] == "arm") && tryCompileProject("unix/neon");
|
||||
} else if (part == "FONT_CONFIG") {
|
||||
@ -2348,6 +2359,10 @@ void Configure::autoDetection()
|
||||
dictionary["SLOG2"] = checkAvailability("SLOG2") ? "yes" : "no";
|
||||
}
|
||||
|
||||
if (dictionary["PPS"] == "auto") {
|
||||
dictionary["PPS"] = checkAvailability("PPS") ? "yes" : "no";
|
||||
}
|
||||
|
||||
if (dictionary["QT_EVENTFD"] == "auto")
|
||||
dictionary["QT_EVENTFD"] = checkAvailability("QT_EVENTFD") ? "yes" : "no";
|
||||
|
||||
@ -3174,6 +3189,9 @@ void Configure::generateQConfigPri()
|
||||
if (dictionary[ "SLOG2" ] == "yes")
|
||||
configStream << " slog2";
|
||||
|
||||
if (dictionary[ "PPS" ] == "yes")
|
||||
configStream << " qqnx_pps";
|
||||
|
||||
if (dictionary["DIRECTWRITE"] == "yes")
|
||||
configStream << " directwrite";
|
||||
|
||||
@ -3540,8 +3558,10 @@ void Configure::displayConfig()
|
||||
sout << " HarfBuzz-NG support....." << dictionary[ "HARFBUZZ" ] << endl;
|
||||
sout << " PCRE support............" << dictionary[ "PCRE" ] << endl;
|
||||
sout << " ICU support............." << dictionary[ "ICU" ] << endl;
|
||||
if ((platform() == QNX) || (platform() == BLACKBERRY))
|
||||
if ((platform() == QNX) || (platform() == BLACKBERRY)) {
|
||||
sout << " SLOG2 support..........." << dictionary[ "SLOG2" ] << endl;
|
||||
sout << " PPS support............." << dictionary[ "PPS" ] << endl;
|
||||
}
|
||||
sout << " ANGLE..................." << dictionary[ "ANGLE" ] << endl;
|
||||
sout << endl;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user