diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-02-26 01:00:25 +0100 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2020-02-26 18:39:21 +0100 |
commit | 75c0ffaf6d2b92cdf26092e01acdd5af4afeac97 (patch) | |
tree | bb9e85c21248790ec99b3665928872e39b14db64 /src/plugins | |
parent | 4753d69d8934258de7fb64550e50a5cbb9b5603f (diff) | |
parent | 462c2745a5168a5b57381d05779b5d16aebe018e (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts:
examples/network/bearermonitor/CMakeLists.txt
examples/network/CMakeLists.txt
src/corelib/tools/qlinkedlist.h
src/sql/kernel/qsqldriver_p.h
src/sql/kernel/qsqlresult_p.h
src/widgets/kernel/qwidget.cpp
src/widgets/kernel/qwidget_p.h
tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
tests/auto/tools/moc/allmocs_baseline_in.json
Change-Id: I21a3c34570ae79ea9d30107fae71759d7eac17d9
Diffstat (limited to 'src/plugins')
24 files changed, 471 insertions, 212 deletions
diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp index fb979ab6cc..7b5f2f16f8 100644 --- a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp +++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp @@ -40,7 +40,6 @@ #include "qandroidplatformfiledialoghelper.h" #include <androidjnimain.h> -#include <private/qjni_p.h> #include <jni.h> QT_BEGIN_NAMESPACE @@ -50,9 +49,11 @@ namespace QtAndroidFileDialogHelper { #define RESULT_OK -1 #define REQUEST_CODE 1305 // Arbitrary +const char JniIntentClass[] = "android/content/Intent"; + QAndroidPlatformFileDialogHelper::QAndroidPlatformFileDialogHelper() - : QPlatformFileDialogHelper() - , m_selectedFile() + : QPlatformFileDialogHelper(), + m_activity(QtAndroid::activity()) { } @@ -61,92 +62,165 @@ bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, ji if (requestCode != REQUEST_CODE) return false; - if (resultCode == RESULT_OK) { - const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data); - const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;"); - const QString uriStr = uri.callObjectMethod("toString", "()Ljava/lang/String;").toString(); - m_selectedFile = QUrl(uriStr); - Q_EMIT fileSelected(m_selectedFile); - Q_EMIT accept(); - } else { + if (resultCode != RESULT_OK) { Q_EMIT reject(); + return true; } - return true; -} - -bool QAndroidPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) -{ - Q_UNUSED(windowFlags) - Q_UNUSED(windowModality) - Q_UNUSED(parent) - - if (options()->fileMode() != QFileDialogOptions::FileMode::ExistingFile) - return false; + const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data); - QtAndroidPrivate::registerActivityResultListener(this); + const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;"); + if (uri.isValid()) { + takePersistableUriPermission(uri); + m_selectedFile.append(QUrl(uri.toString())); + Q_EMIT fileSelected(m_selectedFile.first()); + Q_EMIT accept(); - const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "ACTION_OPEN_DOCUMENT", "Ljava/lang/String;"); - QJNIObjectPrivate intent("android/content/Intent", "(Ljava/lang/String;)V", ACTION_OPEN_DOCUMENT.object()); - const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "CATEGORY_OPENABLE", "Ljava/lang/String;"); - intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;", CATEGORY_OPENABLE.object()); - intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QJNIObjectPrivate::fromString(QStringLiteral("*/*")).object()); + return true; + } - const QJNIObjectPrivate activity(QtAndroid::activity()); - activity.callMethod<void>("startActivityForResult", "(Landroid/content/Intent;I)V", intent.object(), REQUEST_CODE); + const QJNIObjectPrivate uriClipData = + intent.callObjectMethod("getClipData", "()Landroid/content/ClipData;"); + if (uriClipData.isValid()) { + const int size = uriClipData.callMethod<jint>("getItemCount"); + for (int i = 0; i < size; ++i) { + QJNIObjectPrivate item = uriClipData.callObjectMethod( + "getItemAt", "(I)Landroid/content/ClipData$Item;", i); + + QJNIObjectPrivate itemUri = item.callObjectMethod("getUri", "()Landroid/net/Uri;"); + takePersistableUriPermission(itemUri); + m_selectedFile.append(itemUri.toString()); + Q_EMIT filesSelected(m_selectedFile); + Q_EMIT accept(); + } + } return true; } -void QAndroidPlatformFileDialogHelper::exec() +void QAndroidPlatformFileDialogHelper::takePersistableUriPermission(const QJNIObjectPrivate &uri) { - m_eventLoop.exec(QEventLoop::DialogExec); + int modeFlags = QJNIObjectPrivate::getStaticField<jint>( + JniIntentClass, "FLAG_GRANT_READ_URI_PERMISSION"); + + if (options()->acceptMode() == QFileDialogOptions::AcceptSave) { + modeFlags |= QJNIObjectPrivate::getStaticField<jint>( + JniIntentClass, "FLAG_GRANT_WRITE_URI_PERMISSION"); + } + + QJNIObjectPrivate contentResolver = m_activity.callObjectMethod( + "getContentResolver", "()Landroid/content/ContentResolver;"); + contentResolver.callMethod<void>("takePersistableUriPermission", "(Landroid/net/Uri;I)V", + uri.object(), modeFlags); } -void QAndroidPlatformFileDialogHelper::hide() +void QAndroidPlatformFileDialogHelper::setLocalFilesOnly(bool localOnly) { - if (m_eventLoop.isRunning()) - m_eventLoop.exit(); - QtAndroidPrivate::unregisterActivityResultListener(this); + const QJNIObjectPrivate extraLocalOnly = QJNIObjectPrivate::getStaticObjectField( + JniIntentClass, "EXTRA_LOCAL_ONLY", "Ljava/lang/String;"); + m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;", + extraLocalOnly.object(), localOnly); } -QString QAndroidPlatformFileDialogHelper::selectedNameFilter() const +void QAndroidPlatformFileDialogHelper::setIntentTitle(const QString &title) { - return QString(); + const QJNIObjectPrivate extraTitle = QJNIObjectPrivate::getStaticObjectField( + JniIntentClass, "EXTRA_TITLE", "Ljava/lang/String;"); + m_intent.callObjectMethod("putExtra", + "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;", + extraTitle.object(), QJNIObjectPrivate::fromString(title).object()); } -void QAndroidPlatformFileDialogHelper::selectNameFilter(const QString &filter) +void QAndroidPlatformFileDialogHelper::setOpenableCategory() { - Q_UNUSED(filter) + const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField( + JniIntentClass, "CATEGORY_OPENABLE", "Ljava/lang/String;"); + m_intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;", + CATEGORY_OPENABLE.object()); } -void QAndroidPlatformFileDialogHelper::setFilter() +void QAndroidPlatformFileDialogHelper::setAllowMultipleSelections(bool allowMultiple) { + const QJNIObjectPrivate allowMultipleSelections = QJNIObjectPrivate::getStaticObjectField( + JniIntentClass, "EXTRA_ALLOW_MULTIPLE", "Ljava/lang/String;"); + m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;", + allowMultipleSelections.object(), allowMultiple); } -QList<QUrl> QAndroidPlatformFileDialogHelper::selectedFiles() const +void QAndroidPlatformFileDialogHelper::setMimeTypes() { - return {m_selectedFile}; + m_intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", + QJNIObjectPrivate::fromString("*/*").object()); + + const QJNIObjectPrivate extraMimeType = QJNIObjectPrivate::getStaticObjectField( + JniIntentClass, "EXTRA_MIME_TYPES", "Ljava/lang/String;"); + for (const QString &type : options()->mimeTypeFilters()) { + m_intent.callObjectMethod( + "putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;", + extraMimeType.object(), QJNIObjectPrivate::fromString(type).object()); + } } -void QAndroidPlatformFileDialogHelper::selectFile(const QUrl &file) +QJNIObjectPrivate QAndroidPlatformFileDialogHelper::getFileDialogIntent(const QString &intentType) { - Q_UNUSED(file) + const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField( + JniIntentClass, intentType.toLatin1(), "Ljava/lang/String;"); + return QJNIObjectPrivate(JniIntentClass, "(Ljava/lang/String;)V", + ACTION_OPEN_DOCUMENT.object()); } -QUrl QAndroidPlatformFileDialogHelper::directory() const +bool QAndroidPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) { - return QUrl(); + Q_UNUSED(windowFlags) + Q_UNUSED(windowModality) + Q_UNUSED(parent) + + bool isDirDialog = false; + + if (options()->acceptMode() == QFileDialogOptions::AcceptSave) { + m_intent = getFileDialogIntent("ACTION_CREATE_DOCUMENT"); + } else if (options()->acceptMode() == QFileDialogOptions::AcceptOpen) { + switch (options()->fileMode()) { + case QFileDialogOptions::FileMode::DirectoryOnly: + case QFileDialogOptions::FileMode::Directory: + m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT_TREE"); + isDirDialog = true; + break; + case QFileDialogOptions::FileMode::ExistingFiles: + m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT"); + setAllowMultipleSelections(true); + break; + case QFileDialogOptions::FileMode::AnyFile: + case QFileDialogOptions::FileMode::ExistingFile: + m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT"); + break; + } + } + + if (!isDirDialog) { + setOpenableCategory(); + setMimeTypes(); + } + + setIntentTitle(options()->windowTitle()); + setLocalFilesOnly(true); + + QtAndroidPrivate::registerActivityResultListener(this); + m_activity.callMethod<void>("startActivityForResult", "(Landroid/content/Intent;I)V", + m_intent.object(), REQUEST_CODE); + return true; } -void QAndroidPlatformFileDialogHelper::setDirectory(const QUrl &directory) +void QAndroidPlatformFileDialogHelper::hide() { - Q_UNUSED(directory) + if (m_eventLoop.isRunning()) + m_eventLoop.exit(); + QtAndroidPrivate::unregisterActivityResultListener(this); } -bool QAndroidPlatformFileDialogHelper::defaultNameFilterDisables() const +void QAndroidPlatformFileDialogHelper::exec() { - return false; + m_eventLoop.exec(QEventLoop::DialogExec); } } diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h index 5cd26af7c9..fa9c3f47b3 100644 --- a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h +++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h @@ -44,6 +44,8 @@ #include <QEventLoop> #include <qpa/qplatformdialoghelper.h> #include <QtCore/private/qjnihelpers_p.h> +#include <private/qjni_p.h> +#include <QEventLoop> QT_BEGIN_NAMESPACE @@ -55,26 +57,34 @@ class QAndroidPlatformFileDialogHelper: public QPlatformFileDialogHelper, public public: QAndroidPlatformFileDialogHelper(); - void exec() override; - bool show(Qt::WindowFlags windowFlags, - Qt::WindowModality windowModality, - QWindow *parent) override; + void exec() override; + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override; void hide() override; - QString selectedNameFilter() const override; - void selectNameFilter(const QString &filter) override; - void setFilter() override; - QList<QUrl> selectedFiles() const override; - void selectFile(const QUrl &file) override; - QUrl directory() const override; - void setDirectory(const QUrl &directory) override; - bool defaultNameFilterDisables() const override; + QString selectedNameFilter() const override { return QString(); }; + void selectNameFilter(const QString &filter) override { Q_UNUSED(filter) }; + void setFilter() override {}; + QList<QUrl> selectedFiles() const override { return m_selectedFile; }; + void selectFile(const QUrl &file) override { Q_UNUSED(file) }; + QUrl directory() const override { return QUrl(); }; + void setDirectory(const QUrl &directory) override { Q_UNUSED(directory) }; + bool defaultNameFilterDisables() const override { return false; }; bool handleActivityResult(jint requestCode, jint resultCode, jobject data) override; private: + QJNIObjectPrivate getFileDialogIntent(const QString &intentType); + void takePersistableUriPermission(const QJNIObjectPrivate &uri); + void setLocalFilesOnly(bool localOnly); + void setIntentTitle(const QString &title); + void setOpenableCategory(); + void setAllowMultipleSelections(bool allowMultiple); + void setMimeTypes(); + QEventLoop m_eventLoop; - QUrl m_selectedFile; + QList<QUrl> m_selectedFile; + QJNIObjectPrivate m_intent; + const QJNIObjectPrivate m_activity; }; } diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp index 136637800b..c095613ce7 100644 --- a/src/plugins/platforms/android/qandroidplatformservices.cpp +++ b/src/plugins/platforms/android/qandroidplatformservices.cpp @@ -43,6 +43,7 @@ #include <QDebug> #include <QMimeDatabase> #include <QtCore/private/qjni_p.h> +#include <private/qjnihelpers_p.h> QT_BEGIN_NAMESPACE @@ -57,20 +58,20 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl) // if the file is local, we need to pass the MIME type, otherwise Android // does not start an Intent to view this file - if ((url.scheme().isEmpty() && QFile::exists(url.path())) || url.isLocalFile()) { + QLatin1String fileScheme("file"); + if ((url.scheme().isEmpty() || url.scheme() == fileScheme) && QFile::exists(url.path())) { // a real URL including the scheme is needed, else the Intent can not be started - url.setScheme(QLatin1String("file")); - + url.setScheme(fileScheme); QMimeDatabase mimeDb; mime = mimeDb.mimeTypeForUrl(url).name(); } QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString()); QJNIObjectPrivate mimeString = QJNIObjectPrivate::fromString(mime); - return QJNIObjectPrivate::callStaticMethod<jboolean>(QtAndroid::applicationClass(), - "openURL", - "(Ljava/lang/String;Ljava/lang/String;)Z", - urlString.object(), mimeString.object()); + return QJNIObjectPrivate::callStaticMethod<jboolean>( + QtAndroid::applicationClass(), "openURL", + "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Z", + QtAndroidPrivate::context(), urlString.object(), mimeString.object()); } bool QAndroidPlatformServices::openDocument(const QUrl &url) diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 2e15d11564..cb019c3775 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -574,7 +574,8 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion, qCInfo(lcQpaBackingStore) << "Flushing" << subImage << "to" << flushedView.layer << "of subview" << flushedView; - QCFType<CGImageRef> cgImage = subImage.toCGImage(); + QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace( + QCFType<CGImageRef>(subImage.toCGImage()), colorSpace()); flushedView.layer.contents = (__bridge id)static_cast<CGImageRef>(cgImage); } diff --git a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp index ca8db9b215..09acd37abc 100644 --- a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp +++ b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp @@ -194,6 +194,7 @@ void QWasmEventDispatcher::wakeUp() { #ifdef EMSCRIPTEN_HAS_ASYNC_RUN_IN_MAIN_RUNTIME_THREAD if (!emscripten_is_main_runtime_thread()) + if (m_hasMainLoop) emscripten_async_run_in_main_runtime_thread_(EM_FUNC_SIG_VI, (void*)(&QWasmEventDispatcher::mainThreadWakeUp), this); #endif QEventDispatcherUNIX::wakeUp(); diff --git a/src/plugins/platforms/windows/.prev_CMakeLists.txt b/src/plugins/platforms/windows/.prev_CMakeLists.txt index 299dda24af..92b2ccb217 100644 --- a/src/plugins/platforms/windows/.prev_CMakeLists.txt +++ b/src/plugins/platforms/windows/.prev_CMakeLists.txt @@ -95,6 +95,7 @@ qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_accessibility SOURCES uiautomation/qwindowsuiaaccessibility.cpp uiautomation/qwindowsuiaaccessibility.h uiautomation/qwindowsuiabaseprovider.cpp uiautomation/qwindowsuiabaseprovider.h + uiautomation/qwindowsuiaexpandcollapseprovider.cpp uiautomation/qwindowsuiaexpandcollapseprovider.h uiautomation/qwindowsuiagriditemprovider.cpp uiautomation/qwindowsuiagriditemprovider.h uiautomation/qwindowsuiagridprovider.cpp uiautomation/qwindowsuiagridprovider.h uiautomation/qwindowsuiainvokeprovider.cpp uiautomation/qwindowsuiainvokeprovider.h diff --git a/src/plugins/platforms/windows/CMakeLists.txt b/src/plugins/platforms/windows/CMakeLists.txt index 81a8c3bfe9..4cb9608378 100644 --- a/src/plugins/platforms/windows/CMakeLists.txt +++ b/src/plugins/platforms/windows/CMakeLists.txt @@ -96,6 +96,7 @@ qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_accessibility SOURCES uiautomation/qwindowsuiaaccessibility.cpp uiautomation/qwindowsuiaaccessibility.h uiautomation/qwindowsuiabaseprovider.cpp uiautomation/qwindowsuiabaseprovider.h + uiautomation/qwindowsuiaexpandcollapseprovider.cpp uiautomation/qwindowsuiaexpandcollapseprovider.h uiautomation/qwindowsuiagriditemprovider.cpp uiautomation/qwindowsuiagriditemprovider.h uiautomation/qwindowsuiagridprovider.cpp uiautomation/qwindowsuiagridprovider.h uiautomation/qwindowsuiainvokeprovider.cpp uiautomation/qwindowsuiainvokeprovider.h diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index f1f5d3a96e..7c4ddbd2a1 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -285,7 +285,7 @@ void QWindowsInputContext::showInputPanel() // the Surface seems unnecessary there anyway. But leave it hidden for IME. // Only trigger the native OSK if the Qt OSK is not in use. static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE"); - bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_MSWindowsDisableVirtualKeyboard); + bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_DisableNativeVirtualKeyboard); if ((imModuleEmpty && !nativeVKDisabled) && QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 16299)) { diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 325956b7ba..7f47cd712f 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -248,8 +248,7 @@ enum DarkModeColors : QRgb { darkModeBtnHighlightRgb = 0xc0c0c0, darkModeBtnShadowRgb = 0x808080, darkModeHighlightRgb = 0x0055ff, // deviating from 0x800080 - darkModeMenuHighlightRgb = darkModeHighlightRgb, - darkModeGrayTextRgb = 0x00ff00 + darkModeMenuHighlightRgb = darkModeHighlightRgb }; // from QStyle::standardPalette @@ -386,7 +385,7 @@ static inline QPalette menuPalette(const QPalette &systemPalette, bool light) const QColor menuColor = light ? getSysColor(COLOR_MENU) : QColor(Qt::black); const QColor menuTextColor = light ? getSysColor(COLOR_MENUTEXT) : QColor(Qt::white); const QColor disabled = light - ? getSysColor(COLOR_GRAYTEXT) : QColor(darkModeGrayTextRgb); + ? getSysColor(COLOR_GRAYTEXT) : QColor(darkModeBtnHighlightRgb); // we might need a special color group for the result. result.setColor(QPalette::Active, QPalette::Button, menuColor); result.setColor(QPalette::Active, QPalette::Text, menuTextColor); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index ee65b393d4..e635463951 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2629,7 +2629,7 @@ static inline DWORD edgesToWinOrientation(Qt::Edges edges) bool QWindowsWindow::startSystemResize(Qt::Edges edges) { - if (Q_UNLIKELY(!(window()->flags() & Qt::MSWindowsFixedSizeDialogHint))) + if (Q_UNLIKELY(window()->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint))) return false; ReleaseCapture(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.cpp new file mode 100644 index 0000000000..6ac8de23fa --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/qtguiglobal.h> +#if QT_CONFIG(accessibility) + +#include "qwindowsuiaexpandcollapseprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/qaccessible.h> +#include <QtCore/qloggingcategory.h> +#include <QtCore/qstring.h> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaExpandCollapseProvider::QWindowsUiaExpandCollapseProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaExpandCollapseProvider::~QWindowsUiaExpandCollapseProvider() = default; + +HRESULT STDMETHODCALLTYPE QWindowsUiaExpandCollapseProvider::Expand() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleActionInterface *actionInterface = accessible->actionInterface(); + if (!actionInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + if (accessible->childCount() > 0 && accessible->child(0)->state().invisible) + actionInterface->doAction(QAccessibleActionInterface::showMenuAction()); + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaExpandCollapseProvider::Collapse() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleActionInterface *actionInterface = accessible->actionInterface(); + if (!actionInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + if (accessible->childCount() > 0 && !accessible->child(0)->state().invisible) + actionInterface->doAction(QAccessibleActionInterface::showMenuAction()); + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaExpandCollapseProvider::get_ExpandCollapseState(__RPC__out ExpandCollapseState *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = ExpandCollapseState_LeafNode; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + if (accessible->childCount() > 0) + *pRetVal = accessible->child(0)->state().invisible ? + ExpandCollapseState_Collapsed : ExpandCollapseState_Expanded; + + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_CONFIG(accessibility) diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.h new file mode 100644 index 0000000000..f5b4c2e78b --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIAEXPANDCOLLAPSEPROVIDER_H +#define QWINDOWSUIAEXPANDCOLLAPSEPROVIDER_H + +#include <QtGui/qtguiglobal.h> +#if QT_CONFIG(accessibility) + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Expand/Collapse control pattern provider. Used for menu items with submenus. +class QWindowsUiaExpandCollapseProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<IExpandCollapseProvider> +{ + Q_DISABLE_COPY_MOVE(QWindowsUiaExpandCollapseProvider) +public: + explicit QWindowsUiaExpandCollapseProvider(QAccessible::Id id); + virtual ~QWindowsUiaExpandCollapseProvider() override; + + // IExpandCollapseProvider + HRESULT STDMETHODCALLTYPE Expand() override; + HRESULT STDMETHODCALLTYPE Collapse() override; + HRESULT STDMETHODCALLTYPE get_ExpandCollapseState(__RPC__out ExpandCollapseState *pRetVal) override; +}; + +QT_END_NAMESPACE + +#endif // QT_CONFIG(accessibility) + +#endif // QWINDOWSUIAEXPANDCOLLAPSEPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp index 5f564f81c2..9adc5c78dd 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp @@ -53,6 +53,7 @@ #include "qwindowsuiagridprovider.h" #include "qwindowsuiagriditemprovider.h" #include "qwindowsuiawindowprovider.h" +#include "qwindowsuiaexpandcollapseprovider.h" #include "qwindowscombase.h" #include "qwindowscontext.h" #include "qwindowsuiautils.h" @@ -341,6 +342,14 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow *pRetVal = new QWindowsUiaInvokeProvider(id()); } break; + case UIA_ExpandCollapsePatternId: + // Menu items with submenus. + if (accessible->role() == QAccessible::MenuItem + && accessible->childCount() > 0 + && accessible->child(0)->role() == QAccessible::PopupMenu) { + *pRetVal = new QWindowsUiaExpandCollapseProvider(id()); + } + break; default: break; } @@ -396,7 +405,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR // The native OSK should be disbled if the Qt OSK is in use, // or if disabled via application attribute. static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE"); - bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_MSWindowsDisableVirtualKeyboard); + bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_DisableNativeVirtualKeyboard); // If we want to disable the native OSK auto-showing // we have to report text fields as non-editable. @@ -448,6 +457,10 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR setVariantBool(wt == Qt::Popup || wt == Qt::ToolTip || wt == Qt::SplashScreen, pRetVal); } break; + case UIA_IsDialogPropertyId: + setVariantBool(accessible->role() == QAccessible::Dialog + || accessible->role() == QAccessible::AlertMessage, pRetVal); + break; case UIA_FullDescriptionPropertyId: setVariantString(accessible->text(QAccessible::Description), pRetVal); break; diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp index ab04384616..682b8c19c0 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp @@ -161,7 +161,7 @@ long roleToControlTypeId(QAccessible::Role role) {QAccessible::Sound, UIA_CustomControlTypeId}, {QAccessible::Cursor, UIA_CustomControlTypeId}, {QAccessible::Caret, UIA_CustomControlTypeId}, - {QAccessible::AlertMessage, UIA_CustomControlTypeId}, + {QAccessible::AlertMessage, UIA_WindowControlTypeId}, {QAccessible::Window, UIA_WindowControlTypeId}, {QAccessible::Client, UIA_GroupControlTypeId}, {QAccessible::PopupMenu, UIA_MenuControlTypeId}, diff --git a/src/plugins/platforms/windows/uiautomation/uiautomation.pri b/src/plugins/platforms/windows/uiautomation/uiautomation.pri index ee9332e7ea..1c4b018d1c 100644 --- a/src/plugins/platforms/windows/uiautomation/uiautomation.pri +++ b/src/plugins/platforms/windows/uiautomation/uiautomation.pri @@ -19,6 +19,7 @@ SOURCES += \ $$PWD/qwindowsuiagridprovider.cpp \ $$PWD/qwindowsuiagriditemprovider.cpp \ $$PWD/qwindowsuiawindowprovider.cpp \ + $$PWD/qwindowsuiaexpandcollapseprovider.cpp \ $$PWD/qwindowsuiautils.cpp HEADERS += \ @@ -39,6 +40,7 @@ HEADERS += \ $$PWD/qwindowsuiagridprovider.h \ $$PWD/qwindowsuiagriditemprovider.h \ $$PWD/qwindowsuiawindowprovider.h \ + $$PWD/qwindowsuiaexpandcollapseprovider.h \ $$PWD/qwindowsuiautils.h mingw: QMAKE_USE *= uuid diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 4620f0fd1d..27a2526df1 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -514,12 +514,10 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info return isTouchDevice ? &m_touchDevices[deviceinfo->deviceid] : nullptr; } -#if QT_CONFIG(tabletevent) static inline qreal fixed1616ToReal(xcb_input_fp1616_t val) { return qreal(val) / 0x10000; } -#endif // QT_CONFIG(tabletevent) void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) { diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 698be45aa8..505f7343ce 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -665,7 +665,9 @@ QImage::Format QXcbScreen::format() const bool needsRgbSwap; qt_xcb_imageFormatForVisual(connection(), screen()->root_depth, visualForId(screen()->root_visual), &format, &needsRgbSwap); // We are ignoring needsRgbSwap here and just assumes the backing-store will handle it. - return format; + if (format != QImage::Format_Invalid) + return format; + return QImage::Format_RGB32; } int QXcbScreen::forcedDpi() const diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp index 2930df7261..41141e1dd4 100644 --- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp +++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp @@ -78,17 +78,14 @@ class QMYSQLDriverPrivate : public QSqlDriverPrivate Q_DECLARE_PUBLIC(QMYSQLDriver) public: - QMYSQLDriverPrivate() : QSqlDriverPrivate(), mysql(0), + QMYSQLDriverPrivate() : QSqlDriverPrivate(QSqlDriver::MySqlServer) #if QT_CONFIG(textcodec) - tc(QTextCodec::codecForLocale()), -#else - tc(0), + , tc(QTextCodec::codecForLocale()) #endif - preparedQuerysEnabled(false) { dbmsType = QSqlDriver::MySqlServer; } - MYSQL *mysql; - QTextCodec *tc; - - bool preparedQuerysEnabled; + {} + MYSQL *mysql = nullptr; + QTextCodec *tc = nullptr; + bool preparedQuerysEnabled = false; }; static inline QString toUnicode(QTextCodec *tc, const char *str) @@ -201,46 +198,34 @@ class QMYSQLResultPrivate: public QSqlResultPrivate public: Q_DECLARE_SQLDRIVER_PRIVATE(QMYSQLDriver) - QMYSQLResultPrivate(QMYSQLResult *q, const QMYSQLDriver *drv) - : QSqlResultPrivate(q, drv), - result(0), - rowsAffected(0), - hasBlobs(false) - , stmt(0), meta(0), inBinds(0), outBinds(0) - , preparedQuery(false) - { } - - MYSQL_RES *result; - MYSQL_ROW row; - - int rowsAffected; + using QSqlResultPrivate::QSqlResultPrivate; bool bindInValues(); void bindBlobs(); - bool hasBlobs; + MYSQL_RES *result = nullptr; + MYSQL_ROW row; + struct QMyField { - QMyField() - : outField(0), nullIndicator(false), bufLength(0ul), - myField(0), type(QMetaType::UnknownType) - {} - char *outField; - my_bool nullIndicator; - ulong bufLength; - MYSQL_FIELD *myField; - QMetaType::Type type; + char *outField = nullptr; + MYSQL_FIELD *myField = nullptr; + QMetaType::Type type = QMetaType::UnknownType; + my_bool nullIndicator = false; + ulong bufLength = 0ul; }; QVector<QMyField> fields; - MYSQL_STMT* stmt; - MYSQL_RES* meta; + MYSQL_STMT *stmt = nullptr; + MYSQL_RES *meta = nullptr; - MYSQL_BIND *inBinds; - MYSQL_BIND *outBinds; + MYSQL_BIND *inBinds = nullptr; + MYSQL_BIND *outBinds = nullptr; - bool preparedQuery; + int rowsAffected = 0; + bool hasBlobs = false; + bool preparedQuery = false; }; #if QT_CONFIG(textcodec) diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp index 72b2133327..63e8f9f9fe 100644 --- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp +++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp @@ -118,23 +118,19 @@ class QODBCDriverPrivate : public QSqlDriverPrivate Q_DECLARE_PUBLIC(QODBCDriver) public: - enum DefaultCase{Lower, Mixed, Upper, Sensitive}; - QODBCDriverPrivate() - : QSqlDriverPrivate(), hEnv(0), hDbc(0), unicode(false), useSchema(false), disconnectCount(0), datetime_precision(19), - isFreeTDSDriver(false), hasSQLFetchScroll(true), hasMultiResultSets(false), isQuoteInitialized(false), quote(QLatin1Char('"')) - { - } + enum DefaultCase {Lower, Mixed, Upper, Sensitive}; + using QSqlDriverPrivate::QSqlDriverPrivate; - SQLHANDLE hEnv; - SQLHANDLE hDbc; + SQLHANDLE hEnv = nullptr; + SQLHANDLE hDbc = nullptr; - bool unicode; - bool useSchema; - int disconnectCount; - int datetime_precision; - bool isFreeTDSDriver; - bool hasSQLFetchScroll; - bool hasMultiResultSets; + int disconnectCount = 0; + int datetimePrecision = 19; + bool unicode = false; + bool useSchema = false; + bool isFreeTDSDriver = false; + bool hasSQLFetchScroll = true; + bool hasMultiResultSets = false; bool checkDriver() const; void checkUnicode(); @@ -150,8 +146,8 @@ public: QString adjustCase(const QString&) const; QChar quoteChar(); private: - bool isQuoteInitialized; - QChar quote; + bool isQuoteInitialized = false; + QChar quote = QLatin1Char('"'); }; class QODBCResultPrivate; @@ -194,10 +190,7 @@ class QODBCResultPrivate: public QSqlResultPrivate public: Q_DECLARE_SQLDRIVER_PRIVATE(QODBCDriver) QODBCResultPrivate(QODBCResult *q, const QODBCDriver *db) - : QSqlResultPrivate(q, db), - hStmt(0), - useSchema(false), - hasSQLFetchScroll(true) + : QSqlResultPrivate(q, db) { unicode = drv_d_func()->unicode; useSchema = drv_d_func()->useSchema; @@ -210,16 +203,15 @@ public: SQLHANDLE dpEnv() const { return drv_d_func() ? drv_d_func()->hEnv : 0;} SQLHANDLE dpDbc() const { return drv_d_func() ? drv_d_func()->hDbc : 0;} - SQLHANDLE hStmt; - - bool unicode; - bool useSchema; + SQLHANDLE hStmt = nullptr; QSqlRecord rInf; QVector<QVariant> fieldCache; - int fieldCacheIdx; - int disconnectCount; - bool hasSQLFetchScroll; + int fieldCacheIdx = 0; + int disconnectCount = 0; + bool hasSQLFetchScroll = true; + bool unicode = false; + bool useSchema = false; bool isStmtHandleValid() const; void updateStmtHandleState(); @@ -1464,20 +1456,22 @@ bool QODBCResult::exec() case QVariant::DateTime: { QByteArray &ba = tmpStorage[i]; ba.resize(sizeof(TIMESTAMP_STRUCT)); - TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)const_cast<char *>(ba.constData()); - QDateTime qdt = val.toDateTime(); - dt->year = qdt.date().year(); - dt->month = qdt.date().month(); - dt->day = qdt.date().day(); - dt->hour = qdt.time().hour(); - dt->minute = qdt.time().minute(); - dt->second = qdt.time().second(); - - int precision = d->drv_d_func()->datetime_precision - 20; // (20 includes a separating period) + TIMESTAMP_STRUCT *dt = reinterpret_cast<TIMESTAMP_STRUCT *>(const_cast<char *>(ba.constData())); + const QDateTime qdt = val.toDateTime(); + const QDate qdate = qdt.date(); + const QTime qtime = qdt.time(); + dt->year = qdate.year(); + dt->month = qdate.month(); + dt->day = qdate.day(); + dt->hour = qtime.hour(); + dt->minute = qtime.minute(); + dt->second = qtime.second(); + // (20 includes a separating period) + const int precision = d->drv_d_func()->datetimePrecision - 20; if (precision <= 0) { dt->fraction = 0; } else { - dt->fraction = qdt.time().msec() * 1000000; + dt->fraction = qtime.msec() * 1000000; // (How many leading digits do we want to keep? With SQL Server 2005, this should be 3: 123000000) int keep = (int)qPow(10.0, 9 - qMin(9, precision)); @@ -1489,7 +1483,7 @@ bool QODBCResult::exec() qParamType[bindValueType(i) & QSql::InOut], SQL_C_TIMESTAMP, SQL_TIMESTAMP, - d->drv_d_func()->datetime_precision, + d->drv_d_func()->datetimePrecision, precision, (void *) dt, 0, @@ -2245,7 +2239,7 @@ void QODBCDriverPrivate::checkDateTimePrecision() if ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO ) { if (SQLGetData(hStmt, 3, SQL_INTEGER, &columnSize, sizeof(columnSize), 0) == SQL_SUCCESS) { - datetime_precision = (int)columnSize; + datetimePrecision = (int)columnSize; } } } diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index 27841d9494..d2c57bcddc 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -149,26 +149,17 @@ class QPSQLDriverPrivate final : public QSqlDriverPrivate { Q_DECLARE_PUBLIC(QPSQLDriver) public: - QPSQLDriverPrivate() : QSqlDriverPrivate(), - connection(nullptr), - isUtf8(false), - pro(QPSQLDriver::Version6), - sn(nullptr), - pendingNotifyCheck(false), - hasBackslashEscape(false), - stmtCount(0), - currentStmtId(InvalidStatementId) - { dbmsType = QSqlDriver::PostgreSQL; } - - PGconn *connection; - bool isUtf8; - QPSQLDriver::Protocol pro; - QSocketNotifier *sn; + QPSQLDriverPrivate() : QSqlDriverPrivate(QSqlDriver::PostgreSQL) {} + QStringList seid; - mutable bool pendingNotifyCheck; - bool hasBackslashEscape; - int stmtCount; - StatementId currentStmtId; + PGconn *connection = nullptr; + QSocketNotifier *sn = nullptr; + QPSQLDriver::Protocol pro = QPSQLDriver::Version6; + StatementId currentStmtId = InvalidStatementId; + int stmtCount = 0; + mutable bool pendingNotifyCheck = false; + bool hasBackslashEscape = false; + bool isUtf8 = false; void appendTables(QStringList &tl, QSqlQuery &t, QChar type); PGresult *exec(const char *stmt); @@ -297,25 +288,18 @@ class QPSQLResultPrivate : public QSqlResultPrivate Q_DECLARE_PUBLIC(QPSQLResult) public: Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver) - QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv) - : QSqlResultPrivate(q, drv), - result(nullptr), - stmtId(InvalidStatementId), - currentSize(-1), - canFetchMoreRows(false), - preparedQueriesEnabled(false) - { } + using QSqlResultPrivate::QSqlResultPrivate; QString fieldSerial(int i) const override { return QLatin1Char('$') + QString::number(i + 1); } void deallocatePreparedStmt(); - PGresult *result; std::queue<PGresult*> nextResultSets; QString preparedStmtId; - StatementId stmtId; - int currentSize; - bool canFetchMoreRows; - bool preparedQueriesEnabled; + PGresult *result = nullptr; + StatementId stmtId = InvalidStatementId; + int currentSize = -1; + bool canFetchMoreRows = false; + bool preparedQueriesEnabled = false; bool processResults(); }; diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp index 009e8a39ef..27e7d02472 100644 --- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp +++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp @@ -144,42 +144,33 @@ class QSQLiteDriverPrivate : public QSqlDriverPrivate Q_DECLARE_PUBLIC(QSQLiteDriver) public: - inline QSQLiteDriverPrivate() : QSqlDriverPrivate(), access(0) { dbmsType = QSqlDriver::SQLite; } - sqlite3 *access; - QList <QSQLiteResult *> results; + inline QSQLiteDriverPrivate() : QSqlDriverPrivate(QSqlDriver::SQLite) {} + sqlite3 *access = nullptr; + QVector<QSQLiteResult *> results; QStringList notificationid; }; -class QSQLiteResultPrivate: public QSqlCachedResultPrivate +class QSQLiteResultPrivate : public QSqlCachedResultPrivate { Q_DECLARE_PUBLIC(QSQLiteResult) public: Q_DECLARE_SQLDRIVER_PRIVATE(QSQLiteDriver) - QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv); + using QSqlCachedResultPrivate::QSqlCachedResultPrivate; void cleanup(); bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch); // initializes the recordInfo and the cache void initColumns(bool emptyResultset); void finalize(); - sqlite3_stmt *stmt; - - bool skippedStatus; // the status of the fetchNext() that's skipped - bool skipRow; // skip the next fetchNext()? + sqlite3_stmt *stmt = nullptr; QSqlRecord rInf; QVector<QVariant> firstRow; + bool skippedStatus = false; // the status of the fetchNext() that's skipped + bool skipRow = false; // skip the next fetchNext()? }; -QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv) - : QSqlCachedResultPrivate(q, drv), - stmt(0), - skippedStatus(false), - skipRow(false) -{ -} - void QSQLiteResultPrivate::cleanup() { Q_Q(QSQLiteResult); diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 3cd04603e8..f473c3cbe3 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -3959,7 +3959,20 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter CGContextRotateCTM(ctx, M_PI_2); } + // Now, if it's a trick with a popup button, it has an arrow + // which makes no sense on tabs. + NSPopUpArrowPosition oldPosition = NSPopUpArrowAtCenter; + NSPopUpButtonCell *pbCell = nil; + if (isPopupButton) { + pbCell = static_cast<NSPopUpButtonCell *>(pb.cell); + oldPosition = pbCell.arrowPosition; + pbCell.arrowPosition = NSPopUpNoArrow; + } + [pb.cell drawBezelWithFrame:r inView:pb.superview]; + + if (pbCell) // Restore, we may reuse it for a ComboBox. + pbCell.arrowPosition = oldPosition; }; if (needsInactiveHack) { diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp index e8d74180cd..30b3786a80 100644 --- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp @@ -2217,7 +2217,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt { const int controlTop = int(6 * factor); const int controlHeight = int(height - controlTop - 3 * factor); - int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, option); QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent)); if (tb->icon.isNull()) iconSize = QSize(controlHeight, controlHeight); diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp index 9d143da169..e43746e79f 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp @@ -3453,7 +3453,7 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl { const int controlTop = 6; const int controlHeight = height - controlTop - 3; - const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, option); QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent)); if (tb->icon.isNull()) iconSize = QSize(controlHeight, controlHeight); @@ -3575,7 +3575,7 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt sz.rheight() += int(borderSize.bottom() + borderSize.top() - margin + qreal(1) / factor - 1); } - const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1); + const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin, option) + 1); sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option, widget) + textMargins, 23), 0); //arrow button } |