summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp2
-rw-r--r--src/android/java/AndroidManifest.xml16
-rw-r--r--src/android/java/res/values/libs.xml1
-rw-r--r--src/android/java/res/values/strings.xml4
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java8
-rw-r--r--src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch2
-rw-r--r--src/corelib/codecs/qutfcodec.cpp13
-rw-r--r--src/corelib/doc/snippets/code/doc_src_containers.cpp30
-rw-r--r--src/corelib/doc/snippets/qloggingcategory/main.cpp44
-rw-r--r--src/corelib/doc/src/containers.qdoc14
-rw-r--r--src/corelib/doc/src/implicit-sharing.qdoc20
-rw-r--r--src/corelib/doc/src/objectmodel/signalsandslots.qdoc1
-rw-r--r--src/corelib/doc/src/threads-basics.qdoc25
-rw-r--r--src/corelib/doc/src/threads.qdoc118
-rw-r--r--src/corelib/global/qcompilerdetection.h20
-rw-r--r--src/corelib/global/qglobal.cpp36
-rw-r--r--src/corelib/global/qglobal.h18
-rw-r--r--src/corelib/global/qglobalstatic.h9
-rw-r--r--src/corelib/global/qlibraryinfo.cpp4
-rw-r--r--src/corelib/global/qlogging.cpp10
-rw-r--r--src/corelib/global/qnamespace.h22
-rw-r--r--src/corelib/global/qnamespace.qdoc2
-rw-r--r--src/corelib/io/qfileinfo.cpp5
-rw-r--r--src/corelib/io/qfileinfo_p.h14
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp14
-rw-r--r--src/corelib/io/qiodevice.cpp8
-rw-r--r--src/corelib/io/qlockfile_unix.cpp17
-rw-r--r--src/corelib/io/qloggingcategory.cpp87
-rw-r--r--src/corelib/io/qloggingcategory.h6
-rw-r--r--src/corelib/io/qurl.cpp17
-rw-r--r--src/corelib/io/qurlrecode.cpp5
-rw-r--r--src/corelib/json/qjsonarray.cpp2
-rw-r--r--src/corelib/json/qjsonarray.h2
-rw-r--r--src/corelib/json/qjsondocument.cpp6
-rw-r--r--src/corelib/json/qjsondocument.h4
-rw-r--r--src/corelib/json/qjsonobject.cpp2
-rw-r--r--src/corelib/json/qjsonobject.h2
-rw-r--r--src/corelib/json/qjsonparser.cpp2
-rw-r--r--src/corelib/json/qjsonvalue.cpp2
-rw-r--r--src/corelib/json/qjsonvalue.h2
-rw-r--r--src/corelib/json/qjsonwriter.cpp7
-rw-r--r--src/corelib/kernel/qcoreevent.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry.cpp90
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry_p.h4
-rw-r--r--src/corelib/kernel/qvariant.cpp7
-rw-r--r--src/corelib/thread/qthread.cpp29
-rw-r--r--src/corelib/tools/qalgorithms.qdoc2
-rw-r--r--src/corelib/tools/qcollator_posix.cpp3
-rw-r--r--src/corelib/tools/qdatetime.cpp61
-rw-r--r--src/corelib/tools/qhash.cpp10
-rw-r--r--src/corelib/tools/qlinkedlist.cpp14
-rw-r--r--src/corelib/tools/qlist.cpp34
-rw-r--r--src/corelib/tools/qlist.h2
-rw-r--r--src/corelib/tools/qlocale_mac.mm4
-rw-r--r--src/corelib/tools/qmap.cpp25
-rw-r--r--src/corelib/tools/qmargins.h18
-rw-r--r--src/corelib/tools/qset.qdoc14
-rw-r--r--src/corelib/tools/qstring.cpp4
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp4
-rw-r--r--src/corelib/tools/qvector.cpp48
-rw-r--r--src/corelib/tools/qvector.h23
-rw-r--r--src/gui/accessible/qaccessible.h2
-rw-r--r--src/gui/kernel/qevent.cpp115
-rw-r--r--src/gui/kernel/qevent.h28
-rw-r--r--src/gui/kernel/qguiapplication.cpp22
-rw-r--r--src/gui/kernel/qguiapplication_p.h1
-rw-r--r--src/gui/kernel/qguivariant.cpp3
-rw-r--r--src/gui/kernel/qplatformtheme.cpp4
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp4
-rw-r--r--src/gui/kernel/qwindow.cpp2
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp29
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h9
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h16
-rw-r--r--src/gui/opengl/qopengltexture.cpp2
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.cpp50
-rw-r--r--src/gui/text/qfontdatabase.h2
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp6
-rw-r--r--src/gui/text/qfontengine.cpp10
-rw-r--r--src/gui/text/qfontengine_p.h1
-rw-r--r--src/gui/text/qtextdocument.cpp23
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp13
-rw-r--r--src/gui/text/qtextengine.cpp3
-rw-r--r--src/gui/text/qtexthtmlparser.cpp4
-rw-r--r--src/gui/text/qtextlayout.cpp23
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp18
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h5
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp4
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp15
-rw-r--r--src/network/kernel/qhostinfo_unix.cpp15
-rw-r--r--src/opengl/qgl.cpp5
-rw-r--r--src/platformsupport/fbconvenience/qfbcursor.cpp9
-rw-r--r--src/platformsupport/fbconvenience/qfbcursor_p.h2
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen.cpp13
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen_p.h15
-rw-r--r--src/platformsupport/fbconvenience/qfbwindow.cpp20
-rw-r--r--src/platformsupport/fbconvenience/qfbwindow_p.h3
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h28
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouch.cpp15
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.cpp228
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.h23
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp10
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.h2
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp1
-rw-r--r--src/plugins/platforms/android/src/androidjniaccessibility.cpp18
-rw-r--r--src/plugins/platforms/android/src/androidjniinput.cpp57
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.cpp7
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.cpp1
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenu.cpp8
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm42
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm129
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp4
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm18
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp11
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h14
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp37
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.h5
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp10
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp4
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h3
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp33
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.h1
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp2
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport.cpp23
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport_p.h2
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintersupport.cpp52
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintersupport.h4
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix.cpp1
-rw-r--r--src/printsupport/kernel/qcups.cpp15
-rw-r--r--src/printsupport/kernel/qcups_p.h1
-rw-r--r--src/src.pro8
-rw-r--r--src/testlib/doc/src/qttest-index.qdoc1
-rw-r--r--src/testlib/qtestmouse.h2
-rw-r--r--src/tools/moc/generator.cpp2
-rw-r--r--src/tools/qdoc/main.cpp48
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp266
-rw-r--r--src/widgets/dialogs/qfiledialog_p.h6
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicsitemanimation.cpp63
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp54
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h2
-rw-r--r--src/widgets/itemviews/qheaderview.cpp9
-rw-r--r--src/widgets/itemviews/qlistview.cpp62
-rw-r--r--src/widgets/itemviews/qlistview_p.h9
-rw-r--r--src/widgets/itemviews/qtableview.cpp18
-rw-r--r--src/widgets/itemviews/qtableview_p.h2
-rw-r--r--src/widgets/itemviews/qtreeview.cpp8
-rw-r--r--src/widgets/kernel/kernel.pri56
-rw-r--r--src/widgets/kernel/qgesture_p.h35
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp6
-rw-r--r--src/widgets/kernel/qmacgesturerecognizer.cpp275
-rw-r--r--src/widgets/kernel/qmacgesturerecognizer_p.h102
-rw-r--r--src/widgets/kernel/qsizepolicy.qdoc2
-rw-r--r--src/widgets/kernel/qwidget.cpp16
-rw-r--r--src/widgets/kernel/qwidget_p.h1
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp33
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa_p.h4
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp173
-rw-r--r--src/widgets/kernel/qwindowcontainer_p.h5
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp2
-rw-r--r--src/widgets/util/qsystemtrayicon.h4
-rw-r--r--src/widgets/widgets.pro4
-rw-r--r--src/widgets/widgets/qdockwidget.cpp10
-rw-r--r--src/widgets/widgets/qstatusbar.cpp5
170 files changed, 2586 insertions, 1057 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
index 95a6961e7b..51d7f0b653 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
@@ -84,7 +84,7 @@ bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const
#if defined(_MSC_VER) && _MSC_VER < 1600
return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
#else
- return std::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
+ return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
#endif
}
diff --git a/src/android/java/AndroidManifest.xml b/src/android/java/AndroidManifest.xml
index 726801404a..6463793e0b 100644
--- a/src/android/java/AndroidManifest.xml
+++ b/src/android/java/AndroidManifest.xml
@@ -9,21 +9,21 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
+ <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
- <meta-data android:value="@string/repository" android:name="android.app.repository"/>
+ <meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
- <meta-data android:value="@string/app_lib_name" android:name="android.app.lib_name"/>
<!-- Deploy Qt libs as part of package -->
- <meta-data android:value="1" android:name="android.app.bundle_local_qt_libs"/>
+ <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
<!-- Run with local libs -->
- <meta-data android:value="1" android:name="android.app.use_local_qt_libs"/>
- <meta-data android:value="/data/local/tmp/qt/" android:name="android.app.libs_prefix"/>
- <meta-data android:value="@string/local_libs" android:name="android.app.load_local_libs"/>
- <meta-data android:value="@string/local_jars" android:name="android.app.load_local_jars"/>
- <meta-data android:value="@string/init_classes" android:name="android.app.static_init_classes"/>
+ <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
+ <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
+ <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
+ <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
+ <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Messages maps -->
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
diff --git a/src/android/java/res/values/libs.xml b/src/android/java/res/values/libs.xml
index c8e2fb9661..231406d224 100644
--- a/src/android/java/res/values/libs.xml
+++ b/src/android/java/res/values/libs.xml
@@ -3,7 +3,6 @@
<array name="qt_sources">
<item>https://download.qt-project.org/ministro/android/qt5/latest</item>
</array>
- <string name="repository">default</string>
<!-- The following is handled automatically by the deployment tool. It should
not be edited manually. -->
diff --git a/src/android/java/res/values/strings.xml b/src/android/java/res/values/strings.xml
index 0b92c5542e..300f0673a4 100644
--- a/src/android/java/res/values/strings.xml
+++ b/src/android/java/res/values/strings.xml
@@ -1,10 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="app_name"><!-- %%INSERT_APP_NAME%% --></string>
- <string name="app_lib_name"><!-- %%INSERT_APP_LIB_NAME%% --></string>
- <string name="local_libs"><!-- %%INSERT_LOCAL_LIBS%% --></string>
- <string name="local_jars"><!-- %%INSERT_LOCAL_JARS%% --></string>
- <string name="init_classes"><!-- %%INSERT_INIT_CLASSES%% --></string>
<string name="ministro_not_found_msg">Can\'t find Ministro service.\nThe application can\'t start.</string>
<string name="ministro_needed_msg">This application requires Ministro service. Would you like to install it?</string>
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
index 83ed1582bf..9c7b57a4f5 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
@@ -489,6 +489,14 @@ public class QtActivity extends Activity
+ "\tQML2_IMPORT_PATH=" + localPrefix + "/qml"
+ "\tQML_IMPORT_PATH=" + localPrefix + "/imports"
+ "\tQT_PLUGIN_PATH=" + localPrefix + "/plugins");
+
+ Intent intent = getIntent();
+ if (intent != null) {
+ String parameters = intent.getStringExtra("applicationArguments");
+ if (parameters != null)
+ loaderParams.putString(APPLICATION_PARAMETERS_KEY, parameters.replace(' ', '\t'));
+ }
+
loadApplication(loaderParams);
return;
}
diff --git a/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch b/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch
index 0e72c57be6..2fa23aed8f 100644
--- a/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch
+++ b/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch
@@ -22,7 +22,7 @@ index 610a5ef..95a6961 100644
+#if defined(_MSC_VER) && _MSC_VER < 1600
+ return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
+#else
-+ return std::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
++ return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
+#endif
}
diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp
index aeedcf1aa1..e425f8634c 100644
--- a/src/corelib/codecs/qutfcodec.cpp
+++ b/src/corelib/codecs/qutfcodec.cpp
@@ -106,14 +106,6 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve
if (u < 0x0800) {
*cursor++ = 0xc0 | ((uchar) (u >> 6));
} else {
- // is it one of the Unicode non-characters?
- if (QChar::isNonCharacter(u)) {
- *cursor++ = replacement;
- ++ch;
- ++invalid;
- continue;
- }
-
if (QChar::requiresSurrogates(u)) {
*cursor++ = 0xf0 | ((uchar) (u >> 18));
*cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
@@ -180,15 +172,14 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte
--need;
if (!need) {
// utf-8 bom composes into 0xfeff code point
- bool nonCharacter;
if (!headerdone && uc == 0xfeff) {
// don't do anything, just skip the BOM
- } else if (!(nonCharacter = QChar::isNonCharacter(uc)) && QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
+ } else if (QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
// surrogate pair
Q_ASSERT((qch - (ushort*)result.unicode()) + 2 < result.length());
*qch++ = QChar::highSurrogate(uc);
*qch++ = QChar::lowSurrogate(uc);
- } else if ((uc < min_uc) || QChar::isSurrogate(uc) || nonCharacter || uc > QChar::LastValidCodePoint) {
+ } else if ((uc < min_uc) || QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) {
// error: overlong sequence, UTF16 surrogate or non-character
*qch++ = replacement;
++invalid;
diff --git a/src/corelib/doc/snippets/code/doc_src_containers.cpp b/src/corelib/doc/snippets/code/doc_src_containers.cpp
index 350b2a91f2..6e59a8a548 100644
--- a/src/corelib/doc/snippets/code/doc_src_containers.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_containers.cpp
@@ -273,3 +273,33 @@ QString onlyLetters(const QString &in)
return out;
}
//! [23]
+
+//! [24]
+QVector<int> a, b;
+a.resize(100000); // make a big vector filled with 0.
+
+QVector<int>::iterator i = a.begin();
+// WRONG way of using the iterator i:
+b = a;
+/*
+ Now we should be careful with iterator i since it will point to shared data
+ If we do *i = 4 then we would change the shared instance (both vectors)
+ The behavior differs from STL containers. Avoid doing such things in Qt.
+*/
+
+a[0] = 5;
+/*
+ Container a is now detached from the shared data,
+ and even though i was an iterator from the container a, it now works as an iterator in b.
+ Here the situation is that (*i) == 0.
+*/
+
+b.clear(); // Now the iterator i is completely invalid.
+
+int j = *i; // Undefined behavior!
+/*
+ The data from b (which i pointed to) is gone.
+ This would be well-defined with STL containers (and (*i) == 5),
+ but with QVector this is likely to crash.
+*/
+//! [24]
diff --git a/src/corelib/doc/snippets/qloggingcategory/main.cpp b/src/corelib/doc/snippets/qloggingcategory/main.cpp
index 27d64e8253..c1dad7f43a 100644
--- a/src/corelib/doc/snippets/qloggingcategory/main.cpp
+++ b/src/corelib/doc/snippets/qloggingcategory/main.cpp
@@ -67,24 +67,45 @@ QList<UsbEntry> usbEntries() {
return entries;
}
-void main(int argc, char *argv[])
+//![20]
+void myCategoryFilter(QLoggingCategory *);
+//![20]
+
+//![21]
+QLoggingCategory::CategoryFilter oldCategoryFilter;
+
+void myCategoryFilter(QLoggingCategory *category)
+{
+ // configure qt.driver.usb category here, otherwise forward to to default filter.
+ if (qstrcmp(category->categoryName(), "qt.driver.usb") == 0)
+ category->setEnabled(QtDebugMsg, true);
+ else
+ oldCategoryFilter(category);
+}
+//![21]
+
+int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//![2]
- // don't run the expensive code if the string won't print
- if (QT_DRIVER_USB().isDebugEnabled()) {
- QStringList items;
- foreach (const UsbEntry &entry, usbEntries())
- items << QString("%1 (%2)").arg(entry.id, entry.classtype);
- qCDebug(QT_DRIVER_USB) << "devices: " << items;
- }
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.driver.usb.debug=true"));
//![2]
+//![22]
+
+// ...
+oldCategoryFilter = QLoggingCategory::installFilter(myCategoryFilter);
+//![22]
+
+//![3]
+ qSetMessagePattern("%{category} %{message}");
//![3]
+
+//![4]
// usbEntries() will only be called if QT_DRIVER_USB category is enabled
qCDebug(QT_DRIVER_USB) << "devices: " << usbEntries();
-//![3]
+//![4]
{
//![10]
@@ -106,8 +127,7 @@ void main(int argc, char *argv[])
qCCritical(category) << "a critical message";
//![12]
}
+
+ return 0;
}
-//![20]
-void myCategoryFilter(QLoggingCategory *);
-//![20]
diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc
index ff2df9c020..fa26409d83 100644
--- a/src/corelib/doc/src/containers.qdoc
+++ b/src/corelib/doc/src/containers.qdoc
@@ -533,10 +533,18 @@
This problem doesn't occur with functions that return a const or
non-const reference to a container.
+ \section3 Implicit sharing iterator problem
+
\l{Implicit sharing} has another consequence on STL-style
- iterators: You must not take a copy of a container while
- non-const iterators are active on that container. Java-style
- iterators don't suffer from that limitation.
+ iterators: you should avoid copying a container while
+ iterators are active on that container. The iterators
+ point to an internal structure, and if you copy a container
+ you should be very careful with your iterators. E.g:
+
+ \snippet code/doc_src_containers.cpp 24
+
+ The above example only shows a problem with QVector, but
+ the problem exists for all the implicitly shared Qt containers.
\keyword foreach
\section1 The foreach Keyword
diff --git a/src/corelib/doc/src/implicit-sharing.qdoc b/src/corelib/doc/src/implicit-sharing.qdoc
index 814f8140f3..1185fe8348 100644
--- a/src/corelib/doc/src/implicit-sharing.qdoc
+++ b/src/corelib/doc/src/implicit-sharing.qdoc
@@ -89,9 +89,12 @@
of data. Objects can easily be assigned, sent as function arguments,
and returned from functions.
- Implicit sharing takes place behind the scenes; the programmer
- does not need to worry about it. Even in multithreaded
- applications, implicit sharing takes place, as explained in
+ Implicit sharing mostly takes place behind the scenes;
+ the programmer rarely needs to worry about it. However, Qt's
+ container iterators have different behavior than those from
+ the STL. Read \l{Implicit sharing iterator problem}.
+
+ In multithreaded applications, implicit sharing takes place, as explained in
\l{Thread-Support in Qt Modules#Threads and Implicitly Shared Classes}
{Threads and Implicitly Shared Classes}.
@@ -105,9 +108,10 @@
greater than one. (This is often called \e {copy-on-write} or
\e {value semantics}.)
- An implicitly shared class has total control of its internal data. In
+ An implicitly shared class has control of its internal data. In
any member functions that modify its data, it automatically detaches
- before modifying the data.
+ before modifying the data. Notice, however, the special case with
+ container iterators; see \l{Implicit sharing iterator problem}.
The QPen class, which uses implicit sharing, detaches from the shared
data in all member functions that change the internal data.
@@ -133,9 +137,9 @@
In this example, \c p1 and \c p2 share data until QPainter::begin()
is called for \c p2, because painting a pixmap will modify it.
- \warning Do not copy an implicitly shared container (QMap,
- QVector, etc.) while you are iterating over it using an non-const
- \l{STL-style iterators}{STL-style iterator}.
+ \warning Be careful with copying an implicitly shared container
+ (QMap, QVector, etc.) while you use
+ \l{STL-style iterators}{STL-style iterator}. See \l{Implicit sharing iterator problem}.
\keyword implicitly shared classes
\annotatedlist shared
diff --git a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
index b86aae830f..dd93b80cae 100644
--- a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
+++ b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
@@ -28,6 +28,7 @@
/*!
\page signalsandslots.html
\title Signals & Slots
+ \keyword Signals and Slots
\ingroup qt-basic-concepts
\brief An overview of Qt's signals and slots inter-object
communication mechanism.
diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc
index e511c10423..4f381421b4 100644
--- a/src/corelib/doc/src/threads-basics.qdoc
+++ b/src/corelib/doc/src/threads-basics.qdoc
@@ -199,31 +199,6 @@
still important.
On Linux, Valgrind and Helgrind can help detect threading errors.
- The anatomy of QThread is quite interesting:
-
- \list
- \li QThread does not live in the new thread where \l{QThread::}{run()} is
- executed. It lives in the old thread.
- \li Most QThread methods are the thread's control interface and are meant to
- be called from the old thread. Do not move this interface to the newly
- created thread using \l{QObject::}{moveToThread()}; i.e., calling
- \l{QObject::moveToThread()}{moveToThread(this)} is regarded as bad
- practice.
- \li \l{QThread::}{exec()} and the static methods
- \l{QThread::}{usleep()}, \l{QThread::}{msleep()},
- \l{QThread::}{sleep()} are meant to be called from the newly created
- thread.
- \li Additional members defined in the QThread subclass are
- accessible by both threads. The developer is responsible for
- coordinating access. A typical strategy is to set the members before
- \l{QThread::}{start()} is called. Once the worker thread is running,
- the main thread should not touch the additional members anymore. After
- the worker has terminated, the main thread can access the additional
- members again. This is a convenient strategy for passing parameters to a
- thread before it is started as well as for collecting the result once it
- has terminated.
- \endlist
-
\section2 Protecting the Integrity of Data
When writing a multithread application, extra care must be taken to avoid
diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc
index 8962dceb01..890fd9f6ff 100644
--- a/src/corelib/doc/src/threads.qdoc
+++ b/src/corelib/doc/src/threads.qdoc
@@ -123,7 +123,7 @@
\nextpage Synchronizing Threads
Qt offers many classes and functions for working with threads. Below are
- three different approaches that Qt programmers can use to implement
+ four different approaches that Qt programmers can use to implement
multithreaded applications.
@@ -163,19 +163,47 @@
\section1 Qt Concurrent: Using a High-level API
The \l{Qt Concurrent} module provides high-level functions that deal with some
- common parallel computation patterns: map, filter, and reduce. Unlike QThread
- and QRunnable, these functions do not require the use of low-level threading
- primitives such as mutexes or semaphores. \l {Qt Concurrent} will automatically
- adjust the number of threads used according to the number of processor cores
- available, so applications written today will continue to scale when deployed
- later on a system with more cores.
-
- This module also provides the QtConcurrent::run() function, which can run
- any function in a thread managed by the global QThreadPool.
+ common parallel computation patterns: map, filter, and reduce. Unlike using
+ QThread and QRunnable, these functions never require the use of \l{Synchronizing
+ Threads#Low-Level Synchronization Primitives}{low-level threading primitives}
+ such as mutexes or semaphores. Instead, they return a QFuture object which can
+ be used to retrieve the functions' results when they are ready. QFuture can
+ also be used to query computation progress and to pause/resume/cancel the
+ computation. For convenience, QFutureWatcher enables interactions with
+ \l{QFuture}s via signals and slots.
+
+ \l{Qt Concurrent}'s map, filter and reduce algorithms automatically distribute
+ computation across all available processor cores, so applications written today
+ will continue to scale when deployed later on a system with more cores.
+
+ This module also provides the QtConcurrent::run() function, which can run any
+ function in another thread. However, QtConcurrent::run() only supports a subset
+ of features available to the map, filter and reduce functions. The QFuture
+ can be used to retrieve the function's return value and to check if the thread
+ is running. However, a call to QtConcurrent::run() uses one thread only, cannot
+ be paused/resumed/canceled, and cannot be queried for progress.
See the \l{Qt Concurrent} module documentation for details on the individual functions.
+ \section1 WorkerScript: Threading in QML
+
+ The WorkerScript QML type lets JavaScript code run in parallel with the GUI
+ thread.
+
+ Each WorkerScript instance can have one \c{.js} script attached to it. When
+ WorkerScript::sendMessage() is called, the script will run in a separate thread
+ (and a separate \l{QQmlContext}{QML context}). When the script finishes
+ running, it can send a reply back to the GUI thread which will invoke the
+ WorkerScript::onMessage() signal handler.
+
+ Using a WorkerScript is similar to using a worker QObject that has been moved
+ to another thread. Data is transferred between threads via signals.
+
+ See the WorkerScript documentation for details on how to implement the script,
+ and for a list of data types that can be passed between threads.
+
+
\section1 Choosing an Appropriate Approach
As demonstrated above, Qt provides different solutions for developing threaded
@@ -187,52 +215,62 @@
\table
\header
- \li Feature/Characteristic
+ \li Feature
\li QThread
- \li QRunnable
- \li Qt Concurrent\sup{*}
+ \li QRunnable and QThreadPool
+ \li QtConcurrent::run()
+ \li Qt Concurrent (Map, Filter, Reduce)
+ \li WorkerScript
+ \row
+ \li API
+ \li C++
+ \li C++
+ \li C++
+ \li C++
+ \li QML
\row
- \li Supports different thread priorities
+ \li Thread priority can be specified
\li Yes
+ \li Yes
+ \li
\li
\li
\row
- \li Supports an event loop
+ \li Thread can run an event loop
\li Yes
\li
\li
+ \li
+ \li
\row
- \li Supports transferring data to the thread using signals
+ \li Thread can receive data updates through signals
\li Yes (received by a worker QObject)
\li
\li
+ \li
+ \li Yes (received by WorkerScript)
\row
- \li Supports controlling the thread using signals
+ \li Thread can be controlled using signals
\li Yes (received by QThread)
\li
- \li Yes (received by QFutureWatcher)
- \row
- \li Supports thread reuse
\li
- \li Yes
- \li Yes
- \row
- \li Task-oriented
+ \li Yes (received by QFutureWatcher)
\li
- \li Yes
- \li Yes
\row
- \li High level API
+ \li Thread can be monitored through a QFuture
\li
\li
+ \li Partially
\li Yes
+ \li
\row
- \li Supports pausing/resuming/canceling
+ \li Built-in ability to pause/resume/cancel
+ \li
\li
\li
\li Yes
+ \li
\endtable
- \sup{\e{*Except QtConcurrent::run(), which is like QRunnable}}
\section2 Example Use Cases
@@ -244,7 +282,7 @@
\li Solution
\row
\li One call
- \li Run a linear function within another thread, optionally with progress
+ \li Run a new linear function within another thread, optionally with progress
updates during the run.
\li Qt provides different solutions:
\list
@@ -258,13 +296,29 @@
\endlist
\row
\li One call
+ \li Run an existing function within another thread and get its return value.
+ \li Run the function using QtConcurrent::run(). Have a QFutureWatcher emit
+ the \l{QFutureWatcher::}{finished()} signal when the function has
+ returned, and call QFutureWatcher::result() to get the function's return
+ value.
+ \row
+ \li One call
\li Perform an operation on all items of a container, using all available
cores. For example, producing thumbnails from a list of images.
\li Use Qt Concurrent's \l{QtConcurrent::}{filter()} function to select
container elements, and the \l{QtConcurrent::}{map()} function to apply
an operation to each element. To fold the output into a single result,
- use \l{QtConcurrent::}{filterReduced()} and \l{QtConcurrent::}{mapReduced()}
- instead.
+ use \l{QtConcurrent::}{filteredReduced()} and
+ \l{QtConcurrent::}{mappedReduced()} instead.
+ \row
+ \li One call/Permanent
+ \li Perfrom a long computation in a pure QML application, and update the GUI
+ when the results are ready.
+ \li Place the computation code in a \c{.js} script and attach it to a
+ WorkerScript instance. Call \l{WorkerScript::}{sendMessage()} to start the
+ computation in a new thread. Let the script call WorkerScript::sendMessage()
+ too, to pass the result back to the GUI thread. Handle the result in
+ \l{WorkerScript::}{onMessage} and update the GUI there.
\row
\li Permanent
\li Have an object living in another thread that can perform different
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index ef425e8d85..102a6487ee 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -165,6 +165,13 @@
# /* Compatibility with older Clang versions */
# define __has_extension __has_feature
# endif
+# if defined(__APPLE__)
+ /* Apple/clang specific features */
+# define Q_DECL_CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+# ifdef __OBJC__
+# define Q_DECL_NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased))
+# endif
+# endif
# else
/* Plain GCC */
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
@@ -628,14 +635,6 @@
# endif
#endif // Q_CC_CLANG
-#if defined(Q_CC_CLANG) && defined(__APPLE__)
-/* Apple/clang specific features */
-# define Q_DECL_CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
-# ifdef __OBJC__
-# define Q_DECL_NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased))
-# endif
-#endif
-
#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
@@ -704,15 +703,20 @@
# if _MSC_VER >= 1400
/* C++11 features supported in VC8 = VC2005: */
# define Q_COMPILER_VARIADIC_MACROS
+
+# ifndef __cplusplus_cli
/* 2005 supports the override and final contextual keywords, in
the same positions as the C++11 variants, but 'final' is
called 'sealed' instead:
http://msdn.microsoft.com/en-us/library/0w2w91tf%28v=vs.80%29.aspx
+ The behavior is slightly different in C++/CLI, which requires the
+ "virtual" keyword to be present too, so don't define for that.
So don't define Q_COMPILER_EXPLICIT_OVERRIDES (since it's not
the same as the C++11 version), but define the Q_DECL_* flags
accordingly: */
# define Q_DECL_OVERRIDE override
# define Q_DECL_FINAL sealed
+# endif
# endif
# if _MSC_VER >= 1600
/* C++11 features supported in VC10 = VC2010: */
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 2637a6a0d8..6f74c7de88 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -76,6 +76,10 @@
#include <CoreServices/CoreServices.h>
#endif
+#if defined(Q_OS_ANDROID)
+#include <private/qjni_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
#if !QT_DEPRECATED_SINCE(5, 0)
@@ -2348,6 +2352,9 @@ typedef uint SeedStorageType;
typedef QThreadStorage<SeedStorageType *> SeedStorage;
Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value
+#elif defined(Q_OS_ANDROID)
+typedef QThreadStorage<QJNIObjectPrivate> AndroidRandomStorage;
+Q_GLOBAL_STATIC(AndroidRandomStorage, randomTLS)
#endif
/*!
@@ -2381,6 +2388,16 @@ void qsrand(uint seed)
//global static object, fallback to srand(seed)
srand(seed);
}
+#elif defined(Q_OS_ANDROID)
+ QJNIObjectPrivate random = QJNIObjectPrivate("java/util/Random",
+ "(J)V",
+ jlong(seed));
+ if (!random.isValid()) {
+ srand(seed);
+ return;
+ }
+
+ randomTLS->setLocalData(random);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
@@ -2422,6 +2439,25 @@ int qrand()
//global static object, fallback to rand()
return rand();
}
+#elif defined(Q_OS_ANDROID)
+ AndroidRandomStorage *randomStorage = randomTLS();
+ if (!randomStorage)
+ return rand();
+
+ QJNIObjectPrivate random;
+ if (!randomStorage->hasLocalData()) {
+ random = QJNIObjectPrivate("java/util/Random",
+ "(J)V",
+ jlong(1));
+ if (!random.isValid())
+ return rand();
+
+ randomStorage->setLocalData(random);
+ } else {
+ random = randomStorage->localData();
+ }
+
+ return random.callMethod<jint>("nextInt", "(I)I", RAND_MAX);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index ed17709a4d..b654ba3ac8 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1004,13 +1004,19 @@ template <bool B, typename T = void> struct QEnableIf;
template <typename T> struct QEnableIf<true, T> { typedef T Type; };
}
-#ifdef __OBJC__
-#define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
-#else
-#define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
+#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
+# ifdef __OBJC__
+# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
+# else
+# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
+# endif
+#endif
+#ifndef Q_FORWARD_DECLARE_CF_TYPE
+# define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref
+#endif
+#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE
+# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
#endif
-#define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref
-#define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
QT_END_NAMESPACE
// Q_GLOBAL_STATIC
diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h
index 5d0b1e8514..ad39452cf4 100644
--- a/src/corelib/global/qglobalstatic.h
+++ b/src/corelib/global/qglobalstatic.h
@@ -57,11 +57,16 @@ enum GuardValues {
};
}
-#if defined(QT_NO_THREAD) || defined(Q_CC_GNU)
+#if defined(QT_NO_THREAD) || (defined(Q_CC_GNU) && !defined(Q_OS_MAC))
// some compilers support thread-safe statics
// The IA-64 C++ ABI requires this, so we know that all GCC versions since 3.4
// support it. C++11 also requires this behavior.
-// Clang and Intel CC masquerade as GCC when compiling on Linux and Mac OS X.
+// Clang and Intel CC masquerade as GCC when compiling on Linux.
+//
+// Apple's libc++abi however uses a global lock for initializing local statics,
+// which will block other threads also trying to initialize a local static
+// until the constructor returns ...
+// We better avoid these kind of problems by using our own locked implementation.
#define Q_GLOBAL_STATIC_INTERNAL(ARGS) \
Q_DECL_HIDDEN inline Type *innerFunction() \
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 9bc7506e39..a279498e93 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -446,7 +446,11 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
if (urlRef) {
QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
+#ifdef Q_OS_MACX
return QDir::cleanPath(QString(path) + QLatin1String("/Contents/") + ret);
+#else
+ return QDir::cleanPath(QString(path) + QLatin1Char('/') + ret); // iOS
+#endif
}
}
#endif
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 063e94069f..0a261acc77 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -549,6 +549,7 @@ static const char functionTokenC[] = "%{function}";
static const char pidTokenC[] = "%{pid}";
static const char appnameTokenC[] = "%{appname}";
static const char threadidTokenC[] = "%{threadid}";
+static const char ifCategoryTokenC[] = "%{if-category}";
static const char ifDebugTokenC[] = "%{if-debug}";
static const char ifWarningTokenC[] = "%{if-warning}";
static const char ifCriticalTokenC[] = "%{if-critical}";
@@ -556,7 +557,7 @@ static const char ifFatalTokenC[] = "%{if-fatal}";
static const char endifTokenC[] = "%{endif}";
static const char emptyTokenC[] = "";
-static const char defaultPattern[] = "%{message}";
+static const char defaultPattern[] = "%{if-category}%{category}: %{endif}%{message}";
struct QMessagePattern {
@@ -675,6 +676,7 @@ void QMessagePattern::setPattern(const QString &pattern)
tokens[i] = LEVEL; \
inIf = true; \
}
+ IF_TOKEN(ifCategoryTokenC)
IF_TOKEN(ifDebugTokenC)
IF_TOKEN(ifWarningTokenC)
IF_TOKEN(ifCriticalTokenC)
@@ -837,6 +839,9 @@ Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogCont
message.append(QLatin1String("0x"));
message.append(QString::number(qlonglong(QThread::currentThread()->currentThread()), 16));
#endif
+ } else if (token == ifCategoryTokenC) {
+ if (!context.category || (strcmp(context.category, "default") == 0))
+ skip = true;
#define HANDLE_IF_TOKEN(LEVEL) \
} else if (token == if##LEVEL##TokenC) { \
skip = type != Qt##LEVEL##Msg;
@@ -927,7 +932,7 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
#ifndef QT_BOOTSTRAPPED
// qDebug, qWarning, ... macros do not check whether category is enabled
if (!context.category || (strcmp(context.category, "default") == 0)) {
- if (QLoggingCategory *defaultCategory = &QLoggingCategory::defaultCategory()) {
+ if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory()) {
if (!defaultCategory->isEnabled(msgType))
return;
}
@@ -1108,6 +1113,7 @@ void qErrnoWarning(int code, const char *msg, ...)
\table
\header \li Placeholder \li Description
\row \li \c %{appname} \li QCoreApplication::applicationName()
+ \row \li \c %{category} \li Logging category
\row \li \c %{file} \li Path to source file
\row \li \c %{function} \li Function
\row \li \c %{line} \li Line in source file
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 1409e5d977..758f13596e 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -907,7 +907,7 @@ public:
Key_BrightnessAdjust = 0x010000c2,
Key_Finance = 0x010000c3,
Key_Community = 0x010000c4,
- Key_AudioRewind = 0x010000c5,
+ Key_AudioRewind = 0x010000c5, // Media rewind
Key_BackForward = 0x010000c6,
Key_ApplicationLeft = 0x010000c7,
Key_ApplicationRight = 0x010000c8,
@@ -919,7 +919,7 @@ public:
Key_Close = 0x010000ce,
Key_Copy = 0x010000cf,
Key_Cut = 0x010000d0,
- Key_Display = 0x010000d1,
+ Key_Display = 0x010000d1, // Output switch key
Key_DOS = 0x010000d2,
Key_Documents = 0x010000d3,
Key_Excel = 0x010000d4,
@@ -968,9 +968,9 @@ public:
Key_Bluetooth = 0x010000ff,
Key_WLAN = 0x01000100,
Key_UWB = 0x01000101,
- Key_AudioForward = 0x01000102,
- Key_AudioRepeat = 0x01000103,
- Key_AudioRandomPlay = 0x01000104,
+ Key_AudioForward = 0x01000102, // Media fast-forward
+ Key_AudioRepeat = 0x01000103, // Toggle repeat mode
+ Key_AudioRandomPlay = 0x01000104, // Toggle shuffle mode
Key_Subtitle = 0x01000105,
Key_AudioCycleTrack = 0x01000106,
Key_Time = 0x01000107,
@@ -1557,6 +1557,18 @@ public:
IgnoredGesturesPropagateToParent = 0x04
};
Q_DECLARE_FLAGS(GestureFlags, GestureFlag)
+
+ enum NativeGestureType
+ {
+ BeginNativeGesture,
+ EndNativeGesture,
+ PanNativeGesture,
+ ZoomNativeGesture,
+ SmartZoomNativeGesture,
+ RotateNativeGesture,
+ SwipeNativeGesture
+ };
+
#endif // QT_NO_GESTURES
enum NavigationMode
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 78f6a60287..e33fd085f2 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -1735,6 +1735,8 @@
\value LeftEdge The left edge of the rectangle.
\value RightEdge The right edge of the rectangle.
\value BottomEdge The bottom edge of the rectangle.
+
+ \since 5.1
*/
/*!
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 90122a9f0d..897af352c9 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -675,6 +675,8 @@ bool QFileInfo::exists() const
}
/*!
+ \since 5.2
+
Returns \c true if the \a file exists; otherwise returns \c false.
\note If \a file is a symlink that points to a non-existing
@@ -691,7 +693,8 @@ bool QFileInfo::exists(const QString &file)
QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, data);
// Expensive fallback to non-QFileSystemEngine implementation
if (engine)
- return QFileInfo(file).exists();
+ return QFileInfo(new QFileInfoPrivate(entry, data, engine)).exists();
+
QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute);
return data.exists();
}
diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h
index 442e6b5ef0..47359a55ce 100644
--- a/src/corelib/io/qfileinfo_p.h
+++ b/src/corelib/io/qfileinfo_p.h
@@ -120,6 +120,20 @@ public:
metaData = QFileSystemMetaData();
}
+ inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, QAbstractFileEngine *engine)
+ : fileEntry(file),
+ metaData(data),
+ fileEngine(engine),
+ cachedFlags(0),
+#ifndef QT_NO_FSFILEENGINE
+ isDefaultConstructed(false),
+#else
+ isDefaultConstructed(!fileEngine),
+#endif
+ cache_enabled(true), fileFlags(0), fileSize(0)
+ {
+ }
+
inline void clearFlags() const {
fileFlags = 0;
cachedFlags = 0;
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 105c8d34dd..77304b2cb9 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -1038,8 +1038,10 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
return data.hasFlags(what);
}
-static inline bool mkDir(const QString &path)
+static inline bool mkDir(const QString &path, DWORD *lastError = 0)
{
+ if (lastError)
+ *lastError = 0;
#if defined(Q_OS_WINCE)
// Unfortunately CreateDirectory returns true for paths longer than
// 256, but does not create a directory. It starts to fail, when
@@ -1059,7 +1061,11 @@ static inline bool mkDir(const QString &path)
if (platformId == 1 && QFSFileEnginePrivate::longFileName(path).size() > 256)
return false;
#endif
- return ::CreateDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), 0);
+ const QString longPath = QFSFileEnginePrivate::longFileName(path);
+ const bool result = ::CreateDirectory((wchar_t*)longPath.utf16(), 0);
+ if (lastError) // Capture lastError before any QString is freed since custom allocators might change it.
+ *lastError = GetLastError();
+ return result;
}
static inline bool rmDir(const QString &path)
@@ -1131,9 +1137,9 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea
slash = dirName.length();
}
if (slash) {
+ DWORD lastError;
QString chunk = dirName.left(slash);
- if (!mkDir(chunk)) {
- const DWORD lastError = GetLastError();
+ if (!mkDir(chunk, &lastError)) {
if (lastError == ERROR_ALREADY_EXISTS || lastError == ERROR_ACCESS_DENIED) {
bool existed = false;
if (isDirPath(chunk, &existed) && existed)
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 8fb80123fa..a81b8580c4 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -99,8 +99,10 @@ void debugBinaryString(const char *data, qint64 maxlen)
#define CHECK_WRITABLE(function, returnType) \
do { \
if ((d->openMode & WriteOnly) == 0) { \
- if (d->openMode == NotOpen) \
+ if (d->openMode == NotOpen) { \
+ qWarning("QIODevice::"#function": device not open"); \
return returnType; \
+ } \
qWarning("QIODevice::"#function": ReadOnly device"); \
return returnType; \
} \
@@ -109,8 +111,10 @@ void debugBinaryString(const char *data, qint64 maxlen)
#define CHECK_READABLE(function, returnType) \
do { \
if ((d->openMode & ReadOnly) == 0) { \
- if (d->openMode == NotOpen) \
+ if (d->openMode == NotOpen) { \
+ qWarning("QIODevice::"#function": device not open"); \
return returnType; \
+ } \
qWarning("QIODevice::"#function": WriteOnly device"); \
return returnType; \
} \
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index 1676b71133..dc8817706c 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -140,6 +140,13 @@ static bool setNativeLocks(int fd)
QLockFile::LockError QLockFilePrivate::tryLock_sys()
{
+ // Assemble data, to write in a single call to write
+ // (otherwise we'd have to check every write call)
+ // Use operator% from the fast builder to avoid multiple memory allocations.
+ QByteArray fileData = QByteArray::number(QCoreApplication::applicationPid()) % '\n'
+ % qAppName().toUtf8() % '\n'
+ % localHostName().toUtf8() % '\n';
+
const QByteArray lockFileName = QFile::encodeName(fileName);
const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0644);
if (fd < 0) {
@@ -160,16 +167,6 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
// We hold the lock, continue.
fileHandle = fd;
- // Assemble data, to write in a single call to write
- // (otherwise we'd have to check every write call)
- QByteArray fileData;
- fileData += QByteArray::number(QCoreApplication::applicationPid());
- fileData += '\n';
- fileData += qAppName().toUtf8();
- fileData += '\n';
- fileData += localHostName().toUtf8();
- fileData += '\n';
-
QLockFile::LockError error = QLockFile::NoError;
if (qt_write_loop(fd, fileData.constData(), fileData.size()) < fileData.size())
error = QLockFile::UnknownError; // partition full
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 6c5df1e8e7..8d337ec630 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -71,30 +71,36 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
\section1 Checking category configuration
- QLoggingCategory provides a generic \l isEnabled() and message
- type dependent \l isDebugEnabled(), \l isWarningEnabled(),
- \l isCriticalEnabled() and \l isTraceEnabled()
- methods for checking whether the current category is enabled.
+ QLoggingCategory provides \l isDebugEnabled(), \l isWarningEnabled(),
+ \l isCriticalEnabled(), \l isTraceEnabled(), as well as \l isEnabled()
+ to check whether messages for the given message type should be logged.
\note The qCDebug(), qCWarning(), qCCritical(), qCTrace() and
qCTraceGuard() macros prevent arguments from being evaluated if the
respective message types are not enabled for the category, so explicit
checking is not needed:
- \snippet qloggingcategory/main.cpp 3
+ \snippet qloggingcategory/main.cpp 4
- \section1 Default configuration
+ \section1 Default category configuration
In the default configuration \l isWarningEnabled() and \l isCriticalEnabled()
- will return \c true. By default, \l isDebugEnabled() will return \c true only
+ will return \c true. \l isDebugEnabled() will return \c true only
for the \c "default" category.
- \section1 Changing configuration
+ \section1 Changing the configuration of a category
+
+ Use either \l setFilterRules() or \l installFilter() to
+ configure categories, for example
+
+ \snippet qloggingcategory/main.cpp 2
+
+ \section1 Printing the category
+
+ Use the \c %{category} place holder to print the category in the default
+ message handler:
- The default configuration can be changed by calling \l setEnabled(). However,
- this only affects the current category object, not e.g. another object for the
- same category name. Use either \l setFilterRules() or \l installFilter() to
- configure categories globally.
+ \snippet qloggingcategory/main.cpp 3
*/
typedef QVector<QTracer *> Tracers;
@@ -117,7 +123,10 @@ QLoggingCategory::QLoggingCategory(const char *category)
enabledDebug(false),
enabledWarning(true),
enabledCritical(true),
- enabledTrace(false)
+ enabledTrace(false),
+ placeholder1(false),
+ placeholder2(false),
+ placeholder3(false)
{
bool isDefaultCategory
= (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
@@ -215,14 +224,12 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
/*!
Changes the message type \a type for the category to \a enable.
- Changes only affect the current QLoggingCategory object, and won't
- change e.g. the settings of another objects for the same category name.
+ \note Changes only affect the current QLoggingCategory object, and won't
+ change the settings of other objects for the same category name.
+ Use either \l setFilterRules() or \l installFilter() to change the
+ configuration globally.
\note \c QtFatalMsg cannot be changed. It will always return \c true.
-
- Example:
-
- \snippet qtracer/ftracer.cpp 5
*/
void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
{
@@ -244,12 +251,19 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
*/
/*!
- Returns the category \c "default" that is used e.g. by qDebug(), qWarning(),
- qCritical(), qFatal().
+ Returns a pointer to the global category \c "default" that
+ is used e.g. by qDebug(), qWarning(), qCritical(), qFatal().
+
+ \note The returned pointer may be null during destruction of
+ static objects.
+
+ \note Ownership of the category is not transferred, do not
+ \c delete the returned pointer.
+
*/
-QLoggingCategory &QLoggingCategory::defaultCategory()
+QLoggingCategory *QLoggingCategory::defaultCategory()
{
- return *qtDefaultCategory();
+ return qtDefaultCategory();
}
/*!
@@ -272,6 +286,12 @@ QLoggingCategory &QLoggingCategory::defaultCategory()
filter is free to change the respective category configuration with
\l setEnabled().
+ The filter might be called concurrently from different threads, and
+ therefore has to be reentrant.
+
+ Example:
+ \snippet qloggingcategory/main.cpp 21
+
An alternative way of configuring the default filter is via
\l setFilterRules().
*/
@@ -281,7 +301,6 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
return QLoggingRegistry::instance()->installFilter(filter);
}
-
/*!
Configures which categories and message types should be enabled through a
a set of \a rules.
@@ -296,8 +315,13 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
wildcard symbol at the start and/or the end. The optional \c <type> must
be either \c debug, \c warning, \c critical, or \c trace.
- The rules might be ignored if a custom category filter is installed with
- \l installFilter().
+ Example:
+
+ \snippet qloggingcategory/main.cpp 2
+
+ \note The rules might be ignored if a custom category filter is installed
+ with \l installFilter().
+
*/
void QLoggingCategory::setFilterRules(const QString &rules)
{
@@ -380,7 +404,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
The macro expands to code that checks whether
\l QLoggingCategory::isTraceEnabled() evaluates to \c true.
- If so, the stream arguments are processed and sent to the tracers
+ If so, the stream arguments are processed and sent to the \l QTracer objects
registered with the category.
\note Arguments are not processed if trace output for the category is not
@@ -390,7 +414,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\snippet qtracer/ftracer.cpp 6
- \sa qCTraceGuard()
+ \sa qCTraceGuard() QTraceGuard
*/
/*!
@@ -402,11 +426,12 @@ void QLoggingCategory::setFilterRules(const QString &rules)
storage. The guard constructor checks whether
\l QLoggingCategory::isTraceEnabled() evaluates to \c true.
If so, the stream arguments are processed and the \c{start()}
- functions of the tracers registered with the \a category are called.
+ functions of the \l QTracer objects registered with the \a category are
+ called.
The guard destructor also checks whether the category is enabled for
tracing and if so, the \c{end()}
- functions of the tracers registered with the \a category are called.
+ functions of the \l QTracer objects registered with the \a category are called.
\note Arguments are always processed, even if trace output for the
category is disabled. They will, however, in that case not be passed
@@ -416,7 +441,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\snippet qtracer/ftracer.cpp 4
- \sa qCTrace()
+ \sa qCTrace() QTracer
*/
/*!
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index 35da04c8f2..7a119f4937 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -72,7 +72,7 @@ public:
// allows usage of both factory method and variable in qCX macros
QLoggingCategory &operator()() { return *this; }
- static QLoggingCategory &defaultCategory();
+ static QLoggingCategory *defaultCategory();
typedef void (*CategoryFilter)(QLoggingCategory*);
static CategoryFilter installFilter(CategoryFilter);
@@ -92,6 +92,10 @@ private:
bool enabledWarning;
bool enabledCritical;
bool enabledTrace;
+ // reserve space for future use
+ bool placeholder1;
+ bool placeholder2;
+ bool placeholder3;
};
class Q_CORE_EXPORT QTracer
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 6b7c5bde2d..fe5faa2be7 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -1840,12 +1840,21 @@ void QUrl::setUrl(const QString &url, ParsingMode parsingMode)
input. It must also start with an ASCII letter.
The scheme describes the type (or protocol) of the URL. It's
- represented by one or more ASCII characters at the start the URL,
- and is followed by a ':'. The following example shows a URL where
- the scheme is "ftp":
+ represented by one or more ASCII characters at the start the URL.
+
+ A scheme is strictly \l {http://www.ietf.org/rfc/rfc3986.txt} {RFC 3986}-compliant:
+ \tt {scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )}
+
+ The following example shows a URL where the scheme is "ftp":
\image qurl-authority2.png
+ To set the scheme, the following call is used:
+ \code
+ QUrl url;
+ url.setScheme("ftp");
+ \endcode
+
The scheme can also be empty, in which case the URL is interpreted
as relative.
@@ -3327,7 +3336,7 @@ QString QUrl::fromPercentEncoding(const QByteArray &input)
them to \a include.
Unreserved is defined as:
- ALPHA / DIGIT / "-" / "." / "_" / "~"
+ \tt {ALPHA / DIGIT / "-" / "." / "_" / "~"}
\snippet code/src_corelib_io_qurl.cpp 6
*/
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index 7e77b9c251..80fc0319fe 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -304,7 +304,7 @@ static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *b
// we've decoded something; safety-check it
if (uc < min_uc)
return false;
- if (QChar::isSurrogate(uc) || QChar::isNonCharacter(uc) || uc > QChar::LastValidCodePoint)
+ if (QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint)
return false;
if (!QChar::requiresSurrogates(uc)) {
@@ -410,10 +410,9 @@ static int recode(QString &result, const ushort *begin, const ushort *end, QUrl:
const ushort *input = begin;
ushort *output = 0;
+ EncodingAction action = EncodeCharacter;
for ( ; input != end; ++input) {
ushort c;
- EncodingAction action;
-
// try a run where no change is necessary
for ( ; input != end; ++input) {
c = *input;
diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp
index 8dd7f6092f..d81de89628 100644
--- a/src/corelib/json/qjsonarray.cpp
+++ b/src/corelib/json/qjsonarray.cpp
@@ -1089,7 +1089,7 @@ void QJsonArray::compact()
}
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonArray &a)
{
if (!a.a) {
diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h
index 1474ccae41..562e6accd7 100644
--- a/src/corelib/json/qjsonarray.h
+++ b/src/corelib/json/qjsonarray.h
@@ -211,7 +211,7 @@ private:
QJsonPrivate::Array *a;
};
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &);
#endif
diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp
index 4806ac68d6..6e257df39d 100644
--- a/src/corelib/json/qjsondocument.cpp
+++ b/src/corelib/json/qjsondocument.cpp
@@ -303,10 +303,12 @@ QVariant QJsonDocument::toVariant() const
\sa fromJson()
*/
+#ifndef QT_JSON_READONLY
QByteArray QJsonDocument::toJson() const
{
return toJson(Indented);
}
+#endif
/*!
\enum QJsonDocument::JsonFormat
@@ -338,6 +340,7 @@ QByteArray QJsonDocument::toJson() const
\sa fromJson(), JsonFormat
*/
+#ifndef QT_JSON_READONLY
QByteArray QJsonDocument::toJson(JsonFormat format) const
{
if (!d)
@@ -352,6 +355,7 @@ QByteArray QJsonDocument::toJson(JsonFormat format) const
return json;
}
+#endif
/*!
Parses a UTF-8 encoded JSON document and creates a QJsonDocument
@@ -562,7 +566,7 @@ bool QJsonDocument::isNull() const
return (d == 0);
}
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonDocument &o)
{
if (!o.d) {
diff --git a/src/corelib/json/qjsondocument.h b/src/corelib/json/qjsondocument.h
index 0354262e2c..ea42d76b20 100644
--- a/src/corelib/json/qjsondocument.h
+++ b/src/corelib/json/qjsondocument.h
@@ -117,7 +117,7 @@ public:
#ifdef Q_QDOC
QByteArray toJson(JsonFormat format = Indented) const;
-#else
+#elif !defined(QT_JSON_READONLY)
QByteArray toJson() const; //### Merge in Qt6
QByteArray toJson(JsonFormat format) const;
#endif
@@ -148,7 +148,7 @@ private:
QJsonPrivate::Data *d;
};
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonDocument &);
#endif
diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp
index 362d01384e..afc0d5f71f 100644
--- a/src/corelib/json/qjsonobject.cpp
+++ b/src/corelib/json/qjsonobject.cpp
@@ -1036,7 +1036,7 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val)
insert(e->key(), val);
}
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonObject &o)
{
if (!o.o) {
diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h
index 8226b614b4..ad3184b1f2 100644
--- a/src/corelib/json/qjsonobject.h
+++ b/src/corelib/json/qjsonobject.h
@@ -206,7 +206,7 @@ private:
QJsonPrivate::Object *o;
};
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
#endif
diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp
index 8721f06064..516c53775c 100644
--- a/src/corelib/json/qjsonparser.cpp
+++ b/src/corelib/json/qjsonparser.cpp
@@ -853,7 +853,7 @@ static inline bool scanUtf8Char(const char *&json, const char *end, uint *result
uc = (uc << 6) | (ch & 0x3f);
}
- if (uc < min_uc || QChar::isNonCharacter(uc) ||
+ if (uc < min_uc ||
QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) {
return false;
}
diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp
index 8aa1f654c6..0a603b958a 100644
--- a/src/corelib/json/qjsonvalue.cpp
+++ b/src/corelib/json/qjsonvalue.cpp
@@ -661,7 +661,7 @@ QJsonValue QJsonValueRef::toValue() const
return o->valueAt(index);
}
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonValue &o)
{
switch (o.t) {
diff --git a/src/corelib/json/qjsonvalue.h b/src/corelib/json/qjsonvalue.h
index b18bbde0f7..c0ecdd2b61 100644
--- a/src/corelib/json/qjsonvalue.h
+++ b/src/corelib/json/qjsonvalue.h
@@ -179,7 +179,7 @@ private:
uint index : 31;
};
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
#endif
diff --git a/src/corelib/json/qjsonwriter.cpp b/src/corelib/json/qjsonwriter.cpp
index 8426b351f6..86cca4bb26 100644
--- a/src/corelib/json/qjsonwriter.cpp
+++ b/src/corelib/json/qjsonwriter.cpp
@@ -138,13 +138,6 @@ static QByteArray escapedString(const QString &s)
if (u < 0x0800) {
*cursor++ = 0xc0 | ((uchar) (u >> 6));
} else {
- // is it one of the Unicode non-characters?
- if (QChar::isNonCharacter(u)) {
- *cursor++ = replacement;
- ++ch;
- continue;
- }
-
if (QChar::requiresSurrogates(u)) {
*cursor++ = 0xf0 | ((uchar) (u >> 18));
*cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index 2ca0a7d0b0..e974c4d226 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -249,7 +249,7 @@ public:
TouchEnd = 196,
#ifndef QT_NO_GESTURES
- NativeGesture = 197, // Internal for platform gesture support
+ NativeGesture = 197, // QtGui native gesture
#endif
RequestSoftwareInputPanel = 199,
CloseSoftwareInputPanel = 200,
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
index d9e38b68b2..b9137ec139 100644
--- a/src/corelib/kernel/qeventdispatcher_blackberry.cpp
+++ b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Research In Motion
+** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -78,6 +78,19 @@ private:
int outerChannel;
};
+class BBScopedLoopLevelCounter
+{
+ QEventDispatcherBlackberryPrivate *d;
+
+public:
+ inline BBScopedLoopLevelCounter(QEventDispatcherBlackberryPrivate *p)
+ : d(p)
+ { ++d->loop_level; }
+
+ inline ~BBScopedLoopLevelCounter()
+ { --d->loop_level; }
+};
+
struct bpsIOHandlerData
{
bpsIOHandlerData()
@@ -147,7 +160,8 @@ static int bpsIOHandler(int fd, int io_events, void *data)
}
QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate()
- : ioData(new bpsIOHandlerData)
+ : loop_level(0)
+ , ioData(new bpsIOHandlerData)
{
// prepare to use BPS
int result = bps_initialize();
@@ -156,6 +170,11 @@ QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate()
bps_channel = bps_channel_get_active();
+ if (bps_channel_create(&holding_channel, 0) != BPS_SUCCESS) {
+ qWarning("QEventDispatcherBlackberry: bps_channel_create failed");
+ holding_channel = -1;
+ }
+
// get domain for IO ready and wake up events - ignoring race condition here for now
if (bpsUnblockDomain == -1) {
bpsUnblockDomain = bps_register_domain();
@@ -166,6 +185,11 @@ QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate()
QEventDispatcherBlackberryPrivate::~QEventDispatcherBlackberryPrivate()
{
+ if ((holding_channel != -1) &&
+ (bps_channel_destroy(holding_channel) != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_channel_destroy failed");
+ }
+
// we're done using BPS
bps_shutdown();
}
@@ -280,11 +304,21 @@ static inline int timespecToMillisecs(const timespec &tv)
return (tv.tv_sec * 1000) + (tv.tv_nsec / 1000000);
}
+static inline void destroyHeldBpsEvent(int holding_channel)
+{
+ // Switch to the holding channel and use bps_get_event() to trigger its destruction. We
+ // don't care about the return value from this call to bps_get_event().
+ BpsChannelScopeSwitcher holdingChannelSwitcher(holding_channel);
+ bps_event_t *held_event = 0;
+ (void)bps_get_event(&held_event, 0);
+ }
+
int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
timespec *timeout)
{
Q_UNUSED(nfds);
Q_D(QEventDispatcherBlackberry);
+ const BBScopedLoopLevelCounter bbLoopCounter(d);
BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
@@ -307,6 +341,31 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef
bps_event_t *event = 0;
unsigned int eventCount = 0;
+ // If an event handler called through filterEvent() starts a nested event loop by creating a
+ // new QEventLoop, we will recursively enter this function again. However, each time
+ // bps_get_event() is called, it destroys the last event it handed out before returning the
+ // next event. We don't want it to destroy the event that triggered the nested event loop,
+ // since there may still be more handlers that need to get that event, once the nested event
+ // loop is done and control returns to the outer event loop.
+ //
+ // So we move an event to a holding channel, which takes ownership of the event. Putting
+ // the event on our own channel allows us to manage when it is destroyed, keeping it alive
+ // until we know we are done with it. Each recursive call of this function needs to have
+ // it's own holding channel, since a channel is a queue, not a stack.
+ //
+ // However, a recursive call into this function happens very rarely compared to the many
+ // times this function is called. We don't want to create a holding channel for each time
+ // this function is called, only when it is called recursively. Thus we have the instance
+ // variable d->holding_channel to use in the common case. We keep track of recursive calls
+ // with d->loop_level. If we are in a recursive call, then we create a new holding channel
+ // for this run.
+ int holding_channel = d->holding_channel;
+ if ((d->loop_level > 1) &&
+ Q_UNLIKELY(bps_channel_create(&holding_channel, 0) != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_channel_create failed");
+ holding_channel = -1;
+ }
+
// Convert timeout to milliseconds
int timeoutTotal = -1;
if (timeout)
@@ -331,6 +390,11 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef
emit awake();
filterNativeEvent(QByteArrayLiteral("bps_event_t"), static_cast<void*>(event), 0);
emit aboutToBlock();
+
+ if (Q_LIKELY(holding_channel != -1)) {
+ // We are now done with this BPS event. Destroy it.
+ destroyHeldBpsEvent(holding_channel);
+ }
}
// Update the timeout
@@ -370,6 +434,12 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef
if (bps_event_get_domain(event) == bpsUnblockDomain) {
timeoutTotal = 0; // in order to immediately drain the event queue of native events
event = 0; // (especially touch move events) we don't break out here
+ } else {
+ // Move the event to our holding channel so we can manage when it is destroyed.
+ if (Q_LIKELY(holding_channel != 1) &&
+ Q_UNLIKELY(bps_channel_push_event(holding_channel, event) != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_channel_push_event failed");
+ }
}
++eventCount;
@@ -379,12 +449,26 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef
const unsigned int maximumEventCount = 12;
if (Q_UNLIKELY((eventCount > maximumEventCount && timeoutLeft == 0)
|| !QElapsedTimer::isMonotonic())) {
- if (event)
+ if (event) {
filterNativeEvent(QByteArrayLiteral("bps_event_t"), static_cast<void*>(event), 0);
+
+ if (Q_LIKELY(holding_channel != -1)) {
+ // We are now done with this BPS event. Destroy it.
+ destroyHeldBpsEvent(holding_channel);
+ }
+ }
break;
}
}
+ // If this was a recursive call into this function, a new holding channel was created for
+ // this run, so destroy it now.
+ if ((holding_channel != d->holding_channel) &&
+ Q_LIKELY(holding_channel != -1) &&
+ Q_UNLIKELY(bps_channel_destroy(holding_channel) != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_channel_destroy failed");
+ }
+
// the number of bits set in the file sets
return d->ioData->count;
}
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry_p.h b/src/corelib/kernel/qeventdispatcher_blackberry_p.h
index 5a4c3a9dcd..1764c244d8 100644
--- a/src/corelib/kernel/qeventdispatcher_blackberry_p.h
+++ b/src/corelib/kernel/qeventdispatcher_blackberry_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Research In Motion
+** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -95,6 +95,8 @@ public:
int processThreadWakeUp(int nsel);
int bps_channel;
+ int holding_channel;
+ int loop_level;
QScopedPointer<bpsIOHandlerData> ioData;
};
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 20e13a050f..5754af42ac 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1892,6 +1892,7 @@ void QVariant::load(QDataStream &s)
void QVariant::save(QDataStream &s) const
{
quint32 typeId = type();
+ bool fakeUserType = false;
if (s.version() < QDataStream::Qt_4_0) {
int i;
for (i = 0; i <= MapFromThreeCount - 1; ++i) {
@@ -1916,12 +1917,16 @@ void QVariant::save(QDataStream &s) const
} else if (typeId >= QMetaType::QKeySequence && typeId <= QMetaType::QQuaternion) {
// and as a result these types received lower ids too
typeId +=1;
+ } else if (typeId == QMetaType::QPolygonF) {
+ // This existed in Qt 4 only as a custom type
+ typeId = 127;
+ fakeUserType = true;
}
}
s << typeId;
if (s.version() >= QDataStream::Qt_4_2)
s << qint8(d.is_null);
- if (d.type >= QVariant::UserType) {
+ if (d.type >= QVariant::UserType || fakeUserType) {
s << QMetaType::typeName(userType());
}
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index d33cc90127..adad4b81a1 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -206,20 +206,20 @@ QThreadPrivate::~QThreadPrivate()
There will not be any event loop running in the thread unless you call
exec().
- It is important to remember that a QThread object usually lives
- in the thread where it was created, not in the thread that it
- manages. This oft-overlooked detail means that a QThread's slots
- will be executed in the context of its home thread, not in the
- context of the thread it is managing. For this reason,
- implementing new slots in a QThread subclass is error-prone and
- discouraged.
+ It is important to remember that a QThread instance \l{QObject#Thread
+ Affinity}{lives in} the old thread that instantiated it, not in the
+ new thread that calls run(). This means that all of QThread's queued
+ slots will execute in the old thread. Thus, a developer who wishes to
+ invoke slots in the new thread must use the worker-object approach; new
+ slots should not be implemented directly into a subclassed QThread.
- \note If you interact with an object, using any technique other
- than queued signal/slot connections (e.g. direct function calls),
- then the usual multithreading precautions need to be taken.
+ When subclassing QThread, keep in mind that the constructor executes in
+ the old thread while run() executes in the new thread. If a member
+ variable is accessed from both functions, then the variable is accessed
+ from two different threads. Check that it is safe to do so.
- \note It is not possible to change the thread affinity of GUI
- objects; they must remain in the main thread.
+ \note Care must be taken when interacting with objects across different
+ threads. See \l{Synchronizing Threads} for details.
\section1 Managing threads
@@ -264,7 +264,7 @@ QThreadPrivate::~QThreadPrivate()
\l{Mandelbrot Example}, as that is the name of the QThread subclass).
Note that this is currently not available with release builds on Windows.
- \sa {Thread Support in Qt}, QThreadStorage, QMutex, QSemaphore, QWaitCondition,
+ \sa {Thread Support in Qt}, QThreadStorage, {Synchronizing Threads}
{Mandelbrot Example}, {Semaphores Example}, {Wait Conditions Example}
*/
@@ -491,7 +491,8 @@ uint QThread::stackSize() const
that was passed to exit(). The value returned is 0 if exit() is called via
quit().
- It is necessary to call this function to start event handling.
+ This function is meant to be called from within run(). It is necessary to
+ call this function to start event handling.
\sa quit(), exit()
*/
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index 4eb7a170dc..cd389470a4 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -764,7 +764,7 @@
\relates <QtAlgorithms>
\since 5.2
- Returns the number of bits set in \a v. This number also called
+ Returns the number of bits set in \a v. This number is also called
the Hamming Weight of \a v.
*/
diff --git a/src/corelib/tools/qcollator_posix.cpp b/src/corelib/tools/qcollator_posix.cpp
index c6e589c174..a43618dcf1 100644
--- a/src/corelib/tools/qcollator_posix.cpp
+++ b/src/corelib/tools/qcollator_posix.cpp
@@ -44,6 +44,7 @@
#include "qstring.h"
#include <cstring>
+#include <cwchar>
QT_BEGIN_NAMESPACE
@@ -141,7 +142,7 @@ bool QCollatorSortKey::operator<(const QCollatorSortKey &otherKey) const
int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
{
- return wcscmp(d->m_key.constData(),
+ return std::wcscmp(d->m_key.constData(),
otherKey.d->m_key.constData());
}
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 56f715e5c8..6620c55a0f 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -894,7 +894,7 @@ QString QDate::toString(Qt::DateFormat format) const
case Qt::DefaultLocaleLongDate:
return QLocale().toString(*this, QLocale::LongFormat);
case Qt::RFC2822Date:
- return toString(QStringLiteral("dd MMM yyyy"));
+ return QLocale::c().toString(*this, QStringLiteral("dd MMM yyyy"));
default:
#ifndef QT_NO_TEXTDATE
case Qt::TextDate:
@@ -1641,9 +1641,6 @@ QString QTime::toString(Qt::DateFormat format) const
case Qt::DefaultLocaleLongDate:
return QLocale().toString(*this, QLocale::LongFormat);
case Qt::RFC2822Date:
- return QString::fromLatin1("%1:%2:%3").arg(hour(), 2, 10, QLatin1Char('0'))
- .arg(minute(), 2, 10, QLatin1Char('0'))
- .arg(second(), 2, 10, QLatin1Char('0'));
case Qt::ISODate:
case Qt::TextDate:
default:
@@ -3551,27 +3548,8 @@ QString QDateTime::toString(Qt::DateFormat format) const
case Qt::DefaultLocaleLongDate:
return QLocale().toString(*this, QLocale::LongFormat);
case Qt::RFC2822Date: {
- buf = toString(QStringLiteral("dd MMM yyyy hh:mm:ss "));
-
- int utcOffset = d->m_offsetFromUtc;
- if (timeSpec() == Qt::LocalTime) {
- QDateTime utc = toUTC();
- utc.setTimeSpec(timeSpec());
- utcOffset = utc.secsTo(*this);
- }
-
- const int offset = qAbs(utcOffset);
- buf += QLatin1Char((offset == utcOffset) ? '+' : '-');
-
- const int hour = offset / 3600;
- if (hour < 10)
- buf += QLatin1Char('0');
- buf += QString::number(hour);
-
- const int min = (offset - (hour * 3600)) / 60;
- if (min < 10)
- buf += QLatin1Char('0');
- buf += QString::number(min);
+ buf = QLocale::c().toString(*this, QStringLiteral("dd MMM yyyy hh:mm:ss "));
+ buf += toOffsetString(Qt::TextDate, d->m_offsetFromUtc);
return buf;
}
default:
@@ -3924,7 +3902,16 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const
QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
{
- return fromMSecsSinceEpoch(toMSecsSinceEpoch(), spec, 0);
+ if (d->m_spec == spec && (spec == Qt::UTC || spec == Qt::LocalTime))
+ return *this;
+
+ if (!isValid()) {
+ QDateTime ret = *this;
+ ret.setTimeSpec(spec);
+ return ret;
+ }
+
+ return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), spec, 0);
}
/*!
@@ -3942,7 +3929,16 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
{
- return fromMSecsSinceEpoch(toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds);
+ if (d->m_spec == Qt::OffsetFromUTC && d->m_offsetFromUtc == offsetSeconds)
+ return *this;
+
+ if (!isValid()) {
+ QDateTime ret = *this;
+ ret.setOffsetFromUtc(offsetSeconds);
+ return ret;
+ }
+
+ return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds);
}
#ifndef QT_BOOTSTRAPPED
@@ -3956,7 +3952,16 @@ QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const
{
- return fromMSecsSinceEpoch(toMSecsSinceEpoch(), timeZone);
+ if (d->m_spec == Qt::TimeZone && d->m_timeZone == timeZone)
+ return *this;
+
+ if (!isValid()) {
+ QDateTime ret = *this;
+ ret.setTimeZone(timeZone);
+ return ret;
+ }
+
+ return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), timeZone);
}
#endif // QT_BOOTSTRAPPED
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 7f6feaf8a0..f14fac00b8 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -1594,6 +1594,11 @@ void QHashData::checkSanity()
need to keep iterators over a long period of time, we recommend
that you use QMap rather than QHash.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QHash::const_iterator, QMutableHashIterator
*/
@@ -1791,6 +1796,11 @@ void QHashData::checkSanity()
internal data structure. If you need to keep iterators over a long
period of time, we recommend that you use QMap rather than QHash.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QHash::iterator, QHashIterator
*/
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
index 28319f3fda..e967163b8b 100644
--- a/src/corelib/tools/qlinkedlist.cpp
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -691,9 +691,12 @@ const QLinkedListData QLinkedListData::shared_null = {
Multiple iterators can be used on the same list. If you add items
to the list, existing iterators will remain valid. If you remove
items from the list, iterators that point to the removed items
- will become dangling iterators. However, because of how \l{implicit
- sharing} works, you must not take a copy of a container while
- iterators are active on that container.
+ will become dangling iterators.
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
\sa QLinkedList::const_iterator, QMutableLinkedListIterator
*/
@@ -910,6 +913,11 @@ const QLinkedListData QLinkedListData::shared_null = {
items from the list, iterators that point to the removed items
will become dangling iterators.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QLinkedList::iterator, QLinkedListIterator
*/
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 5bced19404..0811c3793e 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -647,7 +647,10 @@ void **QListData::erase(void **xi)
\a i must be a valid index position in the list (i.e., 0 <= \a i <
size()).
- This function is very fast (\l{constant time}).
+ If this function is called on a list that is currently being shared, it
+ will trigger a copy of all elements. Otherwise, this function runs in
+ \l{constant time}. If you do not want to modify the list you should use
+ QList::at().
\sa at(), value()
*/
@@ -656,7 +659,7 @@ void **QListData::erase(void **xi)
\overload
- Same as at().
+ Same as at(). This function runs in \l{constant time}.
*/
/*! \fn QList::reserve(int alloc)
@@ -681,10 +684,10 @@ void **QListData::erase(void **xi)
This is the same as list.insert(size(), \a value).
- This operation is typically very fast (\l{constant time}),
- because QList preallocates extra space on both sides of its
- internal buffer to allow for fast growth at both ends of the
- list.
+ If this list is not shared, this operation is typically
+ very fast (amortized \l{constant time}), because QList
+ preallocates extra space on both sides of its internal
+ buffer to allow for fast growth at both ends of the list.
\sa operator<<(), prepend(), insert()
*/
@@ -709,8 +712,9 @@ void **QListData::erase(void **xi)
This is the same as list.insert(0, \a value).
- This operation is usually very fast (\l{constant time}), because
- QList preallocates extra space on both sides of its internal
+ If this list is not shared, this operation is typically
+ very fast (amortized \l{constant time}), because QList
+ preallocates extra space on both sides of its internal
buffer to allow for fast growth at both ends of the list.
\sa append(), insert()
@@ -802,7 +806,7 @@ void **QListData::erase(void **xi)
same as takeAt(0). This function assumes the list is not empty. To
avoid failure, call isEmpty() before calling this function.
- This operation takes \l{constant time}.
+ If this list is not shared, this operation takes \l{constant time}.
If you don't use the return value, removeFirst() is more
efficient.
@@ -817,7 +821,7 @@ void **QListData::erase(void **xi)
not empty. To avoid failure, call isEmpty() before calling this
function.
- This operation takes \l{constant time}.
+ If this list is not shared, this operation takes \l{constant time}.
If you don't use the return value, removeLast() is more
efficient.
@@ -1288,6 +1292,11 @@ void **QListData::erase(void **xi)
iterators over a long period of time, we recommend that you use
QLinkedList rather than QList.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QList::const_iterator, QMutableListIterator
*/
@@ -1538,6 +1547,11 @@ void **QListData::erase(void **xi)
iterators over a long period of time, we recommend that you use
QLinkedList rather than QList.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QList::iterator, QListIterator
*/
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index b795bbc86e..333ce72849 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -639,7 +639,7 @@ inline void QList<T>::move(int from, int to)
template<typename T>
Q_OUTOFLINE_TEMPLATE QList<T> QList<T>::mid(int pos, int alength) const
{
- if (alength < 0 || pos + alength > size())
+ if (alength < 0 || pos > size() - alength)
alength = size() - pos;
if (pos == 0 && alength == size())
return *this;
diff --git a/src/corelib/tools/qlocale_mac.mm b/src/corelib/tools/qlocale_mac.mm
index deb5d5eb1d..92dfba162c 100644
--- a/src/corelib/tools/qlocale_mac.mm
+++ b/src/corelib/tools/qlocale_mac.mm
@@ -193,7 +193,7 @@ static QString macToQtFormat(const QString &sys_fmt)
// Qt does not support the following options
case 'G': // Era (1..5): 4 = long, 1..3 = short, 5 = narrow
case 'Y': // Year of Week (1..n): 1..n = padded number
- case 'U': // Cyclic Yar Name (1..5): 4 = long, 1..3 = short, 5 = narrow
+ case 'U': // Cyclic Year Name (1..5): 4 = long, 1..3 = short, 5 = narrow
case 'Q': // Quarter (1..4): 4 = long, 3 = short, 1..2 = padded number
case 'q': // Standalone Quarter (1..4): 4 = long, 3 = short, 1..2 = padded number
case 'w': // Week of Year (1..2): 1..2 = padded number
@@ -257,7 +257,7 @@ static QString macToQtFormat(const QString &sys_fmt)
case 's': // Seconds (1..2): 1..2 = padded number
result += QString(repeat, c);
break;
- case 'S': // Fractional second (1..n): 1..n = tuncates to decimal places
+ case 'S': // Fractional second (1..n): 1..n = truncates to decimal places
// Qt uses msecs either unpadded or padded to 3 places
if (repeat < 3)
result += QLatin1Char('z');
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index ab9b1d23ab..9aebbb7b3c 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -395,7 +395,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
differences are:
\list
- \li QHash provides faster lookups than QMap. (See \l{Algorithmic
+ \li QHash provides average faster lookups than QMap. (See \l{Algorithmic
Complexity} for details.)
\li When iterating over a QHash, the items are arbitrarily ordered.
With QMap, the items are always sorted by key.
@@ -901,6 +901,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
Returns a reference to the smallest key in the map.
This function assumes that the map is not empty.
+ This executes in \l{constant time}.
+
\sa lastKey(), first(), isEmpty()
*/
@@ -909,6 +911,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
Returns a reference to the largest key in the map.
This function assumes that the map is not empty.
+ This executes in \l{logarithmic time}.
+
\sa firstKey(), last(), isEmpty()
*/
@@ -917,6 +921,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
Returns a reference to the first value in the map, that is the value mapped
to the smallest key. This function assumes that the map is not empty.
+ When unshared (or const version is called), this executes in \l{constant time}.
+
\sa last(), firstKey(), isEmpty()
*/
@@ -930,6 +936,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
Returns a reference to the last value in the map, that is the value mapped
to the largest key. This function assumes that the map is not empty.
+ When unshared (or const version is called), this executes in \l{logarithmic time}.
+
\sa first(), lastKey(), isEmpty()
*/
@@ -1057,8 +1065,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
If there are multiple items with the key \a key, then exactly one of them
is replaced with \a value.
+ If the hint is correct and the map is unshared, the insert executes in amortized \l{constant time}.
+
When creating a map from sorted data inserting the largest key first with constBegin()
- is faster than inserting in sorted order with constEnd()
+ is faster than inserting in sorted order with constEnd(), since constEnd() - 1 (which is needed
+ to check if the hint is valid) needs \l{logarithmic time}.
\b {Note:} Be careful with the hint. Providing an iterator from an older shared instance might
crash but there is also a risk that it will silently corrupt both the map and the \a pos map.
@@ -1215,6 +1226,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
items from the map, iterators that point to the removed items
will become dangling iterators.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QMap::const_iterator, QMutableMapIterator
*/
@@ -1433,6 +1449,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
items from the map, iterators that point to the removed items
will become dangling iterators.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QMap::iterator, QMapIterator
*/
diff --git a/src/corelib/tools/qmargins.h b/src/corelib/tools/qmargins.h
index 0d68be961e..ad5e94cefe 100644
--- a/src/corelib/tools/qmargins.h
+++ b/src/corelib/tools/qmargins.h
@@ -242,6 +242,24 @@ inline QMargins &QMargins::operator-=(const QMargins &margins)
return *this = *this - margins;
}
+inline QMargins &QMargins::operator+=(int margin)
+{
+ m_left += margin;
+ m_top += margin;
+ m_right += margin;
+ m_bottom += margin;
+ return *this;
+}
+
+inline QMargins &QMargins::operator-=(int margin)
+{
+ m_left -= margin;
+ m_top -= margin;
+ m_right -= margin;
+ m_bottom -= margin;
+ return *this;
+}
+
inline QMargins &QMargins::operator*=(int factor)
{
return *this = *this * factor;
diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc
index a0bc206014..e66a59a09c 100644
--- a/src/corelib/tools/qset.qdoc
+++ b/src/corelib/tools/qset.qdoc
@@ -643,8 +643,12 @@
\snippet code/doc_src_qset.cpp 10
- Multiple iterators can be used on the same set. However, you may
- not attempt to modify the container while iterating on it.
+ Multiple iterators can be used on the same set.
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
\sa QSet::const_iterator, QMutableSetIterator
*/
@@ -682,8 +686,10 @@
\snippet code/doc_src_qset.cpp 12
- Multiple iterators can be used on the same set. However, you may
- not attempt to modify the container while iterating on it.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
\sa QSet::iterator, QSetIterator
*/
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 31acc95ad3..92556ce50a 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -9803,8 +9803,8 @@ QString QString::toHtmlEscaped() const
if (attribute.name() == QLatin1String("http-contents-length")) //...
\endcode
- \note There some restrictions when using the MSVC 2010 or 2012 compilers. The example snippets provided here
- fail to compile with them.
+ \note There are some restrictions when using the MSVC 2010 or 2012 compilers. The example snippets
+ provided here fail to compile with them.
\list
\li Concatenated string literals cannot be used with QStringLiteral.
\code
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 62b8f5f7b6..4bf19178fa 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -883,9 +883,9 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
while (olsenId.isEmpty() && !ts.atEnd() && ts.status() == QTextStream::Ok) {
line = ts.readLine();
if (line.left(5) == QStringLiteral("ZONE=")) {
- olsenId = line.mid(6, line.size() - 2).toUtf8();
+ olsenId = line.mid(6, line.size() - 7).toUtf8();
} else if (line.left(9) == QStringLiteral("TIMEZONE=")) {
- olsenId = line.mid(6, line.size() - 2).toUtf8();
+ olsenId = line.mid(10, line.size() - 11).toUtf8();
}
}
}
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
index 69b656c191..b9281c6915 100644
--- a/src/corelib/tools/qvector.cpp
+++ b/src/corelib/tools/qvector.cpp
@@ -562,6 +562,44 @@
\sa insert(), replace(), fill()
*/
+/*! \fn void QVector::removeAt(int i)
+ \since 5.2
+
+ Equivalent to
+ \code
+ remove(i);
+ \endcode
+
+ Provided for compatibility with QList.
+
+ \sa remove(int), QList::removeAt(int)
+*/
+
+/*! \fn int QVector::length() const
+ \since 5.2
+
+ Same as size() and count().
+
+ Provided for compatibility with QList.
+
+ \sa size(), count(), QList::length()
+*/
+
+/*! \fn T QVector::takeAt(int i)
+ \since 5.2
+
+ Equivalent to
+ \code
+ T t = at(i);
+ remove(i);
+ return t;
+ \endcode
+
+ Provided for compatibility with QList.
+
+ \sa takeFirst(), takeLast(), QList::takeAt(int)
+*/
+
/*! \fn void QVector::removeFirst()
\since 5.1
Removes the first item in the vector. Calling this function is
@@ -919,6 +957,11 @@
iterators}. The STL-style non-const iterator is simply a typedef
for "T *" (pointer to T).
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QVector::begin(), QVector::end(), QVector::const_iterator, QMutableVectorIterator
*/
@@ -931,6 +974,11 @@
iterators}. The STL-style const iterator is simply a typedef for
"const T *" (pointer to const T).
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QVector::constBegin(), QVector::constEnd(), QVector::iterator, QVectorIterator
*/
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 3d86440fcd..f56511edbf 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -152,6 +152,11 @@ public:
bool contains(const T &t) const;
int count(const T &t) const;
+ // QList compatibility
+ void removeAt(int i) { remove(i); }
+ int length() const { return size(); }
+ T takeAt(int i) { T t = at(i); remove(i); return t; }
+
// STL-style
typedef typename Data::iterator iterator;
typedef typename Data::const_iterator const_iterator;
@@ -187,7 +192,7 @@ public:
inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); }
inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }
inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; }
- QVector<T> mid(int pos, int length = -1) const;
+ QVector<T> mid(int pos, int len = -1) const;
T value(int i) const;
T value(int i, const T &defaultValue) const;
@@ -772,17 +777,17 @@ int QVector<T>::count(const T &t) const
}
template <typename T>
-Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int length) const
+Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int len) const
{
- if (length < 0)
- length = size() - pos;
- if (pos == 0 && length == size())
+ if (len < 0)
+ len = size() - pos;
+ if (pos == 0 && len == size())
return *this;
- if (pos + length > size())
- length = size() - pos;
+ if (pos + len > size())
+ len = size() - pos;
QVector<T> copy;
- copy.reserve(length);
- for (int i = pos; i < pos + length; ++i)
+ copy.reserve(len);
+ for (int i = pos; i < pos + len; ++i)
copy += at(i);
return copy;
}
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index ff3e910883..d5b0af550e 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -589,7 +589,7 @@ public:
virtual QString imageDescription() const = 0;
virtual QSize imageSize() const = 0;
- virtual QRect imagePosition() const = 0;
+ virtual QPoint imagePosition() const = 0;
};
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 15ed79c981..816419d155 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -2281,6 +2281,121 @@ QTabletEvent::~QTabletEvent()
#endif // QT_NO_TABLETEVENT
+/*!
+ \class QNativeGestureEvent
+ \since 5.2
+ \brief The QNativeGestureEvent class contains parameters that describe a gesture event.
+ \inmodule QtGui
+ \ingroup events
+
+ Native gesture events are generated by the operating system, typically by
+ interpreting touch events. Gesture events are high-level events such
+ as zoom or rotate.
+
+ \table
+ \header
+ \li Event Type
+ \li Description
+ \li Touch equence
+ \row
+ \li Qt::ZoomNativeGesture
+ \li Magnification delta in percent.
+ \li OS X: Two-finger pinch.
+ \row
+ \li Qt::SmartZoomNativeGesture
+ \li Boolean magnification state.
+ \li OS X: Two-finger douple tap (trackpad) / One-finger douple tap (magic mouse).
+ \row
+ \li Qt::RotateNativeGesture
+ \li Rotation delta in degrees.
+ \li OS X: Two-finger rotate.
+ \endtable
+
+
+ In addition, BeginNativeGesture and EndNativeGesture are sent before and after
+ gesture event streams:
+
+ BeginNativeGesture
+ ZoomNativeGesture
+ ZoomNativeGesture
+ ZoomNativeGesture
+ EndNativeGesture
+
+ \sa Qt::NativeGestureType, QGestureEvent
+*/
+
+/*!
+ Constructs a native gesture event of type \a type.
+
+ The points \a localPos, \a windowPos and \a screenPos specify the
+ gesture position relative to the receiving widget or item,
+ window, and screen, respectively.
+
+ \a realValue is the OS X event parameter, \a sequenceId and \a intValue are the Windows event parameters.
+*/
+QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos,
+ const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue)
+ : QInputEvent(QEvent::NativeGesture), mGestureType(type),
+ mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue),
+ mSequenceId(sequenceId), mIntValue(intValue)
+{ }
+
+/*!
+ \fn QNativeGestureEvent::gestureType() const
+ \since 5.2
+
+ Returns the gesture type.
+*/
+
+/*!
+ \fn QNativeGestureEvent::value() const
+ \since 5.2
+
+ Returns the gesture value. The value should be interpreted based on the
+ gesture type. For example, a Zoom gesture provides a scale factor while a Rotate
+ gesture provides a rotation delta.
+
+ \sa QNativeGestureEvent, gestureType()
+*/
+
+/*!
+ \fn QPoint QNativeGestureEvent::globalPos() const
+ \since 5.2
+
+ Returns the position of the gesture as a QPointF in screen coordinates
+*/
+
+/*!
+ \fn QPoint QNativeGestureEvent::pos() const
+ \since 5.2
+
+ Returns the position of the mouse cursor, relative to the widget
+ or item that received the event.
+*/
+
+/*!
+ \fn QPointF QNativeGestureEvent::localPos() const
+ \since 5.2
+
+ Returns the position of the gesture as a QPointF, relative to the
+ widget or item that received the event.
+*/
+
+/*!
+ \fn QPointF QNativeGestureEvent::screenPos() const
+ \since 5.2
+
+ Returns the position of the gesture as a QPointF in screen coordinates.
+*/
+
+/*!
+ \fn QPointF QNativeGestureEvent::windowPos() const
+ \since 5.2
+
+ Returns the position of the gesture as a QPointF, relative to the
+ window that received the event.
+*/
+
#ifndef QT_NO_DRAGANDDROP
/*!
Creates a QDragMoveEvent of the required \a type indicating
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 7d05e1c5a9..b6b1e0c76b 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -270,6 +270,34 @@ protected:
};
#endif // QT_NO_TABLETEVENT
+#ifndef QT_NO_GESTURES
+class Q_GUI_EXPORT QNativeGestureEvent : public QInputEvent
+{
+public:
+ QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos,
+ const QPointF &screenPos, qreal value, ulong sequenceId, quint64 intArgument);
+ Qt::NativeGestureType gestureType() const { return mGestureType; }
+ qreal value() const { return mRealValue; }
+
+#ifndef QT_NO_INTEGER_EVENT_COORDINATES
+ inline const QPoint pos() const { return mLocalPos.toPoint(); }
+ inline const QPoint globalPos() const { return mScreenPos.toPoint(); }
+#endif
+ const QPointF &localPos() const { return mLocalPos; }
+ const QPointF &windowPos() const { return mWindowPos; }
+ const QPointF &screenPos() const { return mScreenPos; }
+
+protected:
+ Qt::NativeGestureType mGestureType;
+ QPointF mLocalPos;
+ QPointF mWindowPos;
+ QPointF mScreenPos;
+ qreal mRealValue;
+ ulong mSequenceId;
+ quint64 mIntValue;
+};
+#endif // QT_NO_GESTURES
+
class Q_GUI_EXPORT QKeyEvent : public QInputEvent
{
public:
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 591e83c0bd..db655bd2ad 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1477,6 +1477,10 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
QGuiApplicationPrivate::processTabletLeaveProximityEvent(
static_cast<QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *>(e));
break;
+ case QWindowSystemInterfacePrivate::Gesture:
+ QGuiApplicationPrivate::processGestureEvent(
+ static_cast<QWindowSystemInterfacePrivate::GestureEvent *>(e));
+ break;
case QWindowSystemInterfacePrivate::PlatformPanel:
QGuiApplicationPrivate::processPlatformPanelEvent(
static_cast<QWindowSystemInterfacePrivate::PlatformPanelEvent *>(e));
@@ -1493,6 +1497,7 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
#endif
case QWindowSystemInterfacePrivate::EnterWhatsThisMode:
QGuiApplication::postEvent(QGuiApplication::instance(), new QEvent(QEvent::EnterWhatsThisMode));
+ break;
default:
qWarning() << "Unknown user input event type:" << e->type;
break;
@@ -1570,9 +1575,11 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
ev.setTimestamp(e->timestamp);
setMouseEventSource(&ev, e->source);
#ifndef QT_NO_CURSOR
- if (const QScreen *screen = window->screen())
- if (QPlatformCursor *cursor = screen->handle()->cursor())
- cursor->pointerEvent(ev);
+ if (!e->synthetic) {
+ if (const QScreen *screen = window->screen())
+ if (QPlatformCursor *cursor = screen->handle()->cursor())
+ cursor->pointerEvent(ev);
+ }
#endif
if (window->d_func()->blockedByModalWindow) {
@@ -1961,6 +1968,15 @@ void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInter
#endif
}
+#ifndef QT_NO_GESTURES
+void QGuiApplicationPrivate::processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e)
+{
+ QNativeGestureEvent ev(e->type, e->pos, e->pos, e->globalPos, e->realValue, e->sequenceId, e->intValue);
+ ev.setTimestamp(e->timestamp);
+ QGuiApplication::sendSpontaneousEvent(e->window, &ev);
+}
+#endif // QT_NO_GESTURES
+
void QGuiApplicationPrivate::processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e)
{
if (!e->window)
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 1068e1eb2e..b158138bb7 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -148,6 +148,7 @@ public:
static void processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e);
static void processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e);
static void processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e);
+ static void processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e);
static void processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e);
#ifndef QT_NO_CONTEXTMENU
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index 65f57aed84..1739e8c6fd 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -115,7 +115,7 @@ static void clear(QVariant::Private *d)
QMetaTypeSwitcher::switcher<void>(destructor, d->type, 0);
}
-// This class is a hack that customizes access to QPolygon
+// This class is a hack that customizes access to QPolygon and QPolygonF
template<class Filter>
class QGuiVariantIsNull : public QVariantIsNull<Filter> {
typedef QVariantIsNull<Filter> Base;
@@ -126,6 +126,7 @@ public:
template<typename T>
bool delegate(const T *p) { return Base::delegate(p); }
bool delegate(const QPolygon*) { return v_cast<QPolygon>(Base::m_d)->isEmpty(); }
+ bool delegate(const QPolygonF*) { return v_cast<QPolygonF>(Base::m_d)->isEmpty(); }
bool delegate(const void *p) { return Base::delegate(p); }
};
static bool isNull(const QVariant::Private *d)
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 3fb4939b69..562df1c913 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -48,8 +48,8 @@
#include <QtCore/qfileinfo.h>
#include <qpalette.h>
#include <qtextformat.h>
-#include <qiconloader_p.h>
-#include "private/qguiapplication_p.h"
+#include <private/qiconloader_p.h>
+#include <private/qguiapplication_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index b2abed7812..2f1b30ae4a 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -337,7 +337,7 @@ bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOptions opt) const
/*!
Set the minimum depth buffer size to \a size.
- \sa depthBufferSize(), setDepth(), depth()
+ \sa depthBufferSize()
*/
void QSurfaceFormat::setDepthBufferSize(int size)
{
@@ -350,7 +350,7 @@ void QSurfaceFormat::setDepthBufferSize(int size)
/*!
Returns the depth buffer size.
- \sa setDepthBufferSize(), setDepth(), depth()
+ \sa setDepthBufferSize()
*/
int QSurfaceFormat::depthBufferSize() const
{
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index f2e60e0ff3..13218fa178 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -227,6 +227,8 @@ QWindow::~QWindow()
QGuiApplicationPrivate::focus_window = 0;
if (QGuiApplicationPrivate::currentMouseWindow == this)
QGuiApplicationPrivate::currentMouseWindow = 0;
+ if (QGuiApplicationPrivate::tabletPressTarget == this)
+ QGuiApplicationPrivate::tabletPressTarget = 0;
QGuiApplicationPrivate::window_list.removeAll(this);
destroy();
}
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 5ee9bce540..07717bb63d 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -673,6 +673,35 @@ void QWindowSystemInterface::handleTabletLeaveProximityEvent(int device, int poi
handleTabletLeaveProximityEvent(time, device, pointerType, uid);
}
+#ifndef QT_NO_GESTURES
+void QWindowSystemInterface::handleGestureEvent(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
+ QPointF &local, QPointF &global)
+{
+ QWindowSystemInterfacePrivate::GestureEvent *e =
+ new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
+ QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
+ qreal value, QPointF &local, QPointF &global)
+{
+ QWindowSystemInterfacePrivate::GestureEvent *e =
+ new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
+ e->realValue = value;
+ QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
+ ulong sequenceId, quint64 value, QPointF &local, QPointF &global)
+{
+ QWindowSystemInterfacePrivate::GestureEvent *e =
+ new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
+ e->sequenceId = sequenceId;
+ e->intValue = value;
+ QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+}
+#endif // QT_NO_GESTURES
+
void QWindowSystemInterface::handlePlatformPanelEvent(QWindow *w)
{
QWindowSystemInterfacePrivate::PlatformPanelEvent *e =
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 813f538651..0c3494a46d 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -185,6 +185,15 @@ public:
static void handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid);
static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid);
+#ifndef QT_NO_GESTURES
+ static void handleGestureEvent(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
+ QPointF &local, QPointF &global);
+ static void handleGestureEventWithRealValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
+ qreal value, QPointF &local, QPointF &global);
+ static void handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp,Qt::NativeGestureType type,
+ ulong sequenceId, quint64 value, QPointF &local, QPointF &global);
+#endif // QT_NO_GESTURES
+
static void handlePlatformPanelEvent(QWindow *w);
#ifndef QT_NO_CONTEXTMENU
static void handleContextMenuEvent(QWindow *w, bool mouseTriggered,
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index a4221b0e76..f0398ffc51 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -91,6 +91,7 @@ public:
PlatformPanel = UserInputEvent | 0x17,
ContextMenu = UserInputEvent | 0x18,
EnterWhatsThisMode = UserInputEvent | 0x19,
+ Gesture = UserInputEvent | 0x1a,
ApplicationStateChanged = 0x19,
FlushEvents = 0x20,
WindowScreenChanged = 0x21
@@ -401,6 +402,21 @@ public:
};
#endif
+ class GestureEvent : public InputEvent {
+ public:
+ GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, QPointF pos, QPointF globalPos)
+ : InputEvent(window, time, Gesture, Qt::NoModifier), type(type), pos(pos), globalPos(globalPos),
+ realValue(0), sequenceId(0), intValue(0) { }
+ Qt::NativeGestureType type;
+ QPointF pos;
+ QPointF globalPos;
+ // Mac
+ qreal realValue;
+ // Windows
+ ulong sequenceId;
+ quint64 intValue;
+ };
+
class WindowSystemEventList {
QList<WindowSystemEvent *> impl;
mutable QMutex mutex;
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index fcd556e892..d5a7399c18 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -2488,7 +2488,7 @@ void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g,
qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
return;
}
- GLint swizzleMask[] = {r, g, b, a};
+ GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
d->swizzleMask[0] = r;
d->swizzleMask[1] = g;
d->swizzleMask[2] = b;
diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp
index 16ed79ac10..ee8abde77b 100644
--- a/src/gui/opengl/qopenglvertexarrayobject.cpp
+++ b/src/gui/opengl/qopenglvertexarrayobject.cpp
@@ -58,13 +58,19 @@ public:
{
Q_ASSERT(context);
#if !defined(QT_OPENGL_ES_2)
- GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress("glGenVertexArrays"));
- DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress("glDeleteVertexArrays"));
- BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress("glBindVertexArray"));
+ if (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")));
+ } else {
+ 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")));
+ }
#else
- GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress("glGenVertexArraysOES"));
- DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress("glDeleteVertexArraysOES"));
- BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress("glBindVertexArrayOES"));
+ 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")));
#endif
}
@@ -84,7 +90,7 @@ public:
}
private:
- // Function signatures are equivalent between desktop core, ARB and ES 2 extensions
+ // Function signatures are equivalent between desktop core, ARB, APPLE 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);
@@ -109,8 +115,8 @@ public:
#if defined(QT_OPENGL_ES_2)
delete vaoFuncs;
#else
- if (vaoFuncsType == ARB)
- delete vaoFuncs.arb;
+ if ((vaoFuncsType == ARB) || (vaoFuncsType == APPLE))
+ delete vaoFuncs.helper;
#endif
}
@@ -130,13 +136,14 @@ public:
union {
QOpenGLFunctions_3_0 *core_3_0;
QOpenGLFunctions_3_2_Core *core_3_2;
- QVertexArrayObjectHelper *arb;
+ QVertexArrayObjectHelper *helper;
} vaoFuncs;
enum {
NotSupported,
Core_3_0,
Core_3_2,
- ARB
+ ARB,
+ APPLE
} vaoFuncsType;
#endif
QOpenGLContext *context;
@@ -162,7 +169,7 @@ bool QOpenGLVertexArrayObjectPrivate::create()
QObject::connect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
#if defined(QT_OPENGL_ES_2)
- if (ctx->hasExtension("GL_OES_vertex_array_object")) {
+ if (ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
vaoFuncs = new QVertexArrayObjectHelper(ctx);
vaoFuncs->glGenVertexArrays(1, &vao);
}
@@ -180,10 +187,14 @@ bool QOpenGLVertexArrayObjectPrivate::create()
vaoFuncsType = Core_3_0;
vaoFuncs.core_3_0->initializeOpenGLFunctions();
vaoFuncs.core_3_0->glGenVertexArrays(1, &vao);
- } else if (ctx->hasExtension("GL_ARB_vertex_array_object")) {
- vaoFuncs.arb = new QVertexArrayObjectHelper(ctx);
+ } else if (ctx->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
+ vaoFuncs.helper = new QVertexArrayObjectHelper(ctx);
vaoFuncsType = ARB;
- vaoFuncs.arb->glGenVertexArrays(1, &vao);
+ vaoFuncs.helper->glGenVertexArrays(1, &vao);
+ } else if (ctx->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) {
+ vaoFuncs.helper = new QVertexArrayObjectHelper(ctx);
+ vaoFuncsType = APPLE;
+ vaoFuncs.helper->glGenVertexArrays(1, &vao);
}
#endif
return (vao != 0);
@@ -205,7 +216,8 @@ void QOpenGLVertexArrayObjectPrivate::destroy()
vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao);
break;
case ARB:
- vaoFuncs.arb->glDeleteVertexArrays(1, &vao);
+ case APPLE:
+ vaoFuncs.helper->glDeleteVertexArrays(1, &vao);
break;
case NotSupported:
break;
@@ -236,7 +248,8 @@ void QOpenGLVertexArrayObjectPrivate::bind()
vaoFuncs.core_3_0->glBindVertexArray(vao);
break;
case ARB:
- vaoFuncs.arb->glBindVertexArray(vao);
+ case APPLE:
+ vaoFuncs.helper->glBindVertexArray(vao);
break;
case NotSupported:
break;
@@ -258,7 +271,8 @@ void QOpenGLVertexArrayObjectPrivate::release()
vaoFuncs.core_3_0->glBindVertexArray(0);
break;
case ARB:
- vaoFuncs.arb->glBindVertexArray(0);
+ case APPLE:
+ vaoFuncs.helper->glBindVertexArray(0);
break;
case NotSupported:
break;
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 4e8f718962..708b8cbd58 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -151,7 +151,7 @@ public:
static bool removeAllApplicationFonts();
#if QT_DEPRECATED_SINCE(5, 2)
- QT_DEPRECATED static inline bool supportsThreadedFontRendering() { return true; }
+ QT_DEPRECATED static bool supportsThreadedFontRendering();
#endif
static QFont systemFont(SystemFont type);
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
index 7f5281131e..6c0be950dc 100644
--- a/src/gui/text/qfontdatabase_qpa.cpp
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -267,6 +267,12 @@ bool QFontDatabase::removeAllApplicationFonts()
return true;
}
+// QT_DEPRECATED_SINCE(5, 2)
+bool QFontDatabase::supportsThreadedFontRendering()
+{
+ return true;
+}
+
/*!
\internal
*/
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index b3889a02a4..303c85ce75 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -891,6 +891,16 @@ QByteArray QFontEngine::getSfntTable(uint tag) const
return table;
}
+void QFontEngine::clearGlyphCache(const void *key)
+{
+ for (QLinkedList<GlyphCacheEntry>::iterator it = m_glyphCaches.begin(), end = m_glyphCaches.end(); it != end; ) {
+ if (it->context == key)
+ it = m_glyphCaches.erase(it);
+ else
+ ++it;
+ }
+}
+
void QFontEngine::setGlyphCache(const void *key, QFontEngineGlyphCache *data)
{
Q_ASSERT(data);
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index d3faef93bb..c181d61d73 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -256,6 +256,7 @@ public:
virtual int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints);
+ void clearGlyphCache(const void *key);
void setGlyphCache(const void *key, QFontEngineGlyphCache *data);
QFontEngineGlyphCache *glyphCache(const void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const;
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 03602712cc..30e0f32547 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -2531,6 +2531,29 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block)
html += QLatin1Char(';');
}
+ if (format.lineHeightType() != QTextBlockFormat::SingleHeight) {
+ switch (format.lineHeightType()) {
+ case QTextBlockFormat::ProportionalHeight:
+ case QTextBlockFormat::FixedHeight:
+ html += QLatin1String(" line-height:");
+ break;
+ case QTextBlockFormat::MinimumHeight:
+ html += QLatin1String(" min-height:");
+ break;
+ case QTextBlockFormat::LineDistanceHeight:
+ html += QLatin1String(" line-spacing:");
+ break;
+ case QTextBlockFormat::SingleHeight:
+ default:
+ break; // Should never reach here
+ }
+ html += QString::number(format.lineHeight());
+ if (format.lineHeightType() == QTextBlockFormat::ProportionalHeight)
+ html += QLatin1String("%;");
+ else
+ html += QLatin1String("px;");
+ }
+
emitPageBreakPolicy(format.pageBreakPolicy());
QTextCharFormat diff;
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index 6156f56ae1..313700429c 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -1427,19 +1427,6 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
xoff = -xoff - size.width();
r.translate( xoff, (fontMetrics.height() / 2) - (size.height() / 2));
- // Prevent clipping the left side of the list decorator (on left to
- // right layouts) and clipping the right side of the list
- // decorator (on right to left layouts).
- if ((r.left() < 0) && (dir == Qt::LeftToRight)) {
- int horizontalOffset = -r.left();
- r.translate(horizontalOffset, 0);
- layout->setPosition(layout->position() + QPointF(horizontalOffset, 0));
- } else if ((r.right() > document->pageSize().width()) && (dir == Qt::RightToLeft)) {
- int horizontalOffset = r.right() - document->pageSize().width();
- r.translate(-horizontalOffset, 0);
- layout->setPosition(layout->position() - QPointF(horizontalOffset, 0));
- }
-
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index c0e2c5b803..2b0f9ffeb6 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1883,11 +1883,12 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
scaledEngine = feCache.prevScaledFontEngine;
} else {
QFontEngine *scEngine = rawFont.d->fontEngine->cloneWithSize(smallCapsFraction * rawFont.pixelSize());
+ scEngine->ref.ref();
scaledEngine = QFontEngineMultiQPA::createMultiFontEngine(scEngine, script);
scaledEngine->ref.ref();
feCache.prevScaledFontEngine = scaledEngine;
// If scEngine is not ref'ed by scaledEngine, make sure it is deallocated and not leaked.
- if (!scEngine->ref.load())
+ if (!scEngine->ref.deref())
delete scEngine;
}
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 5292ba20a2..a131503b85 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -46,7 +46,7 @@
#include <qstack.h>
#include <qdebug.h>
#include <qthread.h>
-#include <qcoreapplication.h>
+#include <qguiapplication.h>
#include "qtextdocument.h"
#include "qtextformat_p.h"
@@ -1066,7 +1066,7 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent
&& !attributes.at(i + 1).isEmpty()) {
hasHref = true;
charFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
- charFormat.setForeground(Qt::blue);
+ charFormat.setForeground(QGuiApplication::palette().link());
}
}
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index dc8ae06868..66341e186a 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -44,6 +44,7 @@
#include <qthread.h>
#include <qfont.h>
+#include <qmath.h>
#include <qpainter.h>
#include <qvarlengtharray.h>
#include <qtextformat.h>
@@ -207,7 +208,7 @@ void QTextInlineObject::setAscent(qreal a)
}
/*!
- Sets the inline object's decent to \a d.
+ Sets the inline object's descent to \a d.
\sa descent(), setAscent(), width(), rect()
*/
@@ -946,15 +947,23 @@ static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPo
continue;
}
- if (lastSelectionWidth > 0)
- region->addRect(boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight));
+ if (lastSelectionWidth > 0) {
+ QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight);
+ rect.moveLeft(qFloor(rect.left()));
+ rect.moveTop(qFloor(rect.top()));
+ region->addRect(rect);
+ }
lastSelectionX = selectionX;
lastSelectionWidth = selectionWidth;
}
}
- if (lastSelectionWidth > 0)
- region->addRect(boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight));
+ if (lastSelectionWidth > 0) {
+ QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight);
+ rect.moveLeft(qFloor(rect.left()));
+ rect.moveTop(qFloor(rect.top()));
+ region->addRect(rect);
+ }
}
static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip)
@@ -1288,7 +1297,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
After being created, the line can be filled using the setLineWidth()
or setNumColumns() functions. A line has a number of attributes including the
rectangle it occupies, rect(), its coordinates, x() and y(), its
- textLength(), width() and naturalTextWidth(), and its ascent() and decent()
+ textLength(), width() and naturalTextWidth(), and its ascent() and descent()
relative to the text. The position of the cursor in terms of the
line is available from cursorToX() and its inverse from
xToCursor(). A line can be moved with setPosition().
@@ -2077,7 +2086,7 @@ static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const Q
QBrush bg = chf.background();
if (bg.style() != Qt::NoBrush && !chf.property(SuppressBackground).toBool())
- p->fillRect(r, bg);
+ p->fillRect(QRectF(qFloor(r.x()), qFloor(r.y()), r.width(), r.height()), bg);
if (c.style() != Qt::NoBrush) {
p->setPen(QPen(c, 0));
}
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index ba9e5cbdc4..e0996c4072 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -181,7 +181,7 @@ int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const
return 0;
}
-// If the connection is in the InProgress state channel errors should not always be
+// If the connection is in the HostLookupPendening state channel errors should not always be
// emitted. This function will check the status of the connection channels if we
// have not decided the networkLayerState and will return true if the channel error
// should be emitted by the channel.
@@ -200,12 +200,12 @@ bool QHttpNetworkConnectionPrivate::shouldEmitChannelError(QAbstractSocket *sock
}
if (channelCount == 1) {
- if (networkLayerState == QHttpNetworkConnectionPrivate::InProgress)
+ if (networkLayerState == HostLookupPending || networkLayerState == IPv4or6)
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
channels[0].close();
emitError = true;
} else {
- if (networkLayerState == QHttpNetworkConnectionPrivate::InProgress) {
+ if (networkLayerState == HostLookupPending || networkLayerState == IPv4or6) {
if (channels[otherSocket].isSocketBusy() && (channels[otherSocket].state != QHttpNetworkConnectionChannel::ClosingState)) {
// this was the first socket to fail.
channels[i].close();
@@ -560,7 +560,7 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor
// untill we have started the first connection attempt. So no
// request will be started untill we know if IPv4 or IPv6
// should be used.
- if (networkLayerState == Unknown || networkLayerState == InProgress) {
+ if (networkLayerState == Unknown || networkLayerState == HostLookupPending) {
startHostInfoLookup();
} else if ( networkLayerState == IPv4 || networkLayerState == IPv6 ) {
// this used to be called via invokeMethod and a QueuedConnection
@@ -878,7 +878,7 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply)
void QHttpNetworkConnectionPrivate::_q_startNextRequest()
{
// If there is no network layer state decided we should not start any new requests.
- if (networkLayerState == Unknown || networkLayerState == InProgress)
+ if (networkLayerState == Unknown || networkLayerState == HostLookupPending || networkLayerState == IPv4or6)
return;
// If the QHttpNetworkConnection is currently paused then bail out immediately
@@ -986,7 +986,7 @@ void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply)
// lookup as then the hostinfo will already be in the cache.
void QHttpNetworkConnectionPrivate::startHostInfoLookup()
{
- networkLayerState = InProgress;
+ networkLayerState = HostLookupPending;
// check if we already now can decide if this is IPv4 or IPv6
QString lookupHost = hostName;
@@ -1028,6 +1028,8 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(QHostInfo info)
bool bIpv4 = false;
bool bIpv6 = false;
bool foundAddress = false;
+ if (networkLayerState == IPv4 || networkLayerState == IPv6 || networkLayerState == IPv4or6)
+ return;
foreach (const QHostAddress &address, info.addresses()) {
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
@@ -1077,7 +1079,7 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup()
Q_ASSERT(!channels[0].isSocketBusy());
Q_ASSERT(!channels[1].isSocketBusy());
- networkLayerState = InProgress;
+ networkLayerState = IPv4or6;
channels[0].networkLayerPreference = QAbstractSocket::IPv4Protocol;
channels[1].networkLayerPreference = QAbstractSocket::IPv6Protocol;
@@ -1101,7 +1103,7 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup()
else
channels[0].ensureConnection();
} else {
- networkLayerState = InProgress;
+ networkLayerState = IPv4or6;
channels[0].networkLayerPreference = QAbstractSocket::AnyIPProtocol;
channels[0].ensureConnection();
}
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index c54250f6ed..2aaaad24ac 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -165,9 +165,10 @@ public:
enum NetworkLayerPreferenceState {
Unknown,
- InProgress,
+ HostLookupPending,
IPv4,
- IPv6
+ IPv6,
+ IPv4or6
};
QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt);
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index da82fdf8d2..6e786893ed 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -1045,7 +1045,7 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
void QHttpNetworkConnectionChannel::_q_connected()
{
// For the Happy Eyeballs we need to check if this is the first channel to connect.
- if (connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::InProgress) {
+ if (connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::HostLookupPending || connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv4or6) {
if (connection->d_func()->delayedConnectionTimer.isActive())
connection->d_func()->delayedConnectionTimer.stop();
if (networkLayerPreference == QAbstractSocket::IPv4Protocol)
@@ -1212,7 +1212,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
QPointer<QHttpNetworkConnection> that = connection;
QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString());
- // In the InProgress state the channel should not emit the error.
+ // In the HostLookupPending state the channel should not emit the error.
// This will instead be handled by the connection.
if (!connection->d_func()->shouldEmitChannelError(socket))
return;
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index 729729d929..052c492f07 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -52,6 +52,10 @@
#include <arpa/nameser_compat.h>
#include <resolv.h>
+#ifdef __GNU_LIBRARY__
+# include <gnu/lib-names.h>
+#endif
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_LIBRARY
@@ -77,9 +81,16 @@ struct QDnsLookupStateDeleter
static void resolveLibrary()
{
- QLibrary lib(QLatin1String("resolv"));
+ QLibrary lib;
+#ifdef LIBRESOLV_SO
+ lib.setFileName(QStringLiteral(LIBRESOLV_SO));
if (!lib.load())
- return;
+#endif
+ {
+ lib.setFileName(QLatin1String("resolv"));
+ if (!lib.load())
+ return;
+ }
local_dn_expand = dn_expand_proto(lib.resolve("__dn_expand"));
if (!local_dn_expand)
diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp
index 04daf2ecdd..dc2702b552 100644
--- a/src/network/kernel/qhostinfo_unix.cpp
+++ b/src/network/kernel/qhostinfo_unix.cpp
@@ -63,6 +63,10 @@
# include <resolv.h>
#endif
+#ifdef __GNU_LIBRARY__
+# include <gnu/lib-names.h>
+#endif
+
#if defined (QT_NO_GETADDRINFO)
static QBasicMutex getHostByNameMutex;
#endif
@@ -93,9 +97,16 @@ static res_state_ptr local_res = 0;
static void resolveLibrary()
{
#if !defined(QT_NO_LIBRARY) && !defined(Q_OS_QNX)
- QLibrary lib(QLatin1String("resolv"));
+ QLibrary lib;
+#ifdef LIBRESOLV_SO
+ lib.setFileName(QStringLiteral(LIBRESOLV_SO));
if (!lib.load())
- return;
+#endif
+ {
+ lib.setFileName(QLatin1String("resolv"));
+ if (!lib.load())
+ return;
+ }
local_res_init = res_init_proto(lib.resolve("__res_init"));
if (!local_res_init)
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index c96200fe1b..8ee0a8b290 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1638,6 +1638,7 @@ QGLContext* QGLContext::currentCtx = 0;
static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha)
{
+ Q_ASSERT(!img.isNull());
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
// OpenGL gives RGBA; Qt wants ARGB
uint *p = (uint*)img.bits();
@@ -1682,6 +1683,8 @@ QImage qt_gl_read_frame_buffer(const QSize &size, bool alpha_format, bool includ
{
QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
: QImage::Format_RGB32);
+ if (img.isNull())
+ return QImage();
int w = size.width();
int h = size.height();
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
@@ -1692,6 +1695,8 @@ QImage qt_gl_read_frame_buffer(const QSize &size, bool alpha_format, bool includ
QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha)
{
QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
+ if (img.isNull())
+ return QImage();
int w = size.width();
int h = size.height();
#if !defined(QT_OPENGL_ES_2)
diff --git a/src/platformsupport/fbconvenience/qfbcursor.cpp b/src/platformsupport/fbconvenience/qfbcursor.cpp
index fecf9f6380..b86f5830ea 100644
--- a/src/platformsupport/fbconvenience/qfbcursor.cpp
+++ b/src/platformsupport/fbconvenience/qfbcursor.cpp
@@ -137,5 +137,12 @@ void QFbCursor::changeCursor(QCursor * widgetCursor, QWindow *window)
}
#endif
-QT_END_NAMESPACE
+void QFbCursor::setDirty()
+{
+ if (!mDirty) {
+ mDirty = true;
+ mScreen->scheduleUpdate();
+ }
+}
+QT_END_NAMESPACE
diff --git a/src/platformsupport/fbconvenience/qfbcursor_p.h b/src/platformsupport/fbconvenience/qfbcursor_p.h
index cee9f56ab5..40377e2075 100644
--- a/src/platformsupport/fbconvenience/qfbcursor_p.h
+++ b/src/platformsupport/fbconvenience/qfbcursor_p.h
@@ -63,7 +63,7 @@ public:
virtual void changeCursor(QCursor *widgetCursor, QWindow *window);
#endif
- virtual void setDirty() { mDirty = true; /* screen->setDirty(QRect()); */ }
+ virtual void setDirty();
virtual bool isDirty() const { return mDirty; }
virtual bool isOnScreen() const { return mOnScreen; }
virtual QRect lastPainted() const { return mPrevRect; }
diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp
index e5b9f09c14..37d16ddeb6 100644
--- a/src/platformsupport/fbconvenience/qfbscreen.cpp
+++ b/src/platformsupport/fbconvenience/qfbscreen.cpp
@@ -149,9 +149,13 @@ void QFbScreen::setDirty(const QRect &rect)
QRect intersection = rect.intersected(mGeometry);
QPoint screenOffset = mGeometry.topLeft();
mRepaintRegion += intersection.translated(-screenOffset); // global to local translation
- if (!mRedrawTimer.isActive()) {
+ scheduleUpdate();
+}
+
+void QFbScreen::scheduleUpdate()
+{
+ if (!mRedrawTimer.isActive())
mRedrawTimer.start();
- }
}
void QFbScreen::setPhysicalSize(const QSize &size)
@@ -254,8 +258,9 @@ QRegion QFbScreen::doRedraw()
QRect windowRect = mWindowStack[layerIndex]->geometry().translated(-screenOffset);
QRect windowIntersect = rect.translated(-windowRect.left(),
-windowRect.top());
- mCompositePainter->drawImage(rect, mWindowStack[layerIndex]->backingStore()->image(),
- windowIntersect);
+ QFbBackingStore *backingStore = mWindowStack[layerIndex]->backingStore();
+ if (backingStore)
+ mCompositePainter->drawImage(rect, backingStore->image(), windowIntersect);
if (firstLayer) {
firstLayer = false;
}
diff --git a/src/platformsupport/fbconvenience/qfbscreen_p.h b/src/platformsupport/fbconvenience/qfbscreen_p.h
index 01a352e96a..dd940c4a1d 100644
--- a/src/platformsupport/fbconvenience/qfbscreen_p.h
+++ b/src/platformsupport/fbconvenience/qfbscreen_p.h
@@ -45,6 +45,7 @@
#include <qpa/qplatformscreen.h>
#include <QtCore/QTimer>
#include <QtCore/QSize>
+#include "qfbcursor_p.h"
QT_BEGIN_NAMESPACE
@@ -60,13 +61,14 @@ public:
QFbScreen();
~QFbScreen();
- virtual QRect geometry() const { return mGeometry; }
- virtual int depth() const { return mDepth; }
- virtual QImage::Format format() const { return mFormat; }
- virtual QSizeF physicalSize() const { return mPhysicalSize; }
+ QRect geometry() const Q_DECL_OVERRIDE { return mGeometry; }
+ int depth() const Q_DECL_OVERRIDE { return mDepth; }
+ QImage::Format format() const Q_DECL_OVERRIDE { return mFormat; }
+ QSizeF physicalSize() const Q_DECL_OVERRIDE { return mPhysicalSize; }
+ QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return mCursor; }
QWindow *topWindow() const;
- virtual QWindow *topLevelAt(const QPoint & p) const;
+ QWindow *topLevelAt(const QPoint & p) const Q_DECL_OVERRIDE;
// compositor api
virtual void addWindow(QFbWindow *window);
@@ -77,6 +79,8 @@ public:
void addBackingStore(QFbBackingStore *bs) {mBackingStores << bs;}
+ void scheduleUpdate();
+
public slots:
virtual void setDirty(const QRect &rect);
void setPhysicalSize(const QSize &size);
@@ -114,4 +118,3 @@ private:
QT_END_NAMESPACE
#endif // QFBSCREEN_P_H
-
diff --git a/src/platformsupport/fbconvenience/qfbwindow.cpp b/src/platformsupport/fbconvenience/qfbwindow.cpp
index 246f50b4a9..8b6186db79 100644
--- a/src/platformsupport/fbconvenience/qfbwindow.cpp
+++ b/src/platformsupport/fbconvenience/qfbwindow.cpp
@@ -77,6 +77,26 @@ void QFbWindow::setGeometry(const QRect &rect)
QPlatformWindow::setGeometry(rect);
}
+void QFbWindow::setVisible(bool visible)
+{
+ if (visible) {
+ if (mWindowState & Qt::WindowFullScreen)
+ setGeometry(platformScreen()->geometry());
+ else if (mWindowState & Qt::WindowMaximized)
+ setGeometry(platformScreen()->availableGeometry());
+ }
+ QPlatformWindow::setVisible(visible);
+}
+
+
+void QFbWindow::setWindowState(Qt::WindowState state)
+{
+ QPlatformWindow::setWindowState(state);
+ mWindowState = state;
+ platformScreen()->invalidateRectCache();
+}
+
+
void QFbWindow::setWindowFlags(Qt::WindowFlags flags)
{
mWindowFlags = flags;
diff --git a/src/platformsupport/fbconvenience/qfbwindow_p.h b/src/platformsupport/fbconvenience/qfbwindow_p.h
index 25e2afca14..5ad921b0d7 100644
--- a/src/platformsupport/fbconvenience/qfbwindow_p.h
+++ b/src/platformsupport/fbconvenience/qfbwindow_p.h
@@ -59,7 +59,9 @@ public:
virtual void lower();
virtual void setGeometry(const QRect &rect);
+ virtual void setVisible(bool visible);
+ virtual void setWindowState(Qt::WindowState state);
virtual void setWindowFlags(Qt::WindowFlags type);
virtual Qt::WindowFlags windowFlags() const;
@@ -78,6 +80,7 @@ protected:
QFbBackingStore *mBackingStore;
QRect mOldGeometry;
Qt::WindowFlags mWindowFlags;
+ Qt::WindowState mWindowState;
WId mWindowId;
};
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h
index 22d1622516..225b3d41ef 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h
@@ -42,6 +42,9 @@
#ifndef QEVDEVKEYBOARDHANDLER_DEFAULTMAP_P_H
#define QEVDEVKEYBOARDHANDLER_DEFAULTMAP_P_H
+#include "qnamespace.h"
+#include "linux/input.h"
+
// no QT_BEGIN_NAMESPACE, since we include it internally...
const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = {
@@ -631,7 +634,30 @@ const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = {
{ 111, 0xffff, 0x01000007, 0x00, 0x00, 0x0000 },
{ 111, 0xffff, 0x01000000, 0x06, 0x08, 0x0200 },
{ 111, 0xffff, 0x01000000, 0x0c, 0x08, 0x0200 },
- { 119, 0xffff, 0x01000008, 0x00, 0x00, 0x0000 },
+
+ // 113 -> 248
+ { KEY_MUTE, 0xffff, Qt::Key_VolumeMute, 0x00, 0x00, 0x0000 },
+ { KEY_VOLUMEDOWN, 0xffff, Qt::Key_VolumeDown, 0x00, 0x00, 0x0000 },
+ { KEY_VOLUMEUP, 0xffff, Qt::Key_VolumeUp, 0x00, 0x00, 0x0000 },
+ { KEY_PAUSE, 0xffff, Qt::Key_Pause, 0x00, 0x00, 0x0000 },
+ { KEY_STOP, 0xffff, Qt::Key_Stop, 0x00, 0x00, 0x0000 },
+ { KEY_RECORD, 0xffff, Qt::Key_MediaRecord, 0x00, 0x00, 0x0000 },
+ { KEY_REWIND, 0xffff, Qt::Key_AudioRewind, 0x00, 0x00, 0x0000 },
+ { KEY_PLAYPAUSE, 0xffff, Qt::Key_MediaTogglePlayPause, 0x00, 0x00, 0x0000 },
+ { KEY_PLAY, 0xffff, Qt::Key_MediaPlay, 0x00, 0x00, 0x0000 },
+ { KEY_FASTFORWARD, 0xffff, Qt::Key_AudioForward, 0x00, 0x00, 0x0000 },
+ { KEY_CANCEL, 0xffff, Qt::Key_Cancel, 0x00, 0x00, 0x0000 },
+ { 248, 0xffff, Qt::Key_MicMute, 0x00, 0x00, 0x0000 },
+ // 0x160 ->
+ { KEY_SELECT, 0xffff, Qt::Key_Select, 0x00, 0x00, 0x0000 },
+ { KEY_CLEAR, 0xffff, Qt::Key_Clear, 0x00, 0x00, 0x0000 },
+ { KEY_CALENDAR, 0xffff, Qt::Key_Calendar, 0x00, 0x00, 0x0000 },
+ { KEY_RED, 0xffff, Qt::Key_Red, 0x00, 0x00, 0x0000 },
+ { KEY_GREEN, 0xffff, Qt::Key_Green, 0x00, 0x00, 0x0000 },
+ { KEY_YELLOW, 0xffff, Qt::Key_Yellow, 0x00, 0x00, 0x0000 },
+ { KEY_BLUE, 0xffff, Qt::Key_Blue, 0x00, 0x00, 0x0000 },
+ { KEY_CHANNELUP, 0xffff, Qt::Key_ChannelUp, 0x00, 0x00, 0x0000 },
+ { KEY_CHANNELDOWN, 0xffff, Qt::Key_ChannelDown, 0x00, 0x00, 0x0000 },
};
const QEvdevKeyboardMap::Composing QEvdevKeyboardHandler::s_keycompose_default[] = {
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp
index 3b79a2ac80..89215557c1 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp
@@ -300,6 +300,21 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification,
qDebug("evdevtouch: device name: %s", name);
}
+ // Fix up the coordinate ranges for am335x in case the kernel driver does not have them fixed.
+ if (d->hw_name == QLatin1String("ti-tsc")) {
+ if (d->hw_range_x_min == 0 && d->hw_range_x_max == 4095) {
+ d->hw_range_x_min = 165;
+ d->hw_range_x_max = 4016;
+ }
+ if (d->hw_range_y_min == 0 && d->hw_range_y_max == 4095) {
+ d->hw_range_y_min = 220;
+ d->hw_range_y_max = 3907;
+ }
+ if (printDeviceInfo)
+ qDebug("evdevtouch: found ti-tsc, overriding: min X: %d max X: %d min Y: %d max Y: %d",
+ d->hw_range_x_min, d->hw_range_x_max, d->hw_range_y_min, d->hw_range_y_max);
+ }
+
bool grabSuccess = !ioctl(m_fd, EVIOCGRAB, (void *) 1);
if (grabSuccess)
ioctl(m_fd, EVIOCGRAB, (void *) 0);
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
index cbb3092b1d..79a5c82fe0 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -558,37 +558,56 @@ QWidget *QAccessibleCalendarWidget::navigationBar() const
#endif // QT_NO_CALENDARWIDGET
#ifndef QT_NO_DOCKWIDGET
+
+// Dock Widget - order of children:
+// - Content widget
+// - Float button
+// - Close button
+// If there is a custom title bar widget, that one becomes child 1, after the content 0
+// (in that case the buttons are ignored)
QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::Window)
{
+}
+QDockWidgetLayout *QAccessibleDockWidget::dockWidgetLayout() const
+{
+ return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
}
-QAccessibleInterface *QAccessibleDockWidget::child(int index) const
+int QAccessibleDockWidget::childCount() const
{
- if (index == 0) {
- return new QAccessibleTitleBar(dockWidget());
- } else if (index == 1 && dockWidget()->widget()) {
- return QAccessible::queryAccessibleInterface(dockWidget()->widget());
+ if (dockWidget()->titleBarWidget()) {
+ return dockWidget()->widget() ? 2 : 1;
}
- return 0;
+ return dockWidgetLayout()->count();
}
-int QAccessibleDockWidget::childCount() const
+QAccessibleInterface *QAccessibleDockWidget::child(int index) const
{
- return dockWidget()->widget() ? 2 : 1;
+ if (dockWidget()->titleBarWidget()) {
+ if ((!dockWidget()->widget() && index == 0) || (index == 1))
+ return QAccessible::queryAccessibleInterface(dockWidget()->titleBarWidget());
+ if (index == 0)
+ return QAccessible::queryAccessibleInterface(dockWidget()->widget());
+ } else {
+ QLayoutItem *item = dockWidgetLayout()->itemAt(index);
+ if (item)
+ return QAccessible::queryAccessibleInterface(item->widget());
+ }
+ return 0;
}
int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const
{
- if (child) {
- if (child->role() == QAccessible::TitleBar) {
- return 0;
- } else {
- return 1; // FIXME
- }
+ if (!child || !child->object() || child->object()->parent() != object())
+ return -1;
+
+ if (dockWidget()->titleBarWidget() == child->object()) {
+ return dockWidget()->widget() ? 1 : 0;
}
- return -1;
+
+ return dockWidgetLayout()->indexOf(qobject_cast<QWidget*>(child->object()));
}
QRect QAccessibleDockWidget::rect() const
@@ -610,190 +629,13 @@ QDockWidget *QAccessibleDockWidget::dockWidget() const
return static_cast<QDockWidget *>(object());
}
-////
-// QAccessibleTitleBar
-////
-QAccessibleTitleBar::QAccessibleTitleBar(QDockWidget *widget)
- : m_dockWidget(widget)
-{
-
-}
-
-QAccessibleInterface *QAccessibleTitleBar::parent() const
-{
- return new QAccessibleDockWidget(dockWidget());
-}
-
-QAccessibleInterface *QAccessibleTitleBar::child(int index) const
-{
- if (index >= 0) {
- QDockWidgetLayout *layout = dockWidgetLayout();
- int role;
- int currentIndex = 0;
- for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
- QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
- if (!w || !w->isVisible())
- continue;
- if (currentIndex == index)
- return QAccessible::queryAccessibleInterface(w);
- ++currentIndex;
- }
- }
- return 0;
-}
-
-int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const
-{
- return -1;
-}
-
-int QAccessibleTitleBar::childCount() const
-{
- QDockWidgetLayout *layout = dockWidgetLayout();
- int count = 0;
- for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
- QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
- if (w && w->isVisible())
- ++count;
- }
- return count;
-}
-
-QString QAccessibleTitleBar::text(QAccessible::Text t) const
+QString QAccessibleDockWidget::text(QAccessible::Text t) const
{
if (t == QAccessible::Name || t == QAccessible::Value) {
return qt_accStripAmp(dockWidget()->windowTitle());
}
return QString();
}
-
-QAccessible::State QAccessibleTitleBar::state() const
-{
- QAccessible::State state;
-
- QDockWidget *w = dockWidget();
- if (w->testAttribute(Qt::WA_WState_Visible) == false)
- state.invisible = true;
- if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow())
- state.focusable = true;
- if (w->hasFocus())
- state.focused = true;
- if (!w->isEnabled())
- state.disabled = true;
-
- return state;
-}
-
-QRect QAccessibleTitleBar::rect() const
-{
- bool mapToGlobal = true;
- QRect rect;
-
- if (dockWidget()->isFloating()) {
- rect = dockWidget()->frameGeometry();
- if (dockWidget()->widget()) {
- QPoint globalPos = dockWidget()->mapToGlobal(dockWidget()->widget()->rect().topLeft());
- globalPos.ry()--;
- rect.setBottom(globalPos.y());
- mapToGlobal = false;
- }
- } else {
- QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
- rect = layout->titleArea();
- }
-
- if (rect.isNull())
- return rect;
-
- if (mapToGlobal)
- rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft()));
- return rect;
-}
-
-QAccessibleInterface *QAccessibleTitleBar::childAt(int x, int y) const
-{
- for (int i = 0; i < childCount(); ++i) {
- QAccessibleInterface *childIface = child(i);
- if (childIface->rect().contains(x,y)) {
- return childIface;
- }
- }
- return 0;
-}
-
-QObject *QAccessibleTitleBar::object() const
-{
- return 0;
-}
-
-QDockWidgetLayout *QAccessibleTitleBar::dockWidgetLayout() const
-{
- return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
-}
-
-QDockWidget *QAccessibleTitleBar::dockWidget() const
-{
- return m_dockWidget;
-}
-
-//QString QAccessibleTitleBar::actionText(int action, Text t, int child) const
-//{
-// QString str;
-// if (child >= 1 && child <= childCount()) {
-// if (t == Name) {
-// switch (action) {
-// case Press:
-// case DefaultAction:
-// if (child == QDockWidgetLayout::CloseButton) {
-// str = QDockWidget::tr("Close");
-// } else if (child == QDockWidgetLayout::FloatButton) {
-// str = dockWidget()->isFloating() ? QDockWidget::tr("Dock")
-// : QDockWidget::tr("Float");
-// }
-// break;
-// default:
-// break;
-// }
-// }
-// }
-// return str;
-//}
-
-//bool QAccessibleTitleBar::doAction(int action, int child, const QVariantList& /*params*/)
-//{
-// if (!child || !dockWidget()->isEnabled())
-// return false;
-
-// switch (action) {
-// case DefaultAction:
-// case Press: {
-// QDockWidgetLayout *layout = dockWidgetLayout();
-// QAbstractButton *btn = static_cast<QAbstractButton *>(layout->widgetForRole((QDockWidgetLayout::Role)child));
-// if (btn)
-// btn->animateClick();
-// return true;
-// break;}
-// default:
-// break;
-// }
-
-// return false;
-//}
-
-QAccessible::Role QAccessibleTitleBar::role() const
-{
- return QAccessible::TitleBar;
-}
-
-void QAccessibleTitleBar::setText(QAccessible::Text /*t*/, const QString &/*text*/)
-{
-}
-
-bool QAccessibleTitleBar::isValid() const
-{
- return dockWidget();
-}
-
#endif // QT_NO_DOCKWIDGET
#ifndef QT_NO_CURSOR
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h
index 3e982e82d6..3f50010685 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.h
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h
@@ -283,31 +283,10 @@ public:
int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
int childCount() const Q_DECL_OVERRIDE;
QRect rect () const Q_DECL_OVERRIDE;
-
- QDockWidget *dockWidget() const;
-};
-
-class QAccessibleTitleBar : public QAccessibleInterface
-{
-public:
- explicit QAccessibleTitleBar(QDockWidget *widget);
-
- QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
- QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
- int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
- int childCount() const Q_DECL_OVERRIDE;
- QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
- void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE;
QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
- QAccessible::Role role() const Q_DECL_OVERRIDE;
- QRect rect () const Q_DECL_OVERRIDE;
- QAccessible::State state() const Q_DECL_OVERRIDE;
- QObject *object() const Q_DECL_OVERRIDE;
- bool isValid() const Q_DECL_OVERRIDE;
-
- QPointer<QDockWidget> m_dockWidget;
QDockWidget *dockWidget() const;
+protected:
QDockWidgetLayout *dockWidgetLayout() const;
};
diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp
index e3e614d700..1dac199a09 100644
--- a/src/plugins/accessible/widgets/simplewidgets.cpp
+++ b/src/plugins/accessible/widgets/simplewidgets.cpp
@@ -474,16 +474,16 @@ QSize QAccessibleDisplay::imageSize() const
}
/*! \internal */
-QRect QAccessibleDisplay::imagePosition() const
+QPoint QAccessibleDisplay::imagePosition() const
{
QLabel *label = qobject_cast<QLabel *>(widget());
if (!label)
- return QRect();
+ return QPoint();
const QPixmap *pixmap = label->pixmap();
if (!pixmap)
- return QRect();
+ return QPoint();
- return QRect(label->mapToGlobal(label->pos()), label->size());
+ return QPoint(label->mapToGlobal(label->pos()));
}
#ifndef QT_NO_GROUPBOX
@@ -605,7 +605,7 @@ QString QAccessibleLineEdit::text(QAccessible::Text t) const
break;
}
if (str.isEmpty())
- str = QAccessibleWidget::text(t);;
+ str = QAccessibleWidget::text(t);
return qt_accStripAmp(str);
}
diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h
index 66b4c2bd3e..6024788048 100644
--- a/src/plugins/accessible/widgets/simplewidgets.h
+++ b/src/plugins/accessible/widgets/simplewidgets.h
@@ -110,7 +110,7 @@ public:
// QAccessibleImageInterface
QString imageDescription() const Q_DECL_OVERRIDE;
QSize imageSize() const Q_DECL_OVERRIDE;
- QRect imagePosition() const Q_DECL_OVERRIDE;
+ QPoint imagePosition() const Q_DECL_OVERRIDE;
};
#ifndef QT_NO_GROUPBOX
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index 4cfc2a6cc4..459a450222 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -55,6 +55,7 @@
#include <xkbcommon_workaround.h>
#endif
+#include <locale.h> // LC_CTYPE
#include <string.h> // strchr, strncmp, etc.
#include <strings.h> // strncasecmp
#include <clocale> // LC_CTYPE
diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.cpp b/src/plugins/platforms/android/src/androidjniaccessibility.cpp
index 07f3371e72..a27d9f5aed 100644
--- a/src/plugins/platforms/android/src/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/src/androidjniaccessibility.cpp
@@ -164,7 +164,7 @@ if (!clazz) { \
//__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE);
-#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, VALUE) \
+#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, ...) \
{ \
jclass clazz = env->GetObjectClass(OBJECT); \
jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \
@@ -172,7 +172,7 @@ if (!clazz) { \
__android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
return; \
} \
- env->CallVoidMethod(OBJECT, method, VALUE); \
+ env->CallVoidMethod(OBJECT, method, __VA_ARGS__); \
}
@@ -201,9 +201,21 @@ if (!clazz) { \
}
QAccessible::State state = iface->state();
- QString desc = iface->text(QAccessible::Name);
+ // try to fill in the text property, this is what the screen reader reads
+ QString desc = iface->text(QAccessible::Value);
+ if (desc.isEmpty())
+ desc = iface->text(QAccessible::Name);
if (desc.isEmpty())
desc = iface->text(QAccessible::Description);
+ if (QAccessibleTextInterface *textIface = iface->textInterface()) {
+ if (textIface->selectionCount() > 0) {
+ int startSelection;
+ int endSelection;
+ textIface->selection(0, &startSelection, &endSelection);
+ CALL_METHOD(node, "setTextSelection", "(II)V", startSelection, endSelection)
+ }
+ }
+
if ((iface->role() != QAccessible::NoRole) &&
(iface->role() != QAccessible::Client) &&
(iface->role() != QAccessible::Pane)) {
diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp
index 4a2d87d6a4..30d4e69afe 100644
--- a/src/plugins/platforms/android/src/androidjniinput.cpp
+++ b/src/plugins/platforms/android/src/androidjniinput.cpp
@@ -228,6 +228,9 @@ namespace QtAndroidInput
return;
QAndroidPlatformIntegration *platformIntegration = QtAndroid::androidPlatformIntegration();
+ if (!platformIntegration)
+ return;
+
QTouchDevice *touchDevice = platformIntegration->touchDevice();
if (touchDevice == 0) {
touchDevice = new QTouchDevice;
@@ -271,8 +274,8 @@ namespace QtAndroidInput
case 0x00000005:
return Qt::Key_Call;
- case 0x0000001b:
- return Qt::Key_WebCam;
+ case 0x0000001b: // KEYCODE_CAMERA
+ return Qt::Key_Camera;
case 0x0000001c:
return Qt::Key_Clear;
@@ -280,7 +283,7 @@ namespace QtAndroidInput
case 0x00000037:
return Qt::Key_Comma;
- case 0x00000043:
+ case 0x00000043: // KEYCODE_DEL
return Qt::Key_Backspace;
case 0x00000017: // KEYCODE_DPAD_CENTER
@@ -398,6 +401,27 @@ namespace QtAndroidInput
case 0x00000018:
return Qt::Key_VolumeUp;
+ case 0x00000011: // KEYCODE_STAR
+ return Qt::Key_Asterisk;
+
+ case 0x00000012: // KEYCODE_POUND
+ return Qt::Key_NumberSign;
+
+ case 0x00000050: // KEYCODE_FOCUS
+ return Qt::Key_CameraFocus;
+
+ case 0x00000070: // KEYCODE_FORWARD_DEL
+ return Qt::Key_Delete;
+
+ case 0x00000080: // KEYCODE_MEDIA_CLOSE
+ return Qt::Key_Close;
+
+ case 0x00000081: // KEYCODE_MEDIA_EJECT
+ return Qt::Key_Eject;
+
+ case 0x00000082: // KEYCODE_MEDIA_RECORD
+ return Qt::Key_MediaRecord;
+
case 0x000000b7: // KEYCODE_PROG_RED
return Qt::Key_Red;
@@ -416,13 +440,30 @@ namespace QtAndroidInput
case 0x000000a7: // KEYCODE_CHANNEL_DOWN
return Qt::Key_ChannelDown;
+ case 0x000000a8: // KEYCODE_ZOOM_IN
+ return Qt::Key_ZoomIn;
+
+ case 0x000000a9: // KEYCODE_ZOOM_OUT
+ return Qt::Key_ZoomOut;
+
+ case 0x000000af: // KEYCODE_CAPTIONS
+ return Qt::Key_Subtitle;
+
+ case 0x000000d0: // KEYCODE_CALENDAR
+ return Qt::Key_Calendar;
+
+ case 0x000000d1: // KEYCODE_MUSIC
+ return Qt::Key_Music;
+
+ case 0x000000d2: // KEYCODE_CALCULATOR
+ return Qt::Key_Calculator;
+
case 0x00000000: // KEYCODE_UNKNOWN
- case 0x00000011: // KEYCODE_STAR ?!?!?
- case 0x00000012: // KEYCODE_POUND ?!?!?
+ return Qt::Key_unknown;
+
case 0x00000053: // KEYCODE_NOTIFICATION ?!?!?
case 0x0000004f: // KEYCODE_HEADSETHOOK ?!?!?
case 0x00000044: // KEYCODE_GRAVE ?!?!?
- case 0x00000050: // KEYCODE_FOCUS ?!?!?
return Qt::Key_Any;
default:
@@ -447,7 +488,7 @@ namespace QtAndroidInput
mapAndroidKey(key),
modifiers,
QChar(unicode),
- true);
+ false);
}
static void keyUp(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier)
@@ -467,7 +508,7 @@ namespace QtAndroidInput
mapAndroidKey(key),
modifiers,
QChar(unicode),
- true);
+ false);
}
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp
index b51c15c5d9..5c9ca798a8 100644
--- a/src/plugins/platforms/android/src/androidjnimain.cpp
+++ b/src/plugins/platforms/android/src/androidjnimain.cpp
@@ -419,14 +419,11 @@ static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobj
static void *startMainMethod(void */*data*/)
{
- char const **params;
- params = static_cast<char const **>(malloc(m_applicationParams.length() * sizeof(char *)));
+ QVarLengthArray<const char *> params(m_applicationParams.size());
for (int i = 0; i < m_applicationParams.size(); i++)
params[i] = static_cast<const char *>(m_applicationParams[i].constData());
- int ret = m_main(m_applicationParams.length(), const_cast<char **>(params));
-
- free(params);
+ int ret = m_main(m_applicationParams.length(), const_cast<char **>(params.data()));
Q_UNUSED(ret);
if (m_mainLibraryHnd) {
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
index 9ce382bd53..a3db421de9 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
@@ -42,7 +42,6 @@
#include "qandroidplatformintegration.h"
#include "qabstracteventdispatcher.h"
#include "androidjnimain.h"
-#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/qguiapplication.h>
#include <qpa/qwindowsysteminterface.h>
#include <QThread>
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
index 36247e86f9..253c22a12f 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
@@ -67,9 +67,11 @@ void QAndroidPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatform
void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
{
QMutexLocker lock(&m_menuItemsMutex);
- m_menuItems.erase(qFind(m_menuItems.begin(),
- m_menuItems.end(),
- static_cast<QAndroidPlatformMenuItem *>(menuItem)));
+ PlatformMenuItemsType::iterator it = qFind(m_menuItems.begin(),
+ m_menuItems.end(),
+ static_cast<QAndroidPlatformMenuItem *>(menuItem));
+ if (it != m_menuItems.end())
+ m_menuItems.erase(it);
}
void QAndroidPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem)
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 05bf657c1f..7f0f07e912 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -201,9 +201,11 @@ public: // for QNSView
bool m_isExposed;
int m_registerTouchCount;
bool m_resizableTransientParent;
+ bool m_overrideBecomeKey;
static const int NoAlertRequest;
NSInteger m_alertRequest;
+ id monitor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 7bdfd12314..845cc1202f 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -160,7 +160,9 @@ static bool isMouseEvent(NSEvent *ev)
// Only tool or dialog windows should become key:
if (m_cocoaPlatformWindow
- && (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog))
+ && (m_cocoaPlatformWindow->m_overrideBecomeKey ||
+ m_cocoaPlatformWindow->window()->type() == Qt::Tool ||
+ m_cocoaPlatformWindow->window()->type() == Qt::Dialog))
return YES;
return NO;
}
@@ -212,7 +214,9 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_isExposed(false)
, m_registerTouchCount(0)
, m_resizableTransientParent(false)
+ , m_overrideBecomeKey(false)
, m_alertRequest(NoAlertRequest)
+ , monitor(nil)
{
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
@@ -367,6 +371,11 @@ void QCocoaWindow::setVisible(bool visible)
if ((window()->type() == Qt::Popup || window()->type() == Qt::Dialog || window()->type() == Qt::Tool)
&& [m_nsWindow isKindOfClass:[NSPanel class]]) {
[(NSPanel *)m_nsWindow setWorksWhenModal:YES];
+ if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) {
+ monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDown handler:^(NSEvent *) {
+ QWindowSystemInterface::handleMouseEvent(window(), QPointF(-1, -1), QPointF(window()->framePosition() - QPointF(1, 1)), Qt::LeftButton);
+ }];
+ }
}
}
}
@@ -403,6 +412,10 @@ void QCocoaWindow::setVisible(bool visible)
} else {
[m_contentView setHidden:YES];
}
+ if (monitor && window()->type() == Qt::Popup) {
+ [NSEvent removeMonitor:monitor];
+ monitor = nil;
+ }
if (parentCocoaWindow && window()->type() == Qt::Popup) {
parentCocoaWindow->m_activePopupWindow = 0;
if (m_resizableTransientParent
@@ -450,7 +463,6 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
{
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
NSInteger styleMask = NSBorderlessWindowMask;
-
if ((type & Qt::Popup) == Qt::Popup) {
if (!windowIsPopupType(type) && !(flags & Qt::FramelessWindowHint))
styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask |
@@ -458,14 +470,21 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
} else {
// Filter flags for supported properties
flags &= Qt::WindowType_Mask | Qt::FramelessWindowHint | Qt::WindowTitleHint |
- Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint;
+ Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint;
if (flags == Qt::Window) {
styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask);
} else if ((flags & Qt::Dialog) == Qt::Dialog) {
- if (window()->modality() == Qt::NonModal)
+ if (flags & Qt::CustomizeWindowHint) {
+ styleMask = NSResizableWindowMask;
+ if (flags & Qt::WindowTitleHint)
+ styleMask |= NSTitledWindowMask;
+ if (flags & Qt::WindowCloseButtonHint)
+ styleMask |= NSClosableWindowMask;
+ if (flags & Qt::WindowMinimizeButtonHint)
+ styleMask |= NSMiniaturizableWindowMask;
+ } else {
styleMask = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask;
- else
- styleMask = NSResizableWindowMask | NSTitledWindowMask;
+ }
} else if (!(flags & Qt::FramelessWindowHint)) {
if ((flags & Qt::Dialog) || (flags & Qt::WindowMaximizeButtonHint))
styleMask |= NSResizableWindowMask;
@@ -661,6 +680,8 @@ bool QCocoaWindow::setKeyboardGrabEnabled(bool grab)
if (!m_nsWindow)
return false;
+ m_overrideBecomeKey = grab;
+
if (grab && ![m_nsWindow isKeyWindow])
[m_nsWindow makeKeyWindow];
else if (!grab && [m_nsWindow isKeyWindow])
@@ -673,6 +694,8 @@ bool QCocoaWindow::setMouseGrabEnabled(bool grab)
if (!m_nsWindow)
return false;
+ m_overrideBecomeKey = grab;
+
if (grab && ![m_nsWindow isKeyWindow])
[m_nsWindow makeKeyWindow];
else if (!grab && [m_nsWindow isKeyWindow])
@@ -843,10 +866,9 @@ NSWindow * QCocoaWindow::createNSWindow()
// before the window is shown and needs a proper window.).
if ((type & Qt::Popup) == Qt::Popup)
[window setHasShadow:YES];
- else {
- setWindowShadow(flags);
- [window setHidesOnDeactivate: NO];
- }
+ else
+ setWindowShadow(flags);
+ [window setHidesOnDeactivate: NO];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 8813a934bf..f90fc6b205 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -208,6 +208,22 @@ static QTouchDevice *touchDevice = 0;
if ([self window])
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[self window]];
}
+
+- (QWindow *)topLevelWindow
+{
+ QWindow *focusWindow = m_window;
+
+ // For widgets we need to do a bit of trickery as the window
+ // to activate is the window of the top-level widget.
+ if (m_window->metaObject()->className() == QStringLiteral("QWidgetWindow")) {
+ while (focusWindow->parent()) {
+ focusWindow = focusWindow->parent();
+ }
+ }
+
+ return focusWindow;
+}
+
- (void)updateGeometry
{
QRect geometry;
@@ -457,16 +473,7 @@ static QTouchDevice *touchDevice = 0;
{
if (m_window->flags() & Qt::WindowTransparentForInput)
return NO;
- QWindow *focusWindow = m_window;
-
- // For widgets we need to do a bit of trickery as the window
- // to activate is the window of the top-level widget.
- if (m_window->metaObject()->className() == QStringLiteral("QWidgetWindow")) {
- while (focusWindow->parent()) {
- focusWindow = focusWindow->parent();
- }
- }
- QWindowSystemInterface::handleWindowActivated(focusWindow);
+ QWindowSystemInterface::handleWindowActivated([self topLevelWindow]);
return YES;
}
@@ -968,6 +975,102 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, touchDevice, points);
}
+#ifndef QT_NO_GESTURES
+//#define QT_COCOA_ENABLE_GESTURE_DEBUG
+- (void)magnifyWithEvent:(NSEvent *)event
+{
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "magnifyWithEvent" << [event magnification];
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::ZoomNativeGesture,
+ [event magnification], windowPoint, screenPoint);
+}
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
+- (void)smartMagnifyWithEvent:(NSEvent *)event
+{
+ static bool zoomIn = true;
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "smartMagnifyWithEvent" << zoomIn;
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SmartZoomNativeGesture,
+ zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint);
+ zoomIn = !zoomIn;
+}
+#endif
+
+- (void)rotateWithEvent:(NSEvent *)event
+{
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "rotateWithEvent" << [event rotation];
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::RotateNativeGesture,
+ -[event rotation], windowPoint, screenPoint);
+}
+
+- (void)swipeWithEvent:(NSEvent *)event
+{
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "swipeWithEvent" << [event deltaX] << [event deltaY];
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+
+ qreal angle = 0.0f;
+ if ([event deltaX] == 1)
+ angle = 180.0f;
+ else if ([event deltaX] == -1)
+ angle = 0.0f;
+ else if ([event deltaY] == 1)
+ angle = 90.0f;
+ else if ([event deltaY] == -1)
+ angle = 270.0f;
+
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SwipeNativeGesture,
+ angle, windowPoint, screenPoint);
+}
+
+- (void)beginGestureWithEvent:(NSEvent *)event
+{
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "beginGestureWithEvent";
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::BeginNativeGesture,
+ windowPoint, screenPoint);
+}
+
+- (void)endGestureWithEvent:(NSEvent *)event
+{
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "endGestureWithEvent";
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::EndNativeGesture,
+ windowPoint, screenPoint);
+}
+#endif // QT_NO_GESTURES
+
#ifndef QT_NO_WHEELEVENT
- (void)scrollWheel:(NSEvent *)theEvent
{
@@ -1124,10 +1227,12 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
if (ch.unicode() < 0xf700 || ch.unicode() > 0xf8ff)
text = QCFString::toQString(characters);
+ QWindow *focusWindow = [self topLevelWindow];
+
if (eventType == QEvent::KeyPress) {
if (m_composingText.isEmpty())
- m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(m_window, timestamp, keyCode, modifiers, text);
+ m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(focusWindow, timestamp, keyCode, modifiers, text);
QObject *fo = QGuiApplication::focusObject();
if (m_sendKeyEvent && fo) {
@@ -1144,7 +1249,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
}
if (m_sendKeyEvent && m_composingText.isEmpty())
- QWindowSystemInterface::handleExtendedKeyEvent(m_window, timestamp, QEvent::Type(eventType), keyCode, modifiers,
+ QWindowSystemInterface::handleExtendedKeyEvent(focusWindow, timestamp, QEvent::Type(eventType), keyCode, modifiers,
nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat]);
m_sendKeyEvent = false;
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
index 5b4c958616..b56d75a16e 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -282,9 +282,12 @@ QDirectFbKeyMap::QDirectFbKeyMap()
insert(DIKS_MENU , Qt::Key_Menu);
insert(DIKS_HELP , Qt::Key_Help);
+ insert(DIKS_CD , Qt::Key_CD);
insert(DIKS_INTERNET , Qt::Key_HomePage);
insert(DIKS_MAIL , Qt::Key_LaunchMail);
insert(DIKS_FAVORITES , Qt::Key_Favorites);
+ insert(DIKS_PHONE , Qt::Key_Phone);
+ insert(DIKS_TIME , Qt::Key_Time);
insert(DIKS_RED , Qt::Key_Red);
insert(DIKS_GREEN , Qt::Key_Green);
@@ -307,6 +310,7 @@ QDirectFbKeyMap::QDirectFbKeyMap()
insert(DIKS_NEXT , Qt::Key_MediaNext);
insert(DIKS_REWIND , Qt::Key_AudioRewind);
insert(DIKS_FASTFORWARD , Qt::Key_AudioForward);
+ insert(DIKS_SUBTITLE , Qt::Key_Subtitle);
insert(DIKS_F1 , Qt::Key_F1);
insert(DIKS_F2 , Qt::Key_F2);
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index f7df792362..3dd9c7ad9f 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -213,7 +213,7 @@ static int infoPlistValue(NSString* key, int defaultValue)
return value ? [value intValue] : defaultValue;
}
-extern "C" int qtmn(int argc, char *argv[])
+extern "C" int __attribute__((weak)) main(int argc, char *argv[])
{
@autoreleasepool {
size_t defaultStackSize = 512 * kBytesPerKiloByte; // Same as secondary threads
@@ -248,7 +248,18 @@ enum SetJumpResult
kJumpedFromUserMainTrampoline,
};
-extern "C" int main(int argc, char *argv[]);
+// We define qt_main so that user_main_trampoline() will not cause
+// missing symbols in the case of hybrid applications that don't
+// user our main wrapper. Since the symbol is weak, it will not
+// get used or cause a clash in the normal Qt application usecase,
+// where we rename main to qt_main.
+extern "C" int __attribute__((weak)) qt_main(int argc, char *argv[])
+{
+ Q_UNUSED(argc);
+ Q_UNUSED(argv);
+
+ Q_UNREACHABLE();
+}
static void __attribute__((noinline, noreturn)) user_main_trampoline()
{
@@ -261,7 +272,7 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline()
strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]);
}
- int exitCode = main(argc, argv);
+ int exitCode = qt_main(argc, argv);
delete[] argv;
qEventDispatcherDebug() << "Returned from main with exit code " << exitCode;
@@ -496,6 +507,7 @@ void QIOSEventDispatcher::checkIfEventLoopShouldExit()
void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity)
{
+ Q_UNUSED(activity);
Q_ASSERT(activity == kCFRunLoopExit);
m_runLoopExitObserver.removeFromMode(kCFRunLoopCommonModes);
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index aa2687da30..977df8abd0 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -56,9 +56,8 @@ QT_BEGIN_NAMESPACE
QLinuxFbIntegration::QLinuxFbIntegration(const QStringList &paramList)
: m_fontDb(new QGenericUnixFontDatabase())
{
- m_primaryScreen = new QLinuxFbScreen;
- if (m_primaryScreen->initialize(paramList))
- screenAdded(m_primaryScreen);
+ m_primaryScreen = new QLinuxFbScreen(paramList);
+ screenAdded(m_primaryScreen);
}
QLinuxFbIntegration::~QLinuxFbIntegration()
@@ -66,6 +65,12 @@ QLinuxFbIntegration::~QLinuxFbIntegration()
delete m_primaryScreen;
}
+void QLinuxFbIntegration::initialize()
+{
+ if (!m_primaryScreen->initialize())
+ qWarning("linuxfb: Failed to initialize screen");
+}
+
bool QLinuxFbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
index 6de9ac9992..a213f83c6f 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -56,14 +56,16 @@ public:
QLinuxFbIntegration(const QStringList &paramList);
~QLinuxFbIntegration();
- bool hasCapability(QPlatformIntegration::Capability cap) const;
+ void initialize() Q_DECL_OVERRIDE;
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+ QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
+ QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
- QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
- QAbstractEventDispatcher *createEventDispatcher() const;
QList<QPlatformScreen *> screens() const;
- QPlatformFontDatabase *fontDatabase() const;
private:
QLinuxFbScreen *m_primaryScreen;
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index ad5206ba41..4f9284da7f 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -62,6 +62,10 @@
#include <linux/fb.h>
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+#include <QtPlatformSupport/private/qdevicediscovery_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
static int openFramebufferDevice(const QString &dev)
@@ -292,8 +296,8 @@ static void blankScreen(int fd, bool on)
ioctl(fd, FBIOBLANK, on ? VESA_POWERDOWN : VESA_NO_BLANKING);
}
-QLinuxFbScreen::QLinuxFbScreen()
- : mFbFd(-1), mBlitter(0)
+QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)
+ : mArgs(args), mFbFd(-1), mBlitter(0)
{
}
@@ -312,7 +316,7 @@ QLinuxFbScreen::~QLinuxFbScreen()
delete mBlitter;
}
-bool QLinuxFbScreen::initialize(const QStringList &args)
+bool QLinuxFbScreen::initialize()
{
QRegExp ttyRx(QLatin1String("tty=(.*)"));
QRegExp fbRx(QLatin1String("fb=(.*)"));
@@ -326,7 +330,7 @@ bool QLinuxFbScreen::initialize(const QStringList &args)
bool doSwitchToGraphicsMode = true;
// Parse arguments
- foreach (const QString &arg, args) {
+ foreach (const QString &arg, mArgs) {
if (arg == QLatin1String("nographicsmodeswitch"))
doSwitchToGraphicsMode = false;
else if (sizeRx.indexIn(arg) != -1)
@@ -341,8 +345,15 @@ bool QLinuxFbScreen::initialize(const QStringList &args)
userMmSize = QSize(mmSizeRx.cap(1).toInt(), mmSizeRx.cap(2).toInt());
}
- if (fbDevice.isEmpty())
- fbDevice = QLatin1String("/dev/fb0"); // ## auto-detect
+ if (fbDevice.isEmpty()) {
+ fbDevice = QLatin1String("/dev/fb0");
+ if (!QFile::exists(fbDevice))
+ fbDevice = QLatin1String("/dev/graphics/fb0");
+ if (!QFile::exists(fbDevice)) {
+ qWarning("Unable to figure out framebuffer device. Specify it manually.");
+ return false;
+ }
+ }
// Open the device
mFbFd = openFramebufferDevice(fbDevice);
@@ -387,7 +398,19 @@ bool QLinuxFbScreen::initialize(const QStringList &args)
QFbScreen::initializeCompositor();
mFbScreenImage = QImage(mMmap.data, geometry.width(), geometry.height(), mBytesPerLine, mFormat);
- mCursor = new QFbCursor(this);
+
+ QByteArray hideCursorVal = qgetenv("QT_QPA_FB_HIDECURSOR");
+ bool hideCursor = true; // default to true to prevent the cursor showing up with the subclass on Android
+ if (hideCursorVal.isEmpty()) {
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+ QScopedPointer<QDeviceDiscovery> dis(QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse));
+ hideCursor = dis->scanConnectedDevices().isEmpty();
+#endif
+ } else {
+ hideCursor = hideCursorVal.toInt() != 0;
+ }
+ if (!hideCursor)
+ mCursor = new QFbCursor(this);
mTtyFd = openTtyDevice(ttyDevice);
if (mTtyFd == -1)
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
index d34104c6e1..32cd263063 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
@@ -53,15 +53,16 @@ class QLinuxFbScreen : public QFbScreen
{
Q_OBJECT
public:
- QLinuxFbScreen();
+ QLinuxFbScreen(const QStringList &args);
~QLinuxFbScreen();
- bool initialize(const QStringList &args);
+ bool initialize();
public slots:
QRegion doRedraw();
private:
+ QStringList mArgs;
int mFbFd;
int mTtyFd;
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index 355f52c46e..34e8150928 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -124,7 +124,15 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
if (m_eglConfig == 0)
qFatal("QQnxGLContext: failed to find EGL config");
- m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttrs());
+ EGLContext shareContext = EGL_NO_CONTEXT;
+ if (m_glContext) {
+ QQnxGLContext *qshareContext = dynamic_cast<QQnxGLContext*>(m_glContext->shareHandle());
+ if (qshareContext) {
+ shareContext = qshareContext->m_eglContext;
+ }
+ }
+
+ m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, shareContext, contextAttrs());
if (m_eglContext == EGL_NO_CONTEXT) {
checkEGLError("eglCreateContext");
qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError());
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index 6c3fd08a41..dd8cf2131a 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -446,7 +446,7 @@ void QQnxScreen::addWindow(QQnxWindow *window)
m_childWindows.push_back(window);
updateHierarchy();
} else {
-#if !defined(Q_OS_BLACKBERRY_TABLET)
+#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET)
m_coverWindow = window;
#endif
}
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index a129380575..3969a09098 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -562,13 +562,11 @@ void QQnxWindow::initWindow()
setScreen(static_cast<QQnxScreen *>(window()->screen()->handle()));
if (window()->type() == Qt::CoverWindow) {
-#if !defined(Q_OS_BLACKBERRY_TABLET)
+#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET)
screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(),
SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window);
-#if defined(Q_OS_BLACKBERRY)
m_cover.reset(new QQnxNavigatorCover);
#endif
-#endif // Q_OS_BLACKBERRY_TABLET
m_exposed = false;
}
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index ee5b6189b2..f6ed9447ef 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -204,6 +204,9 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
case WM_DISPLAYCHANGE:
return QtWindows::DisplayChangedEvent;
case WM_THEMECHANGED:
+#ifdef WM_SYSCOLORCHANGE // Windows 7: Handle color change as theme change (QTBUG-34170).
+ case WM_SYSCOLORCHANGE:
+#endif
return QtWindows::ThemeChanged;
case WM_DWMCOMPOSITIONCHANGED:
return QtWindows::CompositionSettingsChanged;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 783d50a26a..85b03673ac 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -954,7 +954,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
qGuiAppPriv->commitData();
if (lParam & ENDSESSION_LOGOFF)
- _flushall();
+ fflush(NULL);
return !sessionManager->wasCanceled();
}
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 0ecbf44194..832ce24354 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -578,8 +578,8 @@ bool QWindowsDialogHelperBase<BaseClass>::show(Qt::WindowFlags,
m_ownerWindow = 0;
}
if (QWindowsContext::verboseDialogs)
- qDebug("%s modal=%d native=%p parent=%p" ,
- __FUNCTION__, modal, m_nativeDialog.data(), m_ownerWindow);
+ qDebug("%s modal=%d modal supported? %d native=%p parent=%p" ,
+ __FUNCTION__, modal, supportsNonModalDialog(parent), m_nativeDialog.data(), m_ownerWindow);
if (!modal && !supportsNonModalDialog(parent))
return false; // Was it changed in-between?
if (!ensureNativeDialog())
@@ -1766,7 +1766,9 @@ static int CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UINT uMsg,
return dialog->existingDirCallback(hwnd, uMsg, lParam);
}
-#ifdef Q_CC_MINGW
+/* The correct declaration of the SHGetPathFromIDList symbol is
+ * being used in mingw-w64 as of r6215, which is a v3 snapshot. */
+#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3)
typedef ITEMIDLIST *qt_LpItemIdList;
#else
typedef PIDLIST_ABSOLUTE qt_LpItemIdList;
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index 4a5d7b5a78..1a5c1a2e0c 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -395,8 +395,19 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
const int currentDevice = m_devices.at(m_currentDevice).currentDevice;
const int currentPointer = m_devices.at(m_currentDevice).currentPointerType;
- // When entering proximity, the tablet driver snaps the mouse pointer to the
- // tablet position scaled to the virtual desktop and keeps it in sync.
+ // The tablet can be used in 2 different modes, depending on it settings:
+ // 1) Absolute (pen) mode:
+ // The coordinates are scaled to the virtual desktop (by default). The user
+ // can also choose to scale to the monitor or a region of the screen.
+ // When entering proximity, the tablet driver snaps the mouse pointer to the
+ // tablet position scaled to that area and keeps it in sync.
+ // 2) Relative (mouse) mode:
+ // The pen follows the mouse. The constant 'absoluteRange' specifies the
+ // manhattanLength difference for detecting if a tablet input device is in this mode,
+ // in which case we snap the position to the mouse position.
+ // It seems there is no way to find out the mode programmatically, the LOGCONTEXT orgX/Y/Ext
+ // area is always the virtual desktop.
+ enum { absoluteRange = 20 };
const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
if (QWindowsContext::verboseTablet)
@@ -409,10 +420,24 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
const PACKET &packet = localPacketBuf[i];
const int z = currentDevice == QTabletEvent::FourDMouse ? int(packet.pkZ) : 0;
- const QPointF globalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea);
+
+ // This code is to delay the tablet data one cycle to sync with the mouse location.
+ QPointF globalPosF = m_oldGlobalPosF;
+ m_oldGlobalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea);
QWindow *target = QGuiApplicationPrivate::tabletPressTarget; // Pass to window that grabbed it.
- const QPoint globalPos = globalPosF.toPoint();
+ QPoint globalPos = globalPosF.toPoint();
+
+ // Get Mouse Position and compare to tablet info
+ const QPoint mouseLocation = QWindowsCursor::mousePosition();
+
+ // Positions should be almost the same if we are in absolute
+ // mode. If they are not, use the mouse location.
+ if ((mouseLocation - globalPos).manhattanLength() > absoluteRange) {
+ globalPos = mouseLocation;
+ globalPosF = globalPos;
+ }
+
if (!target)
if (QPlatformWindow *pw = QWindowsContext::instance()->findPlatformWindowAt(GetDesktopWindow(), globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT))
target = pw->window();
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h
index 12f96b618d..5e29cd9554 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.h
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.h
@@ -134,6 +134,7 @@ private:
bool m_tiltSupport;
QVector<QWindowsTabletDeviceData> m_devices;
int m_currentDevice;
+ QPointF m_oldGlobalPosF;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index be739d0551..1909e0313b 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1056,9 +1056,10 @@ void QWindowsWindow::setVisible(bool visible)
// When the window is layered, we won't get WM_PAINT, and "we" are in control
// over the rendering of the window
// There is nobody waiting for this, so we don't need to flush afterwards.
- QWindow *w = window();
- if (w->format().hasAlpha() || qFuzzyCompare(w->opacity(), qreal(1)))
+ if (isLayered()) {
+ QWindow *w = window();
fireExpose(QRect(0, 0, w->width(), w->height()));
+ }
} else {
if (hasMouseCapture())
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 4961e0377c..d18693f6b8 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -835,7 +835,7 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event)
void QXcbDrag::handleStatus(const xcb_client_message_event_t *event)
{
- if (event->window != connection()->clipboard()->owner())
+ if (event->window != connection()->clipboard()->owner() || !drag())
return;
xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index a3d6a65695..8c10b134bd 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -48,6 +48,7 @@
#include <qplatformdefs.h>
#include <qsocketnotifier.h>
#include <X11/SM/SMlib.h>
+#include <errno.h> // ERANGE
#include <cerrno> // ERANGE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 6d986ba601..aa53093868 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1148,7 +1148,7 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
QByteArray ba("Qt NET_WM user time window");
Q_XCB_CALL(xcb_change_property(xcb_connection(),
XCB_PROP_MODE_REPLACE,
- m_window,
+ m_netWmUserTimeWindow,
atom(QXcbAtom::_NET_WM_NAME),
atom(QXcbAtom::UTF8_STRING),
8,
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
index f41d4f5047..b9f0c394f8 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
@@ -66,8 +66,7 @@ QCupsPrinterSupport::QCupsPrinterSupport() : QPlatformPrinterSupport(),
QCupsPrinterSupport::~QCupsPrinterSupport()
{
- if (cupsFreeDests)
- cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters);
+ freeCupsPrinters();
}
QPrintEngine *QCupsPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode printerMode)
@@ -98,14 +97,20 @@ void QCupsPrinterSupport::loadCups()
cupsGetOption = (CupsGetOption) m_cups.resolve("cupsGetOption");
}
+void QCupsPrinterSupport::freeCupsPrinters()
+{
+ if (cupsFreeDests && m_cupsPrintersCount) {
+ cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters);
+ m_cupsPrintersCount = 0;
+ m_cupsPrinters = 0;
+ }
+}
+
void QCupsPrinterSupport::loadCupsPrinters()
{
- m_cupsPrintersCount = 0;
+ freeCupsPrinters();
m_printers.clear();
- if (cupsFreeDests)
- cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters);
-
if (cupsGetDests)
m_cupsPrintersCount = cupsGetDests(&m_cupsPrinters);
@@ -122,6 +127,12 @@ void QCupsPrinterSupport::loadCupsPrinters()
}
}
+QList<QPrinterInfo> QCupsPrinterSupport::availablePrinters()
+{
+ loadCupsPrinters();
+ return QPlatformPrinterSupport::availablePrinters();
+}
+
QString QCupsPrinterSupport::printerOption(const QPrinterInfo &printer, const QString &key) const
{
return cupsOption(printerIndex(printer), key);
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h
index e9fe24203e..d42c0d2630 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h
+++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h
@@ -68,12 +68,14 @@ public:
virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode);
virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
virtual QList<QPair<QString, QSizeF> > supportedSizesWithNames(const QPrinterInfo &) const;
+ virtual QList<QPrinterInfo> availablePrinters();
virtual QString printerOption(const QPrinterInfo &printer, const QString &key) const;
virtual PrinterOptions printerOptions(const QPrinterInfo &printer) const;
private:
void loadCups();
void loadCupsPrinters();
+ void freeCupsPrinters();
QString cupsOption(int i, const QString &key) const;
QLibrary m_cups;
diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp
index 36e7a3fb8e..2faebf6f64 100644
--- a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp
+++ b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp
@@ -42,6 +42,7 @@
#include "qwindowsprintersupport.h"
#include <QtCore/QList>
+#include <QtCore/QScopedArrayPointer>
#include <QtPrintSupport/QPrinterInfo>
#include <qprintengine_win_p.h>
#include <private/qpaintengine_alpha_p.h>
@@ -52,25 +53,7 @@ QT_BEGIN_NAMESPACE
QWindowsPrinterSupport::QWindowsPrinterSupport()
: QPlatformPrinterSupport()
{
- DWORD needed = 0;
- DWORD returned = 0;
- if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) {
- LPBYTE buffer = new BYTE[needed];
- if (EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer, needed, &needed, &returned)) {
- PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer);
- QString defaultPrinterName;
- QString program;
- QString port;
- QWin32PrintEngine::queryDefaultPrinter(defaultPrinterName, program, port);
- for (uint i = 0; i < returned; ++i) {
- QString printerName(QString::fromWCharArray(infoList[i].pPrinterName));
- bool isDefault = (printerName == defaultPrinterName);
- QPrinterInfo printerInfo = createPrinterInfo(printerName, QString(), QString(), QString(), isDefault, i);
- m_printers.append(printerInfo);
- }
- }
- delete [] buffer;
- }
+ m_printers = QWindowsPrinterSupport::queryPrinters();
}
QWindowsPrinterSupport::~QWindowsPrinterSupport()
@@ -98,4 +81,35 @@ QList<QPair<QString, QSizeF> >QWindowsPrinterSupport::supportedSizesWithNames(co
return QWin32PrintEngine::supportedSizesWithNames(printerInfo);
}
+QList<QPrinterInfo> QWindowsPrinterSupport::availablePrinters()
+{
+ m_printers = QWindowsPrinterSupport::queryPrinters();
+ return QPlatformPrinterSupport::availablePrinters();
+}
+
+QList<QPrinterInfo> QWindowsPrinterSupport::queryPrinters()
+{
+ QList<QPrinterInfo> result;
+ DWORD needed = 0;
+ DWORD returned = 0;
+ if ((!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ || !needed) {
+ return result;
+ }
+ QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
+ if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer.data(), needed, &needed, &returned))
+ return result;
+ PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer.data());
+ QString defaultPrinterName;
+ QString program;
+ QString port;
+ QWin32PrintEngine::queryDefaultPrinter(defaultPrinterName, program, port);
+ for (uint i = 0; i < returned; ++i) {
+ const QString printerName(QString::fromWCharArray(infoList[i].pPrinterName));
+ const bool isDefault = (printerName == defaultPrinterName);
+ result.append(QPlatformPrinterSupport::createPrinterInfo(printerName, QString(), QString(), QString(), isDefault, i));
+ }
+ return result;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h
index 1d5a4f3da4..1b1b1fa215 100644
--- a/src/plugins/printsupport/windows/qwindowsprintersupport.h
+++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h
@@ -58,6 +58,10 @@ public:
virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode);
virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
virtual QList<QPair<QString, QSizeF> >supportedSizesWithNames(const QPrinterInfo &printerInfo) const;
+ virtual QList<QPrinterInfo> availablePrinters();
+
+private:
+ static QList<QPrinterInfo> queryPrinters();
};
QT_END_NAMESPACE
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
index cdb80f96a8..8809b52751 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
@@ -408,6 +408,7 @@ void QPageSetupWidget::selectPrinter()
if (QCUPSSupport::isAvailable()) {
m_cups = true;
QCUPSSupport cups;
+ cups.setCurrentPrinter(m_printer->printerName());
const ppd_option_t* pageSizes = cups.pageSizes();
const int numChoices = pageSizes ? pageSizes->num_choices : 0;
diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp
index 643ffef192..e237d44dcd 100644
--- a/src/printsupport/kernel/qcups.cpp
+++ b/src/printsupport/kernel/qcups.cpp
@@ -144,11 +144,13 @@ QCUPSSupport::QCUPSSupport()
for (int i = 0; i < prnCount; ++i) {
if (printers[i].is_default) {
currPrinterIndex = i;
- setCurrentPrinter(i);
break;
}
}
+ if (prnCount > 0)
+ setCurrentPrinter(currPrinterIndex);
+
#ifndef QT_NO_TEXTCODEC
cups_lang_t *cupsLang = _cupsLangGet(0);
codec = QTextCodec::codecForName(_cupsLangEncoding(cupsLang));
@@ -213,6 +215,17 @@ const ppd_file_t* QCUPSSupport::setCurrentPrinter(int index)
return currPPD;
}
+const ppd_file_t* QCUPSSupport::setCurrentPrinter(const QString &printerName)
+{
+ Q_FOREACH (const QCUPSSupport::Printer &printer, QCUPSSupport::availableUnixPrinters()) {
+ if (printer.name == printerName) {
+ return setCurrentPrinter(printer.cupsPrinterIndex);
+ }
+ }
+
+ return 0;
+}
+
int QCUPSSupport::currentPrinterIndex() const
{
return currPrinterIndex;
diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h
index 726bc7eba6..95ca323c22 100644
--- a/src/printsupport/kernel/qcups_p.h
+++ b/src/printsupport/kernel/qcups_p.h
@@ -149,6 +149,7 @@ public:
const cups_dest_t* availablePrinters() const;
int currentPrinterIndex() const;
const ppd_file_t* setCurrentPrinter(int index);
+ const ppd_file_t* setCurrentPrinter(const QString &printerName);
const ppd_file_t* currentPPD() const;
const ppd_option_t* ppdOption(const char *key) const;
diff --git a/src/src.pro b/src/src.pro
index 641a8a98a6..74ca7fbf0b 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -2,36 +2,44 @@ TEMPLATE = subdirs
src_tools_bootstrap.subdir = tools/bootstrap
src_tools_bootstrap.target = sub-bootstrap
+src_tools_bootstrap.CONFIG = host_build
src_tools_moc.subdir = tools/moc
src_tools_moc.target = sub-moc
src_tools_moc.depends = src_tools_bootstrap
+src_tools_moc.CONFIG = host_build
src_tools_rcc.subdir = tools/rcc
src_tools_rcc.target = sub-rcc
src_tools_rcc.depends = src_tools_bootstrap
+src_tools_rcc.CONFIG = host_build
src_tools_uic.subdir = tools/uic
src_tools_uic.target = sub-uic
+src_tools_uic.CONFIG = host_build
force_bootstrap: src_tools_uic.depends = src_tools_bootstrap
else: src_tools_uic.depends = src_corelib
src_tools_qdoc.subdir = tools/qdoc
src_tools_qdoc.target = sub-qdoc
+src_tools_qdoc.CONFIG = host_build
force_bootstrap: src_tools_qdoc.depends = src_tools_bootstrap
else: src_tools_qdoc.depends = src_corelib src_xml
src_tools_bootstrap_dbus.subdir = tools/bootstrap-dbus
src_tools_bootstrap_dbus.target = sub-bootstrap_dbus
src_tools_bootstrap_dbus.depends = src_tools_bootstrap
+src_tools_bootstrap_dbus.CONFIG = host_build
src_tools_qdbusxml2cpp.subdir = tools/qdbusxml2cpp
src_tools_qdbusxml2cpp.target = sub-qdbusxml2cpp
+src_tools_qdbusxml2cpp.CONFIG = host_build
force_bootstrap: src_tools_qdbusxml2cpp.depends = src_tools_bootstrap_dbus
else: src_tools_qdbusxml2cpp.depends = src_dbus
src_tools_qdbuscpp2xml.subdir = tools/qdbuscpp2xml
src_tools_qdbuscpp2xml.target = sub-qdbuscpp2xml
+src_tools_qdbuscpp2xml.CONFIG = host_build
force_bootstrap: src_tools_qdbuscpp2xml.depends = src_tools_bootstrap_dbus
else: src_tools_qdbuscpp2xml.depends = src_dbus
diff --git a/src/testlib/doc/src/qttest-index.qdoc b/src/testlib/doc/src/qttest-index.qdoc
index db42db1687..4cf0726429 100644
--- a/src/testlib/doc/src/qttest-index.qdoc
+++ b/src/testlib/doc/src/qttest-index.qdoc
@@ -56,6 +56,7 @@
\list
\li \l{Qt Test C++ Classes}{C++ Classes}
+ \li \l{Qt Quick Test}{QML Types}
\endlist
*/
diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h
index 8efa80789c..a07d6bc8c6 100644
--- a/src/testlib/qtestmouse.h
+++ b/src/testlib/qtestmouse.h
@@ -61,7 +61,7 @@
#include <QtWidgets/qwidget.h>
#endif
-#include <QDebug>
+#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 34d3c06e97..b39a3b5e9f 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -310,7 +310,7 @@ void Generator::generateCode()
int escapeLen = lengthOfEscapeSequence(s, backSlashPos);
spanLen = qBound(spanLen, backSlashPos + escapeLen - idx, s.length() - idx);
}
- fwrite(s.constData() + idx, 1, spanLen, out);
+ fprintf(out, "%.*s", spanLen, s.constData() + idx);
idx += spanLen;
col += spanLen;
}
diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp
index dd72be7f6e..246e4d2d82 100644
--- a/src/tools/qdoc/main.cpp
+++ b/src/tools/qdoc/main.cpp
@@ -68,27 +68,6 @@
QT_BEGIN_NAMESPACE
-/*
- The default indent for code is 4.
- The default value for false is 0.
- The default supported file extensions are cpp, h, qdoc and qml.
- The default language is c++.
- The default output format is html.
- The default tab size is 8.
- And those are all the default values for configuration variables.
- */
-static const struct {
- const QString key;
- const QString value;
-} defaults[] = {
- { CONFIG_CODEINDENT, QLatin1String("4") },
- { CONFIG_FALSEHOODS, QLatin1String("0") },
- { CONFIG_FILEEXTENSIONS, QLatin1String("*.cpp *.h *.qdoc *.qml") },
- { CONFIG_LANGUAGE, QLatin1String("Cpp") },
- { CONFIG_OUTPUTFORMATS, QLatin1String("HTML") },
- { CONFIG_TABSIZE, QLatin1String("8") },
- { QString(), QString() }
-};
bool creationTimeBefore(const QFileInfo &fi1, const QFileInfo &fi2)
{
@@ -268,11 +247,30 @@ static void processQdocconfFile(const QString &fileName)
initialize the configuration with some default values.
*/
Config config(QCoreApplication::translate("QDoc", "qdoc"));
- int i = 0;
- while (!defaults[i].key.isEmpty()) {
- config.setStringList(defaults[i].key, QStringList() << defaults[i].value);
- ++i;
+
+ /*
+ The default indent for code is 4.
+ The default value for false is 0.
+ The default supported file extensions are cpp, h, qdoc and qml.
+ The default language is c++.
+ The default output format is html.
+ The default tab size is 8.
+ And those are all the default values for configuration variables.
+ */
+ static QHash<QString,QString> defaults;
+ if (defaults.isEmpty()) {
+ defaults.insert(CONFIG_CODEINDENT, QLatin1String("4"));
+ defaults.insert(CONFIG_FALSEHOODS, QLatin1String("0"));
+ defaults.insert(CONFIG_FILEEXTENSIONS, QLatin1String("*.cpp *.h *.qdoc *.qml"));
+ defaults.insert(CONFIG_LANGUAGE, QLatin1String("Cpp"));
+ defaults.insert(CONFIG_OUTPUTFORMATS, QLatin1String("HTML"));
+ defaults.insert(CONFIG_TABSIZE, QLatin1String("8"));
}
+
+ QHash<QString,QString>::iterator iter;
+ for (iter = defaults.begin(); iter != defaults.end(); ++iter)
+ config.setStringList(iter.key(), QStringList() << iter.value());
+
config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(highlighting ? "true" : "false"));
config.setStringList(CONFIG_SHOWINTERNAL, QStringList(showInternal ? "true" : "false"));
config.setStringList(CONFIG_REDIRECTDOCUMENTATIONTODEVNULL, QStringList(redirectDocumentationToDevNull ? "true" : "false"));
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index e8b6218299..d45f623b8d 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -379,7 +379,6 @@ QFileDialog::QFileDialog(QWidget *parent, Qt::WindowFlags f)
{
Q_D(QFileDialog);
d->init();
- d->lineEdit()->selectAll();
}
/*!
@@ -397,7 +396,6 @@ QFileDialog::QFileDialog(QWidget *parent,
{
Q_D(QFileDialog);
d->init(directory, filter, caption);
- d->lineEdit()->selectAll();
}
/*!
@@ -411,7 +409,6 @@ QFileDialog::QFileDialog(const QFileDialogArgs &args)
setFileMode(args.mode);
setOptions(args.options);
selectFile(args.selection);
- d->lineEdit()->selectAll();
}
/*!
@@ -443,7 +440,8 @@ QFileDialog::~QFileDialog()
void QFileDialog::setSidebarUrls(const QList<QUrl> &urls)
{
Q_D(QFileDialog);
- d->qFileDialogUi->sidebar->setUrls(urls);
+ if (!d->nativeDialogInUse)
+ d->qFileDialogUi->sidebar->setUrls(urls);
}
/*!
@@ -453,7 +451,7 @@ void QFileDialog::setSidebarUrls(const QList<QUrl> &urls)
QList<QUrl> QFileDialog::sidebarUrls() const
{
Q_D(const QFileDialog);
- return d->qFileDialogUi->sidebar->urls();
+ return (d->nativeDialogInUse ? QList<QUrl>() : d->qFileDialogUi->sidebar->urls());
}
static const qint32 QFileDialogMagic = 0xbe;
@@ -474,11 +472,19 @@ QByteArray QFileDialog::saveState() const
stream << qint32(QFileDialogMagic);
stream << qint32(version);
- stream << d->qFileDialogUi->splitter->saveState();
- stream << d->qFileDialogUi->sidebar->urls();
+ if (d->usingWidgets()) {
+ stream << d->qFileDialogUi->splitter->saveState();
+ stream << d->qFileDialogUi->sidebar->urls();
+ } else {
+ stream << QByteArray();
+ stream << QList<QUrl>();
+ }
stream << history();
stream << *lastVisitedDir();
- stream << d->qFileDialogUi->treeView->header()->saveState();
+ if (d->usingWidgets())
+ stream << d->qFileDialogUi->treeView->header()->saveState();
+ else
+ stream << QByteArray();
stream << qint32(viewMode());
return data;
}
@@ -520,6 +526,12 @@ bool QFileDialog::restoreState(const QByteArray &state)
>> headerData
>> viewMode;
+ setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir());
+ setViewMode(static_cast<QFileDialog::ViewMode>(viewMode));
+
+ if (!d->usingWidgets())
+ return true;
+
if (!d->qFileDialogUi->splitter->restoreState(splitterState))
return false;
QList<int> list = d->qFileDialogUi->splitter->sizes();
@@ -533,7 +545,6 @@ bool QFileDialog::restoreState(const QByteArray &state)
while (history.count() > 5)
history.pop_front();
setHistory(history);
- setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir());
QHeaderView *headerView = d->qFileDialogUi->treeView->header();
if (!headerView->restoreState(headerData))
return false;
@@ -548,7 +559,6 @@ bool QFileDialog::restoreState(const QByteArray &state)
for (int i = 1; i < total; ++i)
actions.at(i - 1)->setChecked(!headerView->isSectionHidden(i));
- setViewMode(ViewMode(viewMode));
return true;
}
@@ -595,15 +605,16 @@ void QFileDialogPrivate::initHelper(QPlatformDialogHelper *h)
QObject::connect(h, SIGNAL(directoryEntered(QUrl)), d, SLOT(_q_nativeEnterDirectory(QUrl)));
QObject::connect(h, SIGNAL(filterSelected(QString)), d, SIGNAL(filterSelected(QString)));
static_cast<QPlatformFileDialogHelper *>(h)->setOptions(options);
+ nativeDialogInUse = true;
}
void QFileDialogPrivate::helperPrepareShow(QPlatformDialogHelper *)
{
Q_Q(QFileDialog);
options->setWindowTitle(q->windowTitle());
- options->setViewMode(static_cast<QFileDialogOptions::ViewMode>(q->viewMode()));
options->setHistory(q->history());
- options->setSidebarUrls(qFileDialogUi->sidebar->urls());
+ if (usingWidgets())
+ options->setSidebarUrls(qFileDialogUi->sidebar->urls());
const QDir directory = q->directory();
options->setInitialDirectory(directory.exists() ?
QUrl::fromLocalFile(directory.absolutePath()) :
@@ -644,9 +655,17 @@ void QFileDialogPrivate::setLastVisitedDirectory(const QString &dir)
*lastVisitedDir() = dir;
}
+void QFileDialogPrivate::updateLookInLabel()
+{
+ if (options->isLabelExplicitlySet(QFileDialogOptions::LookIn))
+ setLabelTextControl(QFileDialog::LookIn, options->labelText(QFileDialogOptions::LookIn));
+}
+
void QFileDialogPrivate::updateFileNameLabel()
{
- if (!options->isLabelExplicitlySet(QFileDialogOptions::FileName)) {
+ if (options->isLabelExplicitlySet(QFileDialogOptions::FileName)) {
+ setLabelTextControl(QFileDialog::FileName, options->labelText(QFileDialogOptions::FileName));
+ } else {
switch (q_func()->fileMode()) {
case QFileDialog::DirectoryOnly:
case QFileDialog::Directory:
@@ -659,6 +678,12 @@ void QFileDialogPrivate::updateFileNameLabel()
}
}
+void QFileDialogPrivate::updateFileTypeLabel()
+{
+ if (options->isLabelExplicitlySet(QFileDialogOptions::FileType))
+ setLabelTextControl(QFileDialog::FileType, options->labelText(QFileDialogOptions::FileType));
+}
+
void QFileDialogPrivate::updateOkButtonText(bool saveAsOnFolder)
{
Q_Q(QFileDialog);
@@ -684,12 +709,20 @@ void QFileDialogPrivate::updateOkButtonText(bool saveAsOnFolder)
}
}
+void QFileDialogPrivate::updateCancelButtonText()
+{
+ if (options->isLabelExplicitlySet(QFileDialogOptions::Reject))
+ setLabelTextControl(QFileDialog::Reject, options->labelText(QFileDialogOptions::Reject));
+}
+
void QFileDialogPrivate::retranslateStrings()
{
Q_Q(QFileDialog);
/* WIDGETS */
if (defaultFileTypes)
q->setNameFilter(QFileDialog::tr("All Files (*)"));
+ if (nativeDialogInUse)
+ return;
QList<QAction*> actions = qFileDialogUi->treeView->header()->actions();
QAbstractItemModel *abstractModel = model;
@@ -708,7 +741,10 @@ void QFileDialogPrivate::retranslateStrings()
showHiddenAction->setText(QFileDialog::tr("Show &hidden files"));
newFolderAction->setText(QFileDialog::tr("&New Folder"));
qFileDialogUi->retranslateUi(q);
+ updateLookInLabel();
updateFileNameLabel();
+ updateFileTypeLabel();
+ updateCancelButtonText();
}
void QFileDialogPrivate::emitFilesSelected(const QStringList &files)
@@ -734,6 +770,11 @@ bool QFileDialogPrivate::canBeNativeDialog()
return (staticName == dynamicName);
}
+bool QFileDialogPrivate::usingWidgets() const
+{
+ return !nativeDialogInUse && qFileDialogUi;
+}
+
/*!
\since 4.5
Sets the given \a option to be enabled if \a on is true; otherwise,
@@ -784,29 +825,36 @@ void QFileDialog::setOptions(Options options)
return;
d->options->setOptions(QFileDialogOptions::FileDialogOptions(int(options)));
- if (changed & DontResolveSymlinks)
- d->model->setResolveSymlinks(!(options & DontResolveSymlinks));
- if (changed & ReadOnly) {
- bool ro = (options & ReadOnly);
- d->model->setReadOnly(ro);
- d->qFileDialogUi->newFolderButton->setEnabled(!ro);
- d->renameAction->setEnabled(!ro);
- d->deleteAction->setEnabled(!ro);
+
+ if ((options & DontUseNativeDialog) && !d->usingWidgets())
+ d->createWidgets();
+
+ if (d->usingWidgets()) {
+ if (changed & DontResolveSymlinks)
+ d->model->setResolveSymlinks(!(options & DontResolveSymlinks));
+ if (changed & ReadOnly) {
+ bool ro = (options & ReadOnly);
+ d->model->setReadOnly(ro);
+ d->qFileDialogUi->newFolderButton->setEnabled(!ro);
+ d->renameAction->setEnabled(!ro);
+ d->deleteAction->setEnabled(!ro);
+ }
+
+ if (changed & DontUseCustomDirectoryIcons) {
+ QFileIconProvider::Options providerOptions = iconProvider()->options();
+ if (options & DontUseCustomDirectoryIcons)
+ providerOptions |= QFileIconProvider::DontUseCustomDirectoryIcons;
+ else
+ providerOptions &= ~QFileIconProvider::DontUseCustomDirectoryIcons;
+ iconProvider()->setOptions(providerOptions);
+ }
}
+
if (changed & HideNameFilterDetails)
setNameFilters(d->options->nameFilters());
if (changed & ShowDirsOnly)
setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files);
-
- if (changed & DontUseCustomDirectoryIcons) {
- QFileIconProvider::Options providerOptions = iconProvider()->options();
- if (options & DontUseCustomDirectoryIcons)
- providerOptions |= QFileIconProvider::DontUseCustomDirectoryIcons;
- else
- providerOptions &= ~QFileIconProvider::DontUseCustomDirectoryIcons;
- iconProvider()->setOptions(providerOptions);
- }
}
QFileDialog::Options QFileDialog::options() const
@@ -858,21 +906,25 @@ void QFileDialog::setVisible(bool visible)
// updates the state correctly, but skips showing the non-native version:
setAttribute(Qt::WA_DontShowOnScreen);
#ifndef QT_NO_FSCOMPLETER
- //So the completer don't try to complete and therefore to show a popup
- d->completer->setModel(0);
+ // So the completer doesn't try to complete and therefore show a popup
+ if (!d->nativeDialogInUse)
+ d->completer->setModel(0);
#endif
} else {
+ d->createWidgets();
setAttribute(Qt::WA_DontShowOnScreen, false);
#ifndef QT_NO_FSCOMPLETER
- if (d->proxyModel != 0)
- d->completer->setModel(d->proxyModel);
- else
- d->completer->setModel(d->model);
+ if (!d->nativeDialogInUse) {
+ if (d->proxyModel != 0)
+ d->completer->setModel(d->proxyModel);
+ else
+ d->completer->setModel(d->model);
+ }
#endif
}
}
- if (!d->nativeDialogInUse)
+ if (d->usingWidgets())
d->qFileDialogUi->fileNameEdit->setFocus();
QDialog::setVisible(visible);
@@ -914,24 +966,27 @@ void QFileDialog::setDirectory(const QString &directory)
d->setLastVisitedDirectory(newDirectory);
- if (d->nativeDialogInUse){
+ d->options->setInitialDirectory(QUrl::fromLocalFile(directory));
+ if (!d->usingWidgets()) {
d->setDirectory_sys(QUrl::fromLocalFile(newDirectory));
return;
}
if (d->rootPath() == newDirectory)
return;
QModelIndex root = d->model->setRootPath(newDirectory);
- d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled);
- if (root != d->rootIndex()) {
+ if (!d->nativeDialogInUse) {
+ d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled);
+ if (root != d->rootIndex()) {
#ifndef QT_NO_FSCOMPLETER
- if (directory.endsWith(QLatin1Char('/')))
- d->completer->setCompletionPrefix(newDirectory);
- else
- d->completer->setCompletionPrefix(newDirectory + QLatin1Char('/'));
+ if (directory.endsWith(QLatin1Char('/')))
+ d->completer->setCompletionPrefix(newDirectory);
+ else
+ d->completer->setCompletionPrefix(newDirectory + QLatin1Char('/'));
#endif
- d->setRootIndex(root);
+ d->setRootIndex(root);
+ }
+ d->qFileDialogUi->listView->selectionModel()->clear();
}
- d->qFileDialogUi->listView->selectionModel()->clear();
}
/*!
@@ -989,8 +1044,11 @@ void QFileDialog::selectFile(const QString &filename)
if (filename.isEmpty())
return;
- if (d->nativeDialogInUse){
+ if (!d->usingWidgets()) {
d->selectFile_sys(QUrl::fromLocalFile(filename));
+ QList<QUrl> i;
+ i << QUrl(filename);
+ d->options->setInitiallySelectedFiles(i);
return;
}
@@ -1141,7 +1199,7 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
{
QList<QUrl> files;
- if (nativeDialogInUse)
+ if (!usingWidgets())
return addDefaultSuffixToUrls(selectedFiles_sys());
foreach (const QModelIndex &index, qFileDialogUi->listView->selectionModel()->selectedRows())
@@ -1339,6 +1397,9 @@ void QFileDialog::setNameFilters(const QStringList &filters)
}
d->options->setNameFilters(cleanedFilters);
+ if (!d->usingWidgets())
+ return;
+
d->qFileDialogUi->fileTypeCombo->clear();
if (cleanedFilters.isEmpty())
return;
@@ -1373,7 +1434,7 @@ QStringList QFileDialog::nameFilters() const
void QFileDialog::selectNameFilter(const QString &filter)
{
Q_D(QFileDialog);
- if (d->nativeDialogInUse) {
+ if (!d->usingWidgets()) {
d->selectNameFilter_sys(filter);
return;
}
@@ -1401,7 +1462,7 @@ void QFileDialog::selectNameFilter(const QString &filter)
QString QFileDialog::selectedNameFilter() const
{
Q_D(const QFileDialog);
- if (d->nativeDialogInUse)
+ if (!d->usingWidgets())
return d->selectedNameFilter_sys();
return d->qFileDialogUi->fileTypeCombo->currentText();
@@ -1417,7 +1478,9 @@ QString QFileDialog::selectedNameFilter() const
QDir::Filters QFileDialog::filter() const
{
Q_D(const QFileDialog);
- return d->model->filter();
+ if (d->usingWidgets())
+ return d->model->filter();
+ return d->options->filter();
}
/*!
@@ -1432,13 +1495,13 @@ QDir::Filters QFileDialog::filter() const
void QFileDialog::setFilter(QDir::Filters filters)
{
Q_D(QFileDialog);
- d->model->setFilter(filters);
d->options->setFilter(filters);
- if (d->nativeDialogInUse){
+ if (!d->usingWidgets()) {
d->setFilter_sys();
return;
}
+ d->model->setFilter(filters);
d->showHiddenAction->setChecked((filters & QDir::Hidden));
}
@@ -1523,6 +1586,9 @@ void QFileDialog::selectMimeTypeFilter(const QString &filter)
void QFileDialog::setViewMode(QFileDialog::ViewMode mode)
{
Q_D(QFileDialog);
+ d->options->setViewMode(static_cast<QFileDialogOptions::ViewMode>(mode));
+ if (!d->usingWidgets())
+ return;
if (mode == Detail)
d->_q_showDetailsView();
else
@@ -1532,6 +1598,8 @@ void QFileDialog::setViewMode(QFileDialog::ViewMode mode)
QFileDialog::ViewMode QFileDialog::viewMode() const
{
Q_D(const QFileDialog);
+ if (!d->usingWidgets())
+ return QFileDialog::List;
return (d->qFileDialogUi->stackedWidget->currentWidget() == d->qFileDialogUi->listView->parent() ? QFileDialog::List : QFileDialog::Detail);
}
@@ -1554,11 +1622,15 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode)
{
Q_D(QFileDialog);
d->options->setFileMode(static_cast<QFileDialogOptions::FileMode>(mode));
- d->retranslateWindowTitle();
// keep ShowDirsOnly option in sync with fileMode (BTW, DirectoryOnly is obsolete)
setOption(ShowDirsOnly, mode == DirectoryOnly);
+ if (!d->usingWidgets())
+ return;
+
+ d->retranslateWindowTitle();
+
// set selection mode and behavior
QAbstractItemView::SelectionMode selectionMode;
if (mode == QFileDialog::ExistingFiles)
@@ -1577,11 +1649,6 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode)
}
d->updateFileNameLabel();
d->updateOkButtonText();
- if (d->nativeDialogInUse){
- d->setFilter_sys();
- return;
- }
-
d->qFileDialogUi->fileTypeCombo->setEnabled(!testOption(ShowDirsOnly));
d->_q_updateOkButton();
}
@@ -1606,6 +1673,13 @@ void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode)
{
Q_D(QFileDialog);
d->options->setAcceptMode(static_cast<QFileDialogOptions::AcceptMode>(mode));
+ // clear WA_DontShowOnScreen so that d->canBeNativeDialog() doesn't return false incorrectly
+ setAttribute(Qt::WA_DontShowOnScreen, false);
+ if (!d->usingWidgets()) {
+ // we need to recreate the native dialog when changing the AcceptMode
+ d->deletePlatformHelper();
+ return;
+ }
QDialogButtonBox::StandardButton button = (mode == AcceptOpen ? QDialogButtonBox::Open : QDialogButtonBox::Save);
d->qFileDialogUi->buttonBox->setStandardButtons(button | QDialogButtonBox::Cancel);
d->qFileDialogUi->buttonBox->button(button)->setEnabled(false);
@@ -1614,10 +1688,6 @@ void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode)
d->qFileDialogUi->lookInCombo->setEditable(false);
}
d->retranslateWindowTitle();
- // we need to recreate the native dialog when changing the AcceptMode
- d->deletePlatformHelper();
- // clear WA_DontShowOnScreen so that d->canBeNativeDialog() doesn't return false incorrectly
- setAttribute(Qt::WA_DontShowOnScreen, false);
}
/*
@@ -1778,7 +1848,8 @@ QString QFileDialog::defaultSuffix() const
void QFileDialog::setHistory(const QStringList &paths)
{
Q_D(QFileDialog);
- d->qFileDialogUi->lookInCombo->setHistory(paths);
+ if (d->usingWidgets())
+ d->qFileDialogUi->lookInCombo->setHistory(paths);
}
void QFileDialogComboBox::setHistory(const QStringList &paths)
@@ -1800,6 +1871,8 @@ void QFileDialogComboBox::setHistory(const QStringList &paths)
QStringList QFileDialog::history() const
{
Q_D(const QFileDialog);
+ if (!d->usingWidgets())
+ return QStringList();
QStringList currentHistory = d->qFileDialogUi->lookInCombo->history();
//On windows the popup display the "C:\", convert to nativeSeparators
QString newHistory = QDir::toNativeSeparators(d->rootIndex().data(QFileSystemModel::FilePathRole).toString());
@@ -1826,6 +1899,8 @@ QStringList QFileDialog::history() const
void QFileDialog::setItemDelegate(QAbstractItemDelegate *delegate)
{
Q_D(QFileDialog);
+ if (!d->usingWidgets())
+ return;
d->qFileDialogUi->listView->setItemDelegate(delegate);
d->qFileDialogUi->treeView->setItemDelegate(delegate);
}
@@ -1836,6 +1911,8 @@ void QFileDialog::setItemDelegate(QAbstractItemDelegate *delegate)
QAbstractItemDelegate *QFileDialog::itemDelegate() const
{
Q_D(const QFileDialog);
+ if (!d->usingWidgets())
+ return 0;
return d->qFileDialogUi->listView->itemDelegate();
}
@@ -1845,6 +1922,8 @@ QAbstractItemDelegate *QFileDialog::itemDelegate() const
void QFileDialog::setIconProvider(QFileIconProvider *provider)
{
Q_D(QFileDialog);
+ if (!d->usingWidgets())
+ return;
d->model->setIconProvider(provider);
//It forces the refresh of all entries in the side bar, then we can get new icons
d->qFileDialogUi->sidebar->setUrls(d->qFileDialogUi->sidebar->urls());
@@ -1861,6 +1940,8 @@ QFileIconProvider *QFileDialog::iconProvider() const
void QFileDialogPrivate::setLabelTextControl(QFileDialog::DialogLabel label, const QString &text)
{
+ if (!qFileDialogUi)
+ return;
switch (label) {
case QFileDialog::LookIn:
qFileDialogUi->lookInLabel->setText(text);
@@ -1903,8 +1984,10 @@ void QFileDialog::setLabelText(DialogLabel label, const QString &text)
*/
QString QFileDialog::labelText(DialogLabel label) const
{
- QPushButton *button;
Q_D(const QFileDialog);
+ if (!d->usingWidgets())
+ return d->options->labelText(static_cast<QFileDialogOptions::DialogLabel>(label));
+ QPushButton *button;
switch (label) {
case LookIn:
return d->qFileDialogUi->lookInLabel->text();
@@ -2518,7 +2601,7 @@ void QFileDialog::accept()
QStringList files = selectedFiles();
if (files.isEmpty())
return;
- if (d->nativeDialogInUse){
+ if (!d->usingWidgets()) {
d->emitFilesSelected(files);
QDialog::accept();
return;
@@ -2631,16 +2714,19 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte
q->setWindowTitle(caption);
}
- createWidgets();
- createMenuActions();
- retranslateStrings();
+ q->setAcceptMode(QFileDialog::AcceptOpen);
+ nativeDialogInUse = (canBeNativeDialog() && platformFileDialogHelper() != 0);
+ if (!nativeDialogInUse)
+ createWidgets();
q->setFileMode(QFileDialog::AnyFile);
+ if (!nameFilter.isEmpty())
+ q->setNameFilter(nameFilter);
+ q->setDirectory(workingDirectory(directory));
+ q->selectFile(initialSelection(directory));
#ifndef QT_NO_SETTINGS
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
settings.beginGroup(QLatin1String("Qt"));
- if (!directory.isEmpty())
- setLastVisitedDirectory(workingDirectory(directory));
q->restoreState(settings.value(QLatin1String("filedialog")).toByteArray());
#endif
@@ -2650,14 +2736,7 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte
qFileDialogUi->fileTypeLabel->setVisible(false);
qFileDialogUi->sidebar->hide();
#endif
- // Default case
- if (!nameFilter.isEmpty())
- q->setNameFilter(nameFilter);
- q->setAcceptMode(QFileDialog::AcceptOpen);
- q->setDirectory(workingDirectory(directory));
- q->selectFile(initialSelection(directory));
- _q_updateOkButton();
q->resize(q->sizeHint());
}
@@ -2668,6 +2747,8 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte
*/
void QFileDialogPrivate::createWidgets()
{
+ if (qFileDialogUi)
+ return;
Q_Q(QFileDialog);
model = new QFileSystemModel(q);
options->setFilter(model->filter());
@@ -2676,6 +2757,8 @@ void QFileDialogPrivate::createWidgets()
model->setNameFilterDisables(helper->defaultNameFilterDisables());
else
model->setNameFilterDisables(false);
+ if (nativeDialogInUse)
+ deletePlatformHelper();
model->d_func()->disableRecursiveSort = true;
QFileDialog::connect(model, SIGNAL(fileRenamed(QString,QString,QString)), q, SLOT(_q_fileRenamed(QString,QString,QString)));
QFileDialog::connect(model, SIGNAL(rootPathChanged(QString)),
@@ -2789,6 +2872,31 @@ void QFileDialogPrivate::createWidgets()
qFileDialogUi->splitter->setStretchFactor(qFileDialogUi->splitter->indexOf(qFileDialogUi->splitter->widget(1)), QSizePolicy::Expanding);
createToolButtons();
+ createMenuActions();
+
+ // Initial widget states from options
+ q->setFileMode(static_cast<QFileDialog::FileMode>(options->fileMode()));
+ q->setAcceptMode(static_cast<QFileDialog::AcceptMode>(options->acceptMode()));
+ q->setViewMode(static_cast<QFileDialog::ViewMode>(options->viewMode()));
+ q->setOptions(static_cast<QFileDialog::Options>(static_cast<int>(options->options())));
+ if (!options->sidebarUrls().isEmpty())
+ q->setSidebarUrls(options->sidebarUrls());
+ q->setDirectoryUrl(options->initialDirectory());
+ if (!options->mimeTypeFilters().isEmpty())
+ q->setMimeTypeFilters(options->mimeTypeFilters());
+ else if (!options->nameFilters().isEmpty())
+ q->setNameFilters(options->nameFilters());
+ q->selectNameFilter(options->initiallySelectedNameFilter());
+ q->setDefaultSuffix(options->defaultSuffix());
+ q->setHistory(options->history());
+ if (options->initiallySelectedFiles().count() == 1)
+ q->selectFile(options->initiallySelectedFiles().first().fileName());
+ foreach (QUrl url, options->initiallySelectedFiles())
+ q->selectUrl(url);
+ lineEdit()->selectAll();
+ _q_updateOkButton();
+ retranslateStrings();
+ q->resize(q->sizeHint());
}
void QFileDialogPrivate::_q_showHeader(QAction *action)
@@ -2814,6 +2922,8 @@ void QFileDialogPrivate::_q_showHeader(QAction *action)
void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel)
{
Q_D(QFileDialog);
+ if (!d->usingWidgets())
+ return;
if ((!proxyModel && !d->proxyModel)
|| (proxyModel == d->proxyModel))
return;
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index e5a558bb91..36336bdbf6 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -135,8 +135,11 @@ public:
QList<QUrl> addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const;
bool removeDirectory(const QString &path);
void setLabelTextControl(QFileDialog::DialogLabel label, const QString &text);
+ inline void updateLookInLabel();
inline void updateFileNameLabel();
+ inline void updateFileTypeLabel();
void updateOkButtonText(bool saveAsOnFolder = false);
+ void updateCancelButtonText();
inline QModelIndex mapToSource(const QModelIndex &index) const;
inline QModelIndex mapFromSource(const QModelIndex &index) const;
@@ -249,6 +252,7 @@ public:
// dialog. Returning false means that a non-native dialog must be
// used instead.
bool canBeNativeDialog();
+ inline bool usingWidgets() const;
void setDirectory_sys(const QUrl &directory);
QUrl directory_sys() const;
@@ -347,7 +351,7 @@ inline QModelIndex QFileDialogPrivate::mapFromSource(const QModelIndex &index) c
}
inline QString QFileDialogPrivate::rootPath() const {
- return model->rootPath();
+ return (model ? model->rootPath() : QStringLiteral("/"));
}
inline void QFileDialogPrivate::setDirectory_sys(const QUrl &directory)
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 6dcc354f94..bda448bde3 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -204,6 +204,8 @@ bool QFileSystemModel::remove(const QModelIndex &aindex)
#ifndef QT_NO_FILESYSTEMWATCHER
d->fileInfoGatherer.removePath(path);
#endif
+ if (QFileInfo(path).isFile())
+ return QFile::remove(path);
return QDir(path).removeRecursively();
}
diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
index 5dc3e1159e..ff98c147fe 100644
--- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp
+++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
@@ -97,6 +97,15 @@
QT_BEGIN_NAMESPACE
+static inline bool check_step_valid(qreal step, const char *method)
+{
+ if (!(step >= 0 && step <= 1)) {
+ qWarning("QGraphicsItemAnimation::%s: invalid step = %f", method, step);
+ return false;
+ }
+ return true;
+}
+
class QGraphicsItemAnimationPrivate
{
public:
@@ -169,10 +178,8 @@ qreal QGraphicsItemAnimationPrivate::linearValueForStep(qreal step, QList<Pair>
void QGraphicsItemAnimationPrivate::insertUniquePair(qreal step, qreal value, QList<Pair> *binList, const char* method)
{
- if (step < 0.0 || step > 1.0) {
- qWarning("QGraphicsItemAnimation::%s: invalid step = %f", method, step);
+ if (!check_step_valid(step, method))
return;
- }
Pair pair(step, value);
@@ -259,9 +266,7 @@ void QGraphicsItemAnimation::setTimeLine(QTimeLine *timeLine)
*/
QPointF QGraphicsItemAnimation::posAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::posAt: invalid step = %f", step);
-
+ check_step_valid(step, "posAt");
return QPointF(d->linearValueForStep(step, &d->xPosition, d->startPos.x()),
d->linearValueForStep(step, &d->yPosition, d->startPos.y()));
}
@@ -298,8 +303,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::posList() const
*/
QMatrix QGraphicsItemAnimation::matrixAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::matrixAt: invalid step = %f", step);
+ check_step_valid(step, "matrixAt");
QMatrix matrix;
if (!d->rotation.isEmpty())
@@ -320,9 +324,7 @@ QMatrix QGraphicsItemAnimation::matrixAt(qreal step) const
*/
qreal QGraphicsItemAnimation::rotationAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::rotationAt: invalid step = %f", step);
-
+ check_step_valid(step, "rotationAt");
return d->linearValueForStep(step, &d->rotation);
}
@@ -357,9 +359,7 @@ QList<QPair<qreal, qreal> > QGraphicsItemAnimation::rotationList() const
*/
qreal QGraphicsItemAnimation::xTranslationAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::xTranslationAt: invalid step = %f", step);
-
+ check_step_valid(step, "xTranslationAt");
return d->linearValueForStep(step, &d->xTranslation);
}
@@ -370,9 +370,7 @@ qreal QGraphicsItemAnimation::xTranslationAt(qreal step) const
*/
qreal QGraphicsItemAnimation::yTranslationAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::yTranslationAt: invalid step = %f", step);
-
+ check_step_valid(step, "yTranslationAt");
return d->linearValueForStep(step, &d->yTranslation);
}
@@ -409,8 +407,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::translationList() const
*/
qreal QGraphicsItemAnimation::verticalScaleAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::verticalScaleAt: invalid step = %f", step);
+ check_step_valid(step, "verticalScaleAt");
return d->linearValueForStep(step, &d->verticalScale, 1);
}
@@ -422,9 +419,7 @@ qreal QGraphicsItemAnimation::verticalScaleAt(qreal step) const
*/
qreal QGraphicsItemAnimation::horizontalScaleAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::horizontalScaleAt: invalid step = %f", step);
-
+ check_step_valid(step, "horizontalScaleAt");
return d->linearValueForStep(step, &d->horizontalScale, 1);
}
@@ -461,9 +456,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::scaleList() const
*/
qreal QGraphicsItemAnimation::verticalShearAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::verticalShearAt: invalid step = %f", step);
-
+ check_step_valid(step, "verticalShearAt");
return d->linearValueForStep(step, &d->verticalShear, 0);
}
@@ -474,9 +467,7 @@ qreal QGraphicsItemAnimation::verticalShearAt(qreal step) const
*/
qreal QGraphicsItemAnimation::horizontalShearAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::horizontalShearAt: invalid step = %f", step);
-
+ check_step_valid(step, "horizontalShearAt");
return d->linearValueForStep(step, &d->horizontalShear, 0);
}
@@ -529,19 +520,17 @@ void QGraphicsItemAnimation::clear()
Sets the current \a step value for the animation, causing the
transformations scheduled at this step to be performed.
*/
-void QGraphicsItemAnimation::setStep(qreal x)
+void QGraphicsItemAnimation::setStep(qreal step)
{
- if (x < 0.0 || x > 1.0) {
- qWarning("QGraphicsItemAnimation::setStep: invalid step = %f", x);
+ if (!check_step_valid(step, "setStep"))
return;
- }
- beforeAnimationStep(x);
+ beforeAnimationStep(step);
- d->step = x;
+ d->step = step;
if (d->item) {
if (!d->xPosition.isEmpty() || !d->yPosition.isEmpty())
- d->item->setPos(posAt(x));
+ d->item->setPos(posAt(step));
if (!d->rotation.isEmpty()
|| !d->verticalScale.isEmpty()
|| !d->horizontalScale.isEmpty()
@@ -549,11 +538,11 @@ void QGraphicsItemAnimation::setStep(qreal x)
|| !d->horizontalShear.isEmpty()
|| !d->xTranslation.isEmpty()
|| !d->yTranslation.isEmpty()) {
- d->item->setMatrix(d->startMatrix * matrixAt(x));
+ d->item->setMatrix(d->startMatrix * matrixAt(step));
}
}
- afterAnimationStep(x);
+ afterAnimationStep(step);
}
/*!
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 35ba1ed74e..726c2704c4 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1651,7 +1651,7 @@ bool QAbstractItemView::viewportEvent(QEvent *event)
case QEvent::WhatsThis: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
const QModelIndex index = indexAt(he->pos());
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
option.rect = visualRect(index);
option.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
@@ -1851,7 +1851,7 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
emit clicked(index);
if (edited)
return;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
if (d->pressedAlreadySelected)
option.state |= QStyle::State_Selected;
if ((model()->flags(index) & Qt::ItemIsEnabled)
@@ -2627,7 +2627,7 @@ void QAbstractItemView::updateEditorGeometries()
Q_D(QAbstractItemView);
if(d->editorIndexHash.isEmpty())
return;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
QEditorIndexHash::iterator it = d->editorIndexHash.begin();
QWidgetList editorsToRelease;
QWidgetList editorsToHide;
@@ -2972,7 +2972,7 @@ QSize QAbstractItemView::sizeHintForIndex(const QModelIndex &index) const
Q_D(const QAbstractItemView);
if (!d->isIndexValid(index) || !d->itemDelegate)
return QSize();
- return d->delegateForIndex(index)->sizeHint(d->viewOptions(), index);
+ return d->delegateForIndex(index)->sizeHint(d->viewOptionsV1(), index);
}
/*!
@@ -3000,7 +3000,7 @@ int QAbstractItemView::sizeHintForRow(int row) const
ensurePolished();
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
int height = 0;
int colCount = d->model->columnCount(d->root);
QModelIndex index;
@@ -3031,7 +3031,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const
ensurePolished();
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
int width = 0;
int rows = d->model->rowCount(d->root);
QModelIndex index;
@@ -3054,7 +3054,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const
void QAbstractItemView::openPersistentEditor(const QModelIndex &index)
{
Q_D(QAbstractItemView);
- QStyleOptionViewItem options = d->viewOptions();
+ QStyleOptionViewItem options = d->viewOptionsV1();
options.rect = visualRect(index);
options.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
@@ -3600,45 +3600,45 @@ void QAbstractItemView::startDrag(Qt::DropActions supportedActions)
QStyleOptionViewItem QAbstractItemView::viewOptions() const
{
Q_D(const QAbstractItemView);
- return d->viewOptions();
-}
-
-QStyleOptionViewItem QAbstractItemViewPrivate::viewOptions() const
-{
- Q_Q(const QAbstractItemView);
QStyleOptionViewItem option;
- option.init(q);
+ option.init(this);
option.state &= ~QStyle::State_MouseOver;
- option.font = q->font();
+ option.font = font();
#ifndef Q_WS_MAC
// On mac the focus appearance follows window activation
// not widget activation
- if (!q->hasFocus())
+ if (!hasFocus())
option.state &= ~QStyle::State_Active;
#endif
option.state &= ~QStyle::State_HasFocus;
- if (iconSize.isValid()) {
- option.decorationSize = iconSize;
+ if (d->iconSize.isValid()) {
+ option.decorationSize = d->iconSize;
} else {
- int pm = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
+ int pm = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
option.decorationSize = QSize(pm, pm);
}
option.decorationPosition = QStyleOptionViewItem::Left;
option.decorationAlignment = Qt::AlignCenter;
option.displayAlignment = Qt::AlignLeft|Qt::AlignVCenter;
- option.textElideMode = textElideMode;
+ option.textElideMode = d->textElideMode;
option.rect = QRect();
- option.showDecorationSelected = q->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, q);
- if (wrapItemText)
+ option.showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, this);
+ if (d->wrapItemText)
option.features = QStyleOptionViewItem::WrapText;
- option.locale = q->locale();
+ option.locale = locale();
option.locale.setNumberOptions(QLocale::OmitGroupSeparator);
- option.widget = q;
+ option.widget = this;
return option;
}
+QStyleOptionViewItem QAbstractItemViewPrivate::viewOptionsV1() const
+{
+ Q_Q(const QAbstractItemView);
+ return q->viewOptions();
+}
+
/*!
Returns the item view's state.
@@ -4274,7 +4274,7 @@ bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEven
{
Q_Q(const QAbstractItemView);
QModelIndex buddy = model->buddy(index);
- QStyleOptionViewItem options = viewOptions();
+ QStyleOptionViewItem options = viewOptionsV1();
options.rect = q->visualRect(buddy);
options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
QAbstractItemDelegate *delegate = delegateForIndex(index);
@@ -4286,7 +4286,7 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even
Q_Q(QAbstractItemView);
QModelIndex buddy = model->buddy(index);
- QStyleOptionViewItem options = viewOptions();
+ QStyleOptionViewItem options = viewOptionsV1();
options.rect = q->visualRect(buddy);
options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
@@ -4338,7 +4338,7 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,
QPixmap pixmap(r->size());
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
- QStyleOptionViewItem option = viewOptions();
+ QStyleOptionViewItem option = viewOptionsV1();
option.state |= QStyle::State_Selected;
for (int j = 0; j < paintPairs.count(); ++j) {
option.rect = paintPairs.at(j).first.translated(-r->topLeft());
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
index 5da22615e2..1b5987de16 100644
--- a/src/widgets/itemviews/qabstractitemview_p.h
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -347,7 +347,7 @@ public:
QModelIndexList selectedDraggableIndexes() const;
- QStyleOptionViewItem viewOptions() const;
+ QStyleOptionViewItem viewOptionsV1() const;
void doDelayedReset()
{
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 123594637a..1131ef030e 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -3693,8 +3693,7 @@ void QHeaderViewPrivate::write(QDataStream &out) const
out << int(globalResizeMode);
out << sectionItems;
- if (out.version() >= QDataStream::Qt_5_2)
- out << resizeContentsPrecision;
+ out << resizeContentsPrecision;
}
bool QHeaderViewPrivate::read(QDataStream &in)
@@ -3747,8 +3746,10 @@ bool QHeaderViewPrivate::read(QDataStream &in)
sectionItems = newSectionItems;
recalcSectionStartPos();
- if (in.version() >= QDataStream::Qt_5_2)
- in >> resizeContentsPrecision;
+ int tmpint;
+ in >> tmpint;
+ if (in.status() == QDataStream::Ok) // we haven't read past end
+ resizeContentsPrecision = tmpint;
return true;
}
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index e5a8647f87..616a832b88 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Samuel Gaist <samuel.gaist@deltech.ch>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -900,20 +901,14 @@ void QListView::startDrag(Qt::DropActions supportedActions)
QStyleOptionViewItem QListView::viewOptions() const
{
Q_D(const QListView);
- return d->viewOptions();
-}
-
-QStyleOptionViewItem QListViewPrivate::viewOptions() const
-{
- Q_Q(const QListView);
- QStyleOptionViewItem option = QAbstractItemViewPrivate::viewOptions();
- if (!iconSize.isValid()) { // otherwise it was already set in abstractitemview
- int pm = (viewMode == QListView::ListMode
- ? q->style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, q)
- : q->style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, q));
+ QStyleOptionViewItem option = QAbstractItemView::viewOptions();
+ if (!d->iconSize.isValid()) { // otherwise it was already set in abstractitemview
+ int pm = (d->viewMode == QListView::ListMode
+ ? style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, this)
+ : style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, this));
option.decorationSize = QSize(pm, pm);
}
- if (viewMode == QListView::IconMode) {
+ if (d->viewMode == QListView::IconMode) {
option.showDecorationSelected = false;
option.decorationPosition = QStyleOptionViewItem::Top;
option.displayAlignment = Qt::AlignCenter;
@@ -932,7 +927,7 @@ void QListView::paintEvent(QPaintEvent *e)
Q_D(QListView);
if (!d->itemDelegate)
return;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
QPainter painter(d->viewport);
const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
@@ -1461,7 +1456,7 @@ void QListView::updateGeometries()
verticalScrollBar()->setRange(0, 0);
} else {
QModelIndex index = d->model->index(0, d->column, d->root);
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
QSize step = d->itemSize(option, index);
d->commonListView->updateHorizontalScrollBar(step);
d->commonListView->updateVerticalScrollBar(step);
@@ -1833,6 +1828,15 @@ void QCommonListViewBase::removeHiddenRow(int row)
dd->hiddenRows.remove(dd->model->index(row, 0, qq->rootIndex()));
}
+#ifndef QT_NO_DRAGANDDROP
+void QCommonListViewBase::paintDragDrop(QPainter *painter)
+{
+ // FIXME: Until the we can provide a proper drop indicator
+ // in IconMode, it makes no sense to show it
+ dd->paintDropIndicator(painter);
+}
+#endif
+
void QCommonListViewBase::updateHorizontalScrollBar(const QSize & /*step*/)
{
horizontalScrollBar()->setPageStep(viewport()->width());
@@ -1902,13 +1906,6 @@ int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView:
*/
#ifndef QT_NO_DRAGANDDROP
-void QListModeViewBase::paintDragDrop(QPainter *painter)
-{
- // FIXME: Until the we can provide a proper drop indicator
- // in IconMode, it makes no sense to show it
- dd->paintDropIndicator(painter);
-}
-
QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const
{
QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport;
@@ -2651,23 +2648,6 @@ void QIconModeViewBase::removeHiddenRow(int row)
}
#ifndef QT_NO_DRAGANDDROP
-void QIconModeViewBase::paintDragDrop(QPainter *painter)
-{
- if (!draggedItems.isEmpty() && viewport()->rect().contains(draggedItemsPos)) {
- //we need to draw the items that arre dragged
- painter->translate(draggedItemsDelta());
- QStyleOptionViewItem option = viewOptions();
- option.state &= ~QStyle::State_MouseOver;
- QVector<QModelIndex>::const_iterator it = draggedItems.constBegin();
- QListViewItem item = indexToListViewItem(*it);
- for (; it != draggedItems.constEnd(); ++it) {
- item = indexToListViewItem(*it);
- option.rect = viewItemRect(item);
- delegate(*it)->paint(painter, option, *it);
- }
- }
-}
-
bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
{
// This function does the same thing as in QAbstractItemView::startDrag(),
@@ -2682,8 +2662,14 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
&& (*it).column() == dd->column)
draggedItems.push_back(*it);
}
+
+ QRect rect;
+ QPixmap pixmap = dd->renderToPixmap(indexes, &rect);
+ rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
QDrag *drag = new QDrag(qq);
drag->setMimeData(dd->model->mimeData(indexes));
+ drag->setPixmap(pixmap);
+ drag->setHotSpot(dd->pressedPosition - rect.topLeft());
Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction);
draggedItems.clear();
if (action == Qt::MoveAction)
diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h
index 35d11140ef..4f3ccedb62 100644
--- a/src/widgets/itemviews/qlistview_p.h
+++ b/src/widgets/itemviews/qlistview_p.h
@@ -147,7 +147,7 @@ public:
virtual void setPositionForIndex(const QPoint &, const QModelIndex &) { }
#ifndef QT_NO_DRAGANDDROP
- virtual void paintDragDrop(QPainter *painter) = 0;
+ virtual void paintDragDrop(QPainter *painter);
virtual bool filterDragMoveEvent(QDragMoveEvent *) { return false; }
virtual bool filterDragLeaveEvent(QDragLeaveEvent *) { return false; }
virtual bool filterDropEvent(QDropEvent *) { return false; }
@@ -231,8 +231,6 @@ public:
void updateVerticalScrollBar(const QSize &step);
#ifndef QT_NO_DRAGANDDROP
- void paintDragDrop(QPainter *painter);
-
// The next two methods are to be used on LefToRight flow only.
// WARNING: Plenty of duplicated code from QAbstractItemView{,Private}.
QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
@@ -279,7 +277,6 @@ public:
void setPositionForIndex(const QPoint &position, const QModelIndex &index);
#ifndef QT_NO_DRAGANDDROP
- void paintDragDrop(QPainter *painter);
bool filterDragMoveEvent(QDragMoveEvent *);
bool filterDragLeaveEvent(QDragLeaveEvent *);
bool filterDropEvent(QDropEvent *e);
@@ -394,8 +391,6 @@ public:
}
}
- QStyleOptionViewItem viewOptions() const;
-
void scrollElasticBandBy(int dx, int dy);
QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
@@ -470,7 +465,7 @@ inline QModelIndex QCommonListViewBase::modelIndex(int row) const
{ return dd->model->index(row, dd->column, dd->root); }
inline int QCommonListViewBase::rowCount() const { return dd->model->rowCount(dd->root); }
-inline QStyleOptionViewItem QCommonListViewBase::viewOptions() const { return dd->viewOptions(); }
+inline QStyleOptionViewItem QCommonListViewBase::viewOptions() const { return dd->viewOptionsV1(); }
inline QWidget *QCommonListViewBase::viewport() const { return dd->viewport; }
inline QRect QCommonListViewBase::clipRect() const { return dd->clipRect(); }
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index 34e881571e..08600b3ef7 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -1346,20 +1346,14 @@ void QTableView::scrollContentsBy(int dx, int dy)
}
}
-QStyleOptionViewItem QTableViewPrivate::viewOptions() const
-{
- QStyleOptionViewItem option = QAbstractItemViewPrivate::viewOptions();
- option.showDecorationSelected = true;
- return option;
-}
-
/*!
\reimp
*/
QStyleOptionViewItem QTableView::viewOptions() const
{
- Q_D(const QTableView);
- return d->viewOptions();
+ QStyleOptionViewItem option = QAbstractItemView::viewOptions();
+ option.showDecorationSelected = true;
+ return option;
}
/*!
@@ -1369,7 +1363,7 @@ void QTableView::paintEvent(QPaintEvent *event)
{
Q_D(QTableView);
// setup temp variables for the painting
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
const QPoint offset = d->scrollDelayOffset;
const bool showGrid = d->showGrid;
const int gridSize = showGrid ? 1 : 0;
@@ -2241,7 +2235,7 @@ int QTableView::sizeHintForRow(int row) const
if (right == -1) // the table don't have enough columns to fill the viewport
right = d->model->columnCount(d->root) - 1;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
int hint = 0;
QModelIndex index;
@@ -2329,7 +2323,7 @@ int QTableView::sizeHintForColumn(int column) const
if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport
bottom = d->model->rowCount(d->root) - 1;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
int hint = 0;
int rowsProcessed = 0;
diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h
index 74eb7b7728..555ae50daf 100644
--- a/src/widgets/itemviews/qtableview_p.h
+++ b/src/widgets/itemviews/qtableview_p.h
@@ -150,8 +150,6 @@ public:
void init();
void trimHiddenSelections(QItemSelectionRange *range) const;
- QStyleOptionViewItem viewOptions() const;
-
inline bool isHidden(int row, int col) const {
return verticalHeader->isSectionHidden(row)
|| horizontalHeader->isSectionHidden(col);
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 22cd9abc73..792b75ac69 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -1441,7 +1441,7 @@ void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
Q_D(const QTreeView);
const QVector<QTreeViewItem> viewItems = d->viewItems;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
const QStyle::State state = option.state;
d->current = 0;
@@ -2850,7 +2850,7 @@ int QTreeView::sizeHintForColumn(int column) const
return -1;
ensurePolished();
int w = 0;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
const QVector<QTreeViewItem> viewItems = d->viewItems;
const int maximumProcessRows = d->header->resizeContentsPrecision(); // To avoid this to take forever.
@@ -2947,7 +2947,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const
qSwap(end, start);
int height = -1;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
// ### If we want word wrapping in the items,
// ### we need to go through all the columns
// ### and set the width of the column
@@ -3220,7 +3220,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
painter.end();
//and now let's render the editors the editors
- QStyleOptionViewItem option = viewOptions();
+ QStyleOptionViewItem option = viewOptionsV1();
for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) {
QWidget *editor = it.key();
const QModelIndex &index = it.value();
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri
index 533b696faa..444b9b687f 100644
--- a/src/widgets/kernel/kernel.pri
+++ b/src/widgets/kernel/kernel.pri
@@ -66,59 +66,9 @@ SOURCES += \
kernel/qwidgetwindow.cpp \
kernel/qwindowcontainer.cpp
-
-# TODO
-false:!x11:mac {
- SOURCES += \
- kernel/qclipboard_mac.cpp \
- kernel/qmime_mac.cpp \
- kernel/qt_mac.cpp \
- kernel/qkeymapper_mac.cpp
-
- OBJECTIVE_HEADERS += \
- qcocoawindow_mac_p.h \
- qcocoapanel_mac_p.h \
- qcocoawindowdelegate_mac_p.h \
- qcocoaview_mac_p.h \
- qcocoaapplication_mac_p.h \
- qcocoaapplicationdelegate_mac_p.h \
- qmacgesturerecognizer_mac_p.h \
- qmultitouch_mac_p.h \
- qcocoasharedwindowmethods_mac_p.h \
- qcocoaintrospection_p.h
-
- OBJECTIVE_SOURCES += \
- kernel/qcursor_mac.mm \
- kernel/qdnd_mac.mm \
- kernel/qapplication_mac.mm \
- kernel/qwidget_mac.mm \
- kernel/qcocoapanel_mac.mm \
- kernel/qcocoaview_mac.mm \
- kernel/qcocoawindow_mac.mm \
- kernel/qcocoawindowdelegate_mac.mm \
- kernel/qcocoaapplication_mac.mm \
- kernel/qcocoaapplicationdelegate_mac.mm \
- kernel/qt_cocoa_helpers_mac.mm \
- kernel/qdesktopwidget_mac.mm \
- kernel/qeventdispatcher_mac.mm \
- kernel/qcocoawindowcustomthemeframe_mac.mm \
- kernel/qmacgesturerecognizer_mac.mm \
- kernel/qmultitouch_mac.mm \
- kernel/qcocoaintrospection_mac.mm
-
- HEADERS += \
- kernel/qt_cocoa_helpers_mac_p.h \
- kernel/qcocoaapplication_mac_p.h \
- kernel/qcocoaapplicationdelegate_mac_p.h \
- kernel/qeventdispatcher_mac_p.h
-
- MENU_NIB.files = mac/qt_menu.nib
- MENU_NIB.path = Resources
- MENU_NIB.version = Versions
- QMAKE_BUNDLE_DATA += MENU_NIB
- RESOURCES += mac/macresources.qrc
-
- LIBS_PRIVATE += -framework AppKit
+macx: {
+ HEADERS += kernel/qmacgesturerecognizer_p.h
+ SOURCES += kernel/qmacgesturerecognizer.cpp
}
wince*: {
diff --git a/src/widgets/kernel/qgesture_p.h b/src/widgets/kernel/qgesture_p.h
index c041af7317..ae203d2819 100644
--- a/src/widgets/kernel/qgesture_p.h
+++ b/src/widgets/kernel/qgesture_p.h
@@ -190,41 +190,6 @@ public:
static int Timeout;
};
-#ifndef QT_NO_GESTURES
-class QNativeGestureEvent : public QEvent
-{
-public:
- enum Type {
- None,
- GestureBegin,
- GestureEnd,
- Pan,
- Zoom,
- Rotate,
- Swipe
- };
-
- QNativeGestureEvent()
- : QEvent(QEvent::NativeGesture), gestureType(None), percentage(0)
-#ifdef Q_WS_WIN
- , sequenceId(0), argument(0)
-#endif
- {
- }
-
- Type gestureType;
- float percentage;
- QPoint position;
- float angle;
-#ifdef Q_WS_WIN
- ulong sequenceId;
- quint64 argument;
-#endif
-};
-
-#endif // QT_NO_GESTURES
-
-
QT_END_NAMESPACE
#endif // QT_NO_GESTURES
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index d90b187bf0..18abad4b40 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -51,8 +51,8 @@
#include "qevent.h"
#include "qgraphicsitem.h"
-#ifdef Q_WS_MAC
-#include "qmacgesturerecognizer_mac_p.h"
+#ifdef Q_OS_OSX
+#include "qmacgesturerecognizer_p.h"
#endif
#if defined(Q_WS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
#include "qwinnativepangesturerecognizer_win_p.h"
@@ -76,7 +76,7 @@ QGestureManager::QGestureManager(QObject *parent)
{
qRegisterMetaType<Qt::GestureState>();
-#if defined(Q_WS_MAC)
+#if defined(Q_OS_OSX)
registerGestureRecognizer(new QMacSwipeGestureRecognizer);
registerGestureRecognizer(new QMacPinchGestureRecognizer);
registerGestureRecognizer(new QMacPanGestureRecognizer);
diff --git a/src/widgets/kernel/qmacgesturerecognizer.cpp b/src/widgets/kernel/qmacgesturerecognizer.cpp
new file mode 100644
index 0000000000..feb779e53f
--- /dev/null
+++ b/src/widgets/kernel/qmacgesturerecognizer.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmacgesturerecognizer_p.h"
+#include "qgesture.h"
+#include "qgesture_p.h"
+#include "qevent.h"
+#include "qwidget.h"
+#include "qdebug.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer()
+{
+}
+
+QGesture *QMacSwipeGestureRecognizer::create(QObject * /*target*/)
+{
+ return new QSwipeGesture;
+}
+
+QGestureRecognizer::Result
+QMacSwipeGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
+ QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+ switch (ev->gestureType()) {
+ case Qt::SwipeNativeGesture: {
+ QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
+ g->setSwipeAngle(ev->value());
+ g->setHotSpot(ev->screenPos());
+ return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
+ break; }
+ default:
+ break;
+ }
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacSwipeGestureRecognizer::reset(QGesture *gesture)
+{
+ QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
+ g->setSwipeAngle(0);
+ QGestureRecognizer::reset(gesture);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+QMacPinchGestureRecognizer::QMacPinchGestureRecognizer()
+{
+}
+
+QGesture *QMacPinchGestureRecognizer::create(QObject * /*target*/)
+{
+ return new QPinchGesture;
+}
+
+QGestureRecognizer::Result
+QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
+ QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
+ QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+ switch (ev->gestureType()) {
+ case Qt::BeginNativeGesture:
+ reset(gesture);
+ g->setStartCenterPoint(static_cast<QWidget*>(obj)->mapFromGlobal(ev->screenPos().toPoint()));
+ g->setCenterPoint(g->startCenterPoint());
+ g->setChangeFlags(QPinchGesture::CenterPointChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ g->setHotSpot(ev->screenPos());
+ return QGestureRecognizer::MayBeGesture | QGestureRecognizer::ConsumeEventHint;
+ case Qt::RotateNativeGesture:
+ g->setLastScaleFactor(g->scaleFactor());
+ g->setLastRotationAngle(g->rotationAngle());
+ g->setRotationAngle(g->rotationAngle() + ev->value());
+ g->setChangeFlags(QPinchGesture::RotationAngleChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ g->setHotSpot(ev->screenPos());
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
+ case Qt::ZoomNativeGesture:
+ g->setLastScaleFactor(g->scaleFactor());
+ g->setLastRotationAngle(g->rotationAngle());
+ g->setScaleFactor(g->scaleFactor() * (1 + ev->value()));
+ g->setChangeFlags(QPinchGesture::ScaleFactorChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ g->setHotSpot(ev->screenPos());
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
+ case Qt::SmartZoomNativeGesture:
+ g->setLastScaleFactor(g->scaleFactor());
+ g->setLastRotationAngle(g->rotationAngle());
+ g->setScaleFactor(ev->value() ? 1.7f : 1.0f);
+ g->setChangeFlags(QPinchGesture::ScaleFactorChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ g->setHotSpot(ev->screenPos());
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
+ case Qt::EndNativeGesture:
+ return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
+ default:
+ break;
+ }
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacPinchGestureRecognizer::reset(QGesture *gesture)
+{
+ QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
+ g->setChangeFlags(0);
+ g->setTotalChangeFlags(0);
+ g->setScaleFactor(1.0f);
+ g->setTotalScaleFactor(1.0f);
+ g->setLastScaleFactor(1.0f);
+ g->setRotationAngle(0.0f);
+ g->setTotalRotationAngle(0.0f);
+ g->setLastRotationAngle(0.0f);
+ g->setCenterPoint(QPointF());
+ g->setStartCenterPoint(QPointF());
+ g->setLastCenterPoint(QPointF());
+ QGestureRecognizer::reset(gesture);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true)
+{
+}
+
+QGesture *QMacPanGestureRecognizer::create(QObject *target)
+{
+ if (!target)
+ return new QPanGesture;
+
+ if (QWidget *w = qobject_cast<QWidget *>(target)) {
+ w->setAttribute(Qt::WA_AcceptTouchEvents);
+ w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
+ return new QPanGesture;
+ }
+ return 0;
+}
+
+QGestureRecognizer::Result
+QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event)
+{
+ const int panBeginDelay = 300;
+ const int panBeginRadius = 3;
+
+ QPanGesture *g = static_cast<QPanGesture *>(gesture);
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (ev->touchPoints().size() == 1) {
+ reset(gesture);
+ _startPos = QCursor::pos();
+ _panTimer.start(panBeginDelay, target);
+ _panCanceled = false;
+ return QGestureRecognizer::MayBeGesture;
+ }
+ break;}
+ case QEvent::TouchEnd: {
+ if (_panCanceled)
+ break;
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (ev->touchPoints().size() == 1)
+ return QGestureRecognizer::FinishGesture;
+ break;}
+ case QEvent::TouchUpdate: {
+ if (_panCanceled)
+ break;
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (ev->touchPoints().size() == 1) {
+ if (_panTimer.isActive()) {
+ // INVARIANT: Still in maybeGesture. Check if the user
+ // moved his finger so much that it makes sense to cancel the pan:
+ const QPointF p = QCursor::pos();
+ if ((p - _startPos).manhattanLength() > panBeginRadius) {
+ _panCanceled = true;
+ _panTimer.stop();
+ return QGestureRecognizer::CancelGesture;
+ }
+ } else {
+ const QPointF p = QCursor::pos();
+ const QPointF posOffset = p - _startPos;
+ g->setLastOffset(g->offset());
+ g->setOffset(QPointF(posOffset.x(), posOffset.y()));
+ g->setHotSpot(_startPos);
+ return QGestureRecognizer::TriggerGesture;
+ }
+ } else if (_panTimer.isActive()) {
+ // I only want to cancel the pan if the user is pressing
+ // more than one finger, and the pan hasn't started yet:
+ _panCanceled = true;
+ _panTimer.stop();
+ return QGestureRecognizer::CancelGesture;
+ }
+ break;}
+ case QEvent::Timer: {
+ QTimerEvent *ev = static_cast<QTimerEvent *>(event);
+ if (ev->timerId() == _panTimer.timerId()) {
+ _panTimer.stop();
+ if (_panCanceled)
+ break;
+ // Begin new pan session!
+ _startPos = QCursor::pos();
+ g->setHotSpot(_startPos);
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
+ }
+ break; }
+ default:
+ break;
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacPanGestureRecognizer::reset(QGesture *gesture)
+{
+ QPanGesture *g = static_cast<QPanGesture *>(gesture);
+ _startPos = QPointF();
+ _panCanceled = true;
+ g->setOffset(QPointF(0, 0));
+ g->setLastOffset(QPointF(0, 0));
+ g->setAcceleration(qreal(1));
+ QGestureRecognizer::reset(gesture);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
diff --git a/src/widgets/kernel/qmacgesturerecognizer_p.h b/src/widgets/kernel/qmacgesturerecognizer_p.h
new file mode 100644
index 0000000000..02f836b3f7
--- /dev/null
+++ b/src/widgets/kernel/qmacgesturerecognizer_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMACSWIPEGESTURERECOGNIZER_MAC_P_H
+#define QMACSWIPEGESTURERECOGNIZER_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtimer.h"
+#include "qpoint.h"
+#include "qgesturerecognizer.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+class QMacSwipeGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QMacSwipeGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+};
+
+class QMacPinchGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QMacPinchGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+};
+
+class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
+{
+public:
+ QMacPanGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+private:
+ QPointF _startPos;
+ QBasicTimer _panTimer;
+ bool _panCanceled;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
+
+#endif // QMACSWIPEGESTURERECOGNIZER_MAC_P_H
diff --git a/src/widgets/kernel/qsizepolicy.qdoc b/src/widgets/kernel/qsizepolicy.qdoc
index 1c99131bc4..d82f3837f2 100644
--- a/src/widgets/kernel/qsizepolicy.qdoc
+++ b/src/widgets/kernel/qsizepolicy.qdoc
@@ -342,6 +342,7 @@
/*!
\fn void QSizePolicy::retainSizeWhenHidden() const
+ \since 5.2
Returns if the layout should retain the widgets size when it is hidden. This is by default false.
@@ -350,6 +351,7 @@
/*!
\fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize)
+ \since 5.2
Set if a layout should retain the widgets size when it is hidden.
If \a retainSize is true the layout will not be changed by hiding the widget.
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 72e3a56702..55459ac1ac 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1594,6 +1594,7 @@ void QWidgetPrivate::createExtra()
extra->autoFillBackground = 0;
extra->nativeChildrenForced = 0;
extra->inRenderWithPainter = 0;
+ extra->hasWindowContainer = false;
extra->hasMask = 0;
createSysExtra();
#ifdef QWIDGET_EXTRA_DEBUG
@@ -6543,6 +6544,9 @@ void QWidget::move(const QPoint &p)
data->crect.moveTopLeft(p); // no frame yet
setAttribute(Qt::WA_PendingMoveEvent);
}
+
+ if (d->extra && d->extra->hasWindowContainer)
+ QWindowContainer::parentWasMoved(this);
}
/*! \fn void QWidget::resize(int w, int h)
@@ -6581,6 +6585,9 @@ void QWidget::setGeometry(const QRect &r)
setAttribute(Qt::WA_PendingMoveEvent);
setAttribute(Qt::WA_PendingResizeEvent);
}
+
+ if (d->extra && d->extra->hasWindowContainer)
+ QWindowContainer::parentWasMoved(this);
}
/*!
@@ -9715,6 +9722,9 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
ancestorProxy->d_func()->embedSubWindow(this);
}
#endif
+
+ if (d->extra && d->extra->hasWindowContainer)
+ QWindowContainer::parentWasChanged(this);
}
/*!
@@ -10747,6 +10757,9 @@ void QWidget::raise()
if (testAttribute(Qt::WA_WState_Created))
d->raise_sys();
+ if (d->extra && d->extra->hasWindowContainer)
+ QWindowContainer::parentWasRaised(this);
+
QEvent e(QEvent::ZOrderChange);
QApplication::sendEvent(this, &e);
}
@@ -10781,6 +10794,9 @@ void QWidget::lower()
if (testAttribute(Qt::WA_WState_Created))
d->lower_sys();
+ if (d->extra && d->extra->hasWindowContainer)
+ QWindowContainer::parentWasLowered(this);
+
QEvent e(QEvent::ZOrderChange);
QApplication::sendEvent(this, &e);
}
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index cc740034fc..df40908c00 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -254,6 +254,7 @@ struct QWExtra {
uint nativeChildrenForced : 1;
uint inRenderWithPainter : 1;
uint hasMask : 1;
+ uint hasWindowContainer : 1;
// *************************** Platform specific values (bit fields first) **********
#if defined(Q_WS_WIN) // <----------------------------------------------------------- WIN
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index f2bd389769..51a0eb7d72 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -49,6 +49,7 @@
#endif
#include <private/qwidgetbackingstore_p.h>
#include <qpa/qwindowsysteminterface_p.h>
+#include <private/qgesturemanager_p.h>
QT_BEGIN_NAMESPACE
@@ -85,6 +86,12 @@ QWidgetWindow::QWidgetWindow(QWidget *widget)
connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName);
}
+QWidgetWindow::~QWidgetWindow()
+{
+ if (m_widget == qt_tablet_target)
+ qt_tablet_target = 0;
+}
+
#ifndef QT_NO_ACCESSIBILITY
QAccessibleInterface *QWidgetWindow::accessibleRoot() const
{
@@ -220,6 +227,13 @@ bool QWidgetWindow::event(QEvent *event)
handleTabletEvent(static_cast<QTabletEvent *>(event));
return true;
#endif
+
+#ifndef QT_NO_GESTURES
+ case QEvent::NativeGesture:
+ handleGestureEvent(static_cast<QNativeGestureEvent *>(event));
+ return true;
+#endif
+
#ifndef QT_NO_CONTEXTMENU
case QEvent::ContextMenu:
handleContextMenuEvent(static_cast<QContextMenuEvent *>(event));
@@ -732,6 +746,25 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
}
#endif // QT_NO_TABLETEVENT
+#ifndef QT_NO_GESTURES
+void QWidgetWindow::handleGestureEvent(QNativeGestureEvent *e)
+{
+ // copy-pasted code to find correct widget follows:
+ QObject *receiver = 0;
+ if (QApplicationPrivate::inPopupMode()) {
+ QWidget *popup = QApplication::activePopupWidget();
+ QWidget *popupFocusWidget = popup->focusWidget();
+ receiver = popupFocusWidget ? popupFocusWidget : popup;
+ }
+ if (!receiver)
+ receiver = QApplication::widgetAt(e->globalPos());
+ if (!receiver)
+ receiver = m_widget; // last resort
+
+ QApplication::sendSpontaneousEvent(receiver, e);
+}
+#endif // QT_NO_GESTURES
+
#ifndef QT_NO_CONTEXTMENU
void QWidgetWindow::handleContextMenuEvent(QContextMenuEvent *e)
{
diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h
index cb7bef8f3e..ffde44dd27 100644
--- a/src/widgets/kernel/qwidgetwindow_qpa_p.h
+++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h
@@ -58,6 +58,7 @@ class QWidgetWindow : public QWindow
Q_OBJECT
public:
QWidgetWindow(QWidget *widget);
+ ~QWidgetWindow();
QWidget *widget() const { return m_widget; }
#ifndef QT_NO_ACCESSIBILITY
@@ -91,6 +92,9 @@ protected:
#ifndef QT_NO_TABLETEVENT
void handleTabletEvent(QTabletEvent *);
#endif
+#ifndef QT_NO_GESTURES
+ void handleGestureEvent(QNativeGestureEvent *);
+#endif
#ifndef QT_NO_CONTEXTMENU
void handleContextMenuEvent(QContextMenuEvent *);
#endif
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index b02b05552f..6914f64f8e 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -42,6 +42,10 @@
#include "qwindowcontainer_p.h"
#include "qwidget_p.h"
#include <QtGui/qwindow.h>
+#include <QDebug>
+
+#include <QMdiSubWindow>
+#include <QAbstractScrollArea>
QT_BEGIN_NAMESPACE
@@ -50,11 +54,67 @@ class QWindowContainerPrivate : public QWidgetPrivate
public:
Q_DECLARE_PUBLIC(QWindowContainer)
- QWindowContainerPrivate() : window(0), oldFocusWindow(0) { }
+ QWindowContainerPrivate()
+ : window(0)
+ , oldFocusWindow(0)
+ , usesNativeWidgets(false)
+ {
+ }
+
~QWindowContainerPrivate() { }
+ static QWindowContainerPrivate *get(QWidget *w) {
+ QWindowContainer *wc = qobject_cast<QWindowContainer *>(w);
+ if (wc)
+ return wc->d_func();
+ return 0;
+ }
+
+ void updateGeometry() {
+ Q_Q(QWindowContainer);
+ if (usesNativeWidgets)
+ window->setGeometry(q->rect());
+ else
+ window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size()));
+ }
+
+ void updateUsesNativeWidgets()
+ {
+ if (usesNativeWidgets || window->parent() == 0)
+ return;
+ Q_Q(QWindowContainer);
+ QWidget *p = q->parentWidget();
+ while (p) {
+ if (qobject_cast<QMdiSubWindow *>(p) != 0
+ || qobject_cast<QAbstractScrollArea *>(p) != 0) {
+ q->winId();
+ usesNativeWidgets = true;
+ break;
+ }
+ p = p->parentWidget();
+ }
+ }
+
+ void markParentChain() {
+ Q_Q(QWindowContainer);
+ QWidget *p = q;
+ while (p) {
+ QWidgetPrivate *d = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(p));
+ d->createExtra();
+ d->extra->hasWindowContainer = true;
+ p = p->parentWidget();
+ }
+ }
+
+ bool isStillAnOrphan() const {
+ return window->parent() == &fakeParent;
+ }
+
QPointer<QWindow> window;
QWindow *oldFocusWindow;
+ QWindow fakeParent;
+
+ uint usesNativeWidgets : 1;
};
@@ -78,6 +138,14 @@ public:
be removed from the window container with a call to
QWindow::setParent().
+ The window container is attached as a native child window to the
+ toplevel window it is a child of. When a window container is used
+ as a child of a QAbstractScrollArea or QMdiArea, it will
+ create a \l {Native Widgets vs Alien Widgets} {native window} for
+ every widget in its parent chain to allow for proper stacking and
+ clipping in this use case. Applications with many native child
+ windows may suffer from performance issues.
+
The window container has a number of known limitations:
\list
@@ -86,11 +154,6 @@ public:
widget hierarchy as an opaque box. The stacking order of multiple
overlapping window container instances is undefined.
- \li Window Handles; The window container will explicitly invoke
- winId() which will force the use of native window handles
- inside the application. See \l {Native Widgets vs Alien Widgets}
- {QWidget documentation} for more details.
-
\li Rendering Integration; The window container does not interoperate
with QGraphicsProxyWidget, QWidget::render() or similar functionality.
@@ -132,13 +195,7 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt:
}
d->window = embeddedWindow;
-
- // We force this window to become a native window and reparent the
- // window directly to it. This is done so that the order in which
- // the QWindowContainer is added to a QWidget tree and when it
- // gets a window does not matter.
- winId();
- d->window->setParent(windowHandle());
+ d->window->setParent(&d->fakeParent);
connect(QGuiApplication::instance(), SIGNAL(focusWindowChanged(QWindow *)), this, SLOT(focusWindowChanged(QWindow *)));
}
@@ -167,8 +224,6 @@ void QWindowContainer::focusWindowChanged(QWindow *focusWindow)
d->oldFocusWindow = focusWindow;
}
-
-
/*!
\internal
*/
@@ -190,22 +245,38 @@ bool QWindowContainer::event(QEvent *e)
// The only thing we are interested in is making sure our sizes stay
// in sync, so do a catch-all case.
case QEvent::Resize:
+ d->updateGeometry();
+ break;
case QEvent::Move:
+ d->updateGeometry();
+ break;
case QEvent::PolishRequest:
- d->window->setGeometry(0, 0, width(), height());
+ d->updateGeometry();
break;
case QEvent::Show:
- d->window->show();
+ d->updateUsesNativeWidgets();
+ if (d->isStillAnOrphan()) {
+ d->window->setParent(d->usesNativeWidgets
+ ? windowHandle()
+ : window()->windowHandle());
+ }
+ if (d->window->parent()) {
+ d->markParentChain();
+ d->window->show();
+ }
break;
case QEvent::Hide:
- d->window->hide();
+ if (d->window->parent())
+ d->window->hide();
break;
case QEvent::FocusIn:
- if (d->oldFocusWindow != d->window) {
- d->window->requestActivate();
- } else {
- QWidget *next = nextInFocusChain();
- next->setFocus();
+ if (d->window->parent()) {
+ if (d->oldFocusWindow != d->window) {
+ d->window->requestActivate();
+ } else {
+ QWidget *next = nextInFocusChain();
+ next->setFocus();
+ }
}
break;
default:
@@ -215,4 +286,60 @@ bool QWindowContainer::event(QEvent *e)
return QWidget::event(e);
}
+typedef void (*qwindowcontainer_traverse_callback)(QWidget *parent);
+static void qwindowcontainer_traverse(QWidget *parent, qwindowcontainer_traverse_callback callback)
+{
+ const QObjectList &children = parent->children();
+ for (int i=0; i<children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(children.at(i));
+ if (w) {
+ QWidgetPrivate *wd = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(w));
+ if (wd->extra && wd->extra->hasWindowContainer)
+ callback(w);
+ }
+ }
+}
+
+void QWindowContainer::parentWasChanged(QWidget *parent)
+{
+ if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
+ if (d->window->parent()) {
+ d->updateUsesNativeWidgets();
+ d->markParentChain();
+ d->window->setParent(d->usesNativeWidgets
+ ? parent->windowHandle()
+ : parent->window()->windowHandle());
+ d->updateGeometry();
+ }
+ }
+ qwindowcontainer_traverse(parent, parentWasChanged);
+}
+
+void QWindowContainer::parentWasMoved(QWidget *parent)
+{
+ if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
+ if (d->window->parent())
+ d->updateGeometry();
+ }
+ qwindowcontainer_traverse(parent, parentWasMoved);
+}
+
+void QWindowContainer::parentWasRaised(QWidget *parent)
+{
+ if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
+ if (d->window->parent())
+ d->window->raise();
+ }
+ qwindowcontainer_traverse(parent, parentWasRaised);
+}
+
+void QWindowContainer::parentWasLowered(QWidget *parent)
+{
+ if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
+ if (d->window->parent())
+ d->window->lower();
+ }
+ qwindowcontainer_traverse(parent, parentWasLowered);
+}
+
QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qwindowcontainer_p.h b/src/widgets/kernel/qwindowcontainer_p.h
index 37c023fc1d..e2446bef42 100644
--- a/src/widgets/kernel/qwindowcontainer_p.h
+++ b/src/widgets/kernel/qwindowcontainer_p.h
@@ -57,6 +57,11 @@ public:
explicit QWindowContainer(QWindow *embeddedWindow, QWidget *parent = 0, Qt::WindowFlags f = 0);
~QWindowContainer();
+ static void parentWasChanged(QWidget *parent);
+ static void parentWasMoved(QWidget *parent);
+ static void parentWasRaised(QWidget *parent);
+ static void parentWasLowered(QWidget *parent);
+
protected:
bool event(QEvent *ev);
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index 08b24a8200..79ca0a5bdb 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -380,6 +380,8 @@ bool QSystemTrayIcon::supportsMessages()
On Mac OS X, the Growl notification system must be installed for this function to
display messages.
+ Has been turned into a slot in Qt 5.2.
+
\sa show(), supportsMessages()
*/
void QSystemTrayIcon::showMessage(const QString& title, const QString& msg,
diff --git a/src/widgets/util/qsystemtrayicon.h b/src/widgets/util/qsystemtrayicon.h
index 278efae586..d6ba553a3a 100644
--- a/src/widgets/util/qsystemtrayicon.h
+++ b/src/widgets/util/qsystemtrayicon.h
@@ -94,8 +94,6 @@ public:
static bool supportsMessages();
enum MessageIcon { NoIcon, Information, Warning, Critical };
- void showMessage(const QString &title, const QString &msg,
- MessageIcon icon = Information, int msecs = 10000);
QRect geometry() const;
bool isVisible() const;
@@ -104,6 +102,8 @@ public Q_SLOTS:
void setVisible(bool visible);
inline void show() { setVisible(true); }
inline void hide() { setVisible(false); }
+ void showMessage(const QString &title, const QString &msg,
+ QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int msecs = 10000);
Q_SIGNALS:
void activated(QSystemTrayIcon::ActivationReason reason);
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
index 3771b97a31..e3222b49e8 100644
--- a/src/widgets/widgets.pro
+++ b/src/widgets/widgets.pro
@@ -44,7 +44,3 @@ QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtWidgets.dynlist
testcocoon {
load(testcocoon)
}
-
-win32:!contains(QT_CONFIG, directwrite) {
- DEFINES += QT_NO_DIRECTWRITE
-}
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index a9b21cbc81..8b151e65bd 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -674,12 +674,18 @@ void QDockWidgetPrivate::updateButtons()
= qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton));
button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
button->setVisible(canFloat && !hideButtons);
-
+#ifndef QT_NO_ACCESSIBILITY
+ button->setAccessibleName(QDockWidget::tr("Float"));
+ button->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget"));
+#endif
button
= qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton));
button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
button->setVisible(canClose && !hideButtons);
-
+#ifndef QT_NO_ACCESSIBILITY
+ button->setAccessibleName(QDockWidget::tr("Close"));
+ button->setAccessibleDescription(QDockWidget::tr("Closes the dock widget"));
+#endif
q->setAttribute(Qt::WA_ContentsPropagated,
(canFloat || canClose) && !hideButtons);
diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp
index 86fd10699c..7b1d66cf0d 100644
--- a/src/widgets/widgets/qstatusbar.cpp
+++ b/src/widgets/widgets/qstatusbar.cpp
@@ -551,8 +551,6 @@ void QStatusBar::showMessage(const QString &message, int timeout)
{
Q_D(QStatusBar);
- d->tempItem = message;
-
if (timeout > 0) {
if (!d->timer) {
d->timer = new QTimer(this);
@@ -563,6 +561,9 @@ void QStatusBar::showMessage(const QString &message, int timeout)
delete d->timer;
d->timer = 0;
}
+ if (d->tempItem == message)
+ return;
+ d->tempItem = message;
hideOrShow();
}