summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2009-10-29 17:14:16 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2009-10-29 17:14:16 (GMT)
commite4bec39a139363d1ee4cf3fb15a3fe4499215e77 (patch)
tree7a1632a4b1c988312ed9dc0f68d9ca16230d413b /src
parent6f602c01b9dc2b037cb42cacfe1c2df6e092a6b4 (diff)
parent5641bd0cdd9c90427d7d976473b894c530cdb715 (diff)
downloadQt-e4bec39a139363d1ee4cf3fb15a3fe4499215e77.zip
Qt-e4bec39a139363d1ee4cf3fb15a3fe4499215e77.tar.gz
Qt-e4bec39a139363d1ee4cf3fb15a3fe4499215e77.tar.bz2
Merge remote branch 'origin/4.6' into core-4.6
Diffstat (limited to 'src')
-rw-r--r--src/corelib/corelib.pro2
-rw-r--r--src/corelib/eval.pri4
-rw-r--r--src/corelib/global/qlibraryinfo.cpp20
-rw-r--r--src/corelib/global/qlibraryinfo.h2
-rw-r--r--src/corelib/io/qurl.cpp176
-rw-r--r--src/corelib/kernel/qtcore_eval.cpp569
-rw-r--r--src/corelib/statemachine/qabstractstate.cpp8
-rw-r--r--src/corelib/statemachine/qabstractstate_p.h2
-rw-r--r--src/corelib/statemachine/qstate.cpp25
-rw-r--r--src/corelib/statemachine/qstate_p.h2
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp93
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h11
-rw-r--r--src/gui/kernel/qwidget_mac.mm2
13 files changed, 810 insertions, 106 deletions
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index f835bee..9a15bf1 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -35,4 +35,4 @@ symbian: {
# Workaroud for problems with paging this dll
MMP_RULES -= PAGED
MMP_RULES *= UNPAGED
-} \ No newline at end of file
+}
diff --git a/src/corelib/eval.pri b/src/corelib/eval.pri
new file mode 100644
index 0000000..efda56b
--- /dev/null
+++ b/src/corelib/eval.pri
@@ -0,0 +1,4 @@
+SOURCES += \
+ $$QT_SOURCE_TREE/src/corelib/kernel/qtcore_eval.cpp
+INCLUDEPATH += \
+ $$QT_BUILD_TREE/src/corelib/global
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index e227403..32693e0 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -208,6 +208,18 @@ QLibraryInfo::buildKey()
}
/*!
+ \since 4.6
+ Returns the installation date for this build of Qt. The install date will
+ usually be the last time that Qt sources were configured.
+*/
+QDate
+QLibraryInfo::buildDate()
+{
+ return QDate();
+ //return QDate::fromString(QString::fromLatin1(qt_configure_installation + 12), Qt::ISODate);
+}
+
+/*!
Returns the location specified by \a loc.
*/
@@ -481,12 +493,20 @@ void qt_core_boilerplate()
"Contact: Nokia Corporation (qt-info@nokia.com)\n"
"\n"
"Build key: " QT_BUILD_KEY "\n"
+ "Build date: %s\n"
"Installation prefix: %s\n"
"Library path: %s\n"
"Include path: %s\n",
+ qt_configure_installation + 12,
qt_configure_prefix_path_str + 12,
qt_configure_libraries_path_str + 12,
qt_configure_headers_path_str + 12);
+
+#ifdef QT_EVAL
+ extern void qt_core_eval_init(uint);
+ qt_core_eval_init(1);
+#endif
+
exit(0);
}
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index 3195777..88e8566 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -43,6 +43,7 @@
#define QLIBRARYINFO_H
#include <QtCore/qstring.h>
+#include <QtCore/QDate>
QT_BEGIN_HEADER
@@ -59,6 +60,7 @@ public:
static QString licensedProducts();
static QString buildKey();
+ static QDate buildDate();
enum LibraryLocation
{
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 6001d9d..86680a5 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -5556,79 +5556,6 @@ QUrl QUrl::fromEncoded(const QByteArray &input, ParsingMode parsingMode)
}
/*!
- Returns a valid URL from a user supplied \a userInput string if one can be
- deducted. In the case that is not possible, an invalid QUrl() is returned.
-
- \since 4.6
-
- Most applications that can browse the web, allow the user to input a URL
- in the form of a plain string. This string can be manually typed into
- a location bar, obtained from the clipboard, or passed in via command
- line arguments.
-
- When the string is not already a valid URL, a best guess is performed,
- making various web related assumptions.
-
- In the case the string corresponds to a valid file path on the system,
- a file:// URL is constructed, using QUrl::fromLocalFile().
-
- If that is not the case, an attempt is made to turn the string into a
- http:// or ftp:// URL. The latter in the case the string starts with
- 'ftp'. The result is then passed through QUrl's tolerant parser, and
- in the case or success, a valid QUrl is returned, or else a QUrl().
-
- \section1 Examples:
-
- \list
- \o qt.nokia.com becomes http://qt.nokia.com
- \o ftp.qt.nokia.com becomes ftp://ftp.qt.nokia.com
- \o localhost becomes http://localhost
- \o /home/user/test.html becomes file:///home/user/test.html (if exists)
- \endlist
-
- \section2 Tips to avoid erroneous character conversion when dealing with
- URLs and strings:
-
- \list
- \o When creating an URL QString from a QByteArray or a char*, always use
- QString::fromUtf8().
- \o Favor the use of QUrl::fromEncoded() and QUrl::toEncoded() instead of
- QUrl(string) and QUrl::toString() when converting QUrl to/from string.
- \endlist
-*/
-QUrl QUrl::fromUserInput(const QString &userInput)
-{
- QString trimmedString = userInput.trimmed();
-
- // Absolute files
- if (QDir::isAbsolutePath(trimmedString))
- return QUrl::fromLocalFile(trimmedString);
-
- // Check the most common case of a valid url with scheme and host first
- QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode);
- if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty())
- return url;
-
- // If the string is missing the scheme or the scheme is not valid, prepend a scheme
- QString scheme = url.scheme();
- if (scheme.isEmpty() || scheme.contains(QLatin1Char('.')) || scheme == QLatin1String("localhost")) {
- // Do not do anything for strings such as "foo", only "foo.com"
- int dotIndex = trimmedString.indexOf(QLatin1Char('.'));
- if (dotIndex != -1 || trimmedString.startsWith(QLatin1String("localhost"))) {
- const QString hostscheme = trimmedString.left(dotIndex).toLower();
- QByteArray scheme = (hostscheme == QLatin1String("ftp")) ? "ftp" : "http";
- trimmedString = QLatin1String(scheme) + QLatin1String("://") + trimmedString;
- }
- url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode);
- }
-
- if (url.isValid())
- return url;
-
- return QUrl();
-}
-
-/*!
Returns a decoded copy of \a input. \a input is first decoded from
percent encoding, then converted from UTF-8 to unicode.
*/
@@ -6227,4 +6154,107 @@ QString QUrl::errorString() const
\internal
*/
+// The following code has the following copyright:
+/*
+ Copyright (C) Research In Motion Limited 2009. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Research In Motion Limited nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY Research In Motion Limited ''AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL Research In Motion Limited BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+/*!
+ Returns a valid URL from a user supplied \a userInput string if one can be
+ deducted. In the case that is not possible, an invalid QUrl() is returned.
+
+ \since 4.6
+
+ Most applications that can browse the web, allow the user to input a URL
+ in the form of a plain string. This string can be manually typed into
+ a location bar, obtained from the clipboard, or passed in via command
+ line arguments.
+
+ When the string is not already a valid URL, a best guess is performed,
+ making various web related assumptions.
+
+ In the case the string corresponds to a valid file path on the system,
+ a file:// URL is constructed, using QUrl::fromLocalFile().
+
+ If that is not the case, an attempt is made to turn the string into a
+ http:// or ftp:// URL. The latter in the case the string starts with
+ 'ftp'. The result is then passed through QUrl's tolerant parser, and
+ in the case or success, a valid QUrl is returned, or else a QUrl().
+
+ \section1 Examples:
+
+ \list
+ \o qt.nokia.com becomes http://qt.nokia.com
+ \o ftp.qt.nokia.com becomes ftp://ftp.qt.nokia.com
+ \o localhost becomes http://localhost
+ \o /home/user/test.html becomes file:///home/user/test.html (if exists)
+ \endlist
+
+ \section2 Tips to avoid erroneous character conversion when dealing with
+ URLs and strings:
+
+ \list
+ \o When creating an URL QString from a QByteArray or a char*, always use
+ QString::fromUtf8().
+ \o Favor the use of QUrl::fromEncoded() and QUrl::toEncoded() instead of
+ QUrl(string) and QUrl::toString() when converting QUrl to/from string.
+ \endlist
+*/
+QUrl QUrl::fromUserInput(const QString &userInput)
+{
+ QString trimmedString = userInput.trimmed();
+
+ // Check the most common case of a valid url with scheme and host first
+ QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode);
+ if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty())
+ return url;
+
+ // Absolute files that exists
+ if (QDir::isAbsolutePath(trimmedString) && QFile::exists(trimmedString))
+ return QUrl::fromLocalFile(trimmedString);
+
+ // If the string is missing the scheme or the scheme is not valid prepend a scheme
+ QString scheme = url.scheme();
+ if (scheme.isEmpty() || scheme.contains(QLatin1Char('.')) || scheme == QLatin1String("localhost")) {
+ // Do not do anything for strings such as "foo", only "foo.com"
+ int dotIndex = trimmedString.indexOf(QLatin1Char('.'));
+ if (dotIndex != -1 || trimmedString.startsWith(QLatin1String("localhost"))) {
+ const QString hostscheme = trimmedString.left(dotIndex).toLower();
+ QByteArray scheme = (hostscheme == QLatin1String("ftp")) ? "ftp" : "http";
+ trimmedString = QLatin1String(scheme) + QLatin1String("://") + trimmedString;
+ }
+ url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode);
+ }
+
+ if (url.isValid())
+ return url;
+
+ return QUrl();
+}
+// end of BSD code
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp
new file mode 100644
index 0000000..fe47a30
--- /dev/null
+++ b/src/corelib/kernel/qtcore_eval.cpp
@@ -0,0 +1,569 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcoreevent.h>
+#include <qdatetime.h>
+#include <qlibraryinfo.h>
+#include <qobject.h>
+#include <qcoreapplication.h>
+
+#include "stdio.h"
+#include "stdlib.h"
+
+QT_BEGIN_NAMESPACE
+
+#include "qconfig_eval.cpp"
+
+static const char boilerplate_unsuported[] =
+ "\nQt %1 Evaluation License\n"
+ "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).\n"
+ "All rights reserved.\n\n"
+ "This trial version may only be used for evaluation purposes\n"
+ "and will shut down after 120 minutes.\n"
+ "Registered to:\n"
+ " Licensee: %2\n\n"
+ "The evaluation expires in %4 days\n\n"
+ "Contact http://qt.nokia.com/about/contact-us for pricing and purchasing information.\n";
+
+static const char boilerplate_supported[] =
+ "\nQt %1 Evaluation License\n"
+ "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).\n"
+ "All rights reserved.\n\n"
+ "This trial version may only be used for evaluation purposes\n"
+ "Registered to:\n"
+ " Licensee: %2\n\n"
+ "The evaluation expires in %4 days\n\n"
+ "Contact http://qt.nokia.com/about/contact-us for pricing and purchasing information.\n";
+
+static const char boilerplate_expired[] =
+ "This software is using the trial version of the Qt GUI toolkit.\n"
+ "The trial period has expired. If you need more time to\n"
+ "evaluate Qt, or if you have any questions about Qt, contact us\n"
+ "at: http://qt.nokia.com/about/contact-us.\n\n";
+
+static const char will_shutdown_1min[] =
+ "\nThe evaluation of Qt will SHUT DOWN in 1 minute.\n"
+ "Contact http://qt.nokia.com/about/contact-us for pricing and purchasing information.\n";
+
+static const char will_shutdown_now[] =
+ "\nThe evaluation of Qt has now reached its automatic\n"
+ "timeout and will shut down.\n"
+ "Contact http://qt.nokia.com/about/contact-us for pricing and purchasing information.\n";
+
+static int qt_eval_days_left()
+{
+ const char *const license_key = qt_eval_key_data + 12;
+
+ // fast fail
+ if (!qt_eval_key_data[0] || !*license_key)
+ return -2;
+
+ QDate today = QDate::currentDate();
+ QDate build = QLibraryInfo::buildDate();
+ return qMax(-1, today.daysTo(build) + 30);
+}
+
+static int qt_eval_is_supported()
+{
+ const char *const license_key = qt_eval_key_data + 12;
+ if (!qt_eval_key_data[0] || !*license_key)
+ return -1;
+
+ // is this an unsupported evaluation?
+ const char* typecode = license_key;
+ int field = 2;
+ for ( ; field && *typecode; ++typecode)
+ if (*typecode == '-')
+ --field;
+
+ if (!field && typecode[1] == '4' && typecode[2] == 'M') {
+ if (typecode[0] == 'Q')
+ return 0;
+ else if (typecode[0] == 'R' || typecode[0] == 'Z')
+ return 1;
+ }
+ return -1;
+}
+
+static QString qt_eval_string()
+{
+ const char *msg;
+ switch (qt_eval_is_supported()) {
+ case 0:
+ msg = boilerplate_unsuported;
+ break;
+ case 1:
+ msg = boilerplate_supported;
+ break;
+ default:
+ return QString();
+ msg = 0;
+ }
+
+ return QString::fromLatin1(msg)
+ .arg(QLatin1String(QT_VERSION_STR))
+ .arg(QLibraryInfo::licensee())
+ .arg(qt_eval_days_left());
+}
+
+#define WARN_TIMEOUT 60 * 1000 * 119
+#define KILL_DELAY 60 * 1000 * 1
+
+class QCoreFuriCuri : public QObject
+{
+public:
+
+ int warn;
+ int kill;
+
+ QCoreFuriCuri() : QObject(), warn(-1), kill(-1)
+ {
+ if (!qt_eval_is_supported()) {
+ warn = startTimer(WARN_TIMEOUT);
+ kill = 0;
+ }
+ }
+
+ void timerEvent(QTimerEvent *e) {
+ if (e->timerId() == warn) {
+ killTimer(warn);
+ fprintf(stderr, "%s\n", will_shutdown_1min);
+ kill = startTimer(KILL_DELAY);
+ } else if (e->timerId() == kill) {
+ fprintf(stderr, "%s\n", will_shutdown_now);
+ QCoreApplication::instance()->quit();
+ }
+ }
+};
+
+#if defined(QT_BUILD_CORE_LIB) || defined (QT_BOOTSTRAPPED)
+
+void qt_core_eval_init(uint type)
+{
+ switch (qt_eval_days_left()) {
+ case -2:
+ return;
+
+ case -1:
+ fprintf(stderr, "%s\n", boilerplate_expired);
+ if (type == 0) {
+ // if we're a console app only.
+ exit(0);
+ }
+
+ default:
+ fprintf(stderr, "%s\n", qPrintable(qt_eval_string()));
+ if (type == 0) {
+ Q_UNUSED(new QCoreFuriCuri());
+ }
+ }
+}
+#endif
+
+#ifdef QT_BUILD_GUI_LIB
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <qdialog.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qmessagebox.h>
+#include <qpushbutton.h>
+#include <qtimer.h>
+#include <qapplication.h>
+QT_END_INCLUDE_NAMESPACE
+
+
+static const char * const qtlogo_eval_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"46 55 174 2",
+" c #002E02",
+". c #00370D",
+"X c #003A0E",
+"o c #003710",
+"O c #013C13",
+"+ c #043E1A",
+"@ c #084F0A",
+"# c #0B520C",
+"$ c #054413",
+"% c #0C4C17",
+"& c #07421D",
+"* c #09451D",
+"= c #0D491E",
+"- c #125515",
+"; c #13541A",
+": c #17591B",
+"> c #1B5C1D",
+", c #1F611F",
+"< c #20621E",
+"1 c #337B1E",
+"2 c #0B4521",
+"3 c #0F4923",
+"4 c #114B24",
+"5 c #154D2A",
+"6 c #175323",
+"7 c #1C5924",
+"8 c #1C532F",
+"9 c #1E5432",
+"0 c #245936",
+"q c #265938",
+"w c #295C3B",
+"e c #246324",
+"r c #266823",
+"t c #2A6C24",
+"y c #276628",
+"u c #2D7026",
+"i c #327427",
+"p c #367927",
+"a c #37782A",
+"s c #397C2A",
+"d c #2E613E",
+"f c #336C37",
+"g c #2F6040",
+"h c #356545",
+"j c #3C6B4E",
+"k c #3F6C51",
+"l c #406E4F",
+"z c #406D52",
+"x c #477457",
+"c c #497557",
+"v c #4B7857",
+"b c #517B5E",
+"n c #3C8423",
+"m c #3E812C",
+"M c #53A61D",
+"N c #41862C",
+"B c #458A2D",
+"V c #498F2D",
+"C c #479324",
+"Z c #489226",
+"A c #4D952C",
+"S c #478B30",
+"D c #488C30",
+"F c #4D9232",
+"G c #509632",
+"H c #549A33",
+"J c #589F35",
+"K c #56A526",
+"L c #57A821",
+"P c #5BAA27",
+"I c #57A32A",
+"U c #5CA72E",
+"Y c #5DAB2A",
+"T c #5CA336",
+"R c #60AD2E",
+"E c #63B12D",
+"W c #65AF35",
+"Q c #62A53F",
+"! c #65AE39",
+"~ c #66B036",
+"^ c #6AB437",
+"/ c #67B138",
+"( c #6AB339",
+") c #6DB838",
+"_ c #70BA3C",
+"` c #4D8545",
+"' c #4E8942",
+"] c #548851",
+"[ c #6FAF4A",
+"{ c #6DB243",
+"} c #71B546",
+"| c #70B840",
+" . c #73B648",
+".. c #79BA4E",
+"X. c #7CBB53",
+"o. c #598266",
+"O. c #62886D",
+"+. c #6A8F75",
+"@. c #6B9173",
+"#. c #70937A",
+"$. c #799F79",
+"%. c #7BAF66",
+"&. c #81BD5B",
+"*. c #85BF60",
+"=. c #85AC7F",
+"-. c #8DBA7B",
+";. c #87C061",
+":. c #8AC364",
+">. c #8DC46A",
+",. c #90C56E",
+"<. c #93C771",
+"1. c #96CA73",
+"2. c #9ACB7C",
+"3. c #9FD07D",
+"4. c #779981",
+"5. c #7F9F89",
+"6. c #809F88",
+"7. c #82A18B",
+"8. c #86A192",
+"9. c #8DA994",
+"0. c #8FA998",
+"q. c #94AF9B",
+"w. c #97B991",
+"e. c #97B19E",
+"r. c #9DB6A3",
+"t. c #A3BCA7",
+"y. c #A6BCAB",
+"u. c #A9BEB1",
+"i. c #9ECD81",
+"p. c #A2CF85",
+"a. c #A5D284",
+"s. c #A6D189",
+"d. c #A9D28E",
+"f. c #ABD491",
+"g. c #B1D797",
+"h. c #B1D699",
+"j. c #B5D89E",
+"k. c #ADC5AC",
+"l. c #B1CAAE",
+"z. c #B9DAA3",
+"x. c #BDDDA8",
+"c. c #ADC1B4",
+"v. c #B2C6B6",
+"b. c #B5C6BC",
+"n. c #B6C9BA",
+"m. c #BCD1BA",
+"M. c #C6E1B4",
+"N. c #CDE5BD",
+"B. c #C2D2C6",
+"V. c #CADEC2",
+"C. c #C6D3CC",
+"Z. c #C8D7CB",
+"A. c #CEDAD2",
+"S. c #D2DDD4",
+"D. c #D3E9C6",
+"F. c #D7EBC9",
+"G. c #D9EBCD",
+"H. c #DEEED4",
+"J. c #D6E0D9",
+"K. c #DAE4DC",
+"L. c #E0EFD7",
+"P. c #E5F2DD",
+"I. c #DFE8E0",
+"U. c #E4EBE5",
+"Y. c #E9EFEA",
+"T. c #EDF4EB",
+"R. c #F0FAE6",
+"E. c #F1F8EC",
+"W. c #EDF0F0",
+"Q. c #F4F7F3",
+"!. c #F6F9F4",
+"~. c #F8FAF7",
+"^. c #FEFEFE",
+"/. c None",
+/* pixels */
+"/././././.c h ' Q / W _ &.p././././././././././././././././././././././././././././././././.",
+"/././.4 O % Z ~ ~ W ~ W R U R R ( X.>.p././././././././././././././././././././././././././.",
+"/./.. * = J _ ~ ~ ~ ~ ~ / / / / W W U P P U W .;.2././././././././././././././././././././.",
+"/.= = & a ) W ~ ~ ~ ~ ~ / W / ~ ~ ~ ^ ( ( ^ ~ R R U P Y ~ .;.2././././././././././././././.",
+"O.O = = T ^ W ~ ~ ~ ~ ~ ~ W W / W ~ ~ ~ ~ ~ ~ ~ ( ( ( ( ~ W Y Y Y Y W { &.1././././././././.",
+"0 = * 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ / / W ~ ~ ~ ~ ~ ~ ~ ~ W W W ~ ~ ~ ~ ( ( ( W W R U P U W { X.1.f./.",
+"= = & e ^ W ~ ~ ~ ~ ~ ~ ~ ~ / / ~ ~ ~ ~ ~ ~ ~ ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ^ ( ( / ~ W R U U Y ",
+"= = & e ^ W ~ ~ ~ ~ ~ ~ ~ ~ W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( W ~ ~ ~ ^ ^ ( ",
+"= = * e ^ W ~ ~ ~ ~ ~ ~ / W / W ! ( / ~ W ^ ( ( ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ~ W W ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ ! ~ ~ ~ ~ ~ ~ W W ^ _ ~ K Y W W R P Y W ( ~ ~ ~ ~ ~ ~ ~ W / ~ ~ ~ ^ W ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ W ~ ~ ~ ~ ~ ~ W ) W 1 ` w.V.L.H.D.z.,.~ Y ^ ~ ~ ~ ~ ~ W ~ ~ ~ ( ~ W W ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ W ~ ~ ~ ~ ~ W ) V = 8.~.^.^.^.^.^.^.^.U.<.Y ~ ~ ~ ~ ~ W W ! ~ Y W ^ W ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ W ~ ~ ~ ~ W ^ B O u.^.~.^.^.^.^.~.~.^.^.^.h.Y ^ ~ ~ ^ F $ k.R.G.1.Y / ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ ~ ~ ~ / W ( J X 7.^.~.^.^.^.^.^.^.^.^.^.^.^.s.Y / W ) a 2 U.^.^.d.U ( ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ W / ~ ~ ~ ^ > w ~.^.^.^.^.^.F.%.v c.^.^.^.^.~.X.W ~ ^ > h ^.^.^.d.P ( ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ W ~ ~ W ^ H o e.^.^.^.^.^.G.Y E n . y.^.^.^.^.M.Y ( ! $ @.^.~.^.f.U ( / ~ ~ W ~ ~ ",
+"= = & e ^ W ~ W ! ) t 4 U.^.^.^.^.^.>.U ( _ , 9 ~.^.^.^.~...^ A y.^.~.^.s.M W Y ~ ~ ~ ~ ~ ",
+"= 3 & e ^ W ~ ( ^ ( $ c ^.^.^.^.^.E.) ~ ~ ^ S o n.^.^.^.^.=.- l.v.Y.^.^.^.M.:.:.X.~ ~ ~ ~ ~ ",
+"= = & e ^ ! W W ( J X 7.^.^.^.^.^.F.Y ( W ^ T X 6.^.^.~.^.c.. J.^.^.^.^.^.^.^.^.P.~ ~ ~ ~ ~ ",
+"= = & r ^ W / W ) B o v.^.~.^.^.^.M.U / ~ ~ ! $ o.^.^.^.^.K.* S.^.^.^.^.^.^.^.^.P.~ ~ ~ ~ ~ ",
+"= = & e ^ ! ~ W ) a + S.^.^.^.^.^.z.P ( W ~ ( % z ^.^.^.^.~.f t.U.^.^.^.^.~.^.^.P.~ ~ ~ ~ ~ ",
+"* = & e ^ W ~ W ) t 3 Y.^.^.^.^.^.f.P ( ~ ~ ^ ; h ^.^.^.^.^.:.@ j ^.^.^.^.h.{ X.&.~ ~ ~ ~ ~ ",
+"3 = & e ^ W ~ ~ ^ e 8 Q.^.^.^.^.^.s.P ~ ~ W ^ > 0 ~.^.^.^.^.1.# z ^.^.^.^.d.L W R ~ ~ ~ ~ ~ ",
+"= = & e ^ W ~ ~ ^ > q ~.^.^.^.^.^.p.U ^ ~ W ) e 9 ~.^.^.^.^.3.# k ^.^.^.^.f.Y ( / ~ ~ ~ ~ ~ ",
+"= = & e ^ W / W ^ > w ~.^.^.^.^.^.i.Y / ~ W ^ e 8 Q.^.^.^.^.a.# z ^.^.^.^.f.Y / ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ W / W ^ > w ^.^.^.^.^.^.2.Y / ~ ~ ) e 8 Q.^.^.^.^.s.# z ^.^.^.^.d.P ( ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ W W W ^ > q ^.^.^.^.^.^.p.Y / ~ ~ ^ e 9 Q.^.^.^.^.a.@ z ^.^.^.^.f.U / ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ W / W ) 7 9 Q.^.^.^.^.^.a.P / ~ W ) , 9 Q.^.^.^.^.3.# z ^.^.~.^.f.P ^ ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ W / W ) r 5 T.^.^.^.^.^.d.Y / ~ W ) > q ~.^.^.^.^.1.# k ^.^.^.^.f.Y ( ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ / / W ) i 2 I.^.^.^.^.^.h.P ( ~ W ( > g ^.^.^.^.^.:.# z ^.^.^.^.f.P / ~ ~ ~ ~ ~ ~ ",
+"= = & e ( W / W ) m O Z.^.^.^.^.^.x.P / ~ ~ ( ; j ^.^.^.^.~.&.- k ^.^.~.^.f.P / ~ ~ ~ ~ ~ ~ ",
+"= = & e ( W / W ) F o y.^.~.^.^.^.N.U ( ~ ~ W $ b ^.^.^.^.R._ - k ^.^.^.^.f.Y ( ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ W ~ ~ ^ J X 4.^.^.^.^.^.L.~ ~ W ^ T X #.^.^.^.^.F.~ ; j ^.^.^.^.f.U ( ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ ~ ~ ~ / ^ % l ^.^.^.^.^.!. .R ^ ^ G . r.^.~.^.^.j.E : j ^.^.^.^.f.P ) ( ~ ~ ~ ~ ~ ",
+"= = & e ^ W ~ ~ W ) u = U.^.^.^.^.^.1.Y ! ) a & K.^.^.^.^.;.~ : j ^.^.~.^.z.M I I / ~ ~ W ~ ",
+"= = & e ( W ~ ~ W ( G . q.^.^.^.^.^.D.U ^ ! X o.^.^.^.^.P.~ ^ > g ^.^.^.^.E.-.$.m.X.W ~ ~ ~ ",
+"= = & e ^ / ~ ~ ^ ! ( > w ~.^.^.^.^.^.h.T > j T.^.^.~.^.a.Y _ i 3 U.^.^.^.^.^.^.^.X.R ~ ~ ~ ",
+"= = & e ^ / ~ ~ W W ^ H . 9.^.~.^.^.^.^.K.C.~.^.^.^.^.H.W W ^ T . q.^.~.^.^.^.^.^.X.R ~ ~ ~ ",
+"= = + e ^ W / ~ W W W ) m + B.^.~.^.^.^.^.^.^.^.^.^.E.X.Y ( W ^ B 6 y.^.^.^.E.D.2.( ~ ~ ~ ~ ",
+"= = * e ^ ! / ! W ^ W W ) a 4 b.^.^.^.^.^.^.^.^.^.P...Y ( ! W ! ^ W Z [ *.X.{ Y U ~ ~ ~ ~ ~ ",
+"= = & e ( W ~ ~ W / W / W ) A < +.A.~.^.^.^.^.!.p.W R ~ ~ ~ ~ ~ W / ) E U W W / ^ ~ ~ ~ ~ ~ ",
+"= = & e ^ W ~ ~ / W / / / W ( _ Z X 6.^.^.^.^.E.W ~ ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ / ~ ~ ~ ~ ~ ~ ~ ~ ",
+"= = & e ^ ~ ~ ~ W W / W ~ ~ ~ ~ ) ; h ^.^.^.^.^.d.M U ~ / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ",
+"= = & e ^ W ~ ~ ^ W W / ~ ~ ~ W ) p + S.^.^.^.^.~.M.f. .W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ .",
+"= = & e ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( T O +.^.~.^.^.^.^.^.&.Y ( ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( Y 2.",
+"= = & e ( W ~ ~ ~ ~ ~ ~ ~ ~ ~ / W ) N + b.^.^.^.^.^.^.&.R ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W /.",
+"= = & e ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ^ N 7 r.W.^.^.^.!.X.W ~ ~ W ~ W ~ ~ ~ ~ ~ ~ / ( ( K p./.",
+"= = & e ( W ~ ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( W C Q &.:.X.| ~ ~ ~ ~ W ~ / ~ ( / ( ~ W E U P 1././.",
+"= = + e ^ / / / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W / ) ^ R Y W W ~ ~ ( / ( / W R Y Y U R ( X.,././././.",
+"= = * e ( / ~ / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W ! ( ( ( W W E U P Y W ( X.,.d./././././././././.",
+"= = * e ( W ~ ~ ~ ~ W ! ~ W ~ W ~ ( ( / ^ W W U Y P W ( X.,.d./././././././././././././././.",
+"8 $ * e ( W ~ ~ ~ ! ( ( ( / ( W R Y Y Y R ( X.>.d./././././././././././././././././././././.",
+"/.d . y ^ / / / ( W Y Y P P W ( X.>.d./././././././././././././././././././././././././././.",
+"/./.h : ^ R R R W ( X.<.f./././././././././././././././././././././././././././././././././.",
+"/././.] _ *.3./././././././././././././././././././././././././././././././././././././././."
+};
+
+class EvalMessageBox : public QDialog
+{
+public:
+ EvalMessageBox(bool expired)
+ {
+ setWindowTitle(QLatin1String(" "));
+
+ QString str = qt_eval_string();
+ if (expired) {
+ str = QLatin1String(boilerplate_expired);
+ } else {
+ str = qt_eval_string();
+ }
+ str = str.trimmed();
+
+ QFrame *border = new QFrame(this);
+
+ QLabel *pixmap_label = new QLabel(border);
+ pixmap_label->setPixmap(qtlogo_eval_xpm);
+ pixmap_label->setAlignment(Qt::AlignTop);
+
+ QLabel *text_label = new QLabel(str, border);
+
+ QHBoxLayout *pm_and_text_layout = new QHBoxLayout();
+ pm_and_text_layout->addWidget(pixmap_label);
+ pm_and_text_layout->addWidget(text_label);
+
+ QVBoxLayout *master_layout = new QVBoxLayout(border);
+ master_layout->addLayout(pm_and_text_layout);
+
+ QVBoxLayout *border_layout = new QVBoxLayout(this);
+ border_layout->setMargin(0);
+ border_layout->addWidget(border);
+
+ if (expired) {
+ QPushButton *cmd = new QPushButton(QLatin1String("OK"), border);
+ cmd->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ cmd->setDefault(true);
+
+ QHBoxLayout *button_layout = new QHBoxLayout();
+ master_layout->addLayout(button_layout);
+ button_layout->addWidget(cmd);
+
+ connect(cmd, SIGNAL(clicked()), this, SLOT(close()));
+ } else {
+ border->setFrameShape(QFrame::WinPanel);
+ border->setFrameShadow(QFrame::Raised);
+ setParent(parentWidget(), Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
+ QTimer::singleShot(7000, this, SLOT(close()));
+ setAttribute(Qt::WA_DeleteOnClose);
+ }
+
+ setFixedSize(sizeHint());
+ }
+};
+
+class QGuiFuriCuri : public QCoreFuriCuri
+{
+public:
+ void timerEvent(QTimerEvent *e) {
+ if (e->timerId() == warn) {
+ killTimer(warn);
+ QMessageBox::information(0, QLatin1String("Automatic Timeout"), QLatin1String(will_shutdown_1min));
+ kill = startTimer(KILL_DELAY);
+ } else if (e->timerId() == kill) {
+ killTimer(kill);
+ QMessageBox::information(0, QLatin1String("Automatic Timeout"), QLatin1String(will_shutdown_now));
+ qApp->quit();
+ }
+ }
+};
+
+
+void qt_gui_eval_init(uint)
+{
+ switch (qt_eval_days_left()) {
+ case -2:
+ return;
+
+ case -1: {
+ EvalMessageBox box(true);
+ box.exec();
+ ::exit(0);
+ }
+
+ default: {
+ EvalMessageBox *box = new EvalMessageBox(false);
+ box->show();
+ Q_UNUSED(new QGuiFuriCuri());
+ }
+ }
+}
+
+static QString qt_eval_title_prefix()
+{
+ return QLatin1String("[Qt Evaluation] ");
+}
+
+QString qt_eval_adapt_window_title(const QString &title)
+{
+ if (qt_eval_days_left() == -2)
+ return title;
+ return qt_eval_title_prefix() + title;
+}
+
+void qt_eval_init_widget(QWidget *w)
+{
+ if (qt_eval_days_left() == -2)
+ return;
+ if (w->isTopLevel()) {
+ QString windowTitle = w->windowTitle();
+ if (windowTitle.isEmpty()) {
+ w->setWindowTitle(QLatin1String(" "));
+ } else if (!windowTitle.startsWith(qt_eval_title_prefix())) {
+ qt_eval_adapt_window_title(windowTitle);
+ }
+ }
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/corelib/statemachine/qabstractstate.cpp b/src/corelib/statemachine/qabstractstate.cpp
index 72d640b..cf67cdd 100644
--- a/src/corelib/statemachine/qabstractstate.cpp
+++ b/src/corelib/statemachine/qabstractstate.cpp
@@ -78,7 +78,8 @@ QT_BEGIN_NAMESPACE
function to perform custom processing when the state is exited.
*/
-QAbstractStatePrivate::QAbstractStatePrivate()
+QAbstractStatePrivate::QAbstractStatePrivate()
+ : parentState(0)
{
}
@@ -150,7 +151,10 @@ QAbstractState::~QAbstractState()
*/
QState *QAbstractState::parentState() const
{
- return qobject_cast<QState*>(parent());
+ Q_D(const QAbstractState);
+ if (d->parentState != parent())
+ d->parentState = qobject_cast<QState*>(parent());
+ return d->parentState;
}
/*!
diff --git a/src/corelib/statemachine/qabstractstate_p.h b/src/corelib/statemachine/qabstractstate_p.h
index 4b1306d..cd57815 100644
--- a/src/corelib/statemachine/qabstractstate_p.h
+++ b/src/corelib/statemachine/qabstractstate_p.h
@@ -76,6 +76,8 @@ public:
void emitEntered();
void emitExited();
+
+ mutable QState *parentState;
};
QT_END_NAMESPACE
diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp
index 9abf20b..bcd8364 100644
--- a/src/corelib/statemachine/qstate.cpp
+++ b/src/corelib/statemachine/qstate.cpp
@@ -125,7 +125,7 @@ QT_BEGIN_NAMESPACE
QStatePrivate::QStatePrivate()
: errorState(0), initialState(0), childMode(QState::ExclusiveStates),
- transitionsListNeedsRefresh(true)
+ childStatesListNeedsRefresh(true), transitionsListNeedsRefresh(true)
{
}
@@ -181,15 +181,18 @@ QState::~QState()
QList<QAbstractState*> QStatePrivate::childStates() const
{
- QList<QAbstractState*> result;
- QList<QObject*>::const_iterator it;
- for (it = children.constBegin(); it != children.constEnd(); ++it) {
- QAbstractState *s = qobject_cast<QAbstractState*>(*it);
- if (!s || qobject_cast<QHistoryState*>(s))
- continue;
- result.append(s);
+ if (childStatesListNeedsRefresh) {
+ childStatesList.clear();
+ QList<QObject*>::const_iterator it;
+ for (it = children.constBegin(); it != children.constEnd(); ++it) {
+ QAbstractState *s = qobject_cast<QAbstractState*>(*it);
+ if (!s || qobject_cast<QHistoryState*>(s))
+ continue;
+ childStatesList.append(s);
+ }
+ childStatesListNeedsRefresh = false;
}
- return result;
+ return childStatesList;
}
QList<QHistoryState*> QStatePrivate::historyStates() const
@@ -473,8 +476,10 @@ void QState::setChildMode(ChildMode mode)
bool QState::event(QEvent *e)
{
Q_D(QState);
- if ((e->type() == QEvent::ChildAdded) || (e->type() == QEvent::ChildRemoved))
+ if ((e->type() == QEvent::ChildAdded) || (e->type() == QEvent::ChildRemoved)) {
+ d->childStatesListNeedsRefresh = true;
d->transitionsListNeedsRefresh = true;
+ }
return QAbstractState::event(e);
}
diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h
index 3b5f416..34c8838 100644
--- a/src/corelib/statemachine/qstate_p.h
+++ b/src/corelib/statemachine/qstate_p.h
@@ -99,6 +99,8 @@ public:
QAbstractState *errorState;
QAbstractState *initialState;
QState::ChildMode childMode;
+ mutable bool childStatesListNeedsRefresh;
+ mutable QList<QAbstractState*> childStatesList;
mutable bool transitionsListNeedsRefresh;
mutable QList<QAbstractTransition*> transitionsList;
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index e182c88..689967a 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -1216,8 +1216,7 @@ void QStateMachinePrivate::_q_process()
delete e;
e = 0;
}
- if (enabledTransitions.isEmpty() && !internalEventQueue.isEmpty()) {
- e = internalEventQueue.takeFirst();
+ if (enabledTransitions.isEmpty() && ((e = dequeueInternalEvent()) != 0)) {
#ifdef QSTATEMACHINE_DEBUG
qDebug() << q << ": dequeued internal event" << e << "of type" << e->type();
#endif
@@ -1228,13 +1227,7 @@ void QStateMachinePrivate::_q_process()
}
}
if (enabledTransitions.isEmpty()) {
- if (externalEventQueue.isEmpty()) {
- if (internalEventQueue.isEmpty()) {
- processing = false;
- stopProcessingReason = EventQueueEmpty;
- }
- } else {
- e = externalEventQueue.takeFirst();
+ if ((e = dequeueExternalEvent()) != 0) {
#ifdef QSTATEMACHINE_DEBUG
qDebug() << q << ": dequeued external event" << e << "of type" << e->type();
#endif
@@ -1243,6 +1236,11 @@ void QStateMachinePrivate::_q_process()
delete e;
e = 0;
}
+ } else {
+ if (isInternalEventQueueEmpty()) {
+ processing = false;
+ stopProcessingReason = EventQueueEmpty;
+ }
}
}
if (!enabledTransitions.isEmpty()) {
@@ -1278,17 +1276,60 @@ void QStateMachinePrivate::_q_process()
}
}
+void QStateMachinePrivate::postInternalEvent(QEvent *e)
+{
+ QMutexLocker locker(&internalEventMutex);
+ internalEventQueue.append(e);
+}
+
+void QStateMachinePrivate::postExternalEvent(QEvent *e)
+{
+ QMutexLocker locker(&externalEventMutex);
+ externalEventQueue.append(e);
+}
+
+QEvent *QStateMachinePrivate::dequeueInternalEvent()
+{
+ QMutexLocker locker(&internalEventMutex);
+ if (internalEventQueue.isEmpty())
+ return 0;
+ return internalEventQueue.takeFirst();
+}
+
+QEvent *QStateMachinePrivate::dequeueExternalEvent()
+{
+ QMutexLocker locker(&externalEventMutex);
+ if (externalEventQueue.isEmpty())
+ return 0;
+ return externalEventQueue.takeFirst();
+}
+
+bool QStateMachinePrivate::isInternalEventQueueEmpty()
+{
+ QMutexLocker locker(&internalEventMutex);
+ return internalEventQueue.isEmpty();
+}
+
+bool QStateMachinePrivate::isExternalEventQueueEmpty()
+{
+ QMutexLocker locker(&externalEventMutex);
+ return externalEventQueue.isEmpty();
+}
+
void QStateMachinePrivate::processEvents(EventProcessingMode processingMode)
{
+ Q_Q(QStateMachine);
if ((state != Running) || processing || processingScheduled)
return;
switch (processingMode) {
case DirectProcessing:
- _q_process();
- break;
+ if (QThread::currentThread() == q->thread()) {
+ _q_process();
+ break;
+ } // fallthrough -- processing must be done in the machine thread
case QueuedProcessing:
processingScheduled = true;
- QMetaObject::invokeMethod(q_func(), "_q_process", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(q, "_q_process", Qt::QueuedConnection);
break;
}
}
@@ -1296,6 +1337,7 @@ void QStateMachinePrivate::processEvents(EventProcessingMode processingMode)
void QStateMachinePrivate::cancelAllDelayedEvents()
{
Q_Q(QStateMachine);
+ QMutexLocker locker(&delayedEventsMutex);
QHash<int, QEvent*>::const_iterator it;
for (it = delayedEvents.constBegin(); it != delayedEvents.constEnd(); ++it) {
int id = it.key();
@@ -1547,7 +1589,7 @@ void QStateMachinePrivate::handleFilteredEvent(QObject *watched, QEvent *event)
{
Q_ASSERT(qobjectEvents.contains(watched));
if (qobjectEvents[watched].contains(event->type())) {
- internalEventQueue.append(new QStateMachine::WrappedEvent(watched, handler->cloneEvent(event)));
+ postInternalEvent(new QStateMachine::WrappedEvent(watched, handler->cloneEvent(event)));
processEvents(DirectProcessing);
}
}
@@ -1571,7 +1613,7 @@ void QStateMachinePrivate::handleTransitionSignal(QObject *sender, int signalInd
qDebug() << q_func() << ": sending signal event ( sender =" << sender
<< ", signal =" << sender->metaObject()->method(signalIndex).signature() << ')';
#endif
- internalEventQueue.append(new QStateMachine::SignalEvent(sender, signalIndex, vargs));
+ postInternalEvent(new QStateMachine::SignalEvent(sender, signalIndex, vargs));
processEvents(DirectProcessing);
}
@@ -1825,6 +1867,8 @@ void QStateMachine::stop()
}
/*!
+ \threadsafe
+
Posts the given \a event of the given \a priority for processing by this
state machine.
@@ -1852,16 +1896,18 @@ void QStateMachine::postEvent(QEvent *event, EventPriority priority)
#endif
switch (priority) {
case NormalPriority:
- d->externalEventQueue.append(event);
+ d->postExternalEvent(event);
break;
case HighPriority:
- d->internalEventQueue.append(event);
+ d->postInternalEvent(event);
break;
}
d->processEvents(QStateMachinePrivate::QueuedProcessing);
}
/*!
+ \threadsafe
+
Posts the given \a event for processing by this state machine, with the
given \a delay in milliseconds. Returns an identifier associated with the
delayed event, or -1 if the event could not be posted.
@@ -1893,12 +1939,15 @@ int QStateMachine::postDelayedEvent(QEvent *event, int delay)
#ifdef QSTATEMACHINE_DEBUG
qDebug() << this << ": posting event" << event << "with delay" << delay;
#endif
+ QMutexLocker locker(&d->delayedEventsMutex);
int tid = startTimer(delay);
d->delayedEvents[tid] = event;
return tid;
}
/*!
+ \threadsafe
+
Cancels the delayed event identified by the given \a id. The id should be a
value returned by a call to postDelayedEvent(). Returns true if the event
was successfully cancelled, otherwise returns false.
@@ -1912,6 +1961,7 @@ bool QStateMachine::cancelDelayedEvent(int id)
qWarning("QStateMachine::cancelDelayedEvent: the machine is not running");
return false;
}
+ QMutexLocker locker(&d->delayedEventsMutex);
QEvent *e = d->delayedEvents.take(id);
if (!e)
return false;
@@ -1921,8 +1971,6 @@ bool QStateMachine::cancelDelayedEvent(int id)
}
/*!
- \internal
-
Returns the maximal consistent set of states (including parallel and final
states) that this state machine is currently in. If a state \c s is in the
configuration, it is always the case that the parent of \c s is also in
@@ -1963,18 +2011,23 @@ bool QStateMachine::event(QEvent *e)
int tid = te->timerId();
if (d->state != QStateMachinePrivate::Running) {
// This event has been cancelled already
+ QMutexLocker locker(&d->delayedEventsMutex);
Q_ASSERT(!d->delayedEvents.contains(tid));
return true;
}
+ d->delayedEventsMutex.lock();
QEvent *ee = d->delayedEvents.take(tid);
if (ee != 0) {
killTimer(tid);
- d->externalEventQueue.append(ee);
+ d->delayedEventsMutex.unlock();
+ d->postExternalEvent(ee);
d->processEvents(QStateMachinePrivate::DirectProcessing);
return true;
+ } else {
+ d->delayedEventsMutex.unlock();
}
}
- return QObject::event(e);
+ return QState::event(e);
}
#ifndef QT_NO_STATEMACHINE_EVENTFILTER
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index cf7a073..69b727d 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -58,6 +58,7 @@
#include <QtCore/qcoreevent.h>
#include <QtCore/qhash.h>
#include <QtCore/qlist.h>
+#include <QtCore/qmutex.h>
#include <QtCore/qpair.h>
#include <QtCore/qset.h>
#include <QtCore/qvector.h>
@@ -159,6 +160,13 @@ public:
void unregisterAllTransitions();
void handleTransitionSignal(QObject *sender, int signalIndex,
void **args);
+
+ void postInternalEvent(QEvent *e);
+ void postExternalEvent(QEvent *e);
+ QEvent *dequeueInternalEvent();
+ QEvent *dequeueExternalEvent();
+ bool isInternalEventQueueEmpty();
+ bool isExternalEventQueueEmpty();
void processEvents(EventProcessingMode processingMode);
void cancelAllDelayedEvents();
@@ -181,6 +189,8 @@ public:
QSet<QAbstractState*> configuration;
QList<QEvent*> internalEventQueue;
QList<QEvent*> externalEventQueue;
+ QMutex internalEventMutex;
+ QMutex externalEventMutex;
QStateMachine::Error error;
QStateMachine::RestorePolicy globalRestorePolicy;
@@ -214,6 +224,7 @@ public:
QHash<QObject*, QHash<QEvent::Type, int> > qobjectEvents;
#endif
QHash<int, QEvent*> delayedEvents;
+ QMutex delayedEventsMutex;
typedef QEvent* (*f_cloneEvent)(QEvent*);
struct Handler {
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 95c0bed..58252ca 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -2896,6 +2896,7 @@ void QWidgetPrivate::setCursor_sys(const QCursor &)
#else
Q_Q(QWidget);
if (q->testAttribute(Qt::WA_WState_Created)) {
+ QMacCocoaAutoReleasePool pool;
[qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
}
#endif
@@ -2908,6 +2909,7 @@ void QWidgetPrivate::unsetCursor_sys()
#else
Q_Q(QWidget);
if (q->testAttribute(Qt::WA_WState_Created)) {
+ QMacCocoaAutoReleasePool pool;
[qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
}
#endif