summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mkspecs/features/qt_module_pris.prf8
-rw-r--r--mkspecs/features/resources.prf2
-rw-r--r--mkspecs/macx-ios-clang/features/default_pre.prf2
-rw-r--r--qmake/Makefile.win322
-rw-r--r--qmake/doc/snippets/code/doc_src_qmake-manual.pro9
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp21
-rw-r--r--qmake/generators/metamakefile.cpp4
-rw-r--r--qmake/generators/unix/unixmake.cpp2
-rw-r--r--qmake/generators/unix/unixmake2.cpp1
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp4
-rw-r--r--qmake/generators/win32/winmakefile.cpp4
-rw-r--r--qmake/library/qmakebuiltins.cpp29
-rw-r--r--qmake/library/qmakeevaluator.h6
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java51
-rw-r--r--src/corelib/global/qglobal.cpp373
-rw-r--r--src/corelib/global/qlogging.cpp24
-rw-r--r--src/corelib/global/qlogging.h4
-rw-r--r--src/corelib/global/qsysinfo.h11
-rw-r--r--src/corelib/io/io.pri1
-rw-r--r--src/corelib/io/qdebug.h12
-rw-r--r--src/corelib/io/qfileselector.cpp2
-rw-r--r--src/corelib/io/qloggingcategory.cpp12
-rw-r--r--src/corelib/io/qloggingregistry.cpp1
-rw-r--r--src/corelib/json/qjsonobject.cpp27
-rw-r--r--src/corelib/json/qjsonobject.h15
-rw-r--r--src/corelib/statemachine/qabstractstate.cpp39
-rw-r--r--src/corelib/statemachine/qabstractstate.h4
-rw-r--r--src/corelib/statemachine/qabstractstate_p.h3
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp5
-rw-r--r--src/corelib/tools/qbytearray.cpp6
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp35
-rw-r--r--src/gui/opengl/qopengltexturecache.cpp31
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.cpp86
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.h2
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject_p.h (renamed from src/corelib/io/qloggingcategory_p.h)71
-rw-r--r--src/platformsupport/linuxaccessibility/application.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp2
-rw-r--r--src/testlib/qtestlog.cpp6
-rw-r--r--src/widgets/accessible/qaccessiblewidget.cpp14
-rw-r--r--src/widgets/accessible/qaccessiblewidgets.cpp12
-rw-r--r--src/widgets/accessible/simplewidgets.cpp2
-rw-r--r--src/widgets/dialogs/qprogressdialog.cpp2
-rw-r--r--src/widgets/styles/qcommonstyle.cpp2
-rw-r--r--src/widgets/styles/qstyleanimation.cpp25
-rw-r--r--src/widgets/styles/qstyleanimation_p.h15
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp68
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h18
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp42
-rw-r--r--src/widgets/widgets/qmdisubwindow_p.h3
-rw-r--r--tests/auto/corelib/global/qlogging/tst_qlogging.cpp62
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp23
-rw-r--r--tests/auto/corelib/json/tst_qtjson.cpp55
-rw-r--r--tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp904
-rw-r--r--tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp27
-rw-r--r--tests/auto/gui/qopengl/tst_qopengl.cpp110
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp61
-rw-r--r--tests/auto/tools/qmake/testdata/functions/functions.pro9
-rw-r--r--tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp47
59 files changed, 2045 insertions, 377 deletions
diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf
index aba720238f..3d438e52f4 100644
--- a/mkspecs/features/qt_module_pris.prf
+++ b/mkspecs/features/qt_module_pris.prf
@@ -148,9 +148,11 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
"QT_MODULE_HOST_LIB_BASE = $$MODULE_BASE_OUTDIR/lib" \
"QT_MODULE_LIBEXEC_BASE = $$MODULE_BASE_OUTDIR/libexec" \
"QT_MODULE_PLUGIN_BASE = $$MODULE_BASE_OUTDIR/plugins" \
- "include($$MODULE_PRI)"
+ "include($$MODULE_PRI)" \
+ "QT.$${MODULE_ID}.priority = 1"
!internal_module: MODULE_FWD_PRI_CONT += \
- "include($$MODULE_PRIVATE_PRI)"
+ "include($$MODULE_PRIVATE_PRI)" \
+ "QT.$${MODULE}_private.priority = 1"
MODULE_FWD_PRI_CONT += $$MODULE_FWD_PRI_CONT_SUFFIX
write_file($$MODULE_FWD_PRI, MODULE_FWD_PRI_CONT)|error("Aborting.")
touch($$MODULE_FWD_PRI, $$MODULE_PRI)
@@ -178,7 +180,7 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
for(mod, mods_to_load) {
for(var, $$list(VERSION MAJOR_VERSION MINOR_VERSION PATCH_VERSION \
name depends run_depends plugin_types module_config CONFIG DEFINES \
- includes bins libs libexecs plugins imports qml \
+ priority includes bins libs libexecs plugins imports qml \
)):defined(QT.$${mod}.$$var, var):cache(QT.$${mod}.$$var, transient)
}
cache(QT_MODULES, transient)
diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf
index f8a15bc84f..27db7d7d7a 100644
--- a/mkspecs/features/resources.prf
+++ b/mkspecs/features/resources.prf
@@ -11,7 +11,7 @@ rcc.name = RCC ${QMAKE_FILE_IN}
rcc.depend_command = $$QMAKE_RCC_DEP -list $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN}
rcc.CONFIG += add_inputs_as_makefile_deps
-resources_small|ltcg|macx-xcode {
+resources_small|ltcg|macx-xcode|contains(TEMPLATE, "vc.*") {
rcc.output = $$RCC_DIR/$${first(QMAKE_MOD_RCC)}_${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)}
rcc.commands = $$QMAKE_RCC $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
diff --git a/mkspecs/macx-ios-clang/features/default_pre.prf b/mkspecs/macx-ios-clang/features/default_pre.prf
index 7b8f9c9b5d..dfede454b5 100644
--- a/mkspecs/macx-ios-clang/features/default_pre.prf
+++ b/mkspecs/macx-ios-clang/features/default_pre.prf
@@ -16,4 +16,6 @@ iphonesimulator_and_iphoneos:iphonesimulator {
QT_ARCH = i386
QT_CPU_FEATURES.i386 = sse sse2
DEFINES += QT_COMPILER_SUPPORTS_SSE2
+ CONFIG -= neon
+ CONFIG += sse sse2
}
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 44102474b8..bac6e950be 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -61,7 +61,7 @@ OBJS = project.obj main.obj ioutils.obj proitems.obj qmakevfs.obj \
qmakeglobals.obj qmakeparser.obj qmakeevaluator.obj qmakebuiltins.obj \
makefile.obj unixmake.obj unixmake2.obj mingw_make.obj \
option.obj winmakefile.obj projectgenerator.obj property.obj meta.obj \
- makefiledeps.obj metamakefile.obj xmloutput.obj pbuilder_pbx.obj \
+ makefiledeps.obj metamakefile.obj xmloutput.obj \
msvc_nmake.obj msvc_vcproj.obj msvc_vcxproj.obj \
msvc_objectmodel.obj msbuild_objectmodel.obj registry.obj \
gbuild.obj cesdkhandler.obj
diff --git a/qmake/doc/snippets/code/doc_src_qmake-manual.pro b/qmake/doc/snippets/code/doc_src_qmake-manual.pro
index ff1edb878d..07bed62763 100644
--- a/qmake/doc/snippets/code/doc_src_qmake-manual.pro
+++ b/qmake/doc/snippets/code/doc_src_qmake-manual.pro
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -218,13 +218,6 @@ FORMS = mydialog.ui \
#! [32]
-#! [33]
-FORMS3 = my_uic3_dialog.ui \
- my_uic3_widget.ui \
- my_uic3_config.ui
-#! [33]
-
-
#! [34]
HEADERS = myclass.h \
login.h \
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index 835676d9fe..70ac77f5da 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -418,7 +418,7 @@ class ProjectBuilderSources
bool buildable, object_output;
QString key, group, compiler;
public:
- ProjectBuilderSources(const QString &key, bool buildable=false, const QString &group=QString(), const QString &compiler=QString(), bool producesObject=false);
+ ProjectBuilderSources(const QString &key, bool buildable = false, const QString &compiler = QString(), bool producesObject = false);
QStringList files(QMakeProject *project) const;
inline bool isBuildable() const { return buildable; }
inline QString keyName() const { return key; }
@@ -442,8 +442,8 @@ public:
}
};
-ProjectBuilderSources::ProjectBuilderSources(const QString &k, bool b,
- const QString &g, const QString &c, bool o) : buildable(b), object_output(o), key(k), group(g), compiler(c)
+ProjectBuilderSources::ProjectBuilderSources(const QString &k, bool b, const QString &c, bool o) :
+ buildable(b), object_output(o), key(k), compiler(c)
{
// Override group name for a few common keys
if (k == "SOURCES" || k == "OBJECTIVE_SOURCES" || k == "HEADERS")
@@ -463,10 +463,16 @@ ProjectBuilderSources::files(QMakeProject *project) const
{
QStringList ret = project->values(ProKey(key)).toQStringList();
if(key == "QMAKE_INTERNAL_INCLUDED_FILES") {
+ QString qtPrefix(QLibraryInfo::rawLocation(QLibraryInfo::PrefixPath, QLibraryInfo::EffectivePaths) + '/');
+ QString qtSrcPrefix(QLibraryInfo::rawLocation(QLibraryInfo::PrefixPath, QLibraryInfo::EffectiveSourcePaths) + '/');
+
QStringList newret;
for(int i = 0; i < ret.size(); ++i) {
- if(!ret.at(i).endsWith(Option::prf_ext))
- newret.append(ret.at(i));
+ // Don't show files "internal" to Qt in Xcode
+ if (ret.at(i).startsWith(qtPrefix) || ret.at(i).startsWith(qtSrcPrefix))
+ continue;
+
+ newret.append(ret.at(i));
}
ret = newret;
}
@@ -567,6 +573,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
// doesn't have access to any of the information it needs to resolve relative paths.
project->values("QMAKE_INTERNAL_INCLUDED_FILES").prepend(fileFixify(project->projectFile(), qmake_getpwd(), input_dir));
+ // Since we can't fileFixify inside ProjectBuilderSources::files(), we resolve the absolute paths here
+ project->values("QMAKE_INTERNAL_INCLUDED_FILES") = ProStringList(fileFixify(project->values("QMAKE_INTERNAL_INCLUDED_FILES").toQStringList(), FileFixifyAbsolute));
+
//DUMP SOURCES
QMap<QString, ProStringList> groups;
QList<ProjectBuilderSources> sources;
@@ -606,7 +615,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
}
}
sources.append(ProjectBuilderSources(inputs.at(input).toQString(), true,
- QString(), (*it).toQString(), isObj));
+ (*it).toQString(), isObj));
if (isObj) {
inputs.removeAt(input);
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp
index a037a966f6..ababbb2076 100644
--- a/qmake/generators/metamakefile.cpp
+++ b/qmake/generators/metamakefile.cpp
@@ -444,7 +444,11 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO)
} else if(gen == "MINGW") {
mkfile = new MingwMakefileGenerator;
} else if(gen == "PROJECTBUILDER" || gen == "XCODE") {
+#ifdef Q_CC_MSVC
+ fprintf(stderr, "Generating Xcode projects is not supported with an MSVC build of Qt.\n");
+#else
mkfile = new ProjectBuilderMakefileGenerator;
+#endif
} else if(gen == "MSVC.NET") {
if (proj->first("TEMPLATE").startsWith("vc"))
mkfile = new VcprojGenerator;
diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp
index 5ea47cc867..e426180012 100644
--- a/qmake/generators/unix/unixmake.cpp
+++ b/qmake/generators/unix/unixmake.cpp
@@ -111,6 +111,8 @@ UnixMakefileGenerator::init()
QString sroot = project->sourceRoot();
foreach (const ProString &iif, project->values("QMAKE_INTERNAL_INCLUDED_FILES")) {
+ if (iif == project->cacheFile())
+ continue;
if (iif.startsWith(sroot) && iif.at(sroot.length()) == QLatin1Char('/'))
project->values("DISTFILES") += fileFixify(iif.toQString(), FileFixifyRelative);
}
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index 0ac840d9c9..e16e0f5c20 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -278,6 +278,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
if(do_incremental && !src_incremental)
do_incremental = false;
t << "DIST = " << valList(fileFixify(project->values("DISTFILES").toQStringList())) << " "
+ << valList(escapeFilePaths(project->values("HEADERS"))) << " "
<< valList(escapeFilePaths(project->values("SOURCES"))) << endl;
t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl;
// The comment is important for mingw32-make.exe on Windows as otherwise trailing slashes
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index a28ddd63c4..9916db9f92 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -1480,10 +1480,7 @@ void VcprojGenerator::initFormFiles()
vcProject.FormFiles.ParseFiles = _False;
vcProject.FormFiles.Filter = "ui";
vcProject.FormFiles.Guid = _GUIDFormFiles;
-
vcProject.FormFiles.addFiles(project->values("FORMS"));
- vcProject.FormFiles.addFiles(project->values("FORMS3"));
-
vcProject.FormFiles.Project = this;
vcProject.FormFiles.Config = &(vcProject.Configuration);
vcProject.FormFiles.CustomBuild = none;
@@ -1543,7 +1540,6 @@ void VcprojGenerator::initExtraCompilerOutputs()
{
ProStringList otherFilters;
otherFilters << "FORMS"
- << "FORMS3"
<< "GENERATED_FILES"
<< "GENERATED_SOURCES"
<< "HEADERS"
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index da81b85e2a..1fee98fcbd 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -678,7 +678,9 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t)
writeExtraCompilerVariables(t);
writeExtraVariables(t);
- t << "DIST = " << varList("DISTFILES") << endl;
+ t << "DIST = " << varList("DISTFILES") << " "
+ << varList("HEADERS") << " "
+ << varList("SOURCES") << endl;
t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl;
// The comment is important to maintain variable compatibility with Unix
// Makefiles, while not interpreting a trailing-slash as a linebreak
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 46934c83e9..9824b306b9 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -437,8 +437,9 @@ QByteArray QMakeEvaluator::getCommandOutput(const QString &args) const
void QMakeEvaluator::populateDeps(
const ProStringList &deps, const ProString &prefix, const ProStringList &suffixes,
+ const ProString &priosfx,
QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees,
- ProStringList &rootSet) const
+ QMultiMap<int, ProString> &rootSet) const
{
foreach (const ProString &item, deps)
if (!dependencies.contains(item.toKey())) {
@@ -447,13 +448,13 @@ void QMakeEvaluator::populateDeps(
foreach (const ProString &suffix, suffixes)
depends += values(ProKey(prefix + item + suffix));
if (depends.isEmpty()) {
- rootSet << item;
+ rootSet.insert(first(ProKey(prefix + item + priosfx)).toInt(), item);
} else {
foreach (const ProString &dep, depends) {
dset.insert(dep.toKey());
dependees[dep.toKey()] << item;
}
- populateDeps(depends, prefix, suffixes, dependencies, dependees, rootSet);
+ populateDeps(depends, prefix, suffixes, priosfx, dependencies, dependees, rootSet);
}
}
}
@@ -974,27 +975,31 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
break;
case E_SORT_DEPENDS:
case E_RESOLVE_DEPENDS:
- if (args.count() < 1 || args.count() > 3) {
- evalError(fL1S("%1(var, [prefix, [suffixes]]) requires one to three arguments.")
+ if (args.count() < 1 || args.count() > 4) {
+ evalError(fL1S("%1(var, [prefix, [suffixes, [prio-suffix]]]) requires one to four arguments.")
.arg(func.toQString(m_tmp1)));
} else {
QHash<ProKey, QSet<ProKey> > dependencies;
ProValueMap dependees;
- ProStringList rootSet;
+ QMultiMap<int, ProString> rootSet;
ProStringList orgList = values(args.at(0).toKey());
- populateDeps(orgList, (args.count() < 2 ? ProString() : args.at(1)),
+ ProString prefix = args.count() < 2 ? ProString() : args.at(1);
+ ProString priosfx = args.count() < 4 ? ProString(".priority") : args.at(3);
+ populateDeps(orgList, prefix,
args.count() < 3 ? ProStringList(ProString(".depends"))
: split_value_list(args.at(2).toQString(m_tmp2)),
- dependencies, dependees, rootSet);
- for (int i = 0; i < rootSet.size(); ++i) {
- const ProString &item = rootSet.at(i);
+ priosfx, dependencies, dependees, rootSet);
+ while (!rootSet.isEmpty()) {
+ QMultiMap<int, ProString>::iterator it = rootSet.begin();
+ const ProString item = *it;
+ rootSet.erase(it);
if ((func_t == E_RESOLVE_DEPENDS) || orgList.contains(item))
ret.prepend(item);
foreach (const ProString &dep, dependees[item.toKey()]) {
QSet<ProKey> &dset = dependencies[dep.toKey()];
- dset.remove(rootSet.at(i).toKey()); // *Don't* use 'item' - rootSet may have changed!
+ dset.remove(item.toKey());
if (dset.isEmpty())
- rootSet << dep;
+ rootSet.insert(first(ProKey(prefix + dep + priosfx)).toInt(), dep);
}
}
}
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index f322a48011..8b2fc3ef06 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -51,6 +51,7 @@
#include <qlist.h>
#include <qlinkedlist.h>
+#include <qmap.h>
#include <qset.h>
#include <qstack.h>
#include <qstring.h>
@@ -238,8 +239,9 @@ public:
void populateDeps(
const ProStringList &deps, const ProString &prefix, const ProStringList &suffixes,
- QHash<ProKey, QSet<ProKey> > &dependencies,
- ProValueMap &dependees, ProStringList &rootSet) const;
+ const ProString &priosfx,
+ QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees,
+ QMultiMap<int, ProString> &rootSet) const;
VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
const QString &contents);
diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
index ef6d20fc9a..cc7fc505ee 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
@@ -48,6 +48,7 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
@@ -792,8 +793,28 @@ public class ExtractStyle {
}
}
+ class DrawableCache
+ {
+ public DrawableCache(JSONObject json, Object drawable)
+ {
+ object = json;
+ this.drawable = drawable;
+ }
+ JSONObject object;
+ Object drawable;
+ }
+ private HashMap<String, DrawableCache> m_drawableCache = new HashMap<String, DrawableCache>();
+
public JSONObject getDrawable(Object drawable, String filename)
{
+ DrawableCache dc = m_drawableCache.get(filename);
+ if (dc != null)
+ {
+ if (dc.drawable.equals(drawable))
+ return dc.object;
+ else
+ Log.e(QtNative.QtTAG, "Different drawable objects points to the same file name \"" + filename +"\"");
+ }
JSONObject json = new JSONObject();
Bitmap bmp;
if (drawable instanceof Bitmap)
@@ -909,6 +930,7 @@ public class ExtractStyle {
json.put("path", filename);
json.put("width", bmp.getWidth());
json.put("height", bmp.getHeight());
+ m_drawableCache.put(filename, new DrawableCache(json, drawable));
// MinistroActivity.nativeChmode(filename, 0644);
} catch (JSONException e) {
e.printStackTrace();
@@ -1526,6 +1548,34 @@ public class ExtractStyle {
jsonWriter.name("simple_spinner_item").value(extractItemStyle(android.R.layout.simple_spinner_item, "simple_spinner_item", -1));
jsonWriter.name("simple_spinner_dropdown_item").value(extractItemStyle(android.R.layout.simple_spinner_dropdown_item, "simple_spinner_dropdown_item",android.R.style.TextAppearance_Large));
jsonWriter.name("simple_dropdown_item_1line").value(extractItemStyle(android.R.layout.simple_dropdown_item_1line, "simple_dropdown_item_1line",android.R.style.TextAppearance_Large));
+ if (Build.VERSION.SDK_INT > 10) {
+ Class<?> layoutClass = Class.forName("android.R$layout");
+ int styleId = layoutClass.getDeclaredField("simple_selectable_list_item").getInt(null);
+ jsonWriter.name("simple_selectable_list_item").value(extractItemStyle(styleId, "simple_selectable_list_item",android.R.style.TextAppearance_Large));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void extractListView(SimpleJsonWriter writer, String styleName, String qtClass)
+ {
+ JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
+ try {
+ Class<?> attrClass = Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+
+ int[] styleAttrs = (int[]) styleableClass.getDeclaredField("ListView").get(null);
+ TypedArray a = m_theme.obtainStyledAttributes(null, styleAttrs, styleId, 0);
+
+ Drawable divider = a.getDrawable(getField(styleableClass,"ListView_divider"));
+ if (divider != null)
+ json.put("ListView_divider", getDrawable(divider, styleName + "_ListView_divider"));
+
+ json.put("ListView_dividerHeight", a.getDimensionPixelSize(getField(styleableClass, "ListView_dividerHeight"), 0));
+
+ a.recycle();
+ writer.name(styleName).value(json);
} catch (Exception e) {
e.printStackTrace();
}
@@ -1661,6 +1711,7 @@ public class ExtractStyle {
extractCompoundButton(jsonWriter, "radioButtonStyle", "QRadioButton");
jsonWriter.name("textViewStyle").value(extractTextAppearanceInformations("textViewStyle", "QWidget", null, -1));
jsonWriter.name("scrollViewStyle").value(extractTextAppearanceInformations("scrollViewStyle", "QAbstractScrollArea", null, -1));
+ extractListView(jsonWriter, "listViewStyle", "QListView");
extractItemsStyle(jsonWriter);
extractCompoundButton(jsonWriter, "buttonStyleToggle", null);
if (Build.VERSION.SDK_INT > 10) {
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 66f2923370..fb7bd9fa01 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -2051,22 +2051,14 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
#if defined(Q_OS_UNIX)
# if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD)
# define USE_ETC_OS_RELEASE
-# endif
struct QUnixOSVersion
{
- // from uname(2)
- QString sysName;
- QString sysNameLower;
- QString sysRelease;
-
-# if !defined(Q_OS_ANDROID) && !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_MAC)
- // from /etc/os-release or guessed
- QString versionIdentifier; // ${ID}_$VERSION_ID
- QString versionText; // $PRETTY_NAME
-# endif
+ // from /etc/os-release
+ QString productType; // $ID
+ QString productVersion; // $VERSION_ID
+ QString prettyName; // $PRETTY_NAME
};
-# ifdef USE_ETC_OS_RELEASE
static QString unquote(const char *begin, const char *end)
{
if (*begin == '"') {
@@ -2089,7 +2081,6 @@ static bool readEtcOsRelease(QUnixOSVersion &v)
return false;
}
- QString partialIdentifier;
QByteArray buffer(sbuf.st_size, Qt::Uninitialized);
buffer.resize(qt_safe_read(fd, buffer.data(), sbuf.st_size));
qt_safe_close(fd);
@@ -2107,16 +2098,14 @@ static bool readEtcOsRelease(QUnixOSVersion &v)
if (!eol)
eol = end - 1;
+ // note: we're doing a binary search here, so comparison
+ // must always be sorted
int cmp = strncmp(ptr, idString, strlen(idString));
if (cmp < 0)
continue;
if (cmp == 0) {
ptr += strlen(idString);
- QString id = unquote(ptr, eol);
- if (partialIdentifier.isNull())
- partialIdentifier = id;
- else
- v.versionIdentifier = id + QLatin1Char('_') + partialIdentifier;
+ v.productType = unquote(ptr, eol);
continue;
}
@@ -2125,7 +2114,7 @@ static bool readEtcOsRelease(QUnixOSVersion &v)
continue;
if (cmp == 0) {
ptr += strlen(prettyNameString);
- v.versionText = unquote(ptr, eol);
+ v.prettyName = unquote(ptr, eol);
continue;
}
@@ -2134,11 +2123,7 @@ static bool readEtcOsRelease(QUnixOSVersion &v)
continue;
if (cmp == 0) {
ptr += strlen(versionIdString);
- QString id = unquote(ptr, eol);
- if (partialIdentifier.isNull())
- partialIdentifier = id;
- else
- v.versionIdentifier = partialIdentifier + QLatin1Char('_') + id;
+ v.productVersion = unquote(ptr, eol);
continue;
}
}
@@ -2146,34 +2131,6 @@ static bool readEtcOsRelease(QUnixOSVersion &v)
return true;
}
# endif // USE_ETC_OS_RELEASE
-
-static QUnixOSVersion detectUnixVersion()
-{
- QUnixOSVersion v;
- struct utsname u;
- if (uname(&u) != -1) {
- v.sysName = QString::fromLatin1(u.sysname);
- v.sysNameLower = v.sysName.toLower();
- v.sysRelease = QString::fromLatin1(u.release);
- } else {
- v.sysName = QLatin1String("Detection failed");
- // leave sysNameLower & sysRelease unset
- }
-
-# if !defined(Q_OS_ANDROID) && !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_MAC)
-# ifdef USE_ETC_OS_RELEASE
- if (readEtcOsRelease(v))
- return v;
-# endif
-
- if (!v.sysNameLower.isEmpty()) {
- // will produce "qnx_6.5" or "sunos_5.9"
- v.versionIdentifier = v.sysNameLower + QLatin1Char('_') + v.sysRelease;
- }
-# endif
-
- return v;
-}
#endif // Q_OS_UNIX
@@ -2183,7 +2140,8 @@ static QUnixOSVersion detectUnixVersion()
Returns the architecture of the CPU that Qt was compiled for, in text
format. Note that this may not match the actual CPU that the application is
running on if there's an emulation layer or if the CPU supports multiple
- architectures (like x86-64 processors supporting i386 applications).
+ architectures (like x86-64 processors supporting i386 applications). To
+ detect that, use currentCpuArchitecture().
Values returned by this function are stable and will not change over time,
so applications can rely on the returned value as an identifier, except
@@ -2199,7 +2157,7 @@ static QUnixOSVersion detectUnixVersion()
\li "sparc"
\endlist
- \sa QSysInfo::buildAbi()
+ \sa QSysInfo::buildAbi(), QSysInfo::currentCpuArchitecture()
*/
QString QSysInfo::buildCpuArchitecture()
{
@@ -2209,6 +2167,93 @@ QString QSysInfo::buildCpuArchitecture()
/*!
\since 5.4
+ Returns the architecture of the CPU that the application is running on, in
+ text format. Note that this function depends on what the OS will report and
+ may not detect the actual CPU architecture if the OS hides that information
+ or is unable to provide it. For example, a 32-bit OS running on a 64-bit
+ CPU is usually unable to determine the CPU is actually capable of running
+ 64-bit programs.
+
+ Values returned by this function are mostly stable: an attempt will be made
+ to ensure that they stay constant over time and match the values returned
+ by QSysInfo::builldCpuArchitecture(). However, due to the nature of the
+ operating system functions being used, there may be discrepancies.
+
+ Typical returned values are (note: list not exhaustive):
+ \list
+ \li "arm"
+ \li "i386"
+ \li "mips"
+ \li "x86_64"
+ \li "power"
+ \li "sparc"
+ \endlist
+
+ \sa QSysInfo::buildAbi(), QSysInfo::buildCpuArchitecture()
+ */
+QString QSysInfo::currentCpuArchitecture()
+{
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ // We don't need to catch all the CPU architectures in this function;
+ // only those where the host CPU might be different than the build target
+ // (usually, 64-bit platforms).
+ SYSTEM_INFO info;
+ GetNativeSystemInfo(&info);
+ switch (info.wProcessorArchitecture) {
+# ifdef PROCESSOR_ARCHITECTURE_AMD64
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ return QStringLiteral("x86_64");
+# endif
+# ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
+ case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
+# endif
+ case PROCESSOR_ARCHITECTURE_IA64:
+ return QStringLiteral("ia64");
+ }
+#elif defined(Q_OS_UNIX)
+ // we could use detectUnixVersion() above, but we only need a field no other function does
+ struct utsname u;
+ if (uname(&u) != -1) {
+ // the use of QT_BUILD_INTERNAL here is simply to ensure all branches build
+ // as we don't often build on some of the less common platforms
+# if defined(Q_PROCESSOR_ARM) || defined(QT_BUILD_INTERNAL)
+ if (strcmp(u.machine, "aarch64") == 0)
+ return QStringLiteral("arm64");
+ if (strncmp(u.machine, "armv", 4) == 0)
+ return QStringLiteral("arm");
+# endif
+# if defined(Q_PROCESSOR_POWER) || defined(QT_BUILD_INTERNAL)
+ // harmonize "powerpc" and "ppc" to "power"
+ if (strncmp(u.machine, "ppc", 3) == 0)
+ return QLatin1String("power") + QLatin1String(u.machine + 3);
+ if (strncmp(u.machine, "powerpc", 7) == 0)
+ return QLatin1String("power") + QLatin1String(u.machine + 7);
+ if (strcmp(u.machine, "Power Macintosh") == 0)
+ return QLatin1String("power");
+# endif
+# if defined(Q_PROCESSOR_SPARC) || defined(QT_BUILD_INTERNAL)
+ // Solaris psrinfo -v says "sparcv9", but uname -m says "sun4u"
+ // Linux says "sparc64"
+ if (strcmp(u.machine, "sun4u") == 0 || strcmp(u.machine, "sparc64") == 0)
+ return QStringLiteral("sparcv9");
+ if (strcmp(u.machine, "sparc32") == 0)
+ return QStringLiteral("sparc");
+# endif
+# if defined(Q_PROCESSOR_X86) || defined(QT_BUILD_INTERNAL)
+ // harmonize all "i?86" to "i386"
+ if (strlen(u.machine) == 4 && u.machine[0] == 'i'
+ && u.machine[2] == '8' && u.machine[3] == '6')
+ return QStringLiteral("i386");
+# endif
+ return QString::fromLatin1(u.machine);
+ }
+#endif
+ return buildCpuArchitecture();
+}
+
+/*!
+ \since 5.4
+
Returns the full architecture string that Qt was compiled for. This string
is useful for identifying different, incompatible builds. For example, it
can be used as an identifier to request an upgrade package from a server.
@@ -2261,17 +2306,88 @@ static QString unknownText()
/*!
\since 5.4
- Returns the type of the operating system Qt was compiled for. It's also the
- operating system the application is running on, unless the host operating
- system is running a form of compatibility layer.
+ Returns the type of the operating system kernel Qt was compiled for. It's
+ also the kernel the application is running on, unless the host operating
+ system is running a form of compatibility or virtualization layer.
+
+ Values returned by this function are stable and will not change over time,
+ so applications can rely on the returned value as an identifier, except
+ that new OS kernel types may be added over time.
+
+ On Windows, this function returns the type of Windows kernel, like "wince"
+ or "winnt". On Unix systems, it returns the same as the output of \c{uname
+ -s} (lowercased).
+
+ Note that this function may return surprising values: it returns "linux"
+ for all operating systems running Linux (including Android), "qnx" for all
+ operating systems running QNX (including BlackBerry 10), "freebsd" for
+ Debian/kFreeBSD, and "darwin" for OS X and iOS. For information on the type
+ of product the application is running on, see productType().
+
+ \sa QFileSelector, kernelVersion(), productType(), productVersion(), prettyProductName()
+*/
+QString QSysInfo::kernelType()
+{
+#if defined(Q_OS_WINCE)
+ return QStringLiteral("wince");
+#elif defined(Q_OS_WIN)
+ return QStringLiteral("winnt");
+#elif defined(Q_OS_UNIX)
+ struct utsname u;
+ if (uname(&u) == 0)
+ return QString::fromLatin1(u.sysname).toLower();
+#endif
+ return unknownText();
+}
+
+/*!
+ \since 5.4
+
+ Returns the release version of the operating system kernel. On Windows, it
+ returns the version of the NT or CE kernel. On Unix systems, including
+ Android, BlackBerry and OS X, it returns the same as the \c{uname -r}
+ command would return.
+
+ If the version could not be determined, this function may return an empty
+ string.
+
+ \sa kernelType(), productType(), productVersion(), prettyProductName()
+*/
+QString QSysInfo::kernelVersion()
+{
+#ifdef Q_OS_WINRT
+ // TBD
+ return QString();
+#elif defined(Q_OS_WIN)
+ const OSVERSIONINFO osver = winOsVersion();
+ return QString::number(int(osver.dwMajorVersion)) + QLatin1Char('.') + QString::number(int(osver.dwMinorVersion))
+ + QLatin1Char('.') + QString::number(int(osver.dwBuildNumber));
+#else
+ struct utsname u;
+ if (uname(&u) == 0)
+ return QString::fromLatin1(u.release);
+ return QString();
+#endif
+}
+
+
+/*!
+ \since 5.4
+
+ Returns the product name of the operating system this application is
+ running in. If the application is running on some sort of emulation or
+ virtualization layer (such as WINE on a Unix system), this function will
+ inspect the emulation / virtualization layer.
Values returned by this function are stable and will not change over time,
so applications can rely on the returned value as an identifier, except
that new OS types may be added over time.
- \b{Android note}: this function returns "android" for Linux systems running
- Android userspace, notably when using the Bionic library. For all other
- Linux systems, regardless of C library being used, it returns "linux".
+ \b{Linux and Android note}: this function returns "android" for Linux
+ systems running Android userspace, notably when using the Bionic library.
+ For all other Linux systems, regardless of C library being used, it tries
+ to determine the distribution name and returns that. If determining the
+ distribution name failed, it returns "unknown".
\b{BlackBerry note}: this function returns "blackberry" for QNX systems
running the BlackBerry userspace, but "qnx" for all other QNX-based
@@ -2281,13 +2397,18 @@ static QString unknownText()
systems, "ios" for iOS systems and "darwin" in case the system could not be
determined.
- \b{FreeBSD note}: this function returns "freebsd" for systems running the
- FreeBSD kernel, regardless of whether the userspace runs the traditional
- BSD code or whether it's the GNU system (Debian GNU/kFreeBSD).
+ \b{FreeBSD note}: this function returns "debian" for Debian/kFreeBSD and
+ "unknown" otherwise.
+
+ \b{Windows note}: this function returns "winphone" for builds for Windows
+ Phone, "winrt" for WinRT builds, "wince" for Windows CE and Embedded
+ Compact builds, and "windows" for normal desktop builds.
+
+ For other Unix-type systems, this function usually returns "unknown".
- \sa QFileSelector, prettyOsName()
+ \sa QFileSelector, kernelType(), kernelVersion(), productVersion(), prettyProductName()
*/
-QString QSysInfo::osType()
+QString QSysInfo::productType()
{
// similar, but not identical to QFileSelectorPrivate::platformSelectors
#if defined(Q_OS_WINPHONE)
@@ -2306,8 +2427,6 @@ QString QSysInfo::osType()
#elif defined(Q_OS_ANDROID)
return QStringLiteral("android");
-#elif defined(Q_OS_LINUX)
- return QStringLiteral("linux");
#elif defined(Q_OS_IOS)
return QStringLiteral("ios");
@@ -2316,12 +2435,11 @@ QString QSysInfo::osType()
#elif defined(Q_OS_DARWIN)
return QStringLiteral("darwin");
-#elif defined(Q_OS_FREEBSD_KERNEL)
- return QStringLiteral("freebsd");
-#elif defined(Q_OS_UNIX)
- QUnixOSVersion unixOsVersion = detectUnixVersion();
- if (!unixOsVersion.sysNameLower.isEmpty())
- return unixOsVersion.sysNameLower;
+#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
+ QUnixOSVersion unixOsVersion;
+ readEtcOsRelease(unixOsVersion);
+ if (!unixOsVersion.productType.isEmpty())
+ return unixOsVersion.productType;
#endif
return unknownText();
}
@@ -2329,19 +2447,28 @@ QString QSysInfo::osType()
/*!
\since 5.4
- Returns the version of the host operating system in string form. For both
- OS X and iOS systems, this returns just the main OS version, such as "7.1",
- "10.6" and "10.7". For Windows systems, this returns the same types
- detected by winVersion(), without the word "Windows". For Linux-based
- systems, it will try to determine the Linux distribution and version.
+ Returns the product version of the operating system in string form. If the
+ version could not be determined, this function returns "unknown".
- If the version could not be determined, this function returns "unknown" for
- Windows and a combination of the osType() and osKernelVersion() for Unix
- systems.
+ It will return the Android, BlackBerry, iOS, OS X, Windows full-product
+ versions on those systems. In particular, on OS X, iOS and Windows, the
+ returned string is similar to the macVersion() or windowsVersion() enums.
+
+ On Linux systems, it will try to determine the distribution version and will
+ return that. This is also done on Debian/kFreeBSD, so this function will
+ return Debian version in that case.
+
+ In all other Unix-type systems, this function always returns "unknown".
- \sa prettyOsName(), osKernelVersion()
+ \note The version string returned from this function is only guaranteed to
+ be orderable on Android, BlackBerry, OS X and iOS. On Windows, some Windows
+ versions are text ("XP" and "Vista", for example). On Linux, the version of
+ the distribution may jump unexpectedly, please refer to the distribution's
+ documentation for versioning practices.
+
+ \sa kernelType(), kernelVersion(), productType(), prettyProductName()
*/
-QString QSysInfo::osVersion()
+QString QSysInfo::productVersion()
{
#if defined(Q_OS_IOS)
int major = (int(MacintoshVersion) >> 4) & 0xf;
@@ -2378,10 +2505,11 @@ QString QSysInfo::osVersion()
deviceinfo_free_details(&deviceInfo);
return bbVersion;
}
-#elif defined(Q_OS_UNIX)
- QUnixOSVersion unixOsVersion = detectUnixVersion();
- if (!unixOsVersion.versionIdentifier.isEmpty())
- return unixOsVersion.versionIdentifier;
+#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
+ QUnixOSVersion unixOsVersion;
+ readEtcOsRelease(unixOsVersion);
+ if (!unixOsVersion.productVersion.isEmpty())
+ return unixOsVersion.productVersion;
#endif
// fallback
@@ -2391,17 +2519,21 @@ QString QSysInfo::osVersion()
/*!
\since 5.4
- Returns a prettier form of osVersion(), containing other information like
- the operating system type, codenames and other information. The result of
- this function is suitable for displaying to the user, but not for long-term
- storage, as the string may change with updates to Qt.
+ Returns a prettier form of productType() and productVersion(), containing
+ other tokens like the operating system type, codenames and other
+ information. The result of this function is suitable for displaying to the
+ user, but not for long-term storage, as the string may change with updates
+ to Qt.
- \sa osType(), osVersion()
+ If productType() is "unknown", this function will instead use the
+ kernelType() and kernelVersion() functions.
+
+ \sa kernelType(), kernelVersion(), productType(), productVersion()
*/
-QString QSysInfo::prettyOsName()
+QString QSysInfo::prettyProductName()
{
#if defined(Q_OS_IOS)
- return QLatin1String("iOS ") + osVersion();
+ return QLatin1String("iOS ") + productVersion();
#elif defined(Q_OS_OSX)
// get the known codenames
const char *basename = 0;
@@ -2435,55 +2567,30 @@ QString QSysInfo::prettyOsName()
break;
}
if (basename)
- return QLatin1String(basename) + osVersion() + QLatin1Char(')');
+ return QLatin1String(basename) + productVersion() + QLatin1Char(')');
// a future version of OS X
- return QLatin1String("OS X ") + osVersion();
+ return QLatin1String("OS X ") + productVersion();
#elif defined(Q_OS_WINPHONE)
return QLatin1String("Windows Phone ") + QLatin1String(winVer_helper());
#elif defined(Q_OS_WIN)
return QLatin1String("Windows ") + QLatin1String(winVer_helper());
#elif defined(Q_OS_ANDROID)
- return QLatin1String("Android ") + osVersion();
+ return QLatin1String("Android ") + productVersion();
#elif defined(Q_OS_BLACKBERRY)
- return QLatin1String("BlackBerry ") + osVersion();
+ return QLatin1String("BlackBerry ") + productVersion();
#elif defined(Q_OS_UNIX)
- QUnixOSVersion unixOsVersion = detectUnixVersion();
- if (unixOsVersion.versionText.isEmpty())
- return unixOsVersion.sysName;
- else
- return unixOsVersion.sysName + QLatin1String(" (") + unixOsVersion.versionText + QLatin1Char(')');
-#else
- return unknownText();
-#endif
-}
-
-/*!
- \since 5.4
-
- Returns the release version of the operating system. On Windows, it returns
- the version of the kernel, which does not match the version number of the
- OS (e.g., Windows 8 has NT kernel version 6.2). On Unix systems, including
- Android, BlackBerry and OS X, it returns the same as the \c{uname -r}
- command would return.
-
- If the version could not be determined, this function may return an empty
- string.
-
- \sa osVersion(), prettyOsName()
-*/
-QString QSysInfo::osKernelVersion()
-{
-#ifdef Q_OS_WINRT
- // TBD
- return QString();
-#elif defined(Q_OS_WIN)
- const OSVERSIONINFO osver = winOsVersion();
- return QString::number(int(osver.dwMajorVersion)) + QLatin1Char('.') + QString::number(int(osver.dwMinorVersion))
- + QLatin1Char('.') + QString::number(int(osver.dwBuildNumber));
-#else
- return detectUnixVersion().sysRelease;
+# ifdef USE_ETC_OS_RELEASE
+ QUnixOSVersion unixOsVersion;
+ readEtcOsRelease(unixOsVersion);
+ if (!unixOsVersion.prettyName.isEmpty())
+ return unixOsVersion.prettyName;
+# endif
+ struct utsname u;
+ if (uname(&u) == 0)
+ return QString::fromLatin1(u.sysname) + QLatin1Char(' ') + QString::fromLatin1(u.release);
#endif
+ return unknownText();
}
/*!
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 847b7cb4c0..013efec3d5 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
** Contact: http://www.qt-project.org/legal
**
@@ -1052,10 +1052,20 @@ static void slog2_default_handler(QtMsgType msgType, const char *message)
Q_GLOBAL_STATIC(QMessagePattern, qMessagePattern)
/*!
- \internal
-*/
-Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogContext &context,
- const QString &str)
+ \relates <QtGlobal>
+ \since 5.4
+
+ Generates a formatted string out of the \a type, \a context, \a str arguments.
+
+ qFormatLogMessage returns a QString that is formatted according to the current message pattern.
+ It can be used by custom message handlers to format output similar to Qt's default message
+ handler.
+
+ The function is thread-safe.
+
+ \sa qInstallMessageHandler(), qSetMessagePattern()
+ */
+QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str)
{
QString message;
@@ -1278,7 +1288,7 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
bool toConsole;
};
- QString logMessage = qMessageFormatString(type, context, buf);
+ QString logMessage = qFormatLogMessage(type, context, buf);
#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
if (!qWinLogToStderr()) {
@@ -1583,7 +1593,7 @@ void qErrnoWarning(int code, const char *msg, ...)
environment variable; if both qSetMessagePattern() is called and QT_MESSAGE_PATTERN is
set, the environment variable takes precedence.
- qSetMessagePattern() has no effect if a custom message handler is installed.
+ Custom message handlers can use qFormatLogMessage() to take \a pattern into account.
\sa qInstallMessageHandler(), {Debugging Techniques}
*/
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index 043f799414..fe965ec7f5 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -167,6 +167,8 @@ typedef void (*QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QS
Q_CORE_EXPORT QtMessageHandler qInstallMessageHandler(QtMessageHandler);
Q_CORE_EXPORT void qSetMessagePattern(const QString &messagePattern);
+Q_CORE_EXPORT QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context,
+ const QString &buf);
QT_END_NAMESPACE
#endif // QLOGGING_H
diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h
index 45d54c3873..3a443938f9 100644
--- a/src/corelib/global/qsysinfo.h
+++ b/src/corelib/global/qsysinfo.h
@@ -167,11 +167,14 @@ public:
#endif
static QString buildCpuArchitecture();
+ static QString currentCpuArchitecture();
static QString buildAbi();
- static QString osType();
- static QString osKernelVersion();
- static QString osVersion();
- static QString prettyOsName();
+
+ static QString kernelType();
+ static QString kernelVersion();
+ static QString productType();
+ static QString productVersion();
+ static QString prettyProductName();
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index f651860e08..7afff7ff81 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -51,7 +51,6 @@ HEADERS += \
io/qfileselector.h \
io/qfileselector_p.h \
io/qloggingcategory.h \
- io/qloggingcategory_p.h \
io/qloggingregistry_p.h
SOURCES += \
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index d224359724..6b81d9431f 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -259,21 +259,21 @@ inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
template <class T>
inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
{
- const bool oldSetting = debug.autoInsertSpaces();
- debug.nospace() << "QFlags(";
+ QDebugStateSaver saver(debug);
+ debug.resetFormat();
+ debug.nospace() << "QFlags(" << hex << showbase;
bool needSeparator = false;
for (uint i = 0; i < sizeof(T) * 8; ++i) {
if (flags.testFlag(T(1 << i))) {
if (needSeparator)
- debug.nospace() << '|';
+ debug << '|';
else
needSeparator = true;
- debug.nospace() << "0x" << QByteArray::number(typename QFlags<T>::Int(1) << i, 16).constData();
+ debug << (typename QFlags<T>::Int(1) << i);
}
}
debug << ')';
- debug.setAutoInsertSpaces(oldSetting);
- return debug.maybeSpace();
+ return debug;
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp
index 4301536cf7..639310876a 100644
--- a/src/corelib/io/qfileselector.cpp
+++ b/src/corelib/io/qfileselector.cpp
@@ -387,7 +387,7 @@ QStringList QFileSelectorPrivate::platformSelectors()
ret << QStringLiteral("osx");
# endif
# else
- ret << QSysInfo::osType();
+ ret << QSysInfo::kernelType();
# endif
#endif
return ret;
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 63241f6698..a368e92932 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qloggingcategory.h"
-#include "qloggingcategory_p.h"
#include "qloggingregistry_p.h"
QT_BEGIN_NAMESPACE
@@ -221,15 +220,10 @@ void QLoggingCategory::init(const char *category, QtMsgType severityLevel)
{
enabled.store(0x01010101); // enabledDebug = enabledWarning = enabledCritical = true;
- const bool isDefaultCategory
- = (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
-
- // normalize "default" category name, so that we can just do
- // pointer comparison in QLoggingRegistry::updateCategory
- if (isDefaultCategory)
- name = qtDefaultCategoryName;
- else
+ if (category)
name = category;
+ else
+ name = qtDefaultCategoryName;
if (QLoggingRegistry *reg = QLoggingRegistry::instance())
reg->registerCategory(this, severityLevel);
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index dd1612c6b4..3ce0a571b4 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qloggingregistry_p.h"
-#include "qloggingcategory_p.h"
#include <QtCore/qfile.h>
#include <QtCore/qstandardpaths.h>
diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp
index 94ec9a2818..cfd797990f 100644
--- a/src/corelib/json/qjsonobject.cpp
+++ b/src/corelib/json/qjsonobject.cpp
@@ -116,6 +116,20 @@ QJsonObject::QJsonObject()
}
/*!
+ \fn QJsonObject::QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args)
+ \since 5.4
+ Constructs a QJsonObject instance initialized from \a args initialization list.
+ For example:
+ \code
+ QJsonObject object
+ {
+ {"property1", 1},
+ {"property2", 2}
+ };
+ \endcode
+*/
+
+/*!
\internal
*/
QJsonObject::QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object)
@@ -126,6 +140,19 @@ QJsonObject::QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object)
d->ref.ref();
}
+/*!
+ This method replaces part of the QJsonObject(std::initializer_list<QPair<QString, QJsonValue>> args) body.
+ The constructor needs to be inline, but we do not want to leak implementation details
+ of this class.
+ \note this method is called for an uninitialized object
+ \internal
+ */
+
+void QJsonObject::initialize()
+{
+ d = 0;
+ o = 0;
+}
/*!
Destroys the object.
diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h
index ad3184b1f2..92dd19af5e 100644
--- a/src/corelib/json/qjsonobject.h
+++ b/src/corelib/json/qjsonobject.h
@@ -44,6 +44,10 @@
#include <QtCore/qjsonvalue.h>
#include <QtCore/qiterator.h>
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+#include <QtCore/qpair.h>
+#include <initializer_list>
+#endif
QT_BEGIN_NAMESPACE
@@ -55,6 +59,16 @@ class Q_CORE_EXPORT QJsonObject
{
public:
QJsonObject();
+
+#if defined(Q_COMPILER_INITIALIZER_LISTS) || defined(Q_QDOC)
+ QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args)
+ {
+ initialize();
+ for (std::initializer_list<QPair<QString, QJsonValue> >::const_iterator i = args.begin(); i != args.end(); ++i)
+ insert(i->first, i->second);
+ }
+#endif
+
~QJsonObject();
QJsonObject(const QJsonObject &other);
@@ -195,6 +209,7 @@ private:
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object);
+ void initialize();
void detach(uint reserve = 0);
void compact();
diff --git a/src/corelib/statemachine/qabstractstate.cpp b/src/corelib/statemachine/qabstractstate.cpp
index 62b7e448f5..da1eff9b4c 100644
--- a/src/corelib/statemachine/qabstractstate.cpp
+++ b/src/corelib/statemachine/qabstractstate.cpp
@@ -79,8 +79,17 @@ QT_BEGIN_NAMESPACE
function to perform custom processing when the state is exited.
*/
+/*!
+ \property QAbstractState::active
+ \since 5.4
+
+ \brief the active property of this state. A state is active between
+ entered() and exited() signals.
+*/
+
+
QAbstractStatePrivate::QAbstractStatePrivate(StateType type)
- : stateType(type), isMachine(false), parentState(0)
+ : stateType(type), isMachine(false), active(false), parentState(0)
{
}
@@ -121,11 +130,19 @@ void QAbstractStatePrivate::emitEntered()
{
Q_Q(QAbstractState);
emit q->entered(QAbstractState::QPrivateSignal());
+ if (!active) {
+ active = true;
+ emit q->activeChanged(true);
+ }
}
void QAbstractStatePrivate::emitExited()
{
Q_Q(QAbstractState);
+ if (active) {
+ active = false;
+ emit q->activeChanged(false);
+ }
emit q->exited(QAbstractState::QPrivateSignal());
}
@@ -174,6 +191,17 @@ QStateMachine *QAbstractState::machine() const
}
/*!
+ Returns whether this state is active.
+
+ \sa activeChanged(bool), entered(), exited()
+*/
+bool QAbstractState::active() const
+{
+ Q_D(const QAbstractState);
+ return d->active;
+}
+
+/*!
\fn QAbstractState::onExit(QEvent *event)
This function is called when the state is exited. The given \a event is what
@@ -204,6 +232,15 @@ QStateMachine *QAbstractState::machine() const
*/
/*!
+ \fn QAbstractState::activeChanged(bool active)
+ \since 5.4
+
+ This signal is emitted when the active property is changed.
+
+ \sa QAbstractState::active, entered(), exited()
+*/
+
+/*!
\reimp
*/
bool QAbstractState::event(QEvent *e)
diff --git a/src/corelib/statemachine/qabstractstate.h b/src/corelib/statemachine/qabstractstate.h
index a6ac248b85..4318a5b419 100644
--- a/src/corelib/statemachine/qabstractstate.h
+++ b/src/corelib/statemachine/qabstractstate.h
@@ -56,12 +56,15 @@ class QAbstractStatePrivate;
class Q_CORE_EXPORT QAbstractState : public QObject
{
Q_OBJECT
+ Q_PROPERTY(bool active READ active NOTIFY activeChanged)
public:
~QAbstractState();
QState *parentState() const;
QStateMachine *machine() const;
+ bool active() const;
+
Q_SIGNALS:
void entered(
#if !defined(Q_QDOC)
@@ -73,6 +76,7 @@ Q_SIGNALS:
QPrivateSignal
#endif
);
+ void activeChanged(bool active);
protected:
QAbstractState(QState *parent = 0);
diff --git a/src/corelib/statemachine/qabstractstate_p.h b/src/corelib/statemachine/qabstractstate_p.h
index b0334dfbb5..40431a8fcb 100644
--- a/src/corelib/statemachine/qabstractstate_p.h
+++ b/src/corelib/statemachine/qabstractstate_p.h
@@ -85,8 +85,9 @@ public:
void emitEntered();
void emitExited();
- uint stateType:31;
+ uint stateType:30;
uint isMachine:1;
+ bool active:1;
mutable QState *parentState;
};
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index d46fa357ae..a147b85eb7 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -1369,6 +1369,11 @@ void QStateMachinePrivate::_q_start()
{
Q_Q(QStateMachine);
Q_ASSERT(state == Starting);
+ foreach (QAbstractState *state, configuration) {
+ QAbstractStatePrivate *abstractStatePrivate = QAbstractStatePrivate::get(state);
+ abstractStatePrivate->active = false;
+ emit state->activeChanged(false);
+ }
configuration.clear();
qDeleteAll(internalEventQueue);
internalEventQueue.clear();
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 52af67c86a..d57eeaf188 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -2697,8 +2697,9 @@ QByteArray QByteArray::toLower() const
{
QByteArray s(*this);
uchar *p = reinterpret_cast<uchar *>(s.data());
+ uchar *e = reinterpret_cast<uchar *>(s.end());
if (p) {
- while (*p) {
+ while (p != e) {
*p = QChar::toLower((ushort)*p);
p++;
}
@@ -2720,8 +2721,9 @@ QByteArray QByteArray::toUpper() const
{
QByteArray s(*this);
uchar *p = reinterpret_cast<uchar *>(s.data());
+ uchar *e = reinterpret_cast<uchar *>(s.end());
if (p) {
- while (*p) {
+ while (p != e) {
*p = QChar::toUpper((ushort)*p);
p++;
}
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 0c05b61e76..16094804c2 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -104,10 +104,18 @@ QT_BEGIN_NAMESPACE
#define GL_RGB8 0x8051
#endif
+#ifndef GL_RGB10
+#define GL_RGB10 0x8052
+#endif
+
#ifndef GL_RGBA8
#define GL_RGBA8 0x8058
#endif
+#ifndef GL_RGB10_A2
+#define GL_RGB10_A2 0x8059
+#endif
+
#ifndef GL_BGRA
#define GL_BGRA 0x80E1
#endif
@@ -116,6 +124,10 @@ QT_BEGIN_NAMESPACE
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
#endif
+#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#endif
+
/*!
\class QOpenGLFramebufferObjectFormat
@@ -539,8 +551,12 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ GLuint pixelType = GL_UNSIGNED_BYTE;
+ if (internal_format == GL_RGB10_A2 || internal_format == GL_RGB10)
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+
funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ GL_RGBA, pixelType, NULL);
if (mipmap) {
int width = size.width();
int height = size.height();
@@ -550,7 +566,7 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal
height = qMax(1, height >> 1);
++level;
funcs.glTexImage2D(target, level, internal_format, width, height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ GL_RGBA, pixelType, NULL);
}
}
funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
@@ -1142,6 +1158,14 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ
return rgbaImage;
}
+static inline QImage qt_gl_read_framebuffer_rgb10a2(const QSize &size, bool include_alpha, QOpenGLContext *context)
+{
+ // We assume OpenGL 1.2+ or ES 3.0+ here.
+ QImage img(size, include_alpha ? QImage::Format_A2BGR30_Premultiplied : QImage::Format_BGR30);
+ context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, img.bits());
+ return img;
+}
+
static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format, bool include_alpha, bool flip)
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
@@ -1152,6 +1176,10 @@ static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format,
case GL_RGB:
case GL_RGB8:
return qt_gl_read_framebuffer_rgba8(size, false, ctx).mirrored(false, flip);
+ case GL_RGB10:
+ return qt_gl_read_framebuffer_rgb10a2(size, false, ctx).mirrored(false, flip);
+ case GL_RGB10_A2:
+ return qt_gl_read_framebuffer_rgb10a2(size, include_alpha, ctx).mirrored(false, flip);
case GL_RGBA:
case GL_RGBA8:
default:
@@ -1177,7 +1205,8 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format,
of QOpenGLPaintDevice::paintFlipped().
Will try to return a premultiplied ARBG32 or RGB32 image. Since 5.2 it will fall back to
- a premultiplied RGBA8888 or RGBx8888 image when reading to ARGB32 is not supported.
+ a premultiplied RGBA8888 or RGBx8888 image when reading to ARGB32 is not supported. Since 5.4 an
+ A2BGR30 image is returned if the internal format is RGB10_A2.
For multisampled framebuffer objects the samples are resolved using the
\c{GL_EXT_framebuffer_blit} extension. If the extension is not available, the contents
diff --git a/src/gui/opengl/qopengltexturecache.cpp b/src/gui/opengl/qopengltexturecache.cpp
index 4a4a36d7e5..055974d5a4 100644
--- a/src/gui/opengl/qopengltexturecache.cpp
+++ b/src/gui/opengl/qopengltexturecache.cpp
@@ -49,6 +49,10 @@
QT_BEGIN_NAMESPACE
+#ifndef GL_RGB10_A2
+#define GL_RGB10_A2 0x8059
+#endif
+
#ifndef GL_BGR
#define GL_BGR 0x80E0
#endif
@@ -61,6 +65,10 @@ QT_BEGIN_NAMESPACE
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
#endif
+#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#endif
+
class QOpenGLTextureCacheWrapper
{
public:
@@ -228,6 +236,29 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, qint64 key, con
}
targetFormat = image.format();
break;
+ case QImage::Format_BGR30:
+ case QImage::Format_A2BGR30_Premultiplied:
+ if (isOpenGL12orBetter || (context->isOpenGLES() && context->format().majorVersion() >= 3)) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ externalFormat = GL_RGBA;
+ internalFormat = GL_RGB10_A2;
+ targetFormat = image.format();
+ }
+ break;
+ case QImage::Format_RGB30:
+ case QImage::Format_A2RGB30_Premultiplied:
+ if (isOpenGL12orBetter) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ externalFormat = GL_BGRA;
+ internalFormat = GL_RGB10_A2;
+ targetFormat = image.format();
+ } else if (context->isOpenGLES() && context->format().majorVersion() >= 3) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ externalFormat = GL_RGBA;
+ internalFormat = GL_RGB10_A2;
+ targetFormat = QImage::Format_A2BGR30_Premultiplied;
+ }
+ break;
case QImage::Format_RGB444:
case QImage::Format_RGB555:
case QImage::Format_RGB16:
diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp
index d9b9385751..3b106fecf5 100644
--- a/src/gui/opengl/qopenglvertexarrayobject.cpp
+++ b/src/gui/opengl/qopenglvertexarrayobject.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sean Harmer <sean.harmer@kdab.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -49,69 +49,49 @@
#include <QtGui/qopenglfunctions_3_0.h>
#include <QtGui/qopenglfunctions_3_2_core.h>
+#include <private/qopenglvertexarrayobject_p.h>
+
QT_BEGIN_NAMESPACE
class QOpenGLFunctions_3_0;
class QOpenGLFunctions_3_2_Core;
-class QVertexArrayObjectHelper
+void qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper, QOpenGLContext *context)
{
-public:
- QVertexArrayObjectHelper(QOpenGLContext *context)
- {
- Q_ASSERT(context);
- bool tryARB = true;
+ Q_ASSERT(helper);
+ Q_ASSERT(context);
+
+ bool tryARB = true;
- if (context->isOpenGLES()) {
+ if (context->isOpenGLES()) {
#ifdef QT_OPENGL_ES_3
- GenVertexArrays = ::glGenVertexArrays;
- DeleteVertexArrays = ::glDeleteVertexArrays;
- BindVertexArray = ::glBindVertexArray;
+ if (context->format().majorVersion() >= 3) {
+ helper->GenVertexArrays = ::glGenVertexArrays;
+ helper->DeleteVertexArrays = ::glDeleteVertexArrays;
+ helper->BindVertexArray = ::glBindVertexArray;
tryARB = false;
-#else
- if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
- GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES")));
- DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES")));
- BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES")));
- tryARB = false;
- }
+ } else
#endif
- } else if (!context->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))
- && context->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) {
- GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysAPPLE")));
- DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysAPPLE")));
- BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayAPPLE")));
+ if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
+ helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES")));
+ helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES")));
+ helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES")));
tryARB = false;
}
-
- if (tryARB) {
- GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress(QByteArrayLiteral("glGenVertexArrays")));
- DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArrays")));
- BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress(QByteArrayLiteral("glBindVertexArray")));
- }
- }
-
- inline void glGenVertexArrays(GLsizei n, GLuint *arrays)
- {
- GenVertexArrays(n, arrays);
+ } else if (context->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object")) &&
+ !context->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
+ helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysAPPLE")));
+ helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysAPPLE")));
+ helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayAPPLE")));
+ tryARB = false;
}
- inline void glDeleteVertexArrays(GLsizei n, const GLuint *arrays)
- {
- DeleteVertexArrays(n, arrays);
+ if (tryARB && context->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
+ helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glGenVertexArrays")));
+ helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArrays")));
+ helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress(QByteArrayLiteral("glBindVertexArray")));
}
-
- inline void glBindVertexArray(GLuint array)
- {
- BindVertexArray(array);
- }
-
-private:
- // Function signatures are equivalent between desktop core, ARB, APPLE, ES3 and ES 2 extensions
- void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays);
- void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays);
- void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array);
-};
+}
class QOpenGLVertexArrayObjectPrivate : public QObjectPrivate
{
@@ -142,7 +122,7 @@ public:
union {
QOpenGLFunctions_3_0 *core_3_0;
QOpenGLFunctions_3_2_Core *core_3_2;
- QVertexArrayObjectHelper *helper;
+ QOpenGLVertexArrayObjectHelper *helper;
} vaoFuncs;
enum {
NotSupported,
@@ -175,7 +155,7 @@ bool QOpenGLVertexArrayObjectPrivate::create()
if (ctx->isOpenGLES()) {
if (ctx->format().majorVersion() >= 3 || ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
- vaoFuncs.helper = new QVertexArrayObjectHelper(ctx);
+ vaoFuncs.helper = new QOpenGLVertexArrayObjectHelper(ctx);
vaoFuncsType = OES;
vaoFuncs.helper->glGenVertexArrays(1, &vao);
}
@@ -197,11 +177,11 @@ bool QOpenGLVertexArrayObjectPrivate::create()
} else
#endif
if (ctx->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
- vaoFuncs.helper = new QVertexArrayObjectHelper(ctx);
+ vaoFuncs.helper = new QOpenGLVertexArrayObjectHelper(ctx);
vaoFuncsType = ARB;
vaoFuncs.helper->glGenVertexArrays(1, &vao);
} else if (ctx->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) {
- vaoFuncs.helper = new QVertexArrayObjectHelper(ctx);
+ vaoFuncs.helper = new QOpenGLVertexArrayObjectHelper(ctx);
vaoFuncsType = APPLE;
vaoFuncs.helper->glGenVertexArrays(1, &vao);
}
diff --git a/src/gui/opengl/qopenglvertexarrayobject.h b/src/gui/opengl/qopenglvertexarrayobject.h
index 8369497660..19da85bffd 100644
--- a/src/gui/opengl/qopenglvertexarrayobject.h
+++ b/src/gui/opengl/qopenglvertexarrayobject.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sean Harmer <sean.harmer@kdab.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
diff --git a/src/corelib/io/qloggingcategory_p.h b/src/gui/opengl/qopenglvertexarrayobject_p.h
index 7802f017fd..161a388b1a 100644
--- a/src/corelib/io/qloggingcategory_p.h
+++ b/src/gui/opengl/qopenglvertexarrayobject_p.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sean Harmer <sean.harmer@kdab.com>
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtCore module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,15 +39,15 @@
**
****************************************************************************/
-#ifndef QLOGGINGCATEGORY_P_H
-#define QLOGGINGCATEGORY_P_H
+#ifndef QOPENGLVERTEXARRAYOBJECT_P_H
+#define QOPENGLVERTEXARRAYOBJECT_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
-// of a number of Qt sources files. This header file may change from
+// of the Qt OpenGL classes. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
@@ -55,12 +55,65 @@
#include <QtCore/qglobal.h>
+#ifndef QT_NO_OPENGL
+
+#include <QtGui/qopengl.h>
+
QT_BEGIN_NAMESPACE
-// unique pointer to default category
-// (allows to compare for pointers instead of strings)
-extern const char qtDefaultCategoryName[];
+class QOpenGLVertexArrayObjectHelper;
+class QOpenGLContext;
+
+void Q_GUI_EXPORT qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper, QOpenGLContext *context);
+
+class QOpenGLVertexArrayObjectHelper
+{
+ Q_DISABLE_COPY(QOpenGLVertexArrayObjectHelper)
+
+public:
+ explicit inline QOpenGLVertexArrayObjectHelper(QOpenGLContext *context)
+ : GenVertexArrays(Q_NULLPTR)
+ , DeleteVertexArrays(Q_NULLPTR)
+ , BindVertexArray(Q_NULLPTR)
+ {
+ qtInitializeVertexArrayObjectHelper(this, context);
+ }
+
+ inline bool isValid() const
+ {
+ return GenVertexArrays && DeleteVertexArrays && BindVertexArray;
+ }
+
+ inline void glGenVertexArrays(GLsizei n, GLuint *arrays) const
+ {
+ GenVertexArrays(n, arrays);
+ }
+
+ inline void glDeleteVertexArrays(GLsizei n, const GLuint *arrays) const
+ {
+ DeleteVertexArrays(n, arrays);
+ }
+
+ inline void glBindVertexArray(GLuint array) const
+ {
+ BindVertexArray(array);
+ }
+
+private:
+ friend void Q_GUI_EXPORT qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper, QOpenGLContext *context);
+
+ // Function signatures are equivalent between desktop core, ARB, APPLE, ES 3 and ES 2 extensions
+ typedef void (QOPENGLF_APIENTRYP qt_GenVertexArrays_t)(GLsizei n, GLuint *arrays);
+ typedef void (QOPENGLF_APIENTRYP qt_DeleteVertexArrays_t)(GLsizei n, const GLuint *arrays);
+ typedef void (QOPENGLF_APIENTRYP qt_BindVertexArray_t)(GLuint array);
+
+ qt_GenVertexArrays_t GenVertexArrays;
+ qt_DeleteVertexArrays_t DeleteVertexArrays;
+ qt_BindVertexArray_t BindVertexArray;
+};
QT_END_NAMESPACE
-#endif // QLOGGINGCATEGORY_P_H
+#endif // QT_NO_OPENGL
+
+#endif // QOPENGLVERTEXARRAYOBJECT_P_H
diff --git a/src/platformsupport/linuxaccessibility/application.cpp b/src/platformsupport/linuxaccessibility/application.cpp
index 5a8d0e73f0..c651d604ae 100644
--- a/src/platformsupport/linuxaccessibility/application.cpp
+++ b/src/platformsupport/linuxaccessibility/application.cpp
@@ -170,6 +170,8 @@ bool QSpiApplicationAdaptor::eventFilter(QObject *target, QEvent *event)
de.modifiers |= 1 << ATSPI_MODIFIER_CONTROL;
if ((keyEvent->modifiers() & Qt::AltModifier) && (keyEvent->key() != Qt::Key_Alt))
de.modifiers |= 1 << ATSPI_MODIFIER_ALT;
+ if ((keyEvent->modifiers() & Qt::MetaModifier) && (keyEvent->key() != Qt::Key_Meta))
+ de.modifiers |= 1 << ATSPI_MODIFIER_META;
#ifdef KEYBOARD_DEBUG
qDebug() << QStringLiteral("Key event text:") << event->type() << de.text
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index 3fdfb55dcf..c62875d0ef 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -751,7 +751,7 @@ QFunctionPointer QWindowsEGLContext::getProcAddress(const QByteArray &procName)
QFunctionPointer procAddress = reinterpret_cast<QFunctionPointer>(QWindowsEGLStaticContext::libEGL.eglGetProcAddress(procName.constData()));
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaGl) << __FUNCTION__ << procName << QWindowsEGLStaticContext::libEGL.eglGetCurrentContext() << "returns" << procAddress;
- if (!procAddress)
+ if (!procAddress && QWindowsContext::verbose)
qWarning("%s: Unable to resolve '%s'", __FUNCTION__, procName.constData());
return procAddress;
}
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index e336c6414e..e09018ef69 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -1397,7 +1397,7 @@ QFunctionPointer QWindowsGLContext::getProcAddress(const QByteArray &procName)
QFunctionPointer procAddress = reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress(procName.constData()));
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaGl) << __FUNCTION__ << procName << QOpenGLStaticContext::opengl32.wglGetCurrentContext() << "returns" << procAddress;
- if (!procAddress)
+ if (!procAddress && QWindowsContext::verbose)
qWarning("%s: Unable to resolve '%s'", __FUNCTION__, procName.constData());
return procAddress;
}
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index 1e7f131652..708a91b557 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtTest module of the Qt Toolkit.
@@ -59,8 +59,6 @@
QT_BEGIN_NAMESPACE
-Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogContext &context, const QString& msg);
-
static void saveCoverageTool(const char * appname, bool testfailed, bool installedTestCoverage)
{
#ifdef __COVERAGESCANNER__
@@ -287,7 +285,7 @@ namespace QTest {
// the message is expected, so just swallow it.
return;
- QString msg = qMessageFormatString(type, context, message);
+ QString msg = qFormatLogMessage(type, context, message);
msg.chop(1); // remove trailing newline
if (type != QtFatalMsg) {
diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp
index 73425b9acd..48f99f4d35 100644
--- a/src/widgets/accessible/qaccessiblewidget.cpp
+++ b/src/widgets/accessible/qaccessiblewidget.cpp
@@ -240,10 +240,10 @@ QWidget *QAccessibleWidget::widget() const
*/
QObject *QAccessibleWidget::parentObject() const
{
- QObject *parent = object()->parent();
- if (!parent)
- parent = qApp;
- return parent;
+ QWidget *w = widget();
+ if (!w || w->isWindow() || !w->parentWidget())
+ return qApp;
+ return w->parent();
}
/*! \reimp */
@@ -353,11 +353,7 @@ QAccessibleWidget::relations(QAccessible::Relation match /*= QAccessible::AllRel
/*! \reimp */
QAccessibleInterface *QAccessibleWidget::parent() const
{
- Q_ASSERT(widget());
- QObject *parentWidget= widget()->parentWidget();
- if (!parentWidget)
- parentWidget = qApp;
- return QAccessible::queryAccessibleInterface(parentWidget);
+ return QAccessible::queryAccessibleInterface(parentObject());
}
/*! \reimp */
diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp
index da57d4657d..cc6310d591 100644
--- a/src/widgets/accessible/qaccessiblewidgets.cpp
+++ b/src/widgets/accessible/qaccessiblewidgets.cpp
@@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
QString qt_accStripAmp(const QString &text);
-QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel)
+QList<QWidget*> childWidgets(const QWidget *widget)
{
if (widget == 0)
return QList<QWidget*>();
@@ -85,7 +85,7 @@ QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel)
if (!w)
continue;
QString objectName = w->objectName();
- if ((includeTopLevel || !w->isWindow())
+ if (!w->isWindow()
&& !qobject_cast<QFocusFrame*>(w)
&& !qobject_cast<QMenu*>(w)
&& objectName != QLatin1String("qt_rubberband")
@@ -970,7 +970,7 @@ QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget)
QAccessibleInterface *QAccessibleMainWindow::child(int index) const
{
- QList<QWidget*> kids = childWidgets(mainWindow(), true);
+ QList<QWidget*> kids = childWidgets(mainWindow());
if (index >= 0 && index < kids.count()) {
return QAccessible::queryAccessibleInterface(kids.at(index));
}
@@ -979,13 +979,13 @@ QAccessibleInterface *QAccessibleMainWindow::child(int index) const
int QAccessibleMainWindow::childCount() const
{
- QList<QWidget*> kids = childWidgets(mainWindow(), true);
+ QList<QWidget*> kids = childWidgets(mainWindow());
return kids.count();
}
int QAccessibleMainWindow::indexOfChild(const QAccessibleInterface *iface) const
{
- QList<QWidget*> kids = childWidgets(mainWindow(), true);
+ QList<QWidget*> kids = childWidgets(mainWindow());
return kids.indexOf(static_cast<QWidget*>(iface->object()));
}
@@ -998,7 +998,7 @@ QAccessibleInterface *QAccessibleMainWindow::childAt(int x, int y) const
if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y))
return 0;
- QWidgetList kids = childWidgets(mainWindow(), true);
+ QWidgetList kids = childWidgets(mainWindow());
QPoint rp = mainWindow()->mapFromGlobal(QPoint(x, y));
for (int i = 0; i < kids.size(); ++i) {
QWidget *child = kids.at(i);
diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp
index 6160b37a0f..88d3981391 100644
--- a/src/widgets/accessible/simplewidgets.cpp
+++ b/src/widgets/accessible/simplewidgets.cpp
@@ -69,7 +69,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_ACCESSIBILITY
-extern QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel = false);
+extern QList<QWidget*> childWidgets(const QWidget *widget);
QString qt_accStripAmp(const QString &text);
QString qt_accHotKey(const QString &text);
diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp
index 662504fc25..7a88e65b3c 100644
--- a/src/widgets/dialogs/qprogressdialog.cpp
+++ b/src/widgets/dialogs/qprogressdialog.cpp
@@ -507,7 +507,7 @@ bool QProgressDialog::wasCanceled() const
\property QProgressDialog::maximum
\brief the highest value represented by the progress bar
- The default is 0.
+ The default is 100.
\sa minimum, setRange()
*/
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 94498f48c9..d8b67edff8 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -1155,7 +1155,7 @@ void QCommonStylePrivate::startAnimation(QStyleAnimation *animation) const
stopAnimation(animation->target());
q->connect(animation, SIGNAL(destroyed()), SLOT(_q_removeAnimation()), Qt::UniqueConnection);
animations.insert(animation->target(), animation);
- animation->start(QAbstractAnimation::DeleteWhenStopped);
+ animation->start();
}
/*! \internal */
diff --git a/src/widgets/styles/qstyleanimation.cpp b/src/widgets/styles/qstyleanimation.cpp
index 85dc357ab5..e6e47a98e9 100644
--- a/src/widgets/styles/qstyleanimation.cpp
+++ b/src/widgets/styles/qstyleanimation.cpp
@@ -50,7 +50,7 @@ static const qreal ScrollBarFadeOutDuration = 200.0;
static const qreal ScrollBarFadeOutDelay = 450.0;
QStyleAnimation::QStyleAnimation(QObject *target) : QAbstractAnimation(target),
- _delay(0), _duration(-1), _startTime(QTime::currentTime())
+ _delay(0), _duration(-1), _startTime(QTime::currentTime()), _fps(ThirtyFps), _skip(0)
{
}
@@ -93,6 +93,16 @@ void QStyleAnimation::setStartTime(const QTime &time)
_startTime = time;
}
+QStyleAnimation::FrameRate QStyleAnimation::frameRate() const
+{
+ return _fps;
+}
+
+void QStyleAnimation::setFrameRate(FrameRate fps)
+{
+ _fps = fps;
+}
+
void QStyleAnimation::updateTarget()
{
QEvent event(QEvent::StyleAnimationUpdate);
@@ -102,6 +112,12 @@ void QStyleAnimation::updateTarget()
stop();
}
+void QStyleAnimation::start()
+{
+ _skip = 0;
+ QAbstractAnimation::start(DeleteWhenStopped);
+}
+
bool QStyleAnimation::isUpdateNeeded() const
{
return currentTime() > _delay;
@@ -109,8 +125,11 @@ bool QStyleAnimation::isUpdateNeeded() const
void QStyleAnimation::updateCurrentTime(int)
{
- if (target() && isUpdateNeeded())
- updateTarget();
+ if (++_skip >= _fps) {
+ _skip = 0;
+ if (target() && isUpdateNeeded())
+ updateTarget();
+ }
}
QProgressStyleAnimation::QProgressStyleAnimation(int speed, QObject *target) :
diff --git a/src/widgets/styles/qstyleanimation_p.h b/src/widgets/styles/qstyleanimation_p.h
index c344858812..19e629cb25 100644
--- a/src/widgets/styles/qstyleanimation_p.h
+++ b/src/widgets/styles/qstyleanimation_p.h
@@ -78,8 +78,21 @@ public:
QTime startTime() const;
void setStartTime(const QTime &time);
+ enum FrameRate {
+ DefaultFps,
+ SixtyFps,
+ ThirtyFps,
+ TwentyFps
+ };
+
+ FrameRate frameRate() const;
+ void setFrameRate(FrameRate fps);
+
void updateTarget();
+public Q_SLOTS:
+ void start();
+
protected:
virtual bool isUpdateNeeded() const;
virtual void updateCurrentTime(int time);
@@ -88,6 +101,8 @@ private:
int _delay;
int _duration;
QTime _startTime;
+ FrameRate _fps;
+ int _skip;
};
class QProgressStyleAnimation : public QStyleAnimation
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index c026b79103..757d70c64b 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -62,7 +62,10 @@
#include <qmap.h>
#include <qtimer.h>
-#include <qdebug.h>
+#ifndef QT_NO_DEBUG_STREAM
+# include <qdebug.h>
+# include <qtextstream.h>
+#endif
#include <private/qapplication_p.h>
#include <private/qlayoutengine_p.h>
@@ -71,23 +74,17 @@
# include <private/qt_cocoa_helpers_mac_p.h>
#endif
-#ifdef QT_NO_DOCKWIDGET
-extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
-#endif
+QT_BEGIN_NAMESPACE
-#ifdef Q_DEBUG_MAINWINDOW_LAYOUT
-# include <QTextStream>
+#ifndef QT_NO_DOCKWIDGET
+extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
#endif
-QT_BEGIN_NAMESPACE
-
/******************************************************************************
** debug
*/
-#if defined(Q_DEBUG_MAINWINDOW_LAYOUT) && !defined(QT_NO_DOCKWIDGET)
-
-static QTextStream qout(stderr, QIODevice::WriteOnly);
+#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_DEBUG_STREAM)
static void dumpLayout(QTextStream &qout, const QDockAreaLayoutInfo &layout, QString indent);
@@ -101,7 +98,7 @@ static void dumpLayout(QTextStream &qout, const QDockAreaLayoutItem &item, QStri
if (item.widgetItem != 0) {
qout << indent << "widget: "
<< item.widgetItem->widget()->metaObject()->className()
- << ' ' << item.widgetItem->widget()->windowTitle() << '\n';
+ << " \"" << item.widgetItem->widget()->windowTitle() << "\"\n";
} else if (item.subinfo != 0) {
qout << indent << "subinfo:\n";
dumpLayout(qout, *item.subinfo, indent + QLatin1String(" "));
@@ -117,16 +114,17 @@ static void dumpLayout(QTextStream &qout, const QDockAreaLayoutItem &item, QStri
<< " rect:" << r.x() << ',' << r.y() << ' '
<< r.width() << 'x' << r.height() << '\n';
}
- qout.flush();
}
static void dumpLayout(QTextStream &qout, const QDockAreaLayoutInfo &layout, QString indent)
{
+ const QSize minSize = layout.minimumSize();
qout << indent << "QDockAreaLayoutInfo: "
<< layout.rect.left() << ','
<< layout.rect.top() << ' '
<< layout.rect.width() << 'x'
<< layout.rect.height()
+ << " min size: " << minSize.width() << ',' << minSize.height()
<< " orient:" << layout.o
<< " tabbed:" << layout.tabbed
<< " tbshape:" << layout.tabBarShape << '\n';
@@ -137,36 +135,42 @@ static void dumpLayout(QTextStream &qout, const QDockAreaLayoutInfo &layout, QSt
qout << indent << "Item: " << i << '\n';
dumpLayout(qout, layout.item_list.at(i), indent + QLatin1String(" "));
}
- qout.flush();
-};
+}
-static void dumpLayout(QTextStream &qout, const QDockAreaLayout &layout, QString indent)
+static void dumpLayout(QTextStream &qout, const QDockAreaLayout &layout)
{
- qout << indent << "QDockAreaLayout: "
+ qout << "QDockAreaLayout: "
<< layout.rect.left() << ','
<< layout.rect.top() << ' '
<< layout.rect.width() << 'x'
<< layout.rect.height() << '\n';
- qout << indent << "TopDockArea:\n";
- dumpLayout(qout, layout.docks[QInternal::TopDock], indent + QLatin1String(" "));
- qout << indent << "LeftDockArea:\n";
- dumpLayout(qout, layout.docks[QInternal::LeftDock], indent + QLatin1String(" "));
- qout << indent << "RightDockArea:\n";
- dumpLayout(qout, layout.docks[QInternal::RightDock], indent + QLatin1String(" "));
- qout << indent << "BottomDockArea:\n";
- dumpLayout(qout, layout.docks[QInternal::BottomDock], indent + QLatin1String(" "));
+ qout << "TopDockArea:\n";
+ dumpLayout(qout, layout.docks[QInternal::TopDock], QLatin1String(" "));
+ qout << "LeftDockArea:\n";
+ dumpLayout(qout, layout.docks[QInternal::LeftDock], QLatin1String(" "));
+ qout << "RightDockArea:\n";
+ dumpLayout(qout, layout.docks[QInternal::RightDock], QLatin1String(" "));
+ qout << "BottomDockArea:\n";
+ dumpLayout(qout, layout.docks[QInternal::BottomDock], QLatin1String(" "));
+}
- qout.flush();
-};
+QDebug operator<<(QDebug debug, const QDockAreaLayout &layout)
+{
+ QString s;
+ QTextStream str(&s);
+ dumpLayout(str, layout);
+ debug << s;
+ return debug;
+}
-void qt_dumpLayout(QTextStream &qout, QMainWindow *window)
+QDebug operator<<(QDebug debug, const QMainWindowLayout *layout)
{
- QMainWindowLayout *layout = qt_mainwindow_layout(window);
- dumpLayout(qout, layout->layoutState.dockAreaLayout, QString());
+ debug << layout->layoutState.dockAreaLayout;
+ return debug;
}
-#endif // Q_DEBUG_MAINWINDOW_LAYOUT && !QT_NO_DOCKWIDGET
+#endif // !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_DEBUG)
/******************************************************************************
** QMainWindowLayoutState
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h
index f866a554dc..4b578e94b7 100644
--- a/src/widgets/widgets/qmainwindowlayout_p.h
+++ b/src/widgets/widgets/qmainwindowlayout_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -68,15 +68,6 @@
#include "qdockarealayout_p.h"
#include "qtoolbararealayout_p.h"
-//#define Q_DEBUG_MAINWINDOW_LAYOUT
-
-#if defined(Q_DEBUG_MAINWINDOW_LAYOUT) && !defined(QT_NO_DOCKWIDGET)
-QT_BEGIN_NAMESPACE
-class QTextStream;
-Q_WIDGETS_EXPORT void qt_dumpLayout(QTextStream &qout, QMainWindow *window);
-QT_END_NAMESPACE
-#endif // Q_DEBUG_MAINWINDOW_LAYOUT && !QT_NO_DOCKWIDGET
-
#ifdef Q_WS_MAC
// Forward defs to make avoid including Carbon.h (faster compile you know ;).
struct OpaqueHIObjectRef;
@@ -344,6 +335,13 @@ public:
#endif // Q_WS_MAC
};
+
+#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_DEBUG_STREAM)
+class QDebug;
+QDebug operator<<(QDebug debug, const QDockAreaLayout &layout);
+QDebug operator<<(QDebug debug, const QMainWindowLayout *layout);
+#endif
+
QT_END_NAMESPACE
#endif // QT_NO_MAINWINDOW
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index 9104074122..5521d866b2 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -1321,6 +1321,14 @@ void QMdiSubWindowPrivate::setNormalMode()
updateMask();
}
+inline void QMdiSubWindowPrivate::storeFocusWidget()
+{
+ if (QWidget *focus = QApplication::focusWidget()) {
+ if (!restoreFocusWidget && q_func()->isAncestorOf(focus))
+ restoreFocusWidget = focus;
+ }
+}
+
/*!
\internal
*/
@@ -1333,8 +1341,7 @@ void QMdiSubWindowPrivate::setMaximizeMode()
isShadeMode = false;
isMaximizeMode = true;
- if (!restoreFocusWidget && q->isAncestorOf(QApplication::focusWidget()))
- restoreFocusWidget = QApplication::focusWidget();
+ storeFocusWidget();
#ifndef QT_NO_SIZEGRIP
setSizeGripVisible(false);
@@ -1436,6 +1443,7 @@ void QMdiSubWindowPrivate::setActive(bool activate, bool changeFocus)
Qt::WindowStates oldWindowState = q->windowState();
q->overrideWindowState(q->windowState() & ~Qt::WindowActive);
if (changeFocus) {
+ storeFocusWidget();
QWidget *focusWidget = QApplication::focusWidget();
if (focusWidget && (focusWidget == q || q->isAncestorOf(focusWidget)))
focusWidget->clearFocus();
@@ -2026,6 +2034,9 @@ void QMdiSubWindowPrivate::setFocusWidget()
return;
}
+ if (!(q->windowState() & Qt::WindowMinimized) && restoreFocus())
+ return;
+
if (QWidget *focusWidget = baseWidget->focusWidget()) {
if (!focusWidget->hasFocus() && q->isAncestorOf(focusWidget)
&& focusWidget->isVisible() && !q->isMinimized()
@@ -2048,16 +2059,19 @@ void QMdiSubWindowPrivate::setFocusWidget()
q->setFocus();
}
-void QMdiSubWindowPrivate::restoreFocus()
+bool QMdiSubWindowPrivate::restoreFocus()
{
- if (!restoreFocusWidget)
- return;
- if (!restoreFocusWidget->hasFocus() && q_func()->isAncestorOf(restoreFocusWidget)
- && restoreFocusWidget->isVisible()
- && restoreFocusWidget->focusPolicy() != Qt::NoFocus) {
- restoreFocusWidget->setFocus();
+ if (restoreFocusWidget.isNull())
+ return false;
+ QWidget *candidate = restoreFocusWidget;
+ restoreFocusWidget.clear();
+ if (!candidate->hasFocus() && q_func()->isAncestorOf(candidate)
+ && candidate->isVisible()
+ && candidate->focusPolicy() != Qt::NoFocus) {
+ candidate->setFocus();
+ return true;
}
- restoreFocusWidget = 0;
+ return candidate->hasFocus();
}
/*!
@@ -2605,9 +2619,7 @@ void QMdiSubWindow::showShaded()
d->isMaximizeMode = false;
- QWidget *currentFocusWidget = QApplication::focusWidget();
- if (!d->restoreFocusWidget && isAncestorOf(currentFocusWidget))
- d->restoreFocusWidget = currentFocusWidget;
+ d->storeFocusWidget();
if (!d->isShadeRequestFromMinimizeMode) {
d->isShadeMode = true;
@@ -2621,7 +2633,7 @@ void QMdiSubWindow::showShaded()
// showMinimized() will reset Qt::WindowActive, which makes sense
// for top level widgets, but in MDI it makes sense to have an
// active window which is minimized.
- if (hasFocus() || isAncestorOf(currentFocusWidget))
+ if (hasFocus() || isAncestorOf(QApplication::focusWidget()))
d->ensureWindowState(Qt::WindowActive);
#ifndef QT_NO_SIZEGRIP
diff --git a/src/widgets/widgets/qmdisubwindow_p.h b/src/widgets/widgets/qmdisubwindow_p.h
index 90369ff526..6abbe89b4c 100644
--- a/src/widgets/widgets/qmdisubwindow_p.h
+++ b/src/widgets/widgets/qmdisubwindow_p.h
@@ -266,7 +266,8 @@ public:
QPalette desktopPalette() const;
void updateActions();
void setFocusWidget();
- void restoreFocus();
+ bool restoreFocus();
+ void storeFocusWidget();
void setWindowFlags(Qt::WindowFlags windowFlags);
void setVisible(WindowStateAction, bool visible = true);
#ifndef QT_NO_ACTION
diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
index a8027a4157..1df5404995 100644
--- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
+++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
** Contact: http://www.qt-project.org/legal
**
@@ -68,6 +68,9 @@ private slots:
void qMessagePattern();
void setMessagePattern();
+ void formatLogMessage_data();
+ void formatLogMessage();
+
private:
QString m_appDir;
QStringList m_baseEnvironment;
@@ -803,6 +806,63 @@ void tst_qmessagehandler::setMessagePattern()
#endif // !QT_NO_PROCESS
}
+Q_DECLARE_METATYPE(QtMsgType)
+
+void tst_qmessagehandler::formatLogMessage_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QString>("result");
+
+ QTest::addColumn<QtMsgType>("type");
+ QTest::addColumn<QByteArray>("file");
+ QTest::addColumn<int>("line");
+ QTest::addColumn<QByteArray>("function");
+ QTest::addColumn<QByteArray>("category");
+ QTest::addColumn<QString>("message");
+
+#define BA QByteArrayLiteral
+
+ QTest::newRow("basic") << "%{type} %{file} %{line} %{function} %{message}"
+ << "debug main.cpp 1 func msg\n"
+ << QtDebugMsg << BA("main.cpp") << 1 << BA("func") << BA("") << "msg";
+
+ // test the if conditions
+ QString format = "[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{if-category}%{category}: %{endif}%{message}";
+ QTest::newRow("if-debug")
+ << format << "[D] msg\n"
+ << QtDebugMsg << BA("") << 0 << BA("func") << QByteArray() << "msg";
+ QTest::newRow("if_warning")
+ << format << "[W] msg\n"
+ << QtWarningMsg << BA("") << 0 << BA("func") << QByteArray() << "msg";
+ QTest::newRow("if_critical")
+ << format << "[C] msg\n"
+ << QtCriticalMsg << BA("") << 0 << BA("func") << QByteArray() << "msg";
+ QTest::newRow("if_fatal")
+ << format << "[F] msg\n"
+ << QtFatalMsg << BA("") << 0 << BA("func") << QByteArray() << "msg";
+ QTest::newRow("if_cat")
+ << format << "[F] cat: msg\n"
+ << QtFatalMsg << BA("") << 0 << BA("func") << BA("cat") << "msg";
+}
+
+void tst_qmessagehandler::formatLogMessage()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, result);
+
+ QFETCH(QtMsgType, type);
+ QFETCH(QByteArray, file);
+ QFETCH(int, line);
+ QFETCH(QByteArray, function);
+ QFETCH(QByteArray, category);
+ QFETCH(QString, message);
+
+ qSetMessagePattern(pattern);
+ QMessageLogContext ctxt(file, line, function, category.isEmpty() ? 0 : category.data());
+ QString r = qFormatLogMessage(type, ctxt, message);
+ QCOMPARE(r, result);
+}
+
QTEST_MAIN(tst_qmessagehandler)
#include "tst_qlogging.moc"
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
index 767fde7f6c..764c928d76 100644
--- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
+++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
@@ -63,6 +63,7 @@ private slots:
void qDebugQStringRef() const;
void qDebugQLatin1String() const;
void qDebugQByteArray() const;
+ void qDebugQFlags() const;
void textStreamModifiers() const;
void resetFormat() const;
void defaultMessagehandler() const;
@@ -395,6 +396,28 @@ void tst_QDebug::qDebugQByteArray() const
QCOMPARE(QString::fromLatin1(s_function), function);
}
+enum TestEnum {
+ Flag1 = 0x1,
+ Flag2 = 0x10
+};
+
+Q_DECLARE_FLAGS(TestFlags, TestEnum)
+
+void tst_QDebug::qDebugQFlags() const
+{
+ QFlags<TestEnum> flags(Flag1 | Flag2);
+
+ MessageHandlerSetter mhs(myMessageHandler);
+ { qDebug() << flags; }
+ QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("QFlags(0x1|0x10)"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+}
+
void tst_QDebug::textStreamModifiers() const
{
MessageHandlerSetter mhs(myMessageHandler);
diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp
index c7590fd023..ebe7333c47 100644
--- a/tests/auto/corelib/json/tst_qtjson.cpp
+++ b/tests/auto/corelib/json/tst_qtjson.cpp
@@ -148,6 +148,7 @@ private Q_SLOTS:
void longStrings();
void arrayInitializerList();
+ void objectInitializerList();
private:
QString testDataDir;
};
@@ -2681,22 +2682,72 @@ void tst_QtJson::arrayInitializerList()
QCOMPARE(QJsonValue(a3[1]), QJsonValue(o));
QCOMPARE(QJsonValue(a3[2]), QJsonValue(a2));
- QJsonArray a4 { 1, QJsonArray{1,2,3}, QJsonArray{"hello", 2} };
- QCOMPARE(a4.count(), 3);
+ QJsonArray a4 { 1, QJsonArray{1,2,3}, QJsonArray{"hello", 2}, QJsonObject{{"one", 1}} };
+ QCOMPARE(a4.count(), 4);
QCOMPARE(QJsonValue(a4[0]), QJsonValue(1));
{
QJsonArray a41 = a4[1].toArray();
QJsonArray a42 = a4[2].toArray();
+ QJsonObject a43 = a4[3].toObject();
QCOMPARE(a41.count(), 3);
QCOMPARE(a42.count(), 2);
+ QCOMPARE(a43.count(), 1);
QCOMPARE(QJsonValue(a41[2]), QJsonValue(3));
QCOMPARE(QJsonValue(a42[1]), QJsonValue(2));
+ QCOMPARE(QJsonValue(a43["one"]), QJsonValue(1));
}
}
#endif
}
+void tst_QtJson::objectInitializerList()
+{
+#ifndef Q_COMPILER_INITIALIZER_LISTS
+ QSKIP("initializer_list is enabled only with c++11 support");
+#else
+ QVERIFY(QJsonObject{}.isEmpty());
+
+ { // one property
+ QJsonObject one {{"one", 1}};
+ QCOMPARE(one.count(), 1);
+ QVERIFY(one.contains("one"));
+ QCOMPARE(QJsonValue(one["one"]), QJsonValue(1));
+ }
+ { // two properties
+ QJsonObject two {
+ {"one", 1},
+ {"two", 2}
+ };
+ QCOMPARE(two.count(), 2);
+ QVERIFY(two.contains("one"));
+ QVERIFY(two.contains("two"));
+ QCOMPARE(QJsonValue(two["one"]), QJsonValue(1));
+ QCOMPARE(QJsonValue(two["two"]), QJsonValue(2));
+ }
+ { // nested object
+ QJsonObject object{{"nested", QJsonObject{{"innerProperty", 2}}}};
+ QCOMPARE(object.count(), 1);
+ QVERIFY(object.contains("nested"));
+ QVERIFY(object["nested"].isObject());
+
+ QJsonObject nested = object["nested"].toObject();
+ QCOMPARE(QJsonValue(nested["innerProperty"]), QJsonValue(2));
+ }
+ { // nested array
+ QJsonObject object{{"nested", QJsonArray{"innerValue", 2.1, "bum cyk cyk"}}};
+ QCOMPARE(object.count(), 1);
+ QVERIFY(object.contains("nested"));
+ QVERIFY(object["nested"].isArray());
+
+ QJsonArray nested = object["nested"].toArray();
+ QCOMPARE(nested.count(), 3);
+ QCOMPARE(QJsonValue(nested[0]), QJsonValue("innerValue"));
+ QCOMPARE(QJsonValue(nested[1]), QJsonValue(2.1));
+ }
+#endif
+}
+
QTEST_MAIN(tst_QtJson)
#include "tst_qtjson.moc"
diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp
index e8d4fe51a8..67f3477eee 100644
--- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp
+++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp
@@ -92,6 +92,22 @@ static int globalTick;
QCOMPARE(machine.isRunning(), runningArgs.at(0).toBool()); \
}
+#define DEFINE_ACTIVE_SPY(VAR) \
+ QSignalSpy VAR##_activeSpy(VAR, &QState::activeChanged); \
+ QVERIFY(VAR##_activeSpy.isValid());
+
+#define TEST_ACTIVE_CHANGED(VAR, COUNT) \
+{ \
+ QTRY_COMPARE(VAR##_activeSpy.count(), COUNT); \
+ bool active = true; \
+ foreach (const QList<QVariant> &activeArgs, static_cast<QList<QList<QVariant> > >(VAR##_activeSpy)) { \
+ QVERIFY(activeArgs.at(0).type() == QVariant::Bool); \
+ QVERIFY(activeArgs.at(0).toBool() == active); \
+ active = !active; \
+ } \
+ QCOMPARE(VAR->active(), !active); \
+}
+
class SignalEmitter : public QObject
{
Q_OBJECT
@@ -299,6 +315,7 @@ void tst_QStateMachine::transitionToRootState()
machine.setObjectName("machine");
QState *initialState = new QState();
+ DEFINE_ACTIVE_SPY(initialState);
initialState->setObjectName("initial");
machine.addState(initialState);
machine.setInitialState(initialState);
@@ -313,12 +330,14 @@ void tst_QStateMachine::transitionToRootState()
QCOMPARE(machine.configuration().count(), 1);
QVERIFY(machine.configuration().contains(initialState));
+ TEST_ACTIVE_CHANGED(initialState, 1);
machine.postEvent(new QEvent(QEvent::User));
QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 'initial'");
QCoreApplication::processEvents();
QVERIFY(machine.configuration().isEmpty());
QVERIFY(!machine.isRunning());
+ TEST_ACTIVE_CHANGED(initialState, 2);
}
void tst_QStateMachine::transitionFromRootState()
@@ -1120,11 +1139,15 @@ void tst_QStateMachine::rootState()
QCOMPARE(machine.machine(), (QStateMachine*)0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QCOMPARE(s1->parentState(), static_cast<QState*>(&machine));
QState *s2 = new QState();
+ DEFINE_ACTIVE_SPY(s2);
s2->setParent(&machine);
QCOMPARE(s2->parentState(), static_cast<QState*>(&machine));
+ TEST_ACTIVE_CHANGED(s1, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
}
void tst_QStateMachine::machineWithParent()
@@ -1398,6 +1421,7 @@ void tst_QStateMachine::assignProperty()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QTest::ignoreMessage(QtWarningMsg, "QState::assignProperty: cannot assign property 'foo' of null object");
s1->assignProperty(0, "foo", QVariant());
@@ -1408,32 +1432,39 @@ void tst_QStateMachine::assignProperty()
machine.setInitialState(s1);
machine.start();
QTRY_COMPARE(s1->objectName(), QString::fromLatin1("s1"));
+ TEST_ACTIVE_CHANGED(s1, 2);
s1->assignProperty(s1, "objectName", "foo");
machine.start();
QTRY_COMPARE(s1->objectName(), QString::fromLatin1("foo"));
+ TEST_ACTIVE_CHANGED(s1, 4);
s1->assignProperty(s1, "noSuchProperty", 123);
machine.start();
QTRY_COMPARE(s1->dynamicPropertyNames().size(), 1);
QCOMPARE(s1->dynamicPropertyNames().at(0), QByteArray("noSuchProperty"));
QCOMPARE(s1->objectName(), QString::fromLatin1("foo"));
+ TEST_ACTIVE_CHANGED(s1, 6);
{
QSignalSpy propertiesAssignedSpy(s1, &QState::propertiesAssigned);
QVERIFY(propertiesAssignedSpy.isValid());
machine.start();
QTRY_COMPARE(propertiesAssignedSpy.count(), 1);
+ TEST_ACTIVE_CHANGED(s1, 8);
}
// nested states
{
QState *s11 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s11);
QString str = QString::fromLatin1("set by nested state");
s11->assignProperty(s11, "objectName", str);
s1->setInitialState(s11);
machine.start();
QTRY_COMPARE(s11->objectName(), str);
+ TEST_ACTIVE_CHANGED(s1, 10);
+ TEST_ACTIVE_CHANGED(s11, 2);
}
}
@@ -1451,8 +1482,10 @@ void tst_QStateMachine::assignPropertyWithAnimation()
obj.setProperty("foo", 321);
obj.setProperty("bar", 654);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(&obj, "foo", 123);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(&obj, "foo", 456);
s2->assignProperty(&obj, "bar", 789);
QAbstractTransition *trans = s1->addTransition(s2);
@@ -1485,6 +1518,8 @@ void tst_QStateMachine::assignPropertyWithAnimation()
TEST_RUNNING_CHANGED_STARTED_STOPPED;
QCOMPARE(obj.property("foo").toInt(), 456);
QCOMPARE(obj.property("bar").toInt(), 789);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
}
// Two animations
{
@@ -1493,8 +1528,10 @@ void tst_QStateMachine::assignPropertyWithAnimation()
obj.setProperty("foo", 321);
obj.setProperty("bar", 654);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(&obj, "foo", 123);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(&obj, "foo", 456);
s2->assignProperty(&obj, "bar", 789);
QAbstractTransition *trans = s1->addTransition(s2);
@@ -1517,6 +1554,8 @@ void tst_QStateMachine::assignPropertyWithAnimation()
TEST_RUNNING_CHANGED_STARTED_STOPPED;
QCOMPARE(obj.property("foo").toInt(), 456);
QCOMPARE(obj.property("bar").toInt(), 789);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
}
// Animation group
{
@@ -1525,9 +1564,11 @@ void tst_QStateMachine::assignPropertyWithAnimation()
obj.setProperty("foo", 321);
obj.setProperty("bar", 654);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(&obj, "foo", 123);
s1->assignProperty(&obj, "bar", 321);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(&obj, "foo", 456);
s2->assignProperty(&obj, "bar", 654);
s2->assignProperty(&obj, "baz", 789);
@@ -1550,6 +1591,8 @@ void tst_QStateMachine::assignPropertyWithAnimation()
QCOMPARE(obj.property("foo").toInt(), 456);
QCOMPARE(obj.property("bar").toInt(), 654);
QCOMPARE(obj.property("baz").toInt(), 789);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
}
// Nested states
{
@@ -1558,6 +1601,7 @@ void tst_QStateMachine::assignPropertyWithAnimation()
obj.setProperty("foo", 321);
obj.setProperty("bar", 654);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QCOMPARE(s1->childMode(), QState::ExclusiveStates);
s1->setChildMode(QState::ParallelStates);
QCOMPARE(s1->childMode(), QState::ParallelStates);
@@ -1568,12 +1612,15 @@ void tst_QStateMachine::assignPropertyWithAnimation()
s1->assignProperty(&obj, "foo", 123);
s1->assignProperty(&obj, "bar", 456);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->setObjectName("s2");
s2->assignProperty(&obj, "foo", 321);
QState *s21 = new QState(s2);
+ DEFINE_ACTIVE_SPY(s21);
s21->setObjectName("s21");
s21->assignProperty(&obj, "bar", 654);
QState *s22 = new QState(s2);
+ DEFINE_ACTIVE_SPY(s22);
s22->setObjectName("s22");
s22->assignProperty(&obj, "bar", 789);
s2->setInitialState(s21);
@@ -1602,6 +1649,10 @@ void tst_QStateMachine::assignPropertyWithAnimation()
TEST_RUNNING_CHANGED_STARTED_STOPPED;
QCOMPARE(obj.property("foo").toInt(), 321);
QCOMPARE(obj.property("bar").toInt(), 789);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s21, 2);
+ TEST_ACTIVE_CHANGED(s22, 2);
}
// Aborted animation
{
@@ -1612,9 +1663,11 @@ void tst_QStateMachine::assignPropertyWithAnimation()
obj.setProperty("bar", 654);
QState *group = new QState(&machine);
QState *s1 = new QState(group);
+ DEFINE_ACTIVE_SPY(s1);
group->setInitialState(s1);
s1->assignProperty(&obj, "foo", 123);
QState *s2 = new QState(group);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(&obj, "foo", 456);
s2->assignProperty(&obj, "bar", 789);
QAbstractTransition *trans = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s2);
@@ -1625,6 +1678,7 @@ void tst_QStateMachine::assignPropertyWithAnimation()
anim2.setDuration(8000);
trans->addAnimation(&anim2);
QState *s3 = new QState(group);
+ DEFINE_ACTIVE_SPY(s3);
s3->assignProperty(&obj, "foo", 911);
s2->addTransition(&emitter, SIGNAL(signalWithNoArg()), s3);
@@ -1641,6 +1695,10 @@ void tst_QStateMachine::assignPropertyWithAnimation()
QVERIFY(propertiesAssignedSpy.isEmpty());
QCOMPARE(obj.property("foo").toInt(), 911);
QCOMPARE(obj.property("bar").toInt(), 789);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
}
}
@@ -1712,6 +1770,7 @@ void tst_QStateMachine::postEvent()
machine.postEvent(&e);
}
StringEventPoster *s1 = new StringEventPoster("a");
+ DEFINE_ACTIVE_SPY(s1);
if (x == 1)
s1->setDelay(100);
QFinalState *s2 = new QFinalState;
@@ -1728,6 +1787,7 @@ void tst_QStateMachine::postEvent()
TEST_RUNNING_CHANGED_STARTED_STOPPED;
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s2));
+ TEST_ACTIVE_CHANGED(s1, 2);
s1->setString("b");
QFinalState *s3 = new QFinalState();
@@ -1738,6 +1798,7 @@ void tst_QStateMachine::postEvent()
QTRY_COMPARE(finishedSpy.count(), 1);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s3));
+ TEST_ACTIVE_CHANGED(s1, 4);
}
}
@@ -1748,6 +1809,7 @@ void tst_QStateMachine::cancelDelayedEvent()
QVERIFY(!machine.cancelDelayedEvent(-1));
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QFinalState *s2 = new QFinalState(&machine);
s1->addTransition(new StringTransition("a", s2));
machine.setInitialState(s1);
@@ -1759,9 +1821,9 @@ void tst_QStateMachine::cancelDelayedEvent()
machine.start();
QTRY_COMPARE(startedSpy.count(), 1);
TEST_RUNNING_CHANGED(true);
+ TEST_ACTIVE_CHANGED(s1, 1);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
-
int id1 = machine.postDelayedEvent(new StringEvent("c"), 50000);
QVERIFY(id1 != -1);
int id2 = machine.postDelayedEvent(new StringEvent("b"), 25000);
@@ -1779,6 +1841,7 @@ void tst_QStateMachine::cancelDelayedEvent()
QVERIFY(finishedSpy.isValid());
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED(false);
+ TEST_ACTIVE_CHANGED(s1, 2);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s2));
}
@@ -1787,6 +1850,7 @@ void tst_QStateMachine::postDelayedEventAndStop()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QFinalState *s2 = new QFinalState(&machine);
s1->addTransition(new StringTransition("a", s2));
machine.setInitialState(s1);
@@ -1798,6 +1862,7 @@ void tst_QStateMachine::postDelayedEventAndStop()
machine.start();
QTRY_COMPARE(startedSpy.count(), 1);
TEST_RUNNING_CHANGED(true);
+ TEST_ACTIVE_CHANGED(s1, 1);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
@@ -1808,12 +1873,14 @@ void tst_QStateMachine::postDelayedEventAndStop()
machine.stop();
QTRY_COMPARE(stoppedSpy.count(), 1);
TEST_RUNNING_CHANGED(false);
+ TEST_ACTIVE_CHANGED(s1, 1);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
machine.start();
QTRY_COMPARE(startedSpy.count(), 2);
TEST_RUNNING_CHANGED(true);
+ TEST_ACTIVE_CHANGED(s1, 3);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
@@ -1822,12 +1889,15 @@ void tst_QStateMachine::postDelayedEventAndStop()
machine.stop();
QTRY_COMPARE(stoppedSpy.count(), 2);
TEST_RUNNING_CHANGED(false);
+ TEST_ACTIVE_CHANGED(s1, 3);
machine.start();
QTRY_COMPARE(startedSpy.count(), 3);
TEST_RUNNING_CHANGED(true);
QTestEventLoop::instance().enterLoop(2);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
+ TEST_ACTIVE_CHANGED(s1, 5);
+ QVERIFY(machine.isRunning());
}
class DelayedEventPosterThread : public QThread
@@ -1864,6 +1934,7 @@ void tst_QStateMachine::postDelayedEventFromThread()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QFinalState *f = new QFinalState(&machine);
s1->addTransition(new EventTransition(QEvent::User, f));
machine.setInitialState(s1);
@@ -1878,6 +1949,7 @@ void tst_QStateMachine::postDelayedEventFromThread()
machine.start();
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s1, 2);
QVERIFY(poster.firstEventWasCancelled);
}
@@ -1885,6 +1957,7 @@ void tst_QStateMachine::stopAndPostEvent()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
QVERIFY(runningSpy.isValid());
@@ -1893,6 +1966,7 @@ void tst_QStateMachine::stopAndPostEvent()
machine.start();
QTRY_COMPARE(startedSpy.count(), 1);
TEST_RUNNING_CHANGED(true);
+ TEST_ACTIVE_CHANGED(s1, 1);
QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
QVERIFY(stoppedSpy.isValid());
machine.stop();
@@ -1900,6 +1974,7 @@ void tst_QStateMachine::stopAndPostEvent()
machine.postEvent(new QEvent(QEvent::User));
QTRY_COMPARE(stoppedSpy.count(), 1);
TEST_RUNNING_CHANGED(false);
+ TEST_ACTIVE_CHANGED(s1, 1);
QCoreApplication::processEvents();
}
@@ -1907,7 +1982,9 @@ void tst_QStateMachine::stateFinished()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s1_1 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s1_1);
QFinalState *s1_2 = new QFinalState(s1);
s1_1->addTransition(s1_2);
s1->setInitialState(s1_1);
@@ -1921,6 +1998,8 @@ void tst_QStateMachine::stateFinished()
machine.start();
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s1_1, 2);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s2));
}
@@ -1997,9 +2076,11 @@ void tst_QStateMachine::parallelRootState()
QCOMPARE(root->childMode(), QState::ParallelStates);
QState *s1 = new QState(root);
+ DEFINE_ACTIVE_SPY(s1);
QFinalState *s1_f = new QFinalState(s1);
s1->setInitialState(s1_f);
QState *s2 = new QState(root);
+ DEFINE_ACTIVE_SPY(s2);
QFinalState *s2_f = new QFinalState(s2);
s2->setInitialState(s2_f);
@@ -2018,22 +2099,31 @@ void tst_QStateMachine::parallelRootState()
QVERIFY(machine.configuration().contains(s2_f));
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ QVERIFY(!machine.isRunning());
}
void tst_QStateMachine::allSourceToTargetConfigurations()
{
QStateMachine machine;
QState *s0 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s0);
s0->setObjectName("s0");
QState *s1 = new QState(s0);
+ DEFINE_ACTIVE_SPY(s1);
s1->setObjectName("s1");
QState *s11 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s11);
s11->setObjectName("s11");
QState *s2 = new QState(s0);
+ DEFINE_ACTIVE_SPY(s2);
s2->setObjectName("s2");
QState *s21 = new QState(s2);
+ DEFINE_ACTIVE_SPY(s21);
s21->setObjectName("s21");
QState *s211 = new QState(s21);
+ DEFINE_ACTIVE_SPY(s211);
s211->setObjectName("s211");
QFinalState *f = new QFinalState(&machine);
f->setObjectName("f");
@@ -2064,23 +2154,84 @@ void tst_QStateMachine::allSourceToTargetConfigurations()
machine.setInitialState(s0);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s21, 0);
+ TEST_ACTIVE_CHANGED(s211, 0);
machine.postEvent(new StringEvent("a"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
+ TEST_ACTIVE_CHANGED(s1, 3);
+ TEST_ACTIVE_CHANGED(s11, 3);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s21, 0);
+ TEST_ACTIVE_CHANGED(s211, 0);
+
machine.postEvent(new StringEvent("b"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
+ TEST_ACTIVE_CHANGED(s1, 5);
+ TEST_ACTIVE_CHANGED(s11, 5);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s21, 0);
+ TEST_ACTIVE_CHANGED(s211, 0);
+
machine.postEvent(new StringEvent("c"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
+ TEST_ACTIVE_CHANGED(s1, 6);
+ TEST_ACTIVE_CHANGED(s11, 6);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s21, 1);
+ TEST_ACTIVE_CHANGED(s211, 1);
+
machine.postEvent(new StringEvent("d"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
+ TEST_ACTIVE_CHANGED(s1, 6);
+ TEST_ACTIVE_CHANGED(s11, 6);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s21, 3);
+ TEST_ACTIVE_CHANGED(s211, 3);
+
machine.postEvent(new StringEvent("e"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 3);
+ TEST_ACTIVE_CHANGED(s1, 6);
+ TEST_ACTIVE_CHANGED(s11, 6);
+ TEST_ACTIVE_CHANGED(s2, 3);
+ TEST_ACTIVE_CHANGED(s21, 5);
+ TEST_ACTIVE_CHANGED(s211, 5);
+
machine.postEvent(new StringEvent("f"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 3);
+ TEST_ACTIVE_CHANGED(s1, 7);
+ TEST_ACTIVE_CHANGED(s11, 7);
+ TEST_ACTIVE_CHANGED(s2, 4);
+ TEST_ACTIVE_CHANGED(s21, 6);
+ TEST_ACTIVE_CHANGED(s211, 6);
+
machine.postEvent(new StringEvent("g"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 3);
+ TEST_ACTIVE_CHANGED(s1, 8);
+ TEST_ACTIVE_CHANGED(s11, 8);
+ TEST_ACTIVE_CHANGED(s2, 5);
+ TEST_ACTIVE_CHANGED(s21, 7);
+ TEST_ACTIVE_CHANGED(s211, 7);
+
machine.postEvent(new StringEvent("h"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 4);
+ TEST_ACTIVE_CHANGED(s1, 8);
+ TEST_ACTIVE_CHANGED(s11, 8);
+ TEST_ACTIVE_CHANGED(s2, 6);
+ TEST_ACTIVE_CHANGED(s21, 8);
+ TEST_ACTIVE_CHANGED(s211, 8);
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
@@ -2149,6 +2300,7 @@ void tst_QStateMachine::signalTransitions()
{
QStateMachine machine;
QState *s0 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s0);
QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: sender cannot be null");
QCOMPARE(s0->addTransition(0, SIGNAL(noSuchSignal()), 0), (QSignalTransition*)0);
@@ -2182,7 +2334,7 @@ void tst_QStateMachine::signalTransitions()
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
-
+ TEST_ACTIVE_CHANGED(s0, 2);
emitter.emitSignalWithNoArg();
trans->setSignal(SIGNAL(signalWithIntArg(int)));
@@ -2192,6 +2344,7 @@ void tst_QStateMachine::signalTransitions()
emitter.emitSignalWithIntArg(123);
QTRY_COMPARE(finishedSpy.count(), 2);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s0, 4);
machine.start();
QCoreApplication::processEvents();
@@ -2200,6 +2353,7 @@ void tst_QStateMachine::signalTransitions()
emitter.emitSignalWithNoArg();
QTRY_COMPARE(finishedSpy.count(), 3);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s0, 6);
SignalEmitter emitter2;
machine.start();
@@ -2208,6 +2362,7 @@ void tst_QStateMachine::signalTransitions()
emitter2.emitSignalWithNoArg();
QTRY_COMPARE(finishedSpy.count(), 4);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s0, 8);
machine.start();
QCoreApplication::processEvents();
@@ -2215,10 +2370,13 @@ void tst_QStateMachine::signalTransitions()
trans->setSignal(SIGNAL(noSuchSignal()));
QCOMPARE(trans->signal(), QByteArray(SIGNAL(noSuchSignal())));
TEST_RUNNING_CHANGED(true);
+ TEST_ACTIVE_CHANGED(s0, 9);
+ QVERIFY(machine.isRunning());
}
{
QStateMachine machine;
QState *s0 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s0);
QFinalState *s1 = new QFinalState(&machine);
SignalEmitter emitter;
QSignalTransition *trans = s0->addTransition(&emitter, "signalWithNoArg()", s1);
@@ -2235,23 +2393,27 @@ void tst_QStateMachine::signalTransitions()
machine.setInitialState(s0);
machine.start();
QCoreApplication::processEvents();
-
+ TEST_ACTIVE_CHANGED(s0, 1);
emitter.emitSignalWithNoArg();
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s0, 2);
trans->setSignal("signalWithIntArg(int)");
QCOMPARE(trans->signal(), QByteArray("signalWithIntArg(int)"));
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 3);
emitter.emitSignalWithIntArg(123);
QTRY_COMPARE(finishedSpy.count(), 2);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s0, 4);
}
{
QStateMachine machine;
QState *s0 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s0);
QFinalState *s1 = new QFinalState(&machine);
SignalEmitter emitter;
TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithIntArg(int)), s1);
@@ -2264,11 +2426,12 @@ void tst_QStateMachine::signalTransitions()
machine.setInitialState(s0);
machine.start();
QCoreApplication::processEvents();
-
+ TEST_ACTIVE_CHANGED(s0, 1);
emitter.emitSignalWithIntArg(123);
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s0, 2);
QCOMPARE(trans->eventTestSenderReceived(), (QObject*)&emitter);
QCOMPARE(trans->eventTestSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithIntArg(int)"));
QCOMPARE(trans->eventTestArgumentsReceived().size(), 1);
@@ -2281,6 +2444,7 @@ void tst_QStateMachine::signalTransitions()
{
QStateMachine machine;
QState *s0 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s0);
QFinalState *s1 = new QFinalState(&machine);
SignalEmitter emitter;
TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s1);
@@ -2293,12 +2457,14 @@ void tst_QStateMachine::signalTransitions()
machine.setInitialState(s0);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
QString testString = QString::fromLatin1("hello");
emitter.emitSignalWithStringArg(testString);
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s0, 2);
QCOMPARE(trans->eventTestSenderReceived(), (QObject*)&emitter);
QCOMPARE(trans->eventTestSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithStringArg(QString)"));
QCOMPARE(trans->eventTestArgumentsReceived().size(), 1);
@@ -2311,6 +2477,7 @@ void tst_QStateMachine::signalTransitions()
{
QStateMachine machine;
QState *s0 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s0);
QFinalState *s1 = new QFinalState(&machine);
TestSignalTransition *trans = new TestSignalTransition();
@@ -2332,18 +2499,22 @@ void tst_QStateMachine::signalTransitions()
machine.setInitialState(s0);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
emitter.emitSignalWithNoArg();
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s0, 2);
}
// Multiple transitions for same (object,signal)
{
QStateMachine machine;
SignalEmitter emitter;
QState *s0 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1);
QSignalTransition *t1 = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s0);
@@ -2352,28 +2523,38 @@ void tst_QStateMachine::signalTransitions()
machine.setInitialState(s0);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
+ TEST_ACTIVE_CHANGED(s1, 0);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s0));
emitter.emitSignalWithNoArg();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 2);
+ TEST_ACTIVE_CHANGED(s1, 1);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
s0->removeTransition(t0);
emitter.emitSignalWithNoArg();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 3);
+ TEST_ACTIVE_CHANGED(s1, 2);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s0));
emitter.emitSignalWithNoArg();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 3);
+ TEST_ACTIVE_CHANGED(s1, 2);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s0));
s1->removeTransition(t1);
emitter.emitSignalWithNoArg();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 3);
+ TEST_ACTIVE_CHANGED(s1, 2);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s0));
@@ -2381,6 +2562,9 @@ void tst_QStateMachine::signalTransitions()
s1->addTransition(t1);
emitter.emitSignalWithNoArg();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 4);
+ TEST_ACTIVE_CHANGED(s1, 3);
+ QVERIFY(machine.isRunning());
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
}
@@ -2389,6 +2573,7 @@ void tst_QStateMachine::signalTransitions()
QStateMachine machine;
SignalEmitter emitter;
QState *s0 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s0);
QFinalState *s1 = new QFinalState(&machine);
s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1);
QFinalState *s2 = new QFinalState(&machine);
@@ -2405,27 +2590,34 @@ void tst_QStateMachine::signalTransitions()
machine.setInitialState(s0);
machine.start();
+ TEST_ACTIVE_CHANGED(s0, 1);
QTRY_COMPARE(startedSpy.count(), 1);
TEST_RUNNING_CHANGED(true);
emitter.emitSignalWithNoArg();
+ TEST_ACTIVE_CHANGED(s0, 2);
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED(false);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
machine.start();
+ TEST_ACTIVE_CHANGED(s0, 3);
QTRY_COMPARE(startedSpy.count(), 2);
TEST_RUNNING_CHANGED(true);
emitter.emitSignalWithIntArg(123);
+ TEST_ACTIVE_CHANGED(s0, 4);
QTRY_COMPARE(finishedSpy.count(), 2);
TEST_RUNNING_CHANGED(false);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s2));
machine.start();
+ QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 5);
QTRY_COMPARE(startedSpy.count(), 3);
TEST_RUNNING_CHANGED(true);
emitter.emitSignalWithStringArg("hello");
+ TEST_ACTIVE_CHANGED(s0, 6);
QTRY_COMPARE(finishedSpy.count(), 3);
TEST_RUNNING_CHANGED(false);
QCOMPARE(machine.configuration().size(), 1);
@@ -2436,6 +2628,7 @@ void tst_QStateMachine::signalTransitions()
QStateMachine machine;
SignalEmitter emitter;
QState *s0 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s0);
QFinalState *s1 = new QFinalState(&machine);
QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1);
QVERIFY(t0 != 0);
@@ -2453,12 +2646,15 @@ void tst_QStateMachine::signalTransitions()
QVERIFY(runningSpy.isValid());
machine.setInitialState(s0);
machine.start();
+ QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
QTRY_COMPARE(startedSpy.count(), 1);
QCOMPARE(finishedSpy.count(), 0);
TEST_RUNNING_CHANGED(true);
emitter.emitSignalWithNoArg();
+ TEST_ACTIVE_CHANGED(s0, 2);
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED(false);
}
@@ -2848,8 +3044,11 @@ void tst_QStateMachine::historyStates()
QStateMachine machine;
QState *root = &machine;
QState *s0 = new QState(root);
+ DEFINE_ACTIVE_SPY(s0);
QState *s00 = new QState(s0);
+ DEFINE_ACTIVE_SPY(s00);
QState *s01 = new QState(s0);
+ DEFINE_ACTIVE_SPY(s01);
QHistoryState *s0h;
if (x == 0) {
s0h = new QHistoryState(s0);
@@ -2869,6 +3068,7 @@ void tst_QStateMachine::historyStates()
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
s0h->setDefaultState(s0);
QState *s1 = new QState(root);
+ DEFINE_ACTIVE_SPY(s1);
QFinalState *s2 = new QFinalState(root);
s00->addTransition(new StringTransition("a", s01));
@@ -2885,29 +3085,49 @@ void tst_QStateMachine::historyStates()
QVERIFY(finishedSpy.isValid());
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
+ TEST_ACTIVE_CHANGED(s00, 1);
+ TEST_ACTIVE_CHANGED(s01, 0);
+ TEST_ACTIVE_CHANGED(s1, 0);
QCOMPARE(machine.configuration().size(), 2);
QVERIFY(machine.configuration().contains(s0));
QVERIFY(machine.configuration().contains(s00));
machine.postEvent(new StringEvent("a"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 1);
+ TEST_ACTIVE_CHANGED(s00, 2);
+ TEST_ACTIVE_CHANGED(s01, 1);
+ TEST_ACTIVE_CHANGED(s1, 0);
QCOMPARE(machine.configuration().size(), 2);
QVERIFY(machine.configuration().contains(s0));
QVERIFY(machine.configuration().contains(s01));
machine.postEvent(new StringEvent("b"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 2);
+ TEST_ACTIVE_CHANGED(s00, 2);
+ TEST_ACTIVE_CHANGED(s01, 2);
+ TEST_ACTIVE_CHANGED(s1, 1);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
machine.postEvent(new StringEvent("c"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 3);
+ TEST_ACTIVE_CHANGED(s00, 2);
+ TEST_ACTIVE_CHANGED(s01, 3);
+ TEST_ACTIVE_CHANGED(s1, 2);
QCOMPARE(machine.configuration().size(), 2);
QVERIFY(machine.configuration().contains(s0));
QVERIFY(machine.configuration().contains(s01));
machine.postEvent(new StringEvent("d"));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s0, 4);
+ TEST_ACTIVE_CHANGED(s00, 2);
+ TEST_ACTIVE_CHANGED(s01, 4);
+ TEST_ACTIVE_CHANGED(s1, 2);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s2));
@@ -2944,8 +3164,10 @@ void tst_QStateMachine::startAndStop()
QCOMPARE(runningSpy.count(), 0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
QTRY_COMPARE(machine.isRunning(), true);
QTRY_COMPARE(startedSpy.count(), 1);
QCOMPARE(stoppedSpy.count(), 0);
@@ -2959,6 +3181,7 @@ void tst_QStateMachine::startAndStop()
QCOMPARE(runningSpy.count(), 0);
machine.stop();
+ TEST_ACTIVE_CHANGED(s1, 1);
QTRY_COMPARE(machine.isRunning(), false);
QTRY_COMPARE(stoppedSpy.count(), 1);
QCOMPARE(startedSpy.count(), 1);
@@ -2969,9 +3192,11 @@ void tst_QStateMachine::startAndStop()
QVERIFY(machine.configuration().contains(s1));
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 3);
machine.stop();
+ TEST_ACTIVE_CHANGED(s1, 3);
QTRY_COMPARE(startedSpy.count(), 2);
- QCOMPARE(stoppedSpy.count(), 2);
+ QTRY_COMPARE(stoppedSpy.count(), 2);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
}
@@ -3003,8 +3228,10 @@ void tst_QStateMachine::setRunning()
QCOMPARE(runningSpy.count(), 0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
machine.setRunning(true);
+ TEST_ACTIVE_CHANGED(s1, 1);
QTRY_COMPARE(machine.isRunning(), true);
QTRY_COMPARE(startedSpy.count(), 1);
QCOMPARE(stoppedSpy.count(), 0);
@@ -3015,9 +3242,11 @@ void tst_QStateMachine::setRunning()
QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start(): already running");
machine.setRunning(true);
+ TEST_ACTIVE_CHANGED(s1, 1);
QCOMPARE(runningSpy.count(), 0);
machine.setRunning(false);
+ TEST_ACTIVE_CHANGED(s1, 1);
QTRY_COMPARE(machine.isRunning(), false);
QTRY_COMPARE(stoppedSpy.count(), 1);
QCOMPARE(startedSpy.count(), 1);
@@ -3028,11 +3257,14 @@ void tst_QStateMachine::setRunning()
machine.setRunning(false);
QCOMPARE(runningSpy.count(), 0);
+ TEST_ACTIVE_CHANGED(s1, 1);
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 3);
machine.setRunning(false);
+ TEST_ACTIVE_CHANGED(s1, 3);
QTRY_COMPARE(startedSpy.count(), 2);
- QCOMPARE(stoppedSpy.count(), 2);
+ QTRY_COMPARE(stoppedSpy.count(), 2);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
QState *s1_1 = new QState(s1);
QFinalState *s1_2 = new QFinalState(s1);
@@ -3043,6 +3275,7 @@ void tst_QStateMachine::setRunning()
machine.setRunning(false);
QCOMPARE(runningSpy.count(), 0);
machine.setRunning(true);
+ TEST_ACTIVE_CHANGED(s1, 6);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
QTRY_COMPARE(startedSpy.count(), 3);
QCOMPARE(stoppedSpy.count(), 2);
@@ -3053,6 +3286,7 @@ void tst_QStateMachine::targetStateWithNoParent()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->setObjectName("s1");
QState s2;
s1->addTransition(&s2);
@@ -3069,6 +3303,7 @@ void tst_QStateMachine::targetStateWithNoParent()
machine.start();
QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 's1'");
+ TEST_ACTIVE_CHANGED(s1, 2);
QTRY_COMPARE(startedSpy.count(), 1);
QCOMPARE(machine.isRunning(), false);
QCOMPARE(stoppedSpy.count(), 1);
@@ -3098,12 +3333,15 @@ void tst_QStateMachine::defaultGlobalRestorePolicy()
propertyHolder->setProperty("b", 2);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(propertyHolder, "a", 3);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(propertyHolder, "b", 4);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
s1->addTransition(new EventTransition(QEvent::User, s2));
s2->addTransition(new EventTransition(QEvent::User, s3));
@@ -3112,18 +3350,28 @@ void tst_QStateMachine::defaultGlobalRestorePolicy()
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
QCOMPARE(propertyHolder->property("a").toInt(), 3);
QCOMPARE(propertyHolder->property("b").toInt(), 2);
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
QCOMPARE(propertyHolder->property("a").toInt(), 3);
QCOMPARE(propertyHolder->property("b").toInt(), 4);
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QCOMPARE(propertyHolder->property("a").toInt(), 3);
QCOMPARE(propertyHolder->property("b").toInt(), 4);
}
@@ -3133,17 +3381,20 @@ void tst_QStateMachine::noInitialStateForInitialState()
QStateMachine machine;
QState *initialState = new QState(&machine);
+ DEFINE_ACTIVE_SPY(initialState);
initialState->setObjectName("initialState");
machine.setInitialState(initialState);
QState *childState = new QState(initialState);
+ DEFINE_ACTIVE_SPY(childState);
(void)childState;
QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: "
"Missing initial state in compound state 'initialState'");
machine.start();
QCoreApplication::processEvents();
-
+ TEST_ACTIVE_CHANGED(initialState, 1);
+ TEST_ACTIVE_CHANGED(childState, 0);
QCOMPARE(machine.isRunning(), false);
QCOMPARE(int(machine.error()), int(QStateMachine::NoInitialStateError));
}
@@ -3158,12 +3409,15 @@ void tst_QStateMachine::globalRestorePolicySetToDontRestore()
propertyHolder->setProperty("b", 2);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(propertyHolder, "a", 3);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(propertyHolder, "b", 4);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
s1->addTransition(new EventTransition(QEvent::User, s2));
s2->addTransition(new EventTransition(QEvent::User, s3));
@@ -3172,18 +3426,28 @@ void tst_QStateMachine::globalRestorePolicySetToDontRestore()
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
QCOMPARE(propertyHolder->property("a").toInt(), 3);
QCOMPARE(propertyHolder->property("b").toInt(), 2);
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
QCOMPARE(propertyHolder->property("a").toInt(), 3);
QCOMPARE(propertyHolder->property("b").toInt(), 4);
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QCOMPARE(propertyHolder->property("a").toInt(), 3);
QCOMPARE(propertyHolder->property("b").toInt(), 4);
}
@@ -3198,12 +3462,15 @@ void tst_QStateMachine::globalRestorePolicySetToRestore()
propertyHolder->setProperty("b", 2);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(propertyHolder, "a", 3);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(propertyHolder, "b", 4);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
s1->addTransition(new EventTransition(QEvent::User, s2));
s2->addTransition(new EventTransition(QEvent::User, s3));
@@ -3212,18 +3479,28 @@ void tst_QStateMachine::globalRestorePolicySetToRestore()
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
QCOMPARE(propertyHolder->property("a").toInt(), 3);
QCOMPARE(propertyHolder->property("b").toInt(), 2);
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
QCOMPARE(propertyHolder->property("a").toInt(), 1);
QCOMPARE(propertyHolder->property("b").toInt(), 4);
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QCOMPARE(propertyHolder->property("a").toInt(), 1);
QCOMPARE(propertyHolder->property("b").toInt(), 2);
}
@@ -3248,7 +3525,9 @@ void tst_QStateMachine::simpleAnimation()
object->setProperty("fooBar", 1.0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "fooBar", 2.0);
EventTransition *et = new EventTransition(QEvent::User, s2);
@@ -3257,16 +3536,24 @@ void tst_QStateMachine::simpleAnimation()
s1->addTransition(et);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
s2->addTransition(animation, SIGNAL(finished()), s3);
QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
machine.setInitialState(s1);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
machine.postEvent(new QEvent(QEvent::User));
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QVERIFY(machine.configuration().contains(s3));
QCOMPARE(object->property("fooBar").toDouble(), 2.0);
}
@@ -3292,7 +3579,9 @@ void tst_QStateMachine::twoAnimations()
object->setProperty("bar", 3.0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "foo", 2.0);
s2->assignProperty(object, "bar", 10.0);
@@ -3310,15 +3599,23 @@ void tst_QStateMachine::twoAnimations()
s1->addTransition(et);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
machine.setInitialState(s1);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
machine.postEvent(new QEvent(QEvent::User));
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QVERIFY(machine.configuration().contains(s3));
QCOMPARE(object->property("foo").toDouble(), 2.0);
@@ -3335,8 +3632,10 @@ void tst_QStateMachine::twoAnimatedTransitions()
object->setProperty("foo", 1.0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "foo", 5.0);
QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2);
EventTransition *trans = new EventTransition(QEvent::User, s2);
@@ -3344,10 +3643,12 @@ void tst_QStateMachine::twoAnimatedTransitions()
trans->addAnimation(fooAnimation);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
s2->addTransition(fooAnimation, SIGNAL(finished()), s3);
QState *s4 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s4);
s4->assignProperty(object, "foo", 2.0);
QPropertyAnimation *fooAnimation2 = new QPropertyAnimation(object, "foo", s4);
trans = new EventTransition(QEvent::User, s4);
@@ -3355,22 +3656,39 @@ void tst_QStateMachine::twoAnimatedTransitions()
trans->addAnimation(fooAnimation2);
QState *s5 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s5);
QObject::connect(s5, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
s4->addTransition(fooAnimation2, SIGNAL(finished()), s5);
machine.setInitialState(s1);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
+ TEST_ACTIVE_CHANGED(s4, 0);
+ TEST_ACTIVE_CHANGED(s5, 0);
machine.postEvent(new QEvent(QEvent::User));
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ TEST_ACTIVE_CHANGED(s4, 0);
+ TEST_ACTIVE_CHANGED(s5, 0);
QVERIFY(machine.configuration().contains(s3));
QCOMPARE(object->property("foo").toDouble(), 5.0);
machine.postEvent(new QEvent(QEvent::User));
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
+ TEST_ACTIVE_CHANGED(s4, 2);
+ TEST_ACTIVE_CHANGED(s5, 1);
+ QVERIFY(machine.isRunning());
QVERIFY(machine.configuration().contains(s5));
QCOMPARE(object->property("foo").toDouble(), 2.0);
}
@@ -3383,8 +3701,10 @@ void tst_QStateMachine::playAnimationTwice()
object->setProperty("foo", 1.0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "foo", 5.0);
QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2);
EventTransition *trans = new EventTransition(QEvent::User, s2);
@@ -3392,16 +3712,19 @@ void tst_QStateMachine::playAnimationTwice()
trans->addAnimation(fooAnimation);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
s2->addTransition(fooAnimation, SIGNAL(finished()), s3);
QState *s4 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s4);
s4->assignProperty(object, "foo", 2.0);
trans = new EventTransition(QEvent::User, s4);
s3->addTransition(trans);
trans->addAnimation(fooAnimation);
QState *s5 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s5);
QObject::connect(s5, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
s4->addTransition(fooAnimation, SIGNAL(finished()), s5);
@@ -3409,15 +3732,31 @@ void tst_QStateMachine::playAnimationTwice()
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
+ TEST_ACTIVE_CHANGED(s4, 0);
+ TEST_ACTIVE_CHANGED(s5, 0);
machine.postEvent(new QEvent(QEvent::User));
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ TEST_ACTIVE_CHANGED(s4, 0);
+ TEST_ACTIVE_CHANGED(s5, 0);
QVERIFY(machine.configuration().contains(s3));
QCOMPARE(object->property("foo").toDouble(), 5.0);
machine.postEvent(new QEvent(QEvent::User));
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
+ TEST_ACTIVE_CHANGED(s4, 2);
+ TEST_ACTIVE_CHANGED(s5, 1);
+ QVERIFY(machine.isRunning());
QVERIFY(machine.configuration().contains(s5));
QCOMPARE(object->property("foo").toDouble(), 2.0);
}
@@ -3433,15 +3772,19 @@ void tst_QStateMachine::nestedTargetStateForAnimation()
SlotCalledCounter counter;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "foo", 2.0);
QState *s2Child = new QState(s2);
+ DEFINE_ACTIVE_SPY(s2Child);
s2Child->assignProperty(object, "bar", 10.0);
s2->setInitialState(s2Child);
QState *s2Child2 = new QState(s2);
+ DEFINE_ACTIVE_SPY(s2Child2);
s2Child2->assignProperty(object, "bar", 11.0);
QAbstractTransition *at = new EventTransition(QEvent::User, s2Child2);
s2Child->addTransition(at);
@@ -3463,6 +3806,7 @@ void tst_QStateMachine::nestedTargetStateForAnimation()
at->addAnimation(animation);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
s2->addTransition(s2Child, SIGNAL(propertiesAssigned()), s3);
QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
@@ -3470,10 +3814,27 @@ void tst_QStateMachine::nestedTargetStateForAnimation()
machine.setInitialState(s1);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s2Child, 0);
+ TEST_ACTIVE_CHANGED(s2Child2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s2Child, 1);
+ TEST_ACTIVE_CHANGED(s2Child2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
+
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s2Child, 2);
+ TEST_ACTIVE_CHANGED(s2Child2, 0);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QVERIFY(machine.configuration().contains(s3));
QCOMPARE(object->property("foo").toDouble(), 2.0);
QCOMPARE(object->property("bar").toDouble(), 10.0);
@@ -3487,10 +3848,13 @@ void tst_QStateMachine::propertiesAssignedSignalTransitionsReuseAnimationGroup()
object->setProperty("foo", 0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(object, "foo", 123);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "foo", 456);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
s3->assignProperty(object, "foo", 789);
QFinalState *s4 = new QFinalState(&machine);
@@ -3508,13 +3872,17 @@ void tst_QStateMachine::propertiesAssignedSignalTransitionsReuseAnimationGroup()
QSignalSpy machineFinishedSpy(&machine, &QStateMachine::finished);
QVERIFY(machineFinishedSpy.isValid());
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
QTRY_COMPARE(machineFinishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ QVERIFY(!machine.isRunning());
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s4));
QCOMPARE(object->property("foo").toInt(), 789);
-
QCOMPARE(animationFinishedSpy.count(), 2);
+
}
void tst_QStateMachine::animatedGlobalRestoreProperty()
@@ -3528,12 +3896,16 @@ void tst_QStateMachine::animatedGlobalRestoreProperty()
SlotCalledCounter counter;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "foo", 2.0);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
QState *s4 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s4);
QObject::connect(s4, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
QAbstractTransition *at = new EventTransition(QEvent::User, s2);
@@ -3555,11 +3927,24 @@ void tst_QStateMachine::animatedGlobalRestoreProperty()
machine.setInitialState(s1);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
+ TEST_ACTIVE_CHANGED(s4, 0);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
+ TEST_ACTIVE_CHANGED(s4, 0);
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
+ TEST_ACTIVE_CHANGED(s4, 1);
+ QVERIFY(machine.isRunning());
QVERIFY(machine.configuration().contains(s4));
QCOMPARE(object->property("foo").toDouble(), 1.0);
QCOMPARE(counter.counter, 2);
@@ -3573,8 +3958,10 @@ void tst_QStateMachine::specificTargetValueOfAnimation()
object->setProperty("foo", 1.0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "foo", 2.0);
QPropertyAnimation *anim = new QPropertyAnimation(object, "foo");
@@ -3584,16 +3971,28 @@ void tst_QStateMachine::specificTargetValueOfAnimation()
trans->addAnimation(anim);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
s2->addTransition(anim, SIGNAL(finished()), s3);
machine.setInitialState(s1);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
+
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QVERIFY(machine.configuration().contains(s3));
QCOMPARE(object->property("foo").toDouble(), 2.0);
QCOMPARE(anim->endValue().toDouble(), 10.0);
@@ -3609,11 +4008,14 @@ void tst_QStateMachine::addDefaultAnimation()
object->setProperty("foo", 1.0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "foo", 2.0);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
s1->addTransition(new EventTransition(QEvent::User, s2));
@@ -3625,10 +4027,21 @@ void tst_QStateMachine::addDefaultAnimation()
machine.setInitialState(s1);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
+
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QVERIFY(machine.configuration().contains(s3));
QCOMPARE(object->property("foo").toDouble(), 2.0);
@@ -3646,11 +4059,14 @@ void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation()
SlotCalledCounter counter;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "foo", 2.0);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
s1->addTransition(new EventTransition(QEvent::User, s2));
@@ -3667,10 +4083,21 @@ void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation()
machine.setInitialState(s1);
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
+
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QVERIFY(machine.configuration().contains(s3));
QCOMPARE(object->property("foo").toDouble(), 2.0);
QCOMPARE(counter.counter, 1);
@@ -3727,12 +4154,15 @@ void tst_QStateMachine::overrideDefaultAnimationWithSpecific()
SlotCalledCounter counter;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(object, "foo", 2.0);
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
QAbstractTransition *at = new EventTransition(QEvent::User, s2);
@@ -3750,10 +4180,21 @@ void tst_QStateMachine::overrideDefaultAnimationWithSpecific()
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
+
QCOREAPPLICATION_EXEC(5000);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QVERIFY(machine.configuration().contains(s3));
QCOMPARE(counter.counter, 2); // specific animation started and stopped
@@ -3771,20 +4212,26 @@ void tst_QStateMachine::parallelStateAssignmentsDone()
propertyHolder->setProperty("zoot", 789);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QState *parallelState = new QState(QState::ParallelStates, &machine);
parallelState->assignProperty(propertyHolder, "foo", 321);
QState *s2 = new QState(parallelState);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(propertyHolder, "bar", 654);
QState *s3 = new QState(parallelState);
+ DEFINE_ACTIVE_SPY(s3);
s3->assignProperty(propertyHolder, "zoot", 987);
s1->addTransition(new EventTransition(QEvent::User, parallelState));
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
QCOMPARE(propertyHolder->property("foo").toInt(), 123);
QCOMPARE(propertyHolder->property("bar").toInt(), 456);
@@ -3793,6 +4240,10 @@ void tst_QStateMachine::parallelStateAssignmentsDone()
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QCOMPARE(propertyHolder->property("foo").toInt(), 321);
QCOMPARE(propertyHolder->property("bar").toInt(), 654);
QCOMPARE(propertyHolder->property("zoot").toInt(), 987);
@@ -3803,21 +4254,27 @@ void tst_QStateMachine::transitionsFromParallelStateWithNoChildren()
QStateMachine machine;
QState *parallelState = new QState(QState::ParallelStates, &machine);
+ DEFINE_ACTIVE_SPY(parallelState);
machine.setInitialState(parallelState);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
parallelState->addTransition(new EventTransition(QEvent::User, s1));
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(parallelState, 1);
+ TEST_ACTIVE_CHANGED(s1, 0);
QCOMPARE(1, machine.configuration().size());
QVERIFY(machine.configuration().contains(parallelState));
machine.postEvent(new QEvent(QEvent::User));
-
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(parallelState, 2);
+ TEST_ACTIVE_CHANGED(s1, 1);
+ QVERIFY(machine.isRunning());
QCOMPARE(1, machine.configuration().size());
QVERIFY(machine.configuration().contains(s1));
}
@@ -3827,23 +4284,35 @@ void tst_QStateMachine::parallelStateTransition()
QStateMachine machine;
QState *parallelState = new QState(QState::ParallelStates, &machine);
+ DEFINE_ACTIVE_SPY(parallelState);
machine.setInitialState(parallelState);
QState *s1 = new QState(parallelState);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(parallelState);
+ DEFINE_ACTIVE_SPY(s2);
QState *s1InitialChild = new QState(s1);
+ DEFINE_ACTIVE_SPY(s1InitialChild);
s1->setInitialState(s1InitialChild);
QState *s2InitialChild = new QState(s2);
+ DEFINE_ACTIVE_SPY(s2InitialChild);
s2->setInitialState(s2InitialChild);
QState *s1OtherChild = new QState(s1);
+ DEFINE_ACTIVE_SPY(s1OtherChild);
s1->addTransition(new EventTransition(QEvent::User, s1OtherChild));
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(parallelState, 1);
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s1InitialChild, 1);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s2InitialChild, 1);
+ TEST_ACTIVE_CHANGED(s1OtherChild, 0);
QVERIFY(machine.configuration().contains(parallelState));
QVERIFY(machine.configuration().contains(s1));
@@ -3855,10 +4324,17 @@ void tst_QStateMachine::parallelStateTransition()
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(parallelState, 1);
+ TEST_ACTIVE_CHANGED(s1, 3);
+ TEST_ACTIVE_CHANGED(s1InitialChild, 2);
+ TEST_ACTIVE_CHANGED(s2, 3);
+ TEST_ACTIVE_CHANGED(s2InitialChild, 3);
+ TEST_ACTIVE_CHANGED(s1OtherChild, 1);
+ QVERIFY(machine.isRunning());
+
QVERIFY(machine.configuration().contains(parallelState));
QVERIFY(machine.configuration().contains(s1));
-
QVERIFY(machine.configuration().contains(s2));
QVERIFY(machine.configuration().contains(s1OtherChild));
QVERIFY(machine.configuration().contains(s2InitialChild));
@@ -3876,16 +4352,20 @@ void tst_QStateMachine::nestedRestoreProperties()
propertyHolder->setProperty("bar", 2);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(propertyHolder, "foo", 3);
QState *s21 = new QState(s2);
+ DEFINE_ACTIVE_SPY(s21);
s21->assignProperty(propertyHolder, "bar", 4);
s2->setInitialState(s21);
QState *s22 = new QState(s2);
+ DEFINE_ACTIVE_SPY(s22);
s22->assignProperty(propertyHolder, "bar", 5);
s1->addTransition(new EventTransition(QEvent::User, s2));
@@ -3894,6 +4374,10 @@ void tst_QStateMachine::nestedRestoreProperties()
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s21, 0);
+ TEST_ACTIVE_CHANGED(s22, 0);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
QCOMPARE(propertyHolder->property("foo").toInt(), 1);
@@ -3902,6 +4386,10 @@ void tst_QStateMachine::nestedRestoreProperties()
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s21, 1);
+ TEST_ACTIVE_CHANGED(s22, 0);
QCOMPARE(machine.configuration().size(), 2);
QVERIFY(machine.configuration().contains(s2));
QVERIFY(machine.configuration().contains(s21));
@@ -3911,6 +4399,11 @@ void tst_QStateMachine::nestedRestoreProperties()
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s21, 2);
+ TEST_ACTIVE_CHANGED(s22, 1);
+ QVERIFY(machine.isRunning());
QCOMPARE(machine.configuration().size(), 2);
QVERIFY(machine.configuration().contains(s2));
QVERIFY(machine.configuration().contains(s22));
@@ -3928,16 +4421,20 @@ void tst_QStateMachine::nestedRestoreProperties2()
propertyHolder->setProperty("bar", 2);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(propertyHolder, "foo", 3);
QState *s21 = new QState(s2);
+ DEFINE_ACTIVE_SPY(s21);
s21->assignProperty(propertyHolder, "bar", 4);
s2->setInitialState(s21);
QState *s22 = new QState(s2);
+ DEFINE_ACTIVE_SPY(s22);
s22->assignProperty(propertyHolder, "foo", 6);
s22->assignProperty(propertyHolder, "bar", 5);
@@ -3948,6 +4445,10 @@ void tst_QStateMachine::nestedRestoreProperties2()
machine.start();
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s21, 0);
+ TEST_ACTIVE_CHANGED(s22, 0);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
QCOMPARE(propertyHolder->property("foo").toInt(), 1);
@@ -3956,6 +4457,10 @@ void tst_QStateMachine::nestedRestoreProperties2()
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s21, 1);
+ TEST_ACTIVE_CHANGED(s22, 0);
QCOMPARE(machine.configuration().size(), 2);
QVERIFY(machine.configuration().contains(s2));
QVERIFY(machine.configuration().contains(s21));
@@ -3965,6 +4470,10 @@ void tst_QStateMachine::nestedRestoreProperties2()
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s21, 2);
+ TEST_ACTIVE_CHANGED(s22, 1);
QCOMPARE(machine.configuration().size(), 2);
QVERIFY(machine.configuration().contains(s2));
QVERIFY(machine.configuration().contains(s22));
@@ -3974,6 +4483,10 @@ void tst_QStateMachine::nestedRestoreProperties2()
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s21, 3);
+ TEST_ACTIVE_CHANGED(s22, 2);
QCOMPARE(machine.configuration().size(), 2);
QVERIFY(machine.configuration().contains(s2));
QVERIFY(machine.configuration().contains(s21));
@@ -3986,6 +4499,7 @@ void tst_QStateMachine::nestedStateMachines()
{
QStateMachine machine;
QState *group = new QState(&machine);
+ DEFINE_ACTIVE_SPY(group);
group->setChildMode(QState::ParallelStates);
QStateMachine *subMachines[3];
for (int i = 0; i < 3; ++i) {
@@ -4021,12 +4535,14 @@ void tst_QStateMachine::nestedStateMachines()
QVERIFY(machine.configuration().contains(subMachines[i]));
QCoreApplication::processEvents(); // starts the submachines
+ TEST_ACTIVE_CHANGED(group, 1);
for (int i = 0; i < 3; ++i)
subMachines[i]->postEvent(new QEvent(QEvent::User));
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED(false);
+ TEST_ACTIVE_CHANGED(group, 2);
}
void tst_QStateMachine::goToState()
@@ -4119,7 +4635,9 @@ void tst_QStateMachine::clonedSignals()
SignalEmitter emitter;
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
CloneSignalTransition *t1 = new CloneSignalTransition(&emitter, SIGNAL(signalWithDefaultArg()), s2);
s1->addTransition(t1);
@@ -4130,6 +4648,9 @@ void tst_QStateMachine::clonedSignals()
emitter.emitSignalWithDefaultArg();
QTest::qWait(1);
QCOMPARE(t1->eventSignalIndex, emitter.metaObject()->indexOfSignal("signalWithDefaultArg()"));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ QVERIFY(machine.isRunning());
}
class EventPosterThread : public QThread
@@ -4228,6 +4749,7 @@ void tst_QStateMachine::stopInTransitionToFinalState()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
QFinalState *s2 = new QFinalState(&machine);
QAbstractTransition *t1 = s1->addTransition(s2);
machine.setInitialState(s1);
@@ -4242,7 +4764,6 @@ void tst_QStateMachine::stopInTransitionToFinalState()
QVERIFY(s2EnteredSpy.isValid());
QVERIFY(runningSpy.isValid());
machine.start();
-
// Stopping should take precedence over finished.
QTRY_COMPARE(stoppedSpy.count(), 1);
QCOMPARE(finishedSpy.count(), 0);
@@ -4250,6 +4771,7 @@ void tst_QStateMachine::stopInTransitionToFinalState()
TEST_RUNNING_CHANGED_STARTED_STOPPED;
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s2));
+ TEST_ACTIVE_CHANGED(s1, 2);
}
class StopInEventTestTransition : public QAbstractTransition
@@ -4278,6 +4800,7 @@ void tst_QStateMachine::stopInEventTest()
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->addTransition(new StopInEventTestTransition());
machine.setInitialState(s1);
@@ -4286,6 +4809,7 @@ void tst_QStateMachine::stopInEventTest()
QSignalSpy startedSpy(&machine, &QStateMachine::started);
QVERIFY(startedSpy.isValid());
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
QTRY_COMPARE(startedSpy.count(), 1);
TEST_RUNNING_CHANGED(true);
@@ -4300,6 +4824,7 @@ void tst_QStateMachine::stopInEventTest()
TEST_RUNNING_CHANGED(false);
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s1));
+ TEST_ACTIVE_CHANGED(s1, 1);
}
class IncrementReceiversTest : public QObject
@@ -4320,6 +4845,7 @@ void tst_QStateMachine::testIncrementReceivers()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QFinalState *s2 = new QFinalState(&machine);
@@ -4338,12 +4864,14 @@ void tst_QStateMachine::testIncrementReceivers()
TEST_RUNNING_CHANGED(false);
QCOMPARE(testObject.signalList.size(), 1);
QCOMPARE(testObject.signalList.at(0), QMetaMethod::fromSignal(&IncrementReceiversTest::mySignal));
+ TEST_ACTIVE_CHANGED(s1, 2);
}
void tst_QStateMachine::initialStateIsEnteredBeforeStartedEmitted()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QFinalState *s2 = new QFinalState(&machine);
@@ -4357,12 +4885,14 @@ void tst_QStateMachine::initialStateIsEnteredBeforeStartedEmitted()
machine.start();
QTRY_COMPARE(finishedSpy.count(), 1);
TEST_RUNNING_CHANGED_STARTED_STOPPED;
+ TEST_ACTIVE_CHANGED(s1, 2);
}
void tst_QStateMachine::deletePropertyAssignmentObjectBeforeEntry()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QObject *o1 = new QObject;
@@ -4377,6 +4907,8 @@ void tst_QStateMachine::deletePropertyAssignmentObjectBeforeEntry()
QCOMPARE(o2->objectName(), QString::fromLatin1("bar"));
delete o2;
+ TEST_ACTIVE_CHANGED(s1, 1);
+ QVERIFY(machine.isRunning());
}
void tst_QStateMachine::deletePropertyAssignmentObjectBeforeRestore()
@@ -4384,8 +4916,10 @@ void tst_QStateMachine::deletePropertyAssignmentObjectBeforeRestore()
QStateMachine machine;
machine.setGlobalRestorePolicy(QState::RestoreProperties);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s1->addTransition(new EventTransition(QEvent::User, s2));
QObject *o1 = new QObject;
@@ -4396,6 +4930,8 @@ void tst_QStateMachine::deletePropertyAssignmentObjectBeforeRestore()
QVERIFY(o1->objectName().isEmpty());
QVERIFY(o2->objectName().isEmpty());
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s1));
QCOMPARE(o1->objectName(), QString::fromLatin1("foo"));
QCOMPARE(o2->objectName(), QString::fromLatin1("bar"));
@@ -4407,6 +4943,9 @@ void tst_QStateMachine::deletePropertyAssignmentObjectBeforeRestore()
QVERIFY(o2->objectName().isEmpty());
delete o2;
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ QVERIFY(machine.isRunning());
}
void tst_QStateMachine::deleteInitialState()
@@ -4430,24 +4969,36 @@ void tst_QStateMachine::setPropertyAfterRestore()
object->setProperty("a", 1);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
s1->assignProperty(object, "a", 2);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s1->addTransition(new EventTransition(QEvent::User, s2));
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
s3->assignProperty(object, "a", 4);
s2->addTransition(new EventTransition(QEvent::User, s3));
QState *s4 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s4);
s3->addTransition(new EventTransition(QEvent::User, s4));
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
+ TEST_ACTIVE_CHANGED(s4, 0);
QTRY_VERIFY(machine.configuration().contains(s1));
QCOMPARE(object->property("a").toInt(), 2);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
+ TEST_ACTIVE_CHANGED(s4, 0);
QTRY_VERIFY(machine.configuration().contains(s2));
QCOMPARE(object->property("a").toInt(), 1); // restored
@@ -4456,10 +5007,19 @@ void tst_QStateMachine::setPropertyAfterRestore()
object->setProperty("a", 3);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ TEST_ACTIVE_CHANGED(s4, 0);
QTRY_VERIFY(machine.configuration().contains(s3));
QCOMPARE(object->property("a").toInt(), 4);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
+ TEST_ACTIVE_CHANGED(s4, 1);
+ QVERIFY(machine.isRunning());
QTRY_VERIFY(machine.configuration().contains(s4));
QCOMPARE(object->property("a").toInt(), 3); // restored
@@ -4484,6 +5044,7 @@ void tst_QStateMachine::transitionWithNoTarget()
object->setProperty("a", 1);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
s1->assignProperty(object, "a", 2);
EventTransition *t1 = new EventTransition(QEvent::User, /*target=*/0);
@@ -4517,6 +5078,8 @@ void tst_QStateMachine::transitionWithNoTarget()
QCOMPARE(object->property("a").toInt(), 3);
delete object;
+ TEST_ACTIVE_CHANGED(s1, 1);
+ QVERIFY(machine.isRunning());
}
void tst_QStateMachine::initialStateIsFinal()
@@ -4559,53 +5122,95 @@ void tst_QStateMachine::restorePropertiesSimple()
QCOMPARE(po->propWriteCount(), 1);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(po, "prop", 4);
machine.setInitialState(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s1->addTransition(new EventTransition(QEvent::User, s2));
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
s3->assignProperty(po, "prop", 6);
s2->addTransition(new EventTransition(QEvent::User, s3));
QState *s4 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s4);
s4->assignProperty(po, "prop", 8);
s3->addTransition(new EventTransition(QEvent::User, s4));
QState *s5 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s5);
s4->addTransition(new EventTransition(QEvent::User, s5));
QState *s6 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s6);
s5->addTransition(new EventTransition(QEvent::User, s6));
machine.start();
-
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
+ TEST_ACTIVE_CHANGED(s4, 0);
+ TEST_ACTIVE_CHANGED(s5, 0);
+ TEST_ACTIVE_CHANGED(s6, 0);
QTRY_VERIFY(machine.configuration().contains(s1));
QCOMPARE(po->propWriteCount(), 2);
QCOMPARE(po->prop(), 4);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
+ TEST_ACTIVE_CHANGED(s4, 0);
+ TEST_ACTIVE_CHANGED(s5, 0);
+ TEST_ACTIVE_CHANGED(s6, 0);
QTRY_VERIFY(machine.configuration().contains(s2));
QCOMPARE(po->propWriteCount(), 3);
QCOMPARE(po->prop(), 2); // restored
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ TEST_ACTIVE_CHANGED(s4, 0);
+ TEST_ACTIVE_CHANGED(s5, 0);
+ TEST_ACTIVE_CHANGED(s6, 0);
QTRY_VERIFY(machine.configuration().contains(s3));
QCOMPARE(po->propWriteCount(), 4);
QCOMPARE(po->prop(), 6);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
+ TEST_ACTIVE_CHANGED(s4, 1);
+ TEST_ACTIVE_CHANGED(s5, 0);
+ TEST_ACTIVE_CHANGED(s6, 0);
QTRY_VERIFY(machine.configuration().contains(s4));
QCOMPARE(po->propWriteCount(), 5);
QCOMPARE(po->prop(), 8);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
+ TEST_ACTIVE_CHANGED(s4, 2);
+ TEST_ACTIVE_CHANGED(s5, 1);
+ TEST_ACTIVE_CHANGED(s6, 0);
QTRY_VERIFY(machine.configuration().contains(s5));
QCOMPARE(po->propWriteCount(), 6);
QCOMPARE(po->prop(), 2); // restored
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
+ TEST_ACTIVE_CHANGED(s4, 2);
+ TEST_ACTIVE_CHANGED(s5, 2);
+ TEST_ACTIVE_CHANGED(s6, 1);
+ QVERIFY(machine.isRunning());
QTRY_VERIFY(machine.configuration().contains(s6));
QCOMPARE(po->propWriteCount(), 6);
@@ -4622,76 +5227,158 @@ void tst_QStateMachine::restoreProperties2()
QCOMPARE(po->propWriteCount(), 1);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(po, "prop", 4);
machine.setInitialState(s1);
QState *s11 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s11);
s1->setInitialState(s11);
QState *s12 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s12);
s11->addTransition(new EventTransition(QEvent::User, s12));
QState *s13 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s13);
s13->assignProperty(po, "prop", 6);
s12->addTransition(new EventTransition(QEvent::User, s13));
QState *s14 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s14);
s14->assignProperty(po, "prop", 8);
s13->addTransition(new EventTransition(QEvent::User, s14));
QState *s15 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s15);
s14->addTransition(new EventTransition(QEvent::User, s15));
QState *s16 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s16);
s15->addTransition(new EventTransition(QEvent::User, s16));
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(po, "prop", 10);
s16->addTransition(new EventTransition(QEvent::User, s2));
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
s2->addTransition(new EventTransition(QEvent::User, s3));
machine.start();
-
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 1);
+ TEST_ACTIVE_CHANGED(s12, 0);
+ TEST_ACTIVE_CHANGED(s13, 0);
+ TEST_ACTIVE_CHANGED(s14, 0);
+ TEST_ACTIVE_CHANGED(s15, 0);
+ TEST_ACTIVE_CHANGED(s16, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
QTRY_VERIFY(machine.configuration().contains(s11));
QCOMPARE(po->propWriteCount(), 2);
QCOMPARE(po->prop(), 4);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s12, 1);
+ TEST_ACTIVE_CHANGED(s13, 0);
+ TEST_ACTIVE_CHANGED(s14, 0);
+ TEST_ACTIVE_CHANGED(s15, 0);
+ TEST_ACTIVE_CHANGED(s16, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
QTRY_VERIFY(machine.configuration().contains(s12));
QCOMPARE(po->propWriteCount(), 2);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s12, 2);
+ TEST_ACTIVE_CHANGED(s13, 1);
+ TEST_ACTIVE_CHANGED(s14, 0);
+ TEST_ACTIVE_CHANGED(s15, 0);
+ TEST_ACTIVE_CHANGED(s16, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
QTRY_VERIFY(machine.configuration().contains(s13));
QCOMPARE(po->propWriteCount(), 3);
QCOMPARE(po->prop(), 6);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s12, 2);
+ TEST_ACTIVE_CHANGED(s13, 2);
+ TEST_ACTIVE_CHANGED(s14, 1);
+ TEST_ACTIVE_CHANGED(s15, 0);
+ TEST_ACTIVE_CHANGED(s16, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
QTRY_VERIFY(machine.configuration().contains(s14));
QCOMPARE(po->propWriteCount(), 4);
QCOMPARE(po->prop(), 8);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s12, 2);
+ TEST_ACTIVE_CHANGED(s13, 2);
+ TEST_ACTIVE_CHANGED(s14, 2);
+ TEST_ACTIVE_CHANGED(s15, 1);
+ TEST_ACTIVE_CHANGED(s16, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
QTRY_VERIFY(machine.configuration().contains(s15));
QCOMPARE(po->propWriteCount(), 5);
QCOMPARE(po->prop(), 4); // restored s1
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s12, 2);
+ TEST_ACTIVE_CHANGED(s13, 2);
+ TEST_ACTIVE_CHANGED(s14, 2);
+ TEST_ACTIVE_CHANGED(s15, 2);
+ TEST_ACTIVE_CHANGED(s16, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s3, 0);
QTRY_VERIFY(machine.configuration().contains(s16));
QCOMPARE(po->propWriteCount(), 5);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s12, 2);
+ TEST_ACTIVE_CHANGED(s13, 2);
+ TEST_ACTIVE_CHANGED(s14, 2);
+ TEST_ACTIVE_CHANGED(s15, 2);
+ TEST_ACTIVE_CHANGED(s16, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s3, 0);
QTRY_VERIFY(machine.configuration().contains(s2));
QCOMPARE(po->propWriteCount(), 6);
QCOMPARE(po->prop(), 10);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s12, 2);
+ TEST_ACTIVE_CHANGED(s13, 2);
+ TEST_ACTIVE_CHANGED(s14, 2);
+ TEST_ACTIVE_CHANGED(s15, 2);
+ TEST_ACTIVE_CHANGED(s16, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
+ QVERIFY(machine.isRunning());
QTRY_VERIFY(machine.configuration().contains(s3));
QCOMPARE(po->propWriteCount(), 7);
QCOMPARE(po->prop(), 2); // restored original
delete po;
+
}
void tst_QStateMachine::restoreProperties3()
@@ -4704,40 +5391,66 @@ void tst_QStateMachine::restoreProperties3()
QCOMPARE(po->propWriteCount(), 1);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(po, "prop", 4);
machine.setInitialState(s1);
QState *s11 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s11);
s11->assignProperty(po, "prop", 6);
s1->setInitialState(s11);
QState *s12 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s12);
s11->addTransition(new EventTransition(QEvent::User, s12));
QState *s13 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s13);
s13->assignProperty(po, "prop", 8);
s12->addTransition(new EventTransition(QEvent::User, s13));
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s13->addTransition(new EventTransition(QEvent::User, s2));
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 1);
+ TEST_ACTIVE_CHANGED(s12, 0);
+ TEST_ACTIVE_CHANGED(s13, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s11));
QCOMPARE(po->propWriteCount(), 3);
QCOMPARE(po->prop(), 6); // s11
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s12, 1);
+ TEST_ACTIVE_CHANGED(s13, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s12));
QCOMPARE(po->propWriteCount(), 4);
QCOMPARE(po->prop(), 4); // restored s1
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s12, 2);
+ TEST_ACTIVE_CHANGED(s13, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s13));
QCOMPARE(po->propWriteCount(), 5);
QCOMPARE(po->prop(), 8);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s12, 2);
+ TEST_ACTIVE_CHANGED(s13, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ QVERIFY(machine.isRunning());
QTRY_VERIFY(machine.configuration().contains(s2));
QCOMPARE(po->propWriteCount(), 6);
QCOMPARE(po->prop(), 2); // restored original
@@ -4759,31 +5472,47 @@ void tst_QStateMachine::restoreProperties4()
QCOMPARE(po2->propWriteCount(), 1);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->setChildMode(QState::ParallelStates);
machine.setInitialState(s1);
QState *s11 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s11);
QState *s111 = new QState(s11);
+ DEFINE_ACTIVE_SPY(s111);
s111->assignProperty(po1, "prop", 6);
s11->setInitialState(s111);
QState *s112 = new QState(s11);
+ DEFINE_ACTIVE_SPY(s112);
s112->assignProperty(po1, "prop", 8);
s111->addTransition(new EventTransition(QEvent::User, s112));
QState *s12 = new QState(s1);
+ DEFINE_ACTIVE_SPY(s12);
QState *s121 = new QState(s12);
+ DEFINE_ACTIVE_SPY(s121);
s121->assignProperty(po2, "prop", 10);
s12->setInitialState(s121);
QState *s122 = new QState(s12);
+ DEFINE_ACTIVE_SPY(s122);
s122->assignProperty(po2, "prop", 12);
s121->addTransition(new EventTransition(static_cast<QEvent::Type>(QEvent::User+1), s122));
QState *s2 = new QState(&machine);
s112->addTransition(new EventTransition(QEvent::User, s2));
+ DEFINE_ACTIVE_SPY(s2);
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 1);
+ TEST_ACTIVE_CHANGED(s111, 1);
+ TEST_ACTIVE_CHANGED(s112, 0);
+ TEST_ACTIVE_CHANGED(s12, 1);
+ TEST_ACTIVE_CHANGED(s121, 1);
+ TEST_ACTIVE_CHANGED(s122, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s1));
QVERIFY(machine.configuration().contains(s11));
@@ -4796,18 +5525,42 @@ void tst_QStateMachine::restoreProperties4()
QCOMPARE(po2->prop(), 10);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 1);
+ TEST_ACTIVE_CHANGED(s111, 2);
+ TEST_ACTIVE_CHANGED(s112, 1);
+ TEST_ACTIVE_CHANGED(s12, 1);
+ TEST_ACTIVE_CHANGED(s121, 1);
+ TEST_ACTIVE_CHANGED(s122, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s112));
QCOMPARE(po1->propWriteCount(), 3);
QCOMPARE(po1->prop(), 8);
QCOMPARE(po2->propWriteCount(), 2);
machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1)));
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s11, 1);
+ TEST_ACTIVE_CHANGED(s111, 2);
+ TEST_ACTIVE_CHANGED(s112, 1);
+ TEST_ACTIVE_CHANGED(s12, 1);
+ TEST_ACTIVE_CHANGED(s121, 2);
+ TEST_ACTIVE_CHANGED(s122, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s122));
QCOMPARE(po1->propWriteCount(), 3);
QCOMPARE(po2->propWriteCount(), 3);
QCOMPARE(po2->prop(), 12);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s11, 2);
+ TEST_ACTIVE_CHANGED(s111, 2);
+ TEST_ACTIVE_CHANGED(s112, 2);
+ TEST_ACTIVE_CHANGED(s12, 2);
+ TEST_ACTIVE_CHANGED(s121, 2);
+ TEST_ACTIVE_CHANGED(s122, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
QTRY_VERIFY(machine.configuration().contains(s2));
QCOMPARE(po1->propWriteCount(), 4);
QCOMPARE(po1->prop(), 2); // restored original
@@ -4828,27 +5581,37 @@ void tst_QStateMachine::restorePropertiesSelfTransition()
QCOMPARE(po->propWriteCount(), 1);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(po, "prop", 4);
s1->addTransition(new EventTransition(QEvent::User, s1));
machine.setInitialState(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s1->addTransition(new EventTransition(static_cast<QEvent::Type>(QEvent::User+1), s2));
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s1));
QCOMPARE(po->propWriteCount(), 2);
QCOMPARE(po->prop(), 4);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 3);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_COMPARE(po->propWriteCount(), 3);
QCOMPARE(po->prop(), 4);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 5);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_COMPARE(po->propWriteCount(), 4);
QCOMPARE(po->prop(), 4);
machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1)));
+ TEST_ACTIVE_CHANGED(s1, 6);
+ TEST_ACTIVE_CHANGED(s2, 1);
QTRY_VERIFY(machine.configuration().contains(s2));
QCOMPARE(po->propWriteCount(), 5);
QCOMPARE(po->prop(), 2); // restored
@@ -4867,12 +5630,15 @@ void tst_QStateMachine::changeStateWhileAnimatingProperty()
o2->setProperty("y", 20.);
QState *group = new QState(&machine);
+ DEFINE_ACTIVE_SPY(group);
machine.setInitialState(group);
QState *s0 = new QState(group);
+ DEFINE_ACTIVE_SPY(s0);
group->setInitialState(s0);
QState *s1 = new QState(group);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(o1, "x", 15.);
QPropertyAnimation *a1 = new QPropertyAnimation(o1, "x", s1);
a1->setDuration(800);
@@ -4880,6 +5646,7 @@ void tst_QStateMachine::changeStateWhileAnimatingProperty()
group->addTransition(new EventTransition(QEvent::User, s1));
QState *s2 = new QState(group);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(o2, "y", 25.);
QPropertyAnimation *a2 = new QPropertyAnimation(o2, "y", s2);
a2->setDuration(800);
@@ -4887,23 +5654,46 @@ void tst_QStateMachine::changeStateWhileAnimatingProperty()
group->addTransition(new EventTransition(static_cast<QEvent::Type>(QEvent::User+1), s2));
machine.start();
+ TEST_ACTIVE_CHANGED(group, 1);
+ TEST_ACTIVE_CHANGED(s0, 1);
+ TEST_ACTIVE_CHANGED(s1, 0);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s0));
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(group, 3);
+ TEST_ACTIVE_CHANGED(s0, 2);
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s1));
QCOREAPPLICATION_EXEC(400);
machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1)));
+ TEST_ACTIVE_CHANGED(group, 5);
+ TEST_ACTIVE_CHANGED(s0, 2);
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
QTRY_VERIFY(machine.configuration().contains(s2));
QCOREAPPLICATION_EXEC(300);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(group, 7);
+ TEST_ACTIVE_CHANGED(s0, 2);
+ TEST_ACTIVE_CHANGED(s1, 3);
+ TEST_ACTIVE_CHANGED(s2, 2);
QTRY_VERIFY(machine.configuration().contains(s1));
QCOREAPPLICATION_EXEC(200);
machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1)));
+ TEST_ACTIVE_CHANGED(group, 9);
+ TEST_ACTIVE_CHANGED(s0, 2);
+ TEST_ACTIVE_CHANGED(s1, 4);
+ TEST_ACTIVE_CHANGED(s2, 3);
QTRY_VERIFY(machine.configuration().contains(s2));
QCOREAPPLICATION_EXEC(100);
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(group, 11);
+ TEST_ACTIVE_CHANGED(s0, 2);
+ TEST_ACTIVE_CHANGED(s1, 5);
+ TEST_ACTIVE_CHANGED(s2, 4);
QTRY_VERIFY(machine.configuration().contains(s1));
-
QTRY_COMPARE(o1->property("x").toDouble(), 15.);
QTRY_COMPARE(o2->property("y").toDouble(), 20.);
@@ -4945,15 +5735,19 @@ void tst_QStateMachine::propertiesAreAssignedBeforeEntryCallbacks()
machine.setGlobalRestorePolicy(static_cast<QState::RestorePolicy>(restorePolicy));
AssignPropertyTestState *s1 = new AssignPropertyTestState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
s1->assignProperty(s1, "wasAssigned", true);
machine.setInitialState(s1);
AssignPropertyTestState *s2 = new AssignPropertyTestState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s2->assignProperty(s2, "wasAssigned", true);
s1->addTransition(new EventTransition(QEvent::User, s2));
QVERIFY(!s1->property("wasAssigned").toBool());
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s1));
QVERIFY(s1->onEntryPassed);
@@ -4961,6 +5755,8 @@ void tst_QStateMachine::propertiesAreAssignedBeforeEntryCallbacks()
QVERIFY(!s2->property("wasAssigned").toBool());
machine.postEvent(new QEvent(QEvent::User));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
QTRY_VERIFY(machine.configuration().contains(s2));
QVERIFY(s2->onEntryPassed);
@@ -4972,18 +5768,26 @@ void tst_QStateMachine::multiTargetTransitionInsideParallelStateGroup()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QState *s2 = new QState(QState::ParallelStates, &machine);
+ DEFINE_ACTIVE_SPY(s2);
QState *s21 = new QState(s2);
+ DEFINE_ACTIVE_SPY(s21);
QState *s211 = new QState(s21);
+ DEFINE_ACTIVE_SPY(s211);
QState *s212 = new QState(s21);
+ DEFINE_ACTIVE_SPY(s212);
s21->setInitialState(s212);
QState *s22 = new QState(s2);
+ DEFINE_ACTIVE_SPY(s22);
QState *s221 = new QState(s22);
+ DEFINE_ACTIVE_SPY(s221);
QState *s222 = new QState(s22);
+ DEFINE_ACTIVE_SPY(s222);
s22->setInitialState(s222);
QAbstractTransition *t1 = new EventTransition(QEvent::User, QList<QAbstractState *>() << s211 << s221);
@@ -4991,7 +5795,14 @@ void tst_QStateMachine::multiTargetTransitionInsideParallelStateGroup()
machine.start();
QTRY_VERIFY(machine.configuration().contains(s1));
-
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
+ TEST_ACTIVE_CHANGED(s21, 0);
+ TEST_ACTIVE_CHANGED(s211, 0);
+ TEST_ACTIVE_CHANGED(s212, 0);
+ TEST_ACTIVE_CHANGED(s22, 0);
+ TEST_ACTIVE_CHANGED(s221, 0);
+ TEST_ACTIVE_CHANGED(s222, 0);
machine.postEvent(new QEvent(QEvent::User));
QTRY_VERIFY(machine.configuration().contains(s2));
QCOMPARE(machine.configuration().size(), 5);
@@ -4999,19 +5810,31 @@ void tst_QStateMachine::multiTargetTransitionInsideParallelStateGroup()
QVERIFY(machine.configuration().contains(s211));
QVERIFY(machine.configuration().contains(s22));
QVERIFY(machine.configuration().contains(s221));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
+ TEST_ACTIVE_CHANGED(s21, 1);
+ TEST_ACTIVE_CHANGED(s211, 1);
+ TEST_ACTIVE_CHANGED(s212, 0);
+ TEST_ACTIVE_CHANGED(s22, 1);
+ TEST_ACTIVE_CHANGED(s221, 1);
+ TEST_ACTIVE_CHANGED(s222, 0);
}
void tst_QStateMachine::signalTransitionNormalizeSignature()
{
QStateMachine machine;
QState *s0 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s0);
machine.setInitialState(s0);
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
SignalEmitter emitter;
TestSignalTransition *t0 = new TestSignalTransition(&emitter, SIGNAL(signalWithNoArg()), s1);
s0->addTransition(t0);
machine.start();
+ TEST_ACTIVE_CHANGED(s0, 1);
+ TEST_ACTIVE_CHANGED(s1, 0);
QTRY_VERIFY(machine.configuration().contains(s0));
emitter.emitSignalWithNoArg();
QTRY_VERIFY(machine.configuration().contains(s1));
@@ -5022,44 +5845,60 @@ void tst_QStateMachine::signalTransitionNormalizeSignature()
QCOMPARE(t0->transitionSenderReceived(), (QObject*)&emitter);
QCOMPARE(t0->transitionSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithNoArg()"));
QCOMPARE(t0->transitionArgumentsReceived().size(), 0);
+ TEST_ACTIVE_CHANGED(s0, 2);
+ TEST_ACTIVE_CHANGED(s1, 1);
}
void tst_QStateMachine::createSignalTransitionWhenRunning()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
QTRY_VERIFY(machine.configuration().contains(s1));
-
// Create by addTransition()
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
SignalEmitter emitter;
QAbstractTransition *t1 = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s2);
QCOMPARE(t1->sourceState(), s1);
emitter.emitSignalWithNoArg();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 1);
QTRY_VERIFY(machine.configuration().contains(s2));
// Create by constructor that takes sender, signal, source (parent) state
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
QSignalTransition *t2 = new QSignalTransition(&emitter, SIGNAL(signalWithNoArg()), s2);
QCOMPARE(t2->sourceState(), s2);
t2->setTargetState(s3);
emitter.emitSignalWithNoArg();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 1);
QTRY_VERIFY(machine.configuration().contains(s3));
// Create by constructor that takes source (parent) state
QState *s4 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s4);
QSignalTransition *t3 = new QSignalTransition(s3);
QCOMPARE(t3->sourceState(), s3);
t3->setSenderObject(&emitter);
t3->setSignal(SIGNAL(signalWithNoArg()));
t3->setTargetState(s4);
emitter.emitSignalWithNoArg();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
+ TEST_ACTIVE_CHANGED(s4, 1);
QTRY_VERIFY(machine.configuration().contains(s4));
// Create by constructor without parent, then set the parent
QState *s5 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s5);
QSignalTransition *t4 = new QSignalTransition();
t4->setSenderObject(&emitter);
t4->setParent(s4);
@@ -5067,6 +5906,11 @@ void tst_QStateMachine::createSignalTransitionWhenRunning()
t4->setSignal(SIGNAL(signalWithNoArg()));
t4->setTargetState(s5);
emitter.emitSignalWithNoArg();
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
+ TEST_ACTIVE_CHANGED(s4, 2);
+ TEST_ACTIVE_CHANGED(s5, 1);
QTRY_VERIFY(machine.configuration().contains(s5));
}
@@ -5074,12 +5918,15 @@ void tst_QStateMachine::createEventTransitionWhenRunning()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
QTRY_VERIFY(machine.configuration().contains(s1));
// Create by constructor that takes event source, type, source (parent) state
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
QObject object;
QEventTransition *t1 = new QEventTransition(&object, QEvent::Timer, s1);
QCOMPARE(t1->sourceState(), s1);
@@ -5090,6 +5937,7 @@ void tst_QStateMachine::createEventTransitionWhenRunning()
// Create by constructor that takes source (parent) state
QState *s3 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s3);
QEventTransition *t2 = new QEventTransition(s2);
QCOMPARE(t2->sourceState(), s2);
t2->setEventSource(&object);
@@ -5099,6 +5947,7 @@ void tst_QStateMachine::createEventTransitionWhenRunning()
// Create by constructor without parent, then set the parent
QState *s4 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s4);
QEventTransition *t3 = new QEventTransition();
t3->setEventSource(&object);
t3->setParent(s3);
@@ -5106,6 +5955,10 @@ void tst_QStateMachine::createEventTransitionWhenRunning()
t3->setEventType(QEvent::Timer);
t3->setTargetState(s4);
QTRY_VERIFY(machine.configuration().contains(s4));
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ TEST_ACTIVE_CHANGED(s3, 2);
+ TEST_ACTIVE_CHANGED(s4, 1);
}
class SignalEmitterThread : public QThread
@@ -5135,10 +5988,12 @@ void tst_QStateMachine::signalTransitionSenderInDifferentThread()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
SignalEmitterThread thread;
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
s1->addTransition(&thread, SIGNAL(signal1()), s2);
QFinalState *s3 = new QFinalState(&machine);
@@ -5148,29 +6003,41 @@ void tst_QStateMachine::signalTransitionSenderInDifferentThread()
QTRY_VERIFY(thread.isRunning());
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 1);
+ TEST_ACTIVE_CHANGED(s2, 0);
QTRY_VERIFY(machine.configuration().contains(s1));
QMetaObject::invokeMethod(&thread, "emitSignals");
// thread emits both signal1() and signal2(), so we should end in s3
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
+ QTRY_VERIFY(!machine.isRunning());
QTRY_VERIFY(machine.configuration().contains(s3));
// Run the machine again; transitions should still be registered
machine.start();
+ TEST_ACTIVE_CHANGED(s1, 3);
+ TEST_ACTIVE_CHANGED(s2, 2);
QTRY_VERIFY(machine.configuration().contains(s1));
QMetaObject::invokeMethod(&thread, "emitSignals");
QTRY_VERIFY(machine.configuration().contains(s3));
thread.quit();
QTRY_VERIFY(thread.wait());
+ TEST_ACTIVE_CHANGED(s1, 4);
+ TEST_ACTIVE_CHANGED(s2, 4);
+ QVERIFY(!machine.isRunning());
}
void tst_QStateMachine::signalTransitionSenderInDifferentThread2()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
QState *s2 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s2);
SignalEmitter emitter;
// At the time of the transition creation, the machine and the emitter
// are both in the same thread.
@@ -5203,6 +6070,8 @@ void tst_QStateMachine::signalTransitionSenderInDifferentThread2()
thread.quit();
QTRY_VERIFY(thread.wait());
+ TEST_ACTIVE_CHANGED(s1, 2);
+ TEST_ACTIVE_CHANGED(s2, 2);
}
class SignalTransitionMutatorThread : public QThread
@@ -5228,6 +6097,7 @@ void tst_QStateMachine::signalTransitionRegistrationThreadSafety()
{
QStateMachine machine;
QState *s1 = new QState(&machine);
+ DEFINE_ACTIVE_SPY(s1);
machine.setInitialState(s1);
machine.start();
QTRY_VERIFY(machine.configuration().contains(s1));
@@ -5252,6 +6122,8 @@ void tst_QStateMachine::signalTransitionRegistrationThreadSafety()
thread.quit();
QTRY_VERIFY(thread.wait());
+ TEST_ACTIVE_CHANGED(s1, 1);
+ QVERIFY(machine.isRunning());
}
void tst_QStateMachine::childModeConstructor()
diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
index 8fac232962..52e1850c87 100644
--- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
+++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
@@ -151,6 +151,8 @@ private slots:
#if defined(Q_COMPILER_LAMBDA)
void literals();
#endif
+ void toUpperLower_data();
+ void toUpperLower();
void macTypes();
@@ -1999,6 +2001,31 @@ void tst_QByteArray::literals()
}
#endif
+void tst_QByteArray::toUpperLower_data()
+{
+ QTest::addColumn<QByteArray>("input");
+ QTest::addColumn<QByteArray>("upper");
+ QTest::addColumn<QByteArray>("lower");
+
+ QTest::newRow("empty") << QByteArray() << QByteArray() << QByteArray();
+ QTest::newRow("ascii") << QByteArray("Hello World, this is a STRING")
+ << QByteArray("HELLO WORLD, THIS IS A STRING")
+ << QByteArray("hello world, this is a string");
+ QTest::newRow("latin1") << QByteArray("R\311sum\351")
+ << QByteArray("R\311SUM\311")
+ << QByteArray("r\351sum\351");
+ QTest::newRow("nul") << QByteArray("a\0B", 3) << QByteArray("A\0B", 3) << QByteArray("a\0b", 3);
+}
+
+void tst_QByteArray::toUpperLower()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(QByteArray, upper);
+ QFETCH(QByteArray, lower);
+ QCOMPARE(input.toUpper(), upper);
+ QCOMPARE(input.toLower(), lower);
+}
+
void tst_QByteArray::macTypes()
{
#ifndef Q_OS_MAC
diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp
index 972c2a7ea4..6d83defdeb 100644
--- a/tests/auto/gui/qopengl/tst_qopengl.cpp
+++ b/tests/auto/gui/qopengl/tst_qopengl.cpp
@@ -43,6 +43,7 @@
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/QOpenGLFramebufferObject>
#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QOpenGLFunctions_4_2_Core>
#include <QtGui/QOpenGLVertexArrayObject>
#include <QtGui/QOpenGLPaintDevice>
#include <QtGui/QPainter>
@@ -88,6 +89,8 @@ private slots:
void fboTextureOwnership();
void fboRendering_data();
void fboRendering();
+ void fboRenderingRGB30_data();
+ void fboRenderingRGB30();
void fboHandleNulledAfterContextDestroyed();
void openGLPaintDevice_data();
void openGLPaintDevice();
@@ -563,7 +566,7 @@ void tst_QOpenGL::fboRendering()
QOpenGLFramebufferObjectFormat fboFormat;
fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
- // Uncomplicate things by using NPOT:
+ // Uncomplicate things by using POT:
const QSize size(256, 128);
QOpenGLFramebufferObject fbo(size, fboFormat);
@@ -587,6 +590,111 @@ void tst_QOpenGL::fboRendering()
qt_opengl_check_test_pattern(fb);
}
+void tst_QOpenGL::fboRenderingRGB30_data()
+{
+ common_data();
+}
+
+#ifndef GL_RGB10_A2
+#define GL_RGB10_A2 0x8059
+#endif
+
+#ifndef GL_FRAMEBUFFER_RENDERABLE
+#define GL_FRAMEBUFFER_RENDERABLE 0x8289
+#endif
+
+#ifndef GL_FULL_SUPPORT
+#define GL_FULL_SUPPORT 0x82B7
+#endif
+
+void tst_QOpenGL::fboRenderingRGB30()
+{
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__)
+ QSKIP("QTBUG-22617");
+#endif
+
+ QFETCH(int, surfaceClass);
+ QScopedPointer<QSurface> surface(createSurface(surfaceClass));
+
+ QOpenGLContext ctx;
+ QVERIFY(ctx.create());
+
+ QVERIFY(ctx.makeCurrent(surface.data()));
+
+ if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects())
+ QSKIP("QOpenGLFramebufferObject not supported on this platform");
+
+ if (ctx.format().majorVersion() < 3)
+ QSKIP("An internal RGB30_A2 format is not guaranteed on this platform");
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+ // NVidia currently only supports RGB30 and RGB30_A2 in their Quadro drivers,
+ // but they do provide an extension for querying the support. We use the query
+ // in case they implement the required formats later.
+ if (!ctx.isOpenGLES() && ctx.format().majorVersion() >= 4) {
+ GLint value = -1;
+ QOpenGLFunctions_4_2_Core* vFuncs = ctx.versionFunctions<QOpenGLFunctions_4_2_Core>();
+ if (vFuncs && vFuncs->initializeOpenGLFunctions()) {
+ vFuncs->glGetInternalformativ(GL_TEXTURE_2D, GL_RGB10_A2, GL_FRAMEBUFFER_RENDERABLE, 1, &value);
+ if (value != GL_FULL_SUPPORT)
+ QSKIP("The required RGB30_A2 format is not supported by this driver");
+ }
+ }
+#endif
+
+ // No multisample with combined depth/stencil attachment:
+ QOpenGLFramebufferObjectFormat fboFormat;
+ fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ fboFormat.setInternalTextureFormat(GL_RGB10_A2);
+
+ // Uncomplicate things by using POT:
+ const QSize size(256, 128);
+ QOpenGLFramebufferObject fbo(size, fboFormat);
+
+ if (fbo.attachment() != QOpenGLFramebufferObject::CombinedDepthStencil)
+ QSKIP("FBOs missing combined depth~stencil support");
+
+ QVERIFY(fbo.bind());
+
+ QPainter fboPainter;
+ QOpenGLPaintDevice device(fbo.width(), fbo.height());
+ bool painterBegun = fboPainter.begin(&device);
+ QVERIFY(painterBegun);
+
+ qt_opengl_draw_test_pattern(&fboPainter, fbo.width(), fbo.height());
+
+ fboPainter.end();
+
+ QImage fb = fbo.toImage();
+ QCOMPARE(fb.format(), QImage::Format_A2BGR30_Premultiplied);
+ QCOMPARE(fb.size(), size);
+
+ qt_opengl_check_test_pattern(fb);
+
+ // Check rendering can handle color values below 1/256.
+ fboPainter.begin(&device);
+ fboPainter.fillRect(QRect(0, 0, 256, 128), QColor::fromRgbF(1.0/512, 1.0/512, 1.0/512));
+ fboPainter.end();
+ fb = fbo.toImage();
+ uint pixel = ((uint*)fb.bits())[0];
+ QVERIFY((pixel & 0x3f) > 0);
+ QVERIFY(((pixel >> 10) & 0x3f) > 0);
+ QVERIFY(((pixel >> 20) & 0x3f) > 0);
+
+ pixel = (3U << 30) | (2U << 20) | (2U << 10) | 2U;
+ fb.fill(pixel);
+
+ fboPainter.begin(&device);
+ fboPainter.setCompositionMode(QPainter::CompositionMode_Source);
+ fboPainter.drawImage(0, 0, fb);
+ fboPainter.end();
+ fb = fbo.toImage();
+ pixel = ((uint*)fb.bits())[0];
+ QVERIFY((pixel & 0x3f) > 0);
+ QVERIFY(((pixel >> 10) & 0x3f) > 0);
+ QVERIFY(((pixel >> 20) & 0x3f) > 0);
+}
+
void tst_QOpenGL::fboHandleNulledAfterContextDestroyed()
{
QWindow window;
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 6068391ce1..c9df497b07 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -251,6 +251,7 @@ private slots:
void applicationTest();
void mainWindowTest();
+ void subWindowTest();
void buttonTest();
void scrollBarTest();
void tabTest();
@@ -1003,6 +1004,66 @@ void tst_QAccessibility::mainWindowTest()
}
}
+// Dialogs and other sub-windows must appear in the
+// accessibility hierarchy exactly once as top level objects
+void tst_QAccessibility::subWindowTest()
+{
+ {
+ QWidget mainWidget;
+ mainWidget.setGeometry(100, 100, 100, 100);
+ mainWidget.show();
+ QLabel label(QStringLiteral("Window Contents"), &mainWidget);
+ mainWidget.setLayout(new QHBoxLayout());
+ mainWidget.layout()->addWidget(&label);
+
+ QDialog d(&mainWidget);
+ d.show();
+
+ QAccessibleInterface *app = QAccessible::queryAccessibleInterface(qApp);
+ QVERIFY(app);
+ QCOMPARE(app->childCount(), 2);
+
+ QAccessibleInterface *windowIface = QAccessible::queryAccessibleInterface(&mainWidget);
+ QVERIFY(windowIface);
+ QCOMPARE(windowIface->childCount(), 1);
+ QCOMPARE(app->child(0), windowIface);
+ QCOMPARE(windowIface->parent(), app);
+
+ QAccessibleInterface *dialogIface = QAccessible::queryAccessibleInterface(&d);
+ QVERIFY(dialogIface);
+ QCOMPARE(app->child(1), dialogIface);
+ QCOMPARE(dialogIface->parent(), app);
+ QCOMPARE(dialogIface->parent(), app);
+ }
+
+ {
+ QMainWindow mainWindow;
+ mainWindow.setGeometry(100, 100, 100, 100);
+ mainWindow.show();
+ QLabel label(QStringLiteral("Window Contents"), &mainWindow);
+ mainWindow.setCentralWidget(&label);
+
+ QDialog d(&mainWindow);
+ d.show();
+
+ QAccessibleInterface *app = QAccessible::queryAccessibleInterface(qApp);
+ QVERIFY(app);
+ QCOMPARE(app->childCount(), 2);
+
+ QAccessibleInterface *windowIface = QAccessible::queryAccessibleInterface(&mainWindow);
+ QVERIFY(windowIface);
+ QCOMPARE(windowIface->childCount(), 1);
+ QCOMPARE(app->child(0), windowIface);
+
+ QAccessibleInterface *dialogIface = QAccessible::queryAccessibleInterface(&d);
+ QVERIFY(dialogIface);
+ QCOMPARE(app->child(1), dialogIface);
+ QCOMPARE(dialogIface->parent(), app);
+ QCOMPARE(windowIface->parent(), app);
+ }
+ QTestAccessibility::clearEvents();
+}
+
class CounterButton : public QPushButton {
Q_OBJECT
public:
diff --git a/tests/auto/tools/qmake/testdata/functions/functions.pro b/tests/auto/tools/qmake/testdata/functions/functions.pro
index 84f97c2022..a0e88300d4 100644
--- a/tests/auto/tools/qmake/testdata/functions/functions.pro
+++ b/tests/auto/tools/qmake/testdata/functions/functions.pro
@@ -173,3 +173,12 @@ testReplace($$shell_quote($$in), $$out, "shell_quote")
testReplace($$reverse($$list(one two three)), three two one, "reverse")
testReplace($$cat(textfile), hi '"holla he"' 'hu!')
+
+MOD.a.depends =
+MOD.b.depends =
+MOD.b.priority = 1
+MOD.c.depends = a b
+testReplace($$resolve_depends($$list(c), "MOD."), c b a)
+MOD.a.priority = 1
+MOD.b.priority = 0
+testReplace($$resolve_depends($$list(c), "MOD."), c a b)
diff --git a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
index ffc3e3b67d..60fd946d52 100644
--- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
+++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
@@ -58,6 +58,7 @@
#include <QStyle>
#include <QStyleOptionTitleBar>
#include <QPushButton>
+#include <QScreen>
#include <QSizeGrip>
#include "../../../qtest-config.h"
@@ -182,6 +183,7 @@ private slots:
void mouseDoubleClick();
void setSystemMenu();
void restoreFocus();
+ void restoreFocusOverCreation();
void changeFocusWithTab();
void closeEvent();
void setWindowTitle();
@@ -1126,6 +1128,7 @@ void tst_QMdiSubWindow::restoreFocus()
expectedFocusWindow->showMinimized();
qApp->processEvents();
QVERIFY(expectedFocusWindow->isMinimized());
+ qDebug() << expectedFocusWindow<< qApp->focusWidget();
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(expectedFocusWindow));
// Minimized -> normal
@@ -1178,6 +1181,48 @@ void tst_QMdiSubWindow::restoreFocus()
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(expectedFocusWindow));
}
+class MultiWidget : public QWidget {
+public:
+ explicit MultiWidget(QWidget *parent = 0) : QWidget(parent)
+ , m_lineEdit1(new QLineEdit(this)), m_lineEdit2(new QLineEdit(this))
+ {
+ QVBoxLayout *lt = new QVBoxLayout(this);
+ lt->addWidget(m_lineEdit1);
+ lt->addWidget(m_lineEdit2);
+ }
+
+ QLineEdit *m_lineEdit1;
+ QLineEdit *m_lineEdit2;
+};
+
+void tst_QMdiSubWindow::restoreFocusOverCreation()
+{
+ // QTBUG-38378, verify that the focus child of a subwindow
+ // is not "forgotten" when adding yet another subwindow.
+ QMdiArea mdiArea;
+ mdiArea.resize(800, 800);
+ mdiArea.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(400, 400));
+ mdiArea.setWindowTitle(QStringLiteral("restoreFocusOverCreation"));
+
+ MultiWidget *subWidget1 = new MultiWidget;
+ MultiWidget *subWidget2 = new MultiWidget;
+
+ QMdiSubWindow *subWindow1 = mdiArea.addSubWindow(subWidget1);
+ subWidget1->m_lineEdit2->setFocus();
+ subWindow1->show();
+ mdiArea.show();
+ QApplication::setActiveWindow(&mdiArea);
+ QVERIFY(QTest::qWaitForWindowActive(&mdiArea));
+ QCOMPARE(QApplication::focusWidget(), subWidget1->m_lineEdit2);
+
+ QMdiSubWindow *subWindow2 = mdiArea.addSubWindow(subWidget2);
+ subWindow2->show();
+ QTRY_COMPARE(QApplication::focusWidget(), subWidget2->m_lineEdit1);
+
+ mdiArea.setActiveSubWindow(subWindow1);
+ QTRY_COMPARE(QApplication::focusWidget(), subWidget1->m_lineEdit2);
+}
+
void tst_QMdiSubWindow::changeFocusWithTab()
{
QWidget *widget = new QWidget;