From 8948042bd049d08e7653f78b60951408603edb8c Mon Sep 17 00:00:00 2001 From: Julien Blanc Date: Thu, 13 Aug 2015 09:03:39 +0200 Subject: QString perf improvement : removal of useless test Removed a test in QStringAlgorithms trimmed_helper. That test is not needed because both null / empty QStrings are already handled by the previous test, other cases are handled just fine by the general case. Change-Id: I26db1142a656a7d06dfdd6b3b8f8a3ee6ca22302 Reviewed-by: Thiago Macieira --- src/corelib/tools/qstringalgorithms_p.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/tools/qstringalgorithms_p.h b/src/corelib/tools/qstringalgorithms_p.h index 65901b0286..a12874f567 100644 --- a/src/corelib/tools/qstringalgorithms_p.h +++ b/src/corelib/tools/qstringalgorithms_p.h @@ -101,8 +101,6 @@ template struct QStringAlgorithms if (begin == str.cbegin() && end == str.cend()) return str; - if (begin == end) - return StringType(); if (!isConst && str.isDetached()) return trimmed_helper_inplace(str, begin, end); return StringType(begin, end - begin); -- cgit v1.2.3 From b098f8344440e300544b5bca3358f6f2097d71ca Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 27 Aug 2015 13:46:53 +0200 Subject: Fix global modifiers state after triggering shortcuts When using for example alt-tab in Qt Creator, the list of recent documents is kept open as long as alt is pressed. The new tryHandleShortcutOverrideEvent(QWindow *w, QKeyEvent *ev) function failed to record the modifier state (contrary to the other overloads). Change-Id: Ia0fc5d1ff486aa5aac7e25b41acb972dcb6dbf7d Task-number: QTBUG-47122 Reviewed-by: Eike Ziller Reviewed-by: Gabriel de Dietrich --- src/gui/kernel/qwindowsysteminterface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 9a9eab2fe7..850b69d729 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -229,6 +229,7 @@ bool QWindowSystemInterface::tryHandleShortcutOverrideEvent(QWindow *w, QKeyEven { #ifndef QT_NO_SHORTCUT Q_ASSERT(ev->type() == QKeyEvent::ShortcutOverride); + QGuiApplicationPrivate::modifier_buttons = ev->modifiers(); QObject *focus = w->focusObject(); if (!focus) -- cgit v1.2.3 From 4dca8314c36f38ae9d6f0078f62996a8f1f477a5 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 27 Aug 2015 14:32:33 +0200 Subject: windows: Avoid __eglMustCast... in EGL WinCE headers do not have this type. Task-number: QTBUG-47964 Change-Id: I5573eaf754b825774576c55b7cb4acfbd9e8d8dd Reviewed-by: Andy Shaw Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowseglcontext.cpp | 2 +- src/plugins/platforms/windows/qwindowseglcontext.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 06c9985cac..f2547d5cdd 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -152,7 +152,7 @@ bool QWindowsLibEGL::init() eglGetCurrentSurface = RESOLVE((EGLSurface (EGLAPIENTRY *)(EGLint )), eglGetCurrentSurface); eglGetCurrentDisplay = RESOLVE((EGLDisplay (EGLAPIENTRY *)(void)), eglGetCurrentDisplay); eglSwapBuffers = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface)), eglSwapBuffers); - eglGetProcAddress = RESOLVE((__eglMustCastToProperFunctionPointerType (EGLAPIENTRY * )(const char *)), eglGetProcAddress); + eglGetProcAddress = RESOLVE((QFunctionPointer (EGLAPIENTRY * )(const char *)), eglGetProcAddress); if (!eglGetError || !eglGetDisplay || !eglInitialize || !eglGetProcAddress) return false; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index d8302c97a7..555d633a78 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -71,7 +71,7 @@ struct QWindowsLibEGL EGLSurface (EGLAPIENTRY * eglGetCurrentSurface)(EGLint readdraw); EGLDisplay (EGLAPIENTRY * eglGetCurrentDisplay)(void); EGLBoolean (EGLAPIENTRY * eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface); - __eglMustCastToProperFunctionPointerType (EGLAPIENTRY * eglGetProcAddress)(const char *procname); + QFunctionPointer (EGLAPIENTRY *eglGetProcAddress)(const char *procname); EGLDisplay (EGLAPIENTRY * eglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list); -- cgit v1.2.3 From a8f4fa217daa1b6f7b13cc48c1e5ee8d2d76b008 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Sat, 22 Aug 2015 12:07:42 +0300 Subject: Add QLockFilePrivate::processNameByPid implementation for GNU/kFreeBSD GLIBC does not provide kinfo_getproc, so we need to call sysctl manually. Change-Id: I3bf22959ff74b3b6c34b5360738e52086a3ff1b4 Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qlockfile_unix.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index 815c0f025b..5ff4b1cbe1 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -56,7 +56,13 @@ # include #elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) # include +# if defined(__GLIBC__) && defined(__FreeBSD_kernel__) +# include +# include +# include +# else # include +# endif #endif QT_BEGIN_NAMESPACE @@ -234,9 +240,27 @@ QString QLockFilePrivate::processNameByPid(qint64 pid) buf[len] = 0; return QFileInfo(QFile::decodeName(buf)).fileName(); #elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) +# if defined(__GLIBC__) && defined(__FreeBSD_kernel__) + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; + size_t len = 0; + if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) + return QString(); + kinfo_proc *proc = static_cast(malloc(len)); +# else kinfo_proc *proc = kinfo_getproc(pid); +# endif if (!proc) return QString(); +# if defined(__GLIBC__) && defined(__FreeBSD_kernel__) + if (sysctl(mib, 4, proc, &len, NULL, 0) < 0) { + free(proc); + return QString(); + } + if (proc->ki_pid != pid) { + free(proc); + return QString(); + } +# endif QString name = QFile::decodeName(proc->ki_comm); free(proc); return name; -- cgit v1.2.3 From 064439eae4942e5aec1f1819d8f60fee9514baae Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 10 Aug 2015 15:07:42 +0200 Subject: Update KDE theme defaults for Plasma 5. Add fallback icon and widgets styles for Plasma 5 Change-Id: I3ca5ebe2388b43754afec141a64db8564153b545 Reviewed-by: David Faure --- src/platformsupport/themes/genericunix/qgenericunixthemes.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp index ba328bfb41..2963b0502d 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -240,8 +240,13 @@ void QKdeThemePrivate::refresh() toolButtonStyle = Qt::ToolButtonTextBesideIcon; toolBarIconSize = 0; styleNames.clear(); + if (kdeVersion >= 5) + styleNames << QStringLiteral("breeze"); styleNames << QStringLiteral("Oxygen") << QStringLiteral("fusion") << QStringLiteral("windows"); - iconFallbackThemeName = iconThemeName = QStringLiteral("oxygen"); + if (kdeVersion >= 5) + iconFallbackThemeName = iconThemeName = QStringLiteral("breeze"); + else + iconFallbackThemeName = iconThemeName = QStringLiteral("oxygen"); QHash kdeSettings; -- cgit v1.2.3 From 7010da2e6274febf71db40a535ce1d0c4858f143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 24 Aug 2015 16:37:34 +0200 Subject: iOS: Make setFrame in desktop view take superview transforms into account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An assumption we do for the QIOSDesktopManagerView is that it should always cover the whole UIWindow. To achieve that, we override setFrame to be stop any attempt from UIKit to make our view smaller, e.g. when the statusbar changes height. In case the view is not a direct child of the window, we need to take any transformations into account when computing the new frame. This happens e.g. during presentation of other view-controllers, where our view is temporarily reparented into a UITransitionView that may have a transform set. Task-number: QTBUG-47506 Change-Id: I388143f2cbb566541ffb1068443ce21e62ea2b42 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosviewcontroller.mm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index a7068b9246..62f5387979 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -185,7 +185,14 @@ - (void)setFrame:(CGRect)newFrame { - [super setFrame:CGRectMake(0, 0, CGRectGetWidth(newFrame), CGRectGetHeight(self.window.bounds))]; + Q_UNUSED(newFrame); + Q_ASSERT(!self.window || self.window.rootViewController.view == self); + + // When presenting view controllers our view may be temporarily reparented into a UITransitionView + // instead of the UIWindow, and the UITransitionView may have a transform set, so we need to do a + // mapping even if we still expect to always be the root view-controller. + CGRect transformedWindowBounds = [self.superview convertRect:self.window.bounds fromView:self.window]; + [super setFrame:transformedWindowBounds]; } - (void)setBounds:(CGRect)newBounds -- cgit v1.2.3 From 17aaaad653e08f566aabb26dfc6b6958fa79ca03 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Mon, 1 Jun 2015 15:40:41 +0200 Subject: Ensure sendPostedEvents() can be called independently MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If Qt is not running its own event loop (e.g. if Qt is a plugin running in a non-Qt host application with its own event loop, a call to sendPostedEvents() should process all events by default, and not depend on the flags passed to the last call to processEvents() We also modify sendPostedEvents() to call its base implementation instead of directly calling QCoreApplication::sendPostedEvents(). (The behavior of the base implementation is the same, so no behavior change there). This also adds a test for QWindow event handling without Qts event loop is running. This is a black box test, just to ensure that basic functionality is working. It can be extended later. Task-number: QTBUG-45956 Change-Id: I7d688c0c6dec5f133fb495f07526debdde5389af Reviewed-by: Jørgen Lind --- .../windows/qwindowsguieventdispatcher.cpp | 4 +- tests/auto/gui/kernel/kernel.pro | 2 + .../gui/kernel/noqteventloop/noqteventloop.pro | 8 + .../gui/kernel/noqteventloop/tst_noqteventloop.cpp | 271 +++++++++++++++++++++ 4 files changed, 284 insertions(+), 1 deletion(-) create mode 100644 tests/auto/gui/kernel/noqteventloop/noqteventloop.pro create mode 100644 tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp index 0dd2facd4d..0bfa0239aa 100644 --- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp +++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp @@ -67,18 +67,20 @@ QWindowsGuiEventDispatcher::QWindowsGuiEventDispatcher(QObject *parent) : bool QWindowsGuiEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { + const QEventLoop::ProcessEventsFlags oldFlags = m_flags; m_flags = flags; if (QWindowsContext::verbose > 2 && lcQpaEvents().isDebugEnabled()) qCDebug(lcQpaEvents) << '>' << __FUNCTION__ << objectName() << flags; const bool rc = QEventDispatcherWin32::processEvents(flags); if (QWindowsContext::verbose > 2 && lcQpaEvents().isDebugEnabled()) qCDebug(lcQpaEvents) << '<' << __FUNCTION__ << "returns" << rc; + m_flags = oldFlags; return rc; } void QWindowsGuiEventDispatcher::sendPostedEvents() { - QCoreApplication::sendPostedEvents(); + QEventDispatcherWin32::sendPostedEvents(); QWindowSystemInterface::sendWindowSystemEvents(m_flags); } diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro index 7d47a4167d..b03a117f83 100644 --- a/tests/auto/gui/kernel/kernel.pro +++ b/tests/auto/gui/kernel/kernel.pro @@ -24,6 +24,8 @@ SUBDIRS=\ qopenglwindow \ qrasterwindow +win32:!wince*:!winrt: SUBDIRS += noqteventloop + !qtHaveModule(widgets): SUBDIRS -= \ qmouseevent_modal \ qtouchevent diff --git a/tests/auto/gui/kernel/noqteventloop/noqteventloop.pro b/tests/auto/gui/kernel/noqteventloop/noqteventloop.pro new file mode 100644 index 0000000000..de5715e147 --- /dev/null +++ b/tests/auto/gui/kernel/noqteventloop/noqteventloop.pro @@ -0,0 +1,8 @@ +CONFIG += testcase +TARGET = tst_noqteventloop + +QT += core-private gui-private testlib + +SOURCES += tst_noqteventloop.cpp + +contains(QT_CONFIG,dynamicgl):win32:!wince*:!winrt: LIBS += -luser32 diff --git a/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp b/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp new file mode 100644 index 0000000000..d21569dcc0 --- /dev/null +++ b/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp @@ -0,0 +1,271 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include +#include + +#include + +class tst_NoQtEventLoop : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanup(); + void consumeMouseEvents(); + +}; + +void tst_NoQtEventLoop::initTestCase() +{ +} + +void tst_NoQtEventLoop::cleanup() +{ +} + +class Window : public QWindow +{ +public: + Window(QWindow *parentWindow = 0) : QWindow(parentWindow) + { + } + + void reset() + { + m_received.clear(); + } + + bool event(QEvent *event) + { + m_received[event->type()]++; + return QWindow::event(event); + } + + int received(QEvent::Type type) + { + return m_received.value(type, 0); + } + + + QHash m_received; +}; + +bool g_exit = false; + +extern "C" LRESULT QT_WIN_CALLBACK wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_SHOWWINDOW && wParam == 0) + g_exit = true; + return DefWindowProc(hwnd, message, wParam, lParam); +} + +class TestThread : public QThread +{ + Q_OBJECT +public: + TestThread(HWND parentWnd, Window *childWindow) : QThread(), m_hwnd(parentWnd), m_childWindow(childWindow) { + m_screenW = ::GetSystemMetrics(SM_CXSCREEN); + m_screenH = ::GetSystemMetrics(SM_CYSCREEN); + } + + enum { + MouseClick, + MouseMove + }; + + void mouseInput(int command, const QPoint &p = QPoint()) + { + INPUT mouseEvent; + mouseEvent.type = INPUT_MOUSE; + MOUSEINPUT &mi = mouseEvent.mi; + mi.mouseData = 0; + mi.time = 0; + mi.dwExtraInfo = 0; + mi.dx = 0; + mi.dy = 0; + switch (command) { + case MouseClick: + mi.dwFlags = MOUSEEVENTF_LEFTDOWN; + ::SendInput(1, &mouseEvent, sizeof(INPUT)); + ::Sleep(50); + mi.dwFlags = MOUSEEVENTF_LEFTUP; + ::SendInput(1, &mouseEvent, sizeof(INPUT)); + break; + case MouseMove: + mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; + mi.dx = p.x() * 65536 / m_screenW; + mi.dy = p.y() * 65536 / m_screenH; + ::SendInput(1, &mouseEvent, sizeof(INPUT)); + break; + } + } + + void mouseClick() + { + mouseInput(MouseClick); + } + + void mouseMove(const QPoint &pt) + { + mouseInput(MouseMove, pt); + } + + + void run() { + struct ScopedCleanup + { + /* This is in order to ensure that the window is hidden when returning from run(), + regardless of the return point (e.g. with QTRY_COMPARE) */ + ScopedCleanup(HWND hwnd) : m_hwnd(hwnd) { } + ~ScopedCleanup() { + ::ShowWindow(m_hwnd, SW_HIDE); + } + HWND m_hwnd; + } cleanup(m_hwnd); + + m_testPassed = false; + POINT pt; + pt.x = 0; + pt.y = 0; + if (!::ClientToScreen(m_hwnd, &pt)) + return; + m_windowPos = QPoint(pt.x, pt.y); + + + // First activate the parent window (which will also activate the child window) + m_windowPos += QPoint(5,5); + mouseMove(m_windowPos); + ::Sleep(150); + mouseClick(); + + + + // At this point the windows are activated, no further events will be send to the QWindow + // if we click on the native parent HWND + m_childWindow->reset(); + ::Sleep(150); + mouseClick(); + ::Sleep(150); + + QTRY_COMPARE(m_childWindow->received(QEvent::MouseButtonPress) + m_childWindow->received(QEvent::MouseButtonRelease), 0); + + // Now click in the QWindow. The QWindow should receive those events. + m_windowPos.ry() += 50; + mouseMove(m_windowPos); + ::Sleep(150); + mouseClick(); + QTRY_COMPARE(m_childWindow->received(QEvent::MouseButtonPress), 1); + QTRY_COMPARE(m_childWindow->received(QEvent::MouseButtonRelease), 1); + + m_testPassed = true; + + // ScopedCleanup will hide the window here + // Once the native window is hidden, it will exit the event loop. + } + + bool passed() const { return m_testPassed; } + +private: + int m_screenW; + int m_screenH; + bool m_testPassed; + HWND m_hwnd; + Window *m_childWindow; + QPoint m_windowPos; + +}; + + +void tst_NoQtEventLoop::consumeMouseEvents() +{ + int argc = 1; + char *argv[] = {const_cast("test")}; + QGuiApplication app(argc, argv); + QString clsName(QStringLiteral("tst_NoQtEventLoop_WINDOW")); + const HINSTANCE appInstance = (HINSTANCE)GetModuleHandle(0); + WNDCLASSEX wc; + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_DBLCLKS | CS_OWNDC; // CS_SAVEBITS + wc.lpfnWndProc = wndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = appInstance; + wc.hIcon = 0; + wc.hIconSm = 0; + wc.hCursor = 0; + wc.hbrBackground = ::GetSysColorBrush(COLOR_BTNFACE /*COLOR_WINDOW*/); + wc.lpszMenuName = 0; + wc.lpszClassName = (wchar_t*)clsName.utf16(); + + ATOM atom = ::RegisterClassEx(&wc); + QVERIFY2(atom, "RegisterClassEx failed"); + + DWORD dwExStyle = WS_EX_APPWINDOW; + DWORD dwStyle = WS_CAPTION | WS_HSCROLL | WS_TABSTOP | WS_VISIBLE; + + HWND mainWnd = ::CreateWindowEx(dwExStyle, (wchar_t*)clsName.utf16(), TEXT("tst_NoQtEventLoop"), dwStyle, 100, 100, 300, 300, 0, NULL, appInstance, NULL); + QVERIFY2(mainWnd, "CreateWindowEx failed"); + + ::ShowWindow(mainWnd, SW_SHOW); + + Window *childWindow = new Window; + childWindow->setParent(QWindow::fromWinId((WId)mainWnd)); + childWindow->setGeometry(0, 50, 200, 200); + childWindow->show(); + + TestThread *testThread = new TestThread(mainWnd, childWindow); + connect(testThread, SIGNAL(finished()), testThread, SLOT(deleteLater())); + testThread->start(); + + // Our own message loop... + MSG msg; + while (::GetMessage(&msg, NULL, 0, 0) > 0) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + if (g_exit) + break; + } + + QCOMPARE(testThread->passed(), true); + +} + +#include + +QTEST_APPLESS_MAIN(tst_NoQtEventLoop) + -- cgit v1.2.3 From fee16baca1e1db441c1d95952373aa324f704990 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 11 Aug 2015 14:13:51 +0200 Subject: Another fix of cosmetic QPainter::drawPolyline() At the edge of the view, a line segment could end up as not producing any pixels even if not clipped by the floating-point clip routine. Make sure the starting point for the next line is still updated correctly for any significant segment lengths. Change-Id: I381a4efb81ce6006f3da4c67abf279aea79e4663 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qcosmeticstroker.cpp | 3 ++- tests/auto/gui/painting/qpainter/tst_qpainter.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp index 8fb5f4fd3f..e9fada10a5 100644 --- a/src/gui/painting/qcosmeticstroker.cpp +++ b/src/gui/painting/qcosmeticstroker.cpp @@ -719,10 +719,11 @@ static inline void capAdjust(int caps, int &x1, int &x2, int &y, int yinc) template static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps) { + bool didDraw = qAbs(rx2 - rx1) + qAbs(ry2 - ry1) >= 1.0; + if (stroker->clipLine(rx1, ry1, rx2, ry2)) return true; - bool didDraw = false; const int half = stroker->legacyRounding ? 31 : 0; int x1 = toF26Dot6(rx1) + half; int y1 = toF26Dot6(ry1) + half; diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 6582755aec..752ab0fd8c 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -4885,6 +4885,7 @@ void tst_QPainter::drawPolyline_data() QTest::newRow("basic") << (QVector() << QPointF(10, 10) << QPointF(20, 10) << QPointF(20, 20) << QPointF(10, 20)); QTest::newRow("clipped") << (QVector() << QPoint(-10, 100) << QPoint(-1, 100) << QPoint(-1, -2) << QPoint(100, -2) << QPoint(100, 40)); // QTBUG-31579 QTest::newRow("shortsegment") << (QVector() << QPoint(20, 100) << QPoint(20, 99) << QPoint(21, 99) << QPoint(21, 104)); // QTBUG-42398 + QTest::newRow("edge") << (QVector() << QPointF(4.5, 121.6) << QPointF(9.4, 150.9) << QPointF(14.2, 184.8) << QPointF(19.1, 130.4)); } void tst_QPainter::drawPolyline() @@ -4894,7 +4895,7 @@ void tst_QPainter::drawPolyline() for (int r = 0; r < 2; r++) { images[r] = QImage(150, 150, QImage::Format_ARGB32); - images[r].fill(Qt::transparent); + images[r].fill(Qt::white); QPainter p(images + r); QPen pen(Qt::red, 0, Qt::SolidLine, Qt::FlatCap); p.setPen(pen); -- cgit v1.2.3 From b4ed054e2f6b4c460f64c33b61b8800dc78f9e6d Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 18 Aug 2015 14:06:07 +0200 Subject: PPM image format: avoid useless processing on truncated files For ascii formatted files, the handler would not stop processing on a premature EOF, but instead continue to fill the whole image memory area byte by byte. This could lead to unexpected CPU exhaustion in the case of a small image file declaring huge image dimensions, but having no content. Instead, check for EOF for each scanline and quit processing if found. Change-Id: I8dbcd7eb34553873e49706d61b5752f22e04eb6a Reviewed-by: Lars Knoll --- src/gui/image/qppmhandler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index 0f4256b740..f460431c2b 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -182,7 +182,8 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q } else { // read ascii data uchar *p; int n; - for (y=0; ypeek(&buf, 1) == 1); y++) { p = outImage->scanLine(y); n = pbm_bpl; if (nbits == 1) { -- cgit v1.2.3 From 06be9f026f042f994d7c3548a331babca8d03545 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Aug 2015 14:36:07 +0200 Subject: iOS: send key events through QPA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far we have chosen to send key events directly to the focus object since we do already do that for IM events. But Qt expects key events (especially control keys) to be sendt through QPA. This means that key events can end up somewhere else than at the focus object, which is expected and needed if shortcut propagation is to work. Change-Id: I160bf3309572719eda352cdb11b46c4b5a455e0d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiostextresponder.mm | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index be9c3b9e27..68364d3c77 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -324,10 +324,8 @@ - (void)sendKeyPressRelease:(Qt::Key)key modifiers:(Qt::KeyboardModifiers)modifiers { - QKeyEvent press(QEvent::KeyPress, key, modifiers); - QKeyEvent release(QEvent::KeyRelease, key, modifiers); - [self sendEventToFocusObject:press]; - [self sendEventToFocusObject:release]; + QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyPress, key, modifiers); + QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyRelease, key, modifiers); } - (void)cut:(id)sender @@ -711,10 +709,10 @@ - (void)deleteBackward { - // Since we're posting im events directly to the focus object, we should do the - // same for key events. Otherwise they might end up in a different place or out - // of sync with im events. + // UITextInput selects the text to be deleted before calling this method. To avoid + // drawing the selection, we flush after posting the key press/release. [self sendKeyPressRelease:Qt::Key_Backspace modifiers:Qt::NoModifier]; + QWindowSystemInterface::flushWindowSystemEvents(); } @end -- cgit v1.2.3 From 82538aebe4b22978a6f7735924f5451304c3e2a8 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 17 Aug 2015 12:36:14 +0200 Subject: iOS: send arrow keys to Qt to handle cursor movement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Controlling cursor position through input methods in Qt is very limited. You cannot e.g move the cursor vertically, or select text that spans several paragraphs. The reason for the latter is that Qt works with input methods on a per-paragraph basis, which effectively locks UIKit to only being able to move the cursor and select text within a single paragraph. Fixing up input methods to support more advanced navigation means changing the whole design (working on a whole document, instead of per paragraph), and is out of scope. Instead we choose to listen for arrow keys and forward them to Qt in the same fashing as we already do for backspace and enter. This will make the iOS port on-par with the other platforms, which also sends control characters like these on the side of IM events. Note that registering shortcuts and overriding default IM navigation behavior will only take effect when a hardware keyboard is connected. Only then will [UIresponder keyCommands] be called from UIKit. Change-Id: I634205e0578447c4aa6e9fdff342ee3b281901ea Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiostextresponder.mm | 65 ++++++++++++++++++++++++++ src/plugins/platforms/ios/qiostheme.mm | 2 + 2 files changed, 67 insertions(+) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 68364d3c77..d16ad40414 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -328,6 +328,8 @@ QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyRelease, key, modifiers); } +#ifndef QT_NO_SHORTCUT + - (void)cut:(id)sender { Q_UNUSED(sender); @@ -360,6 +362,69 @@ // ------------------------------------------------------------------------- +- (void)keyCommandTriggered:(UIKeyCommand *)keyCommand +{ + Qt::Key key = Qt::Key_unknown; + Qt::KeyboardModifiers modifiers = Qt::NoModifier; + + if (keyCommand.input == UIKeyInputLeftArrow) + key = Qt::Key_Left; + else if (keyCommand.input == UIKeyInputRightArrow) + key = Qt::Key_Right; + else if (keyCommand.input == UIKeyInputUpArrow) + key = Qt::Key_Up; + else if (keyCommand.input == UIKeyInputDownArrow) + key = Qt::Key_Down; + else + Q_UNREACHABLE(); + + if (keyCommand.modifierFlags & UIKeyModifierAlternate) + modifiers |= Qt::AltModifier; + if (keyCommand.modifierFlags & UIKeyModifierShift) + modifiers |= Qt::ShiftModifier; + if (keyCommand.modifierFlags & UIKeyModifierCommand) + modifiers |= Qt::ControlModifier; + + [self sendKeyPressRelease:key modifiers:modifiers]; +} + +- (void)addKeyCommandsToArray:(NSMutableArray *)array key:(NSString *)key +{ + SEL s = @selector(keyCommandTriggered:); + [array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:0 action:s]]; + [array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierShift action:s]]; + [array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierAlternate action:s]]; + [array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierAlternate|UIKeyModifierShift action:s]]; + [array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierCommand action:s]]; + [array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierCommand|UIKeyModifierShift action:s]]; +} + +- (NSArray *)keyCommands +{ + // Since keyCommands is called for every key + // press/release, we cache the result + static dispatch_once_t once; + static NSMutableArray *array; + + dispatch_once(&once, ^{ + // We let Qt move the cursor around when the arrow keys are being used. This + // is normally implemented through UITextInput, but since IM in Qt have poor + // support for moving the cursor vertically, and even less support for selecting + // text across multiple paragraphs, we do this through key events. + array = [NSMutableArray new]; + [self addKeyCommandsToArray:array key:UIKeyInputUpArrow]; + [self addKeyCommandsToArray:array key:UIKeyInputDownArrow]; + [self addKeyCommandsToArray:array key:UIKeyInputLeftArrow]; + [self addKeyCommandsToArray:array key:UIKeyInputRightArrow]; + }); + + return array; +} + +#endif // QT_NO_SHORTCUT + +// ------------------------------------------------------------------------- + - (void)notifyInputDelegate:(Qt::InputMethodQueries)updatedProperties { // As documented, we should not report textWillChange/textDidChange unless the text diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm index edeabf66dc..bc40069670 100644 --- a/src/plugins/platforms/ios/qiostheme.mm +++ b/src/plugins/platforms/ios/qiostheme.mm @@ -107,6 +107,8 @@ QVariant QIOSTheme::themeHint(ThemeHint hint) const switch (hint) { case QPlatformTheme::StyleNames: return QStringList(QStringLiteral("fusion")); + case KeyboardScheme: + return QVariant(int(MacKeyboardScheme)); default: return QPlatformTheme::themeHint(hint); } -- cgit v1.2.3 From dbb24ce477702768534d64b260e269d2abc13e41 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Aug 2015 15:21:30 +0200 Subject: iOS: listen for standard text edit shortcuts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Catch the missing shortcuts sent by UIKit, and forward them to Qt as key events so that the app can respond to them. Change-Id: If63c4b05466e64843982fce32fbd594d2a0ef312 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiostextresponder.mm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index d16ad40414..fdcc703267 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -360,6 +360,24 @@ [self sendKeyPressRelease:Qt::Key_Delete modifiers:Qt::ControlModifier]; } +- (void)toggleBoldface:(id)sender +{ + Q_UNUSED(sender); + [self sendKeyPressRelease:Qt::Key_B modifiers:Qt::ControlModifier]; +} + +- (void)toggleItalics:(id)sender +{ + Q_UNUSED(sender); + [self sendKeyPressRelease:Qt::Key_I modifiers:Qt::ControlModifier]; +} + +- (void)toggleUnderline:(id)sender +{ + Q_UNUSED(sender); + [self sendKeyPressRelease:Qt::Key_U modifiers:Qt::ControlModifier]; +} + // ------------------------------------------------------------------------- - (void)keyCommandTriggered:(UIKeyCommand *)keyCommand -- cgit v1.2.3 From af5b62844ca62bf30b47a8ecc9ed1f8b24dbff3c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 21 Aug 2015 15:39:35 +0200 Subject: iOS: add undo/redo support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable the undo/redo buttons on the keyboard, as well as the Cmd-Z/Cmd-Shift-Z shortcuts. For UIKit to support this, we need to add undo actions to first responders undo manager. Since we don't know if Qt has anything to undo/redo, we just enable the shortcuts all the time. To do that, we trick NSUndoManager to always have both an undo operation and a redo operation in the stack. Change-Id: I3294a962cc24f56585e7e515856142f3dda56d0a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiostextresponder.mm | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index fdcc703267..624411ebbc 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -209,6 +209,9 @@ if (UIView *accessoryView = static_cast(platformData.value(kImePlatformDataInputAccessoryView).value())) self.inputAccessoryView = [[[WrapperView alloc] initWithView:accessoryView] autorelease]; + self.undoManager.groupsByEvent = NO; + [self rebuildUndoStack]; + return self; } @@ -380,6 +383,56 @@ // ------------------------------------------------------------------------- +- (void)undo +{ + [self sendKeyPressRelease:Qt::Key_Z modifiers:Qt::ControlModifier]; + [self rebuildUndoStack]; +} + +- (void)redo +{ + [self sendKeyPressRelease:Qt::Key_Z modifiers:Qt::ControlModifier|Qt::ShiftModifier]; + [self rebuildUndoStack]; +} + +- (void)registerRedo +{ + NSUndoManager *undoMgr = self.undoManager; + [undoMgr beginUndoGrouping]; + [undoMgr registerUndoWithTarget:self selector:@selector(redo) object:nil]; + [undoMgr endUndoGrouping]; +} + +- (void)rebuildUndoStack +{ + dispatch_async(dispatch_get_main_queue (), ^{ + // Register dummy undo/redo operations to enable Cmd-Z and Cmd-Shift-Z + // Ensure we do this outside any undo/redo callback since NSUndoManager + // will treat registerUndoWithTarget as registering a redo when called + // from within a undo callback. + NSUndoManager *undoMgr = self.undoManager; + [undoMgr removeAllActions]; + [undoMgr beginUndoGrouping]; + [undoMgr registerUndoWithTarget:self selector:@selector(undo) object:nil]; + [undoMgr endUndoGrouping]; + + // Schedule an operation that we immediately pop off to be able to schedule a redo + [undoMgr beginUndoGrouping]; + [undoMgr registerUndoWithTarget:self selector:@selector(registerRedo) object:nil]; + [undoMgr endUndoGrouping]; + [undoMgr undo]; + + // Note that, perhaps because of a bug in UIKit, the buttons on the shortcuts bar ends up + // disabled if a undo/redo callback doesn't lead to a [UITextInputDelegate textDidChange]. + // And we only call that method if Qt made changes to the text. The effect is that the buttons + // become disabled when there is nothing more to undo (Qt didn't change anything upon receiving + // an undo request). This seems to be OK behavior, so we let it stay like that unless it shows + // to cause problems. + }); +} + +// ------------------------------------------------------------------------- + - (void)keyCommandTriggered:(UIKeyCommand *)keyCommand { Qt::Key key = Qt::Key_unknown; -- cgit v1.2.3 From 163158bf4f79bb6719ac3c39547ea31acc1cb506 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 28 Aug 2015 11:41:57 +0200 Subject: iOS: store shortcut sequence in menu item MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I4c99516fb98ce0da84b8690cc4c1fd71c0db9dca Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosmenu.h | 3 ++- src/plugins/platforms/ios/qiosmenu.mm | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosmenu.h b/src/plugins/platforms/ios/qiosmenu.h index 4fa0416df7..5bebcc3cc6 100644 --- a/src/plugins/platforms/ios/qiosmenu.h +++ b/src/plugins/platforms/ios/qiosmenu.h @@ -62,7 +62,7 @@ public: void setRole(MenuRole role) Q_DECL_OVERRIDE; void setCheckable(bool) Q_DECL_OVERRIDE {} void setChecked(bool) Q_DECL_OVERRIDE {} - void setShortcut(const QKeySequence&) Q_DECL_OVERRIDE {} + void setShortcut(const QKeySequence&) Q_DECL_OVERRIDE; void setEnabled(bool enabled) Q_DECL_OVERRIDE; void setIconSize(int) Q_DECL_OVERRIDE {} @@ -73,6 +73,7 @@ public: bool m_enabled; bool m_separator; QIOSMenu *m_menu; + QKeySequence m_shortcut; private: QString removeMnemonics(const QString &original); diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index 08fc8a5e9c..9936296ae8 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -277,6 +277,11 @@ void QIOSMenuItem::setRole(QPlatformMenuItem::MenuRole role) m_role = role; } +void QIOSMenuItem::setShortcut(const QKeySequence &sequence) +{ + m_shortcut = sequence; +} + void QIOSMenuItem::setEnabled(bool enabled) { m_enabled = enabled; -- cgit v1.2.3 From b494d859a7fc18ac3e6d9a57194c1ac7dc1855ab Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 28 Aug 2015 10:57:44 +0200 Subject: iOS: filter first responder actions from edit menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UIResponderStandardEditActions found in first responder will be prepended to the edit menu automatically (or e.g made available as buttons on the virtual keyboard). So we filter them out to avoid duplicates, and let first responder handle the actions instead. In case of QIOSTextResponder, edit actions will be converted to key events that ends up triggering the shortcuts of the filtered menu items. Change-Id: I046c6cc5b358d8a6f7623e10579e2dcd92f75139 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosmenu.h | 1 + src/plugins/platforms/ios/qiosmenu.mm | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosmenu.h b/src/plugins/platforms/ios/qiosmenu.h index 5bebcc3cc6..ec23b55507 100644 --- a/src/plugins/platforms/ios/qiosmenu.h +++ b/src/plugins/platforms/ios/qiosmenu.h @@ -135,6 +135,7 @@ private: void toggleShowUsingUIMenuController(bool show); void toggleShowUsingUIPickerView(bool show); QIOSMenuItemList visibleMenuItems() const; + QIOSMenuItemList filterFirstResponderActions(const QIOSMenuItemList &menuItems); void repositionMenu(); }; diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index 9936296ae8..de77097bf8 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -474,7 +474,7 @@ void QIOSMenu::toggleShowUsingUIMenuController(bool show) { if (show) { Q_ASSERT(!m_menuController); - m_menuController = [[QUIMenuController alloc] initWithVisibleMenuItems:visibleMenuItems()]; + m_menuController = [[QUIMenuController alloc] initWithVisibleMenuItems:filterFirstResponderActions(visibleMenuItems())]; repositionMenu(); connect(qGuiApp->inputMethod(), &QInputMethod::keyboardRectangleChanged, this, &QIOSMenu::repositionMenu); } else { @@ -547,6 +547,36 @@ QIOSMenuItemList QIOSMenu::visibleMenuItems() const return visibleMenuItems; } +QIOSMenuItemList QIOSMenu::filterFirstResponderActions(const QIOSMenuItemList &menuItems) +{ + // UIResponderStandardEditActions found in first responder will be prepended to the edit + // menu automatically (or e.g made available as buttons on the virtual keyboard). So we + // filter them out to avoid duplicates, and let first responder handle the actions instead. + // In case of QIOSTextResponder, edit actions will be converted to key events that ends up + // triggering the shortcuts of the filtered menu items. + QIOSMenuItemList filteredMenuItems; + UIResponder *responder = [UIResponder currentFirstResponder]; + + for (int i = 0; i < menuItems.count(); ++i) { + QIOSMenuItem *menuItem = menuItems.at(i); + QKeySequence shortcut = menuItem->m_shortcut; + if ((shortcut == QKeySequence::Cut && [responder canPerformAction:@selector(cut:) withSender:nil]) + || (shortcut == QKeySequence::Copy && [responder canPerformAction:@selector(copy:) withSender:nil]) + || (shortcut == QKeySequence::Paste && [responder canPerformAction:@selector(paste:) withSender:nil]) + || (shortcut == QKeySequence::Delete && [responder canPerformAction:@selector(delete:) withSender:nil]) + || (shortcut == QKeySequence::SelectAll && [responder canPerformAction:@selector(selectAll:) withSender:nil]) + || (shortcut == QKeySequence::Undo && [responder canPerformAction:@selector(undo:) withSender:nil]) + || (shortcut == QKeySequence::Redo && [responder canPerformAction:@selector(redo:) withSender:nil]) + || (shortcut == QKeySequence::Bold && [responder canPerformAction:@selector(toggleBoldface:) withSender:nil]) + || (shortcut == QKeySequence::Italic && [responder canPerformAction:@selector(toggleItalics:) withSender:nil]) + || (shortcut == QKeySequence::Underline && [responder canPerformAction:@selector(toggleUnderline:) withSender:nil])) { + continue; + } + filteredMenuItems.append(menuItem); + } + return filteredMenuItems; +} + void QIOSMenu::repositionMenu() { switch (m_effectiveMenuType) { -- cgit v1.2.3 From 97b525e3bee99d8c5bb6ae3819c82d5144c08f1d Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 27 Aug 2015 10:31:06 +0200 Subject: Doc: Improve documentation for QAuthenticator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make it explicit what 'isNull()' is really about. and mention which data type is in the QVariant stored in the options. Fix the links to the Options section in the summary: So far they where pointing to the options() method. Fix capitalization and trailing dots. Change-Id: I030c0a273e784b28d642ae40b28e36b0d406c920 Reviewed-by: Topi Reiniö --- src/network/kernel/qauthenticator.cpp | 39 ++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index abb47e9e29..d626d0bcfc 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -85,6 +85,7 @@ static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& \li Digest-MD5 \endlist + \target qauthenticator-options \section1 Options In addition to the username and password required for authentication, a @@ -104,8 +105,8 @@ static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& \section2 Basic \table - \header \li Option \li Direction \li Description - \row \li \tt{realm} \li Incoming \li Contains the realm of the authentication, the same as realm() + \header \li Option \li Direction \li Type \li Description + \row \li \tt{realm} \li Incoming \li QString \li Contains the realm of the authentication, the same as realm() \endtable The Basic authentication mechanism supports no outgoing options. @@ -119,8 +120,8 @@ static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& \section2 Digest-MD5 \table - \header \li Option \li Direction \li Description - \row \li \tt{realm} \li Incoming \li Contains the realm of the authentication, the same as realm() + \header \li Option \li Direction \li Type \li Description + \row \li \tt{realm} \li Incoming \li QString \li Contains the realm of the authentication, the same as realm() \endtable The Digest-MD5 authentication mechanism supports no outgoing options. @@ -130,7 +131,7 @@ static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& /*! - Constructs an empty authentication object + Constructs an empty authentication object. */ QAuthenticator::QAuthenticator() : d(0) @@ -138,7 +139,7 @@ QAuthenticator::QAuthenticator() } /*! - Destructs the object + Destructs the object. */ QAuthenticator::~QAuthenticator() { @@ -207,7 +208,7 @@ bool QAuthenticator::operator==(const QAuthenticator &other) const */ /*! - returns the user used for authentication. + Returns the user used for authentication. */ QString QAuthenticator::user() const { @@ -227,7 +228,7 @@ void QAuthenticator::setUser(const QString &user) } /*! - returns the password used for authentication. + Returns the password used for authentication. */ QString QAuthenticator::password() const { @@ -260,7 +261,7 @@ void QAuthenticator::detach() } /*! - returns the realm requiring authentication. + Returns the realm requiring authentication. */ QString QAuthenticator::realm() const { @@ -279,10 +280,11 @@ void QAuthenticator::setRealm(const QString &realm) /*! \since 4.7 Returns the value related to option \a opt if it was set by the server. - See \l{QAuthenticator#Options} for more information on incoming options. + See the \l{QAuthenticator#qauthenticator-options}{Options section} for + more information on incoming options. If option \a opt isn't found, an invalid QVariant will be returned. - \sa options(), QAuthenticator#Options + \sa options(), {QAuthenticator#qauthenticator-options}{QAuthenticator options} */ QVariant QAuthenticator::option(const QString &opt) const { @@ -292,10 +294,10 @@ QVariant QAuthenticator::option(const QString &opt) const /*! \since 4.7 Returns all incoming options set in this QAuthenticator object by parsing - the server reply. See \l{QAuthenticator#Options} for more information - on incoming options. + the server reply. See the \l{QAuthenticator#qauthenticator-options}{Options section} + for more information on incoming options. - \sa option(), QAuthenticator#Options + \sa option(), {QAuthenticator#qauthenticator-options}{QAuthenticator options} */ QVariantHash QAuthenticator::options() const { @@ -306,9 +308,9 @@ QVariantHash QAuthenticator::options() const \since 4.7 Sets the outgoing option \a opt to value \a value. - See \l{QAuthenticator#Options} for more information on outgoing options. + See the \l{QAuthenticator#qauthenticator-options}{Options section} for more information on outgoing options. - \sa options(), option(), QAuthenticator#Options + \sa options(), option(), {QAuthenticator#qauthenticator-options}{QAuthenticator options} */ void QAuthenticator::setOption(const QString &opt, const QVariant &value) { @@ -318,7 +320,10 @@ void QAuthenticator::setOption(const QString &opt, const QVariant &value) /*! - Returns \c true if the authenticator is null. + Returns \c true if the object has not been initialized. Returns + \c false if non-const member functions have been called, or + the content was constructed or copied from another initialized + QAuthenticator object. */ bool QAuthenticator::isNull() const { -- cgit v1.2.3 From 21e1354d42d1bb3967dedb62facc684a8ab702ce Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 3 Aug 2015 12:59:01 +0200 Subject: iOS: handle all directions when calculating positionFromPosition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The method is currently a bit buggy, since it does not take UITextLayoutDirectionUp and UITextLayoutDirectionDown into account. This patch is mostly for fixing something "just in case", since we so far have not seen UIKit calling this method for those directions unless a hardware keyboard is connected. And in that case, we anyway override IM navigation by dealing with the arrow keys explicit. Since IM in Qt does not support getting the position above or below the current position, we just return the current position, making it a no-op. Change-Id: I4bcb9e2a00ab4e3d785058d7ff7f4855142dabbc Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiostextresponder.mm | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 624411ebbc..685ff8ff47 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -652,7 +652,17 @@ - (UITextPosition *)positionFromPosition:(UITextPosition *)position inDirection:(UITextLayoutDirection)direction offset:(NSInteger)offset { int p = static_cast(position).index; - return [QUITextPosition positionWithIndex:(direction == UITextLayoutDirectionRight ? p + offset : p - offset)]; + + switch (direction) { + case UITextLayoutDirectionLeft: + return [QUITextPosition positionWithIndex:p - offset]; + case UITextLayoutDirectionRight: + return [QUITextPosition positionWithIndex:p + offset]; + default: + // Qt doesn't support getting the position above or below the current position, so + // for those cases we just return the current position, making it a no-op. + return position; + } } - (UITextPosition *)positionWithinRange:(UITextRange *)range farthestInDirection:(UITextLayoutDirection)direction -- cgit v1.2.3 From b39c9011db62f154d255edeba9242463ad58e570 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 20 Aug 2015 17:12:14 +0200 Subject: QDBusPlatformMenu and Item: remove stored pointers when deleted Prevents memory leak and later access of dangling pointers. Change-Id: I6a1da1ec191ad5fa880c5884c37fd5582215e825 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/platformsupport/dbusmenu/qdbusplatformmenu.cpp | 6 ++++++ src/platformsupport/dbusmenu/qdbusplatformmenu_p.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp index a64e107e71..1dd2b462ed 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -59,6 +59,11 @@ QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag) menuItemsByID.insert(m_dbusID, this); } +QDBusPlatformMenuItem::~QDBusPlatformMenuItem() +{ + menuItemsByID.remove(m_dbusID); +} + void QDBusPlatformMenuItem::setTag(quintptr tag) { m_tag = tag; @@ -155,6 +160,7 @@ QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag) QDBusPlatformMenu::~QDBusPlatformMenu() { menusByID.remove(m_dbusID); + m_topLevelMenus.removeOne(this); } void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h index 16bb4f195c..fdad7990e9 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h @@ -57,6 +57,7 @@ class QDBusPlatformMenuItem : public QPlatformMenuItem public: QDBusPlatformMenuItem(quintptr tag = 0LL); + ~QDBusPlatformMenuItem(); quintptr tag()const Q_DECL_OVERRIDE { return m_tag; } void setTag(quintptr tag) Q_DECL_OVERRIDE; -- cgit v1.2.3 From 6f9e845d9b02ed2becaab4af837535173dad2068 Mon Sep 17 00:00:00 2001 From: Alexander Soplyakov Date: Wed, 26 Aug 2015 13:58:10 +0300 Subject: Make tooltips transparent for mouse events. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This behavior is important because controls (widgets) under tooltips don't receive mouse events and don't update their state if it is really needed. [ChangeLog][QtWidgets][Important behavior changes] Tooltips on OS X are now transparent for mouse events. Change-Id: I06403db7b66c87fe53debb033f8a74aa1c93e26a Task-number: QTBUG-46379 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index f27335d752..1ec33df744 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -704,8 +704,12 @@ QT_WARNING_POP // Popups implicitly grap mouse events; forward to the active popup if there is one if (QCocoaWindow *popup = QCocoaIntegration::instance()->activePopupWindow()) { - if (QNSView *popupView = popup->qtView()) - targetView = popupView; + // Tooltips must be transparent for mouse events + // The bug reference is QTBUG-46379 + if (!popup->m_windowFlags.testFlag(Qt::ToolTip)) { + if (QNSView *popupView = popup->qtView()) + targetView = popupView; + } } [targetView convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; -- cgit v1.2.3 From 111ee58c065602bfcde520b54f44809d854e73f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 18 Aug 2015 11:39:01 +0200 Subject: Prevent QGestureManager crash. Use QPointer to prevent dereferencing stale pointers stored in m_gestureTargets. Add null pointer tests in addition to the Q_ASSERTs on the pointers returned by m_gestureTargets.value(). The intention is to assert in debug mode but keep going in release mode. Change-Id: Icdef8cc02040bddc88f4bcb268e9ca0ac252557d Task-number: QTBUG-46264 Reviewed-by: Pawel Kurdybacha Reviewed-by: Gabriel de Dietrich --- src/widgets/kernel/qgesturemanager.cpp | 5 ++++- src/widgets/kernel/qgesturemanager_p.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index b5d3a56d3f..8b918a72a2 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -405,6 +405,8 @@ void QGestureManager::cancelGesturesForChildren(QGesture *original) Q_ASSERT(original); QWidget *originatingWidget = m_gestureTargets.value(original); Q_ASSERT(originatingWidget); + if (!originatingWidget) + return; // iterate over all active gestures and all maybe gestures // for each find the owner @@ -565,7 +567,8 @@ void QGestureManager::getGestureTargets(const QSet &gestures, foreach (QGesture *gesture, gestures) { QWidget *receiver = m_gestureTargets.value(gesture, 0); Q_ASSERT(receiver); - gestureByTypes[gesture->gestureType()].insert(receiver, gesture); + if (receiver) + gestureByTypes[gesture->gestureType()].insert(receiver, gesture); } // for each gesture type diff --git a/src/widgets/kernel/qgesturemanager_p.h b/src/widgets/kernel/qgesturemanager_p.h index 8ba253d17e..4e349ac731 100644 --- a/src/widgets/kernel/qgesturemanager_p.h +++ b/src/widgets/kernel/qgesturemanager_p.h @@ -117,7 +117,7 @@ private: QHash m_gestureToRecognizer; QHash m_gestureOwners; - QHash m_gestureTargets; + QHash > m_gestureTargets; int m_lastCustomGestureId; -- cgit v1.2.3 From 055cbaafd6c48ddfd00f918006c0a2ffe3a72f81 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 23 Jun 2015 12:59:34 +0200 Subject: Fixed connectToHost connectToHost is not meant to be synchronous, but waitForWrite is used internally to wait for the connection to be established. Thus the same logic that is used in the callback has to be applied in there. Task-number: QTBUG-46339 Change-Id: Ia1fb5c1ae609a9942ff4d8fe2f5fab2ef572da0c Reviewed-by: Andrew Knight --- src/network/socket/qnativesocketengine_winrt.cpp | 72 +++++++++++++++--------- src/network/socket/qnativesocketengine_winrt_p.h | 3 +- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 5e58ee3895..faea132b86 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -285,23 +285,11 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) return false; } d->socketState = QAbstractSocket::ConnectingState; - hr = QWinRTFunctions::await(d->connectOp); - RETURN_FALSE_IF_FAILED("Connection could not be established"); - bool connectionErrors = false; - d->handleConnectionErrors(d->connectOp.Get(), &connectionErrors); - if (connectionErrors) - return false; - d->connectOp.Reset(); - - d->socketState = QAbstractSocket::ConnectedState; - emit connectionReady(); + hr = d->connectOp->put_Completed(Callback( + d, &QNativeSocketEnginePrivate::handleConnectToHost).Get()); + Q_ASSERT_SUCCEEDED(hr); - // Delay the reader so that the SSL socket can upgrade - if (d->sslSocket) - connect(d->sslSocket, SIGNAL(encrypted()), SLOT(establishRead())); - else - establishRead(); - return true; + return d->socketState == QAbstractSocket::ConnectedState; } bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) @@ -687,6 +675,14 @@ bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut) { Q_UNUSED(msecs); Q_UNUSED(timedOut); + Q_D(QNativeSocketEngine); + if (d->socketState == QAbstractSocket::ConnectingState) { + HRESULT hr = QWinRTFunctions::await(d->connectOp, QWinRTFunctions::ProcessMainThreadEvents); + if (SUCCEEDED(hr)) { + d->handleConnectionEstablished(d->connectOp.Get()); + return true; + } + } return false; } @@ -727,7 +723,6 @@ void QNativeSocketEngine::setWriteNotificationEnabled(bool enable) if (bytesToWrite()) return; // will be emitted as a result of bytes written writeNotification(); - d->notifyOnWrite = false; } } @@ -1116,10 +1111,19 @@ HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener return S_OK; } -void QNativeSocketEnginePrivate::handleConnectionErrors(IAsyncAction *connectAction, bool *errorsOccured) +HRESULT QNativeSocketEnginePrivate::handleConnectToHost(IAsyncAction *action, AsyncStatus) { - bool error = true; - HRESULT hr = connectAction->GetResults(); + handleConnectionEstablished(action); + return S_OK; +} + +void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *action) +{ + Q_Q(QNativeSocketEngine); + if (wasDeleted || !connectOp) // Protect against a late callback + return; + + HRESULT hr = action->GetResults(); switch (hr) { case 0x8007274c: // A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString); @@ -1137,13 +1141,29 @@ void QNativeSocketEnginePrivate::handleConnectionErrors(IAsyncAction *connectAct if (FAILED(hr)) { setError(QAbstractSocket::UnknownSocketError, UnknownSocketErrorString); socketState = QAbstractSocket::UnconnectedState; - } else { - error = false; } break; } - if (errorsOccured) - *errorsOccured = error; + + // The callback might be triggered several times if we do not cancel/reset it here + if (connectOp) { + ComPtr info; + connectOp.As(&info); + if (info) { + info->Cancel(); + info->Close(); + } + connectOp.Reset(); + } + + socketState = QAbstractSocket::ConnectedState; + emit q->connectionReady(); + + // Delay the reader so that the SSL socket can upgrade + if (sslSocket) + QObject::connect(qobject_cast(sslSocket), &QSslSocket::encrypted, q, &QNativeSocketEngine::establishRead); + else + q->establishRead(); } HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) @@ -1163,7 +1183,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async hr = buffer->get_Length(&bufferLength); Q_ASSERT_SUCCEEDED(hr); if (!bufferLength) { - if (q->isReadNotificationEnabled()) + if (notifyOnRead) emit q->readReady(); return S_OK; } @@ -1187,7 +1207,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async readBytes.seek(readPos); readMutex.unlock(); - if (q->isReadNotificationEnabled()) + if (notifyOnRead) emit q->readReady(); ComPtr stream; diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index eb032bc977..8e8448e6a8 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -216,7 +216,8 @@ private: ABI::Windows::Networking::Sockets::IDatagramSocketMessageReceivedEventArgs *args); HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener, ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args); - void handleConnectionErrors(ABI::Windows::Foundation::IAsyncAction *connectAction, bool *errorsOccured); + HRESULT handleConnectToHost(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); + void handleConnectionEstablished(ABI::Windows::Foundation::IAsyncAction *action); HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress *asyncInfo, ABI::Windows::Foundation::AsyncStatus); }; -- cgit v1.2.3 From d8130786b68b2b4188f6c0b7ad285899e1cbe778 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 31 Jul 2015 14:54:38 +0200 Subject: WinRT: Do not try to read from TCP inputstream in case of UDP Change-Id: I2cdf0f4c7642c420ccec0a3f6e05a1c5bc7da020 Reviewed-by: Samuel Nevala Reviewed-by: Andrew Knight --- src/network/socket/qnativesocketengine_winrt.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index faea132b86..a22bf61cb8 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -1159,6 +1159,9 @@ void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *actio socketState = QAbstractSocket::ConnectedState; emit q->connectionReady(); + if (socketType != QAbstractSocket::TcpSocket) + return; + // Delay the reader so that the SSL socket can upgrade if (sslSocket) QObject::connect(qobject_cast(sslSocket), &QSslSocket::encrypted, q, &QNativeSocketEngine::establishRead); -- cgit v1.2.3 From 1840cc982a3a8882728b586f8924c74a7b79767f Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 31 Jul 2015 14:55:14 +0200 Subject: WinRT: Unregister callbacks when socket engine is destroyed Change-Id: I66e8fff2556ce23a66db1148bdb68e9a448227b2 Reviewed-by: Andrew Knight --- src/network/socket/qnativesocketengine_winrt.cpp | 14 ++++++++++---- src/network/socket/qnativesocketengine_winrt_p.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index a22bf61cb8..378a539411 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -318,8 +318,7 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) return false; } - EventRegistrationToken token; - d->tcpListener->add_ConnectionReceived(Callback(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), &token); + d->tcpListener->add_ConnectionReceived(Callback(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), &d->connectionToken); hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); if (FAILED(hr)) { qErrnoWarning(hr, "Unable to bind socket."); // ### Set error message @@ -779,9 +778,8 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc qWarning("Failed to create stream socket"); return false; } - EventRegistrationToken token; socketDescriptor = qintptr(socket.Detach()); - udpSocket()->add_MessageReceived(Callback(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &token); + udpSocket()->add_MessageReceived(Callback(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken); break; } default: @@ -807,11 +805,19 @@ QNativeSocketEnginePrivate::QNativeSocketEnginePrivate() , closingDown(false) , socketDescriptor(-1) , sslSocket(Q_NULLPTR) + , connectionToken( { -1 } ) { } QNativeSocketEnginePrivate::~QNativeSocketEnginePrivate() { + if (socketDescriptor == -1 || connectionToken.value == -1) + return; + + if (socketType == QAbstractSocket::UdpSocket) + udpSocket()->remove_MessageReceived(connectionToken); + else if (socketType == QAbstractSocket::TcpSocket) + tcpListener->remove_ConnectionReceived(connectionToken); } void QNativeSocketEnginePrivate::setError(QAbstractSocket::SocketError error, ErrorString errorString) const diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 8e8448e6a8..79e1a3391e 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -210,6 +210,7 @@ private: QList currentConnections; QEventLoop eventLoop; QAbstractSocket *sslSocket; + EventRegistrationToken connectionToken; HRESULT handleBindCompleted(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); HRESULT handleNewDatagram(ABI::Windows::Networking::Sockets::IDatagramSocket *socket, -- cgit v1.2.3 From fbd0e4489c936394a55f8084af2aab4ef2456360 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 28 Aug 2015 10:34:43 +0200 Subject: Copy the state to the picture paintengine when updating the state When the state of the paint changes then the one used for the picture paintengine needs to be kept in sync. Otherwise the rendering will be incorrect. Task-number: QTBUG-43145 Change-Id: Ia55a4e940d109bedb7c2eff4d985d3b212da75a4 Reviewed-by: Lars Knoll --- src/printsupport/kernel/qpaintengine_alpha.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/printsupport/kernel/qpaintengine_alpha.cpp b/src/printsupport/kernel/qpaintengine_alpha.cpp index 010a628e4f..a81f3eae43 100644 --- a/src/printsupport/kernel/qpaintengine_alpha.cpp +++ b/src/printsupport/kernel/qpaintengine_alpha.cpp @@ -146,8 +146,16 @@ void QAlphaPaintEngine::updateState(const QPaintEngineState &state) d->m_hasalpha = d->m_alphaOpacity || d->m_alphaBrush || d->m_alphaPen; - if (d->m_picengine) + if (d->m_picengine) { + const QPainter *p = painter(); + d->m_picpainter->setPen(p->pen()); + d->m_picpainter->setBrush(p->brush()); + d->m_picpainter->setBrushOrigin(p->brushOrigin()); + d->m_picpainter->setFont(p->font()); + d->m_picpainter->setOpacity(p->opacity()); + d->m_picpainter->setTransform(p->combinedTransform()); d->m_picengine->updateState(state); + } } void QAlphaPaintEngine::drawPath(const QPainterPath &path) -- cgit v1.2.3 From 97de58db672fe0489faba856fcfd59a125609796 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Fri, 21 Aug 2015 12:43:36 +0200 Subject: Doc: Added link to Declarative State Machine Framework Added link in C++ documentation Task-number: QTBUG-46285 Change-Id: I0f330829f7df713d4f5292b2a300c5c9d3732bda Reviewed-by: Venugopal Shivashankar --- src/corelib/doc/qtcore.qdocconf | 3 +-- src/corelib/doc/src/statemachine.qdoc | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index 502689e4c2..3d64708def 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -25,8 +25,7 @@ qhp.QtCore.subprojects.classes.sortPages = true tagfile = ../../../doc/qtcore/qtcore.tags -depends += activeqt qtdbus qtgui qtwidgets qtnetwork qtdoc qtmacextras qtquick qtlinguist qtdesigner qtconcurrent qtxml qmake qtwinextras -# depends += qtqml # Qt namespace collides with QtQml::Qt, see QTBUG-38630 +depends += activeqt qtdbus qtgui qtwidgets qtnetwork qtdoc qtmacextras qtquick qtlinguist qtdesigner qtconcurrent qtxml qmake qtwinextras qtqml headerdirs += .. diff --git a/src/corelib/doc/src/statemachine.qdoc b/src/corelib/doc/src/statemachine.qdoc index e44a603959..d50851d816 100644 --- a/src/corelib/doc/src/statemachine.qdoc +++ b/src/corelib/doc/src/statemachine.qdoc @@ -71,6 +71,8 @@ which are currently active. All the states in a valid configuration of the state machine will have a common ancestor. + \sa {The Declarative State Machine Framework} + \section1 Classes in the State Machine Framework These classes are provided by qt for creating event-driven state machines. -- cgit v1.2.3 From dfb55da5d67c21179ccef107351a90be2815e1e2 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Thu, 3 Sep 2015 14:40:21 +0200 Subject: Doc: Added enums in qnamespace.qdoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-43810 Change-Id: Ib756382833fabecaae2526a413d046646f3e443e Reviewed-by: Topi Reiniö Reviewed-by: Martin Smith --- src/corelib/global/qnamespace.qdoc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index c6098007d1..2323ee2cb0 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1695,6 +1695,17 @@ \value Key_Sleep \value Key_Zoom \value Key_Cancel + \value Key_MicVolumeUp + \value Key_Find + \value Key_Open + \value Key_MicVolumeDown + \value Key_New + \value Key_Settings + \value Key_Redo + \value Key_Exit + \value Key_Info + \value Key_Undo + \value Key_Guide \sa QKeyEvent::key() */ -- cgit v1.2.3 From 9588e1bba348acf9aa0d023ebb5195aa1bf69909 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 7 Jul 2015 15:29:05 +0200 Subject: Doc: Corrected link issues in qtbase Task-number: QTBUG-43810 Change-Id: I0a019becc53b222cb6a7df1fafdccd57aca5b598 Reviewed-by: Martin Smith --- qmake/doc/src/qmake-manual.qdoc | 3 +-- src/corelib/io/qtextstream.cpp | 2 +- src/corelib/kernel/qmetaobject.cpp | 5 +++-- src/gui/doc/qtgui.qdocconf | 3 ++- src/gui/image/qimage.cpp | 2 +- src/gui/image/qimagereader.cpp | 2 +- src/gui/math3d/qmatrix4x4.cpp | 2 -- src/network/doc/qtnetwork.qdocconf | 2 +- src/network/ssl/qsslellipticcurve.cpp | 5 ++--- src/network/ssl/qsslpresharedkeyauthenticator.cpp | 2 -- src/opengl/doc/qtopengl.qdocconf | 2 +- src/sql/doc/qtsql.qdocconf | 2 +- src/tools/qdoc/doc/examples/examples.qdoc | 5 ++--- src/widgets/doc/qtwidgets.qdocconf | 2 +- src/xml/doc/qtxml.qdocconf | 2 +- 15 files changed, 18 insertions(+), 23 deletions(-) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index a2afeaf765..ccb8d95973 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -728,8 +728,7 @@ \section2 Creating and Moving Xcode Projects Developers on OS X can take advantage of the qmake support for Xcode - project files, as described in - \l{Qt is OS X Native#Development Tools}{Qt is OS X Native}, + project files, as described in \l{Additional Command-Line Options}, by running qmake to generate an Xcode project from an existing qmake project file. For example: diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 8ad1c2852c..aa14f545ec 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -2858,7 +2858,7 @@ QTextStream &endl(QTextStream &stream) /*! \relates QTextStream - Calls \l{QTextStream::flush()}{flush()} on \a stream and returns \a stream. + Calls QTextStream::flush() on \a stream and returns \a stream. \sa endl(), reset(), {QTextStream manipulators} */ diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 6858209b12..1ef5ee0547 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1548,12 +1548,13 @@ bool QMetaObject::invokeMethod(QObject *obj, /*! \fn QMetaObject::Connection &QMetaObject::Connection::operator=(Connection &&other) - Move-assigns \a other to this object. + Move-assigns \a other to this object, and returns a reference. */ /*! \fn QMetaObject::Connection::Connection(Connection &&o) - Move-constructs a Connection instance, making it point to the same object that \a o was pointing to. + Move-constructs a Connection instance, making it point to the same object + that \a o was pointing to. */ /*! diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf index e2194839d2..436e2e0b34 100644 --- a/src/gui/doc/qtgui.qdocconf +++ b/src/gui/doc/qtgui.qdocconf @@ -37,7 +37,8 @@ depends += \ qtqml \ qtquick \ qtwidgets \ - qtdoc + qtdoc \ + qmake headerdirs += .. diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 176cdfe09f..c4691b5f5e 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -313,7 +313,7 @@ bool QImageData::checkForAlphaPixels() const sharing}. QImage objects can also be streamed and compared. \note If you would like to load QImage objects in a static build of Qt, - refer to the \l{How To Create Qt Plugins}{Plugin HowTo}. + refer to the \l{How to Create Qt Plugins}{Plugin HowTo}. \warning Painting on a QImage with the format QImage::Format_Indexed8 is not supported. diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index ba79bf40e5..a35442308f 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -1170,7 +1170,7 @@ QImageIOHandler::Transformations QImageReader::transformation() const Sets if images returned by read() should have transformation metadata automatically applied. - \sa autoTransform(), transform(), read() + \sa autoTransform(), transformation(), read() */ void QImageReader::setAutoTransform(bool enabled) { diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index eb7c7f4b7a..9d363dc895 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -148,8 +148,6 @@ QMatrix4x4::QMatrix4x4(const float *values) top-most 4 rows of \a matrix. If \a matrix has less than 4 columns or rows, the remaining elements are filled with elements from the identity matrix. - - \sa QMatrix4x4(const QGenericMatrix &) */ /*! diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf index 522d71fd27..2a8e577dda 100644 --- a/src/network/doc/qtnetwork.qdocconf +++ b/src/network/doc/qtnetwork.qdocconf @@ -26,7 +26,7 @@ qhp.QtNetwork.subprojects.classes.sortPages = true tagfile = ../../../doc/qtnetwork/qtnetwork.tags -depends += qtcore qtgui qtdoc +depends += qtcore qtgui qtdoc qmake headerdirs += .. diff --git a/src/network/ssl/qsslellipticcurve.cpp b/src/network/ssl/qsslellipticcurve.cpp index a16f726429..b4396d567b 100644 --- a/src/network/ssl/qsslellipticcurve.cpp +++ b/src/network/ssl/qsslellipticcurve.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE elliptic-curve cipher algorithms. Elliptic curves can be constructed from a "short name" (SN) (fromShortName()), - and by a call to QSslSocket::supportedEllipticCurves(). + and by a call to QSslConfiguration::supportedEllipticCurves(). QSslEllipticCurve instances can be compared for equality and can be used as keys in QHash and QSet. They cannot be used as key in a QMap. @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE Constructs an invalid elliptic curve. - \sa isValid(), QSslSocket::supportedEllipticCurves() + \sa isValid(), QSslConfiguration::supportedEllipticCurves() */ /*! @@ -136,7 +136,6 @@ QT_BEGIN_NAMESPACE \relates QSslEllipticCurve Returns true if the curve \a lhs represents the same curve of \a rhs; - false otherwise. */ /*! diff --git a/src/network/ssl/qsslpresharedkeyauthenticator.cpp b/src/network/ssl/qsslpresharedkeyauthenticator.cpp index 4a3b1aa807..ab78aea1cd 100644 --- a/src/network/ssl/qsslpresharedkeyauthenticator.cpp +++ b/src/network/ssl/qsslpresharedkeyauthenticator.cpp @@ -257,7 +257,6 @@ int QSslPreSharedKeyAuthenticator::maximumPreSharedKeyLength() const identity hint, identity, pre shared key, maximum length for the identity and maximum length for the pre shared key. - \sa operator!=(const QSslPreSharedKeyAuthenticator &lhs, const QSslPreSharedKeyAuthenticator &rhs) */ bool operator==(const QSslPreSharedKeyAuthenticator &lhs, const QSslPreSharedKeyAuthenticator &rhs) { @@ -277,7 +276,6 @@ bool operator==(const QSslPreSharedKeyAuthenticator &lhs, const QSslPreSharedKey Returns true if the authenticator object \a lhs is different than \a rhs; false otherwise. - \sa operator==(const QSslPreSharedKeyAuthenticator &lhs, const QSslPreSharedKeyAuthenticator &rhs) */ QT_END_NAMESPACE diff --git a/src/opengl/doc/qtopengl.qdocconf b/src/opengl/doc/qtopengl.qdocconf index 5b6d09dfcd..6ff6cae2cb 100644 --- a/src/opengl/doc/qtopengl.qdocconf +++ b/src/opengl/doc/qtopengl.qdocconf @@ -19,7 +19,7 @@ exampledirs += ../../../examples/opengl \ imagedirs += images \ ../../../examples/opengl/doc/images -depends += qtdoc qtcore qtgui qtwidgets +depends += qtdoc qtcore qtgui qtwidgets qmake examplesinstallpath = opengl diff --git a/src/sql/doc/qtsql.qdocconf b/src/sql/doc/qtsql.qdocconf index b8632c5260..5a224adeb9 100644 --- a/src/sql/doc/qtsql.qdocconf +++ b/src/sql/doc/qtsql.qdocconf @@ -25,7 +25,7 @@ qhp.QtSql.subprojects.classes.selectors = class fake:headerfile qhp.QtSql.subprojects.classes.sortPages = true tagfile = ../../../doc/qtsql/qtsql.tags -depends += qtcore qtwidgets qtdoc +depends += qtcore qtwidgets qtdoc qmake headerdirs += .. diff --git a/src/tools/qdoc/doc/examples/examples.qdoc b/src/tools/qdoc/doc/examples/examples.qdoc index 777c869c65..28810e30da 100644 --- a/src/tools/qdoc/doc/examples/examples.qdoc +++ b/src/tools/qdoc/doc/examples/examples.qdoc @@ -90,9 +90,8 @@ \brief Basic set of UI components This is a listing of a list of UI components implemented by QML types. These - - files are available for general import and they are based off the \l{Qt - Quick Code Samples}. + files are available for general import and they are based on the + \l{Qt Quick Examples and Tutorials}{Qt Quick Code Samples}. This module is part of the \l{componentset}{UIComponents} example. */ diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf index 1f79d144bf..f307e9d3e4 100644 --- a/src/widgets/doc/qtwidgets.qdocconf +++ b/src/widgets/doc/qtwidgets.qdocconf @@ -26,7 +26,7 @@ qhp.QtWidgets.subprojects.classes.sortPages = true tagfile = ../../../doc/qtwidgets/qtwidgets.tags -depends += qtcore qtgui qtdoc qtsql qtdesigner qtquick +depends += qtcore qtgui qtdoc qtsql qtdesigner qtquick qmake qtsvg headerdirs += .. diff --git a/src/xml/doc/qtxml.qdocconf b/src/xml/doc/qtxml.qdocconf index 419859ac8b..a23915487f 100644 --- a/src/xml/doc/qtxml.qdocconf +++ b/src/xml/doc/qtxml.qdocconf @@ -26,7 +26,7 @@ qhp.QtXml.subprojects.classes.sortPages = true tagfile = ../../../doc/qtxml/qtxml.tags -depends += qtcore qtnetwork qtdoc qtwidgets +depends += qtcore qtnetwork qtdoc qtwidgets qmake headerdirs += .. -- cgit v1.2.3 From 5919edc5231f58d2d7c04ea875064a368f0df254 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Thu, 3 Sep 2015 15:52:55 +0300 Subject: forkfd: fix _POSIX_SPAWN feature check Change-Id: Ia44edbac3a1bd2da92ee8c92956abfe49d8763b8 Reviewed-by: Thiago Macieira --- src/3rdparty/forkfd/forkfd.c | 2 +- src/3rdparty/forkfd/forkfd.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index a61198a954..55dc92fe45 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -648,7 +648,7 @@ err_free: } #endif // FORKFD_NO_FORKFD -#if defined(_POSIX_SPAWN) && !defined(FORKFD_NO_SPAWNFD) +#if _POSIX_SPAWN > 0 && !defined(FORKFD_NO_SPAWNFD) int spawnfd(int flags, pid_t *ppid, const char *path, const posix_spawn_file_actions_t *file_actions, posix_spawnattr_t *attrp, char *const argv[], char *const envp[]) { diff --git a/src/3rdparty/forkfd/forkfd.h b/src/3rdparty/forkfd/forkfd.h index dcb36f9f33..38858c00fe 100644 --- a/src/3rdparty/forkfd/forkfd.h +++ b/src/3rdparty/forkfd/forkfd.h @@ -29,7 +29,7 @@ #include #include // to get the POSIX flags -#ifdef _POSIX_SPAWN +#if _POSIX_SPAWN > 0 # include #endif @@ -51,7 +51,7 @@ int forkfd(int flags, pid_t *ppid); int forkfd_wait(int ffd, forkfd_info *info, struct rusage *rusage); int forkfd_close(int ffd); -#ifdef _POSIX_SPAWN +#if _POSIX_SPAWN > 0 /* only for spawnfd: */ # define FFD_SPAWN_SEARCH_PATH O_RDWR -- cgit v1.2.3 From ee8c09f7c219ae9b55194408ba854f81b8086cb0 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 31 Jul 2015 14:16:53 +0200 Subject: qprintdialog_unix: small optimization, no need to extract a substring Change-Id: Ie5fdfd6aa3866c14b6fbfabf4533327f5c73c5a3 Reviewed-by: Friedemann Kleint Reviewed-by: Frederik Gladhorn Reviewed-by: Marc Mutz --- src/printsupport/dialogs/qprintdialog_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 502ff7d98a..880b233aef 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -805,7 +805,7 @@ void QUnixPrintWidgetPrivate::applyPrinterProperties() home += QLatin1Char('/'); if (!cur.isEmpty() && cur.at(cur.length()-1) != QLatin1Char('/')) cur += QLatin1Char('/'); - if (cur.left(home.length()) != home) + if (!cur.startsWith(home)) cur = home; if (QGuiApplication::platformName() == QLatin1String("xcb")) { if (printer->docName().isEmpty()) { -- cgit v1.2.3 From 69e1b1de935511e5513fb002e2df96ac08e433f6 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 17 Aug 2015 13:01:09 +0200 Subject: Doc: System Tray Icon example Moved from qtsvg to qtbase Task-number: QTBUG-47201 Change-Id: Iab185ea2e270893c0937d1ff87fdb544d226d603 Reviewed-by: Martin Smith --- .../systray/doc/images/systemtray-editor.png | Bin 0 -> 18147 bytes .../systray/doc/images/systemtray-example.png | Bin 0 -> 47588 bytes .../widgets/desktop/systray/doc/src/systray.qdoc | 183 +++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 examples/widgets/desktop/systray/doc/images/systemtray-editor.png create mode 100644 examples/widgets/desktop/systray/doc/images/systemtray-example.png create mode 100644 examples/widgets/desktop/systray/doc/src/systray.qdoc diff --git a/examples/widgets/desktop/systray/doc/images/systemtray-editor.png b/examples/widgets/desktop/systray/doc/images/systemtray-editor.png new file mode 100644 index 0000000000..fb15dea8cb Binary files /dev/null and b/examples/widgets/desktop/systray/doc/images/systemtray-editor.png differ diff --git a/examples/widgets/desktop/systray/doc/images/systemtray-example.png b/examples/widgets/desktop/systray/doc/images/systemtray-example.png new file mode 100644 index 0000000000..98b5c8133e Binary files /dev/null and b/examples/widgets/desktop/systray/doc/images/systemtray-example.png differ diff --git a/examples/widgets/desktop/systray/doc/src/systray.qdoc b/examples/widgets/desktop/systray/doc/src/systray.qdoc new file mode 100644 index 0000000000..074012b6a7 --- /dev/null +++ b/examples/widgets/desktop/systray/doc/src/systray.qdoc @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example desktop/systray + \title System Tray Icon Example + + + The System Tray Icon example shows how to add an icon with a menu + and popup messages to a desktop environment's system tray. + + \image systemtray-example.png Screenshot of the System Tray Icon. + + Modern operating systems usually provide a special area on the + desktop, called the system tray or notification area, where + long-running applications can display icons and short messages. + + This example consists of one single class, \c Window, providing + the main application window (i.e., an editor for the system tray + icon) and the associated icon. + + \image systemtray-editor.png + + The editor allows the user to choose the preferred icon as well as + set the balloon message's type and duration. The user can also + edit the message's title and body. Finally, the editor provide a + checkbox controlling whether the icon is actually shown in the + system tray, or not. + + \section1 Window Class Definition + + The \c Window class inherits QWidget: + + \snippet desktop/systray/window.h 0 + + We implement several private slots to respond to user + interaction. The other private functions are only convenience + functions provided to simplify the constructor. + + The tray icon is an instance of the QSystemTrayIcon class. To + check whether a system tray is present on the user's desktop, call + the static QSystemTrayIcon::isSystemTrayAvailable() + function. Associated with the icon, we provide a menu containing + the typical \gui minimize, \gui maximize, \gui restore and \gui + quit actions. We reimplement the QWidget::setVisible() function to + update the tray icon's menu whenever the editor's appearance + changes, e.g., when maximizing or minimizing the main application + window. + + Finally, we reimplement QWidget's \l {QWidget::}{closeEvent()} + function to be able to inform the user (when closing the editor + window) that the program will keep running in the system tray + until the user chooses the \gui Quit entry in the icon's context + menu. + + \section1 Window Class Implementation + + When constructing the editor widget, we first create the various + editor elements before we create the actual system tray icon: + + \snippet desktop/systray/window.cpp 0 + + We ensure that the application responds to user input by + connecting most of the editor's input widgets (including the + system tray icon) to the application's private slots. But note the + visibility checkbox; its \l {QCheckBox::}{toggled()} signal is + connected to the \e {icon}'s \l {QSystemTrayIcon::}{setVisible()} + function instead. + + \snippet desktop/systray/window.cpp 3 + + The \c setIcon() slot is triggered whenever the current index in + the icon combobox changes, i.e., whenever the user chooses another + icon in the editor. Note that it is also called when the user + activates the tray icon with the left mouse button, triggering the + icon's \l {QSystemTrayIcon::}{activated()} signal. We will come + back to this signal shortly. + + The QSystemTrayIcon::setIcon() function sets the \l + {QSystemTrayIcon::}{icon} property that holds the actual system + tray icon. On Windows, the system tray icon size is 16x16; on X11, + the preferred size is 22x22. The icon will be scaled to the + appropriate size as necessary. + + Note that on X11, due to a limitation in the system tray + specification, mouse clicks on transparent areas in the icon are + propagated to the system tray. If this behavior is unacceptable, + we suggest using an icon with no transparency. + + \snippet desktop/systray/window.cpp 4 + + Whenever the user activates the system tray icon, it emits its \l + {QSystemTrayIcon::}{activated()} signal passing the triggering + reason as parameter. QSystemTrayIcon provides the \l + {QSystemTrayIcon::}{ActivationReason} enum to describe how the + icon was activated. + + In the constructor, we connected our icon's \l + {QSystemTrayIcon::}{activated()} signal to our custom \c + iconActivated() slot: If the user has clicked the icon using the + left mouse button, this function changes the icon image by + incrementing the icon combobox's current index, triggering the \c + setIcon() slot as mentioned above. If the user activates the icon + using the middle mouse button, it calls the custom \c + showMessage() slot: + + \snippet desktop/systray/window.cpp 5 + + When the \e showMessage() slot is triggered, we first retrieve the + message icon depending on the currently chosen message type. The + QSystemTrayIcon::MessageIcon enum describes the icon that is shown + when a balloon message is displayed. Then we call + QSystemTrayIcon's \l {QSystemTrayIcon::}{showMessage()} function + to show the message with the title, body, and icon for the time + specified in milliseconds. + + OS X users note: The Growl notification system must be + installed for QSystemTrayIcon::showMessage() to display messages. + + QSystemTrayIcon also has the corresponding, \l {QSystemTrayIcon::} + {messageClicked()} signal, which is emitted when the user clicks a + message displayed by \l {QSystemTrayIcon::}{showMessage()}. + + \snippet desktop/systray/window.cpp 6 + + In the constructor, we connected the \l + {QSystemTrayIcon::}{messageClicked()} signal to our custom \c + messageClicked() slot that simply displays a message using the + QMessageBox class. + + QMessageBox provides a modal dialog with a short message, an icon, + and buttons laid out depending on the current style. It supports + four severity levels: "Question", "Information", "Warning" and + "Critical". The easiest way to pop up a message box in Qt is to + call one of the associated static functions, e.g., + QMessageBox::information(). + + As we mentioned earlier, we reimplement a couple of QWidget's + virtual functions: + + \snippet desktop/systray/window.cpp 1 + + Our reimplementation of the QWidget::setVisible() function updates + the tray icon's menu whenever the editor's appearance changes, + e.g., when maximizing or minimizing the main application window, + before calling the base class implementation. + + \snippet desktop/systray/window.cpp 2 + + We have reimplemented the QWidget::closeEvent() event handler to + receive widget close events, showing the above message to the + users when they are closing the editor window. + + In addition to the functions and slots discussed above, we have + also implemented several convenience functions to simplify the + constructor: \c createIconGroupBox(), \c createMessageGroupBox(), + \c createActions() and \c createTrayIcon(). See the \l + {desktop/systray/window.cpp}{window.cpp} file for details. +*/ -- cgit v1.2.3 From d4799d02385ffd9bb4c0ba2c757059a70305daf0 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 28 Aug 2015 15:46:07 +0200 Subject: iOS: compose key events from QKeySequences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of hard-coding the key and modifier that should trigger a shortcut, we read it out from the QKeySequence that corresponds to a StandardKey instead. Change-Id: I6325534d3ff91c788d7e660d9009954e437b8534 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiostextresponder.mm | 28 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 685ff8ff47..4e109f6921 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -333,65 +333,73 @@ #ifndef QT_NO_SHORTCUT +- (void)sendShortcut:(QKeySequence::StandardKey)standardKey +{ + const int keys = QKeySequence(standardKey)[0]; + Qt::Key key = Qt::Key(keys & 0x0000FFFF); + Qt::KeyboardModifiers modifiers = Qt::KeyboardModifiers(keys & 0xFFFF0000); + [self sendKeyPressRelease:key modifiers:modifiers]; +} + - (void)cut:(id)sender { Q_UNUSED(sender); - [self sendKeyPressRelease:Qt::Key_X modifiers:Qt::ControlModifier]; + [self sendShortcut:QKeySequence::Cut]; } - (void)copy:(id)sender { Q_UNUSED(sender); - [self sendKeyPressRelease:Qt::Key_C modifiers:Qt::ControlModifier]; + [self sendShortcut:QKeySequence::Copy]; } - (void)paste:(id)sender { Q_UNUSED(sender); - [self sendKeyPressRelease:Qt::Key_V modifiers:Qt::ControlModifier]; + [self sendShortcut:QKeySequence::Paste]; } - (void)selectAll:(id)sender { Q_UNUSED(sender); - [self sendKeyPressRelease:Qt::Key_A modifiers:Qt::ControlModifier]; + [self sendShortcut:QKeySequence::SelectAll]; } - (void)delete:(id)sender { Q_UNUSED(sender); - [self sendKeyPressRelease:Qt::Key_Delete modifiers:Qt::ControlModifier]; + [self sendShortcut:QKeySequence::Delete]; } - (void)toggleBoldface:(id)sender { Q_UNUSED(sender); - [self sendKeyPressRelease:Qt::Key_B modifiers:Qt::ControlModifier]; + [self sendShortcut:QKeySequence::Bold]; } - (void)toggleItalics:(id)sender { Q_UNUSED(sender); - [self sendKeyPressRelease:Qt::Key_I modifiers:Qt::ControlModifier]; + [self sendShortcut:QKeySequence::Italic]; } - (void)toggleUnderline:(id)sender { Q_UNUSED(sender); - [self sendKeyPressRelease:Qt::Key_U modifiers:Qt::ControlModifier]; + [self sendShortcut:QKeySequence::Underline]; } // ------------------------------------------------------------------------- - (void)undo { - [self sendKeyPressRelease:Qt::Key_Z modifiers:Qt::ControlModifier]; + [self sendShortcut:QKeySequence::Undo]; [self rebuildUndoStack]; } - (void)redo { - [self sendKeyPressRelease:Qt::Key_Z modifiers:Qt::ControlModifier|Qt::ShiftModifier]; + [self sendShortcut:QKeySequence::Redo]; [self rebuildUndoStack]; } -- cgit v1.2.3 From feff56827b86ff00930a903944afe913a926a9a1 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 1 Sep 2015 13:06:07 +0200 Subject: iOS: filter responder actions from menu sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow up from b494d85. We need to filter the responder actions after a sync as well, otherwise they will be added back if a menu item e.g changes text. Change-Id: I2ecbcc292400ada97a8e29d4b97f087349d8a061 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosmenu.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index de77097bf8..09395805bf 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -369,7 +369,7 @@ void QIOSMenu::syncMenuItem(QPlatformMenuItem *) switch (m_effectiveMenuType) { case EditMenu: - [m_menuController setVisibleMenuItems:visibleMenuItems()]; + [m_menuController setVisibleMenuItems:filterFirstResponderActions(visibleMenuItems())]; break; default: [m_pickerView setVisibleMenuItems:visibleMenuItems() selectItem:m_targetItem]; -- cgit v1.2.3 From 1a0384cb15f7a2194341ec4b102948fa9337f5cf Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Sun, 16 Aug 2015 15:09:51 +0100 Subject: Support device pixel ratio in QWidget graphic effects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie20bd30328ae353ace82fbeee5808546f0568703 Reviewed-by: Christoph Cullmann Reviewed-by: Morten Johan Sørvig --- src/widgets/kernel/qwidget.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index ba0fcf75d0..49da4d1faf 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5828,7 +5828,10 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint * pixmapOffset -= effectRect.topLeft(); - QPixmap pixmap(effectRect.size()); + const qreal dpr = context->painter->device()->devicePixelRatio(); + QPixmap pixmap(effectRect.size() * dpr); + pixmap.setDevicePixelRatio(dpr); + pixmap.fill(Qt::transparent); m_widget->render(&pixmap, pixmapOffset, QRegion(), QWidget::DrawChildren); return pixmap; -- cgit v1.2.3 From 880a8aa7e99bb91e7a815cadde72bb5230c815ea Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 26 Aug 2015 13:27:49 +0200 Subject: QMimeType: add KDAB copyright to the code I contributed a lot to. Change-Id: I794259f28c7adbaad3cfb40f92a0ad2dc512e5b4 Reviewed-by: Thiago Macieira --- src/corelib/mimetypes/qmimedatabase.cpp | 1 + src/corelib/mimetypes/qmimedatabase.h | 1 + src/corelib/mimetypes/qmimedatabase_p.h | 1 + src/corelib/mimetypes/qmimeprovider.cpp | 1 + src/corelib/mimetypes/qmimeprovider_p.h | 1 + src/corelib/mimetypes/qmimetype.cpp | 1 + src/corelib/mimetypes/qmimetype.h | 1 + 7 files changed, 7 insertions(+) diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index bec7a79e8f..1ef890c46a 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. diff --git a/src/corelib/mimetypes/qmimedatabase.h b/src/corelib/mimetypes/qmimedatabase.h index 912d9b8443..fd19636e27 100644 --- a/src/corelib/mimetypes/qmimedatabase.h +++ b/src/corelib/mimetypes/qmimedatabase.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h index e3cfe3443f..aa86f607c6 100644 --- a/src/corelib/mimetypes/qmimedatabase_p.h +++ b/src/corelib/mimetypes/qmimedatabase_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index 887db51e5c..d26bfd0848 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h index eaf95942f7..c0517d69a4 100644 --- a/src/corelib/mimetypes/qmimeprovider_p.h +++ b/src/corelib/mimetypes/qmimeprovider_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp index a5f9cb70d5..5398f9358e 100644 --- a/src/corelib/mimetypes/qmimetype.cpp +++ b/src/corelib/mimetypes/qmimetype.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. diff --git a/src/corelib/mimetypes/qmimetype.h b/src/corelib/mimetypes/qmimetype.h index 4ba3c53470..13184905b8 100644 --- a/src/corelib/mimetypes/qmimetype.h +++ b/src/corelib/mimetypes/qmimetype.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. -- cgit v1.2.3 From 5e41f4137dd42a9a639be8743ae95c8e159bd4e0 Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 25 Aug 2015 14:30:07 +0200 Subject: QMimeDatabase: warn instead of asserting on bad magic. An invalid mime magic definition could lead to an assert. Replaced with a qWarning. Move all checking to the QMimeMagicRule constructor, and do keep invalid rules since they are need to parse child rules. Unit test added, with QTest::ignoreMessage when using the XML backend (there's no warning from update-mime-database when using the cache). Also make it easier to add more shared mime info files for tests. Task-number: QTBUG-44319 Done-with: Eike Ziller Change-Id: Ie39a160a106b650cdcee88778fa7eff9e932a988 Reviewed-by: Thiago Macieira --- src/corelib/mimetypes/qmimemagicrule.cpp | 68 +++++++++++++--- src/corelib/mimetypes/qmimemagicrule_p.h | 3 +- src/corelib/mimetypes/qmimetypeparser.cpp | 40 +++------- src/corelib/mimetypes/qmimetypeparser_p.h | 2 + .../mimetypes/qmimedatabase/invalid-magic1.xml | 9 +++ .../mimetypes/qmimedatabase/invalid-magic2.xml | 9 +++ .../mimetypes/qmimedatabase/invalid-magic3.xml | 9 +++ .../corelib/mimetypes/qmimedatabase/testdata.qrc | 3 + .../mimetypes/qmimedatabase/tst_qmimedatabase.cpp | 92 ++++++++++++++-------- .../mimetypes/qmimedatabase/tst_qmimedatabase.h | 6 +- 10 files changed, 159 insertions(+), 82 deletions(-) create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic1.xml create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic2.xml create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic3.xml diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp index c8508ac0d2..6a3a429179 100644 --- a/src/corelib/mimetypes/qmimemagicrule.cpp +++ b/src/corelib/mimetypes/qmimemagicrule.cpp @@ -38,6 +38,7 @@ #ifndef QT_NO_MIMETYPE +#include "qmimetypeparser_p.h" #include #include #include @@ -231,26 +232,53 @@ static inline QByteArray makePattern(const QByteArray &value) return pattern; } -QMimeMagicRule::QMimeMagicRule(QMimeMagicRule::Type theType, +// Evaluate a magic match rule like +// +// + +QMimeMagicRule::QMimeMagicRule(const QString &typeStr, const QByteArray &theValue, - int theStartPos, - int theEndPos, - const QByteArray &theMask) : + const QString &offsets, + const QByteArray &theMask, + QString *errorString) : d(new QMimeMagicRulePrivate) { - Q_ASSERT(!theValue.isEmpty()); - - d->type = theType; d->value = theValue; - d->startPos = theStartPos; - d->endPos = theEndPos; d->mask = theMask; d->matchFunction = 0; + d->type = QMimeMagicRule::type(typeStr.toLatin1()); + if (d->type == Invalid) { + *errorString = QStringLiteral("Type %s is not supported").arg(typeStr); + } + + // Parse for offset as "1" or "1:10" + const int colonIndex = offsets.indexOf(QLatin1Char(':')); + const QString startPosStr = colonIndex == -1 ? offsets : offsets.mid(0, colonIndex); + const QString endPosStr = colonIndex == -1 ? offsets : offsets.mid(colonIndex + 1); + if (!QMimeTypeParserBase::parseNumber(startPosStr, &d->startPos, errorString) || + !QMimeTypeParserBase::parseNumber(endPosStr, &d->endPos, errorString)) { + d->type = Invalid; + return; + } + + if (d->value.isEmpty()) { + d->type = Invalid; + if (errorString) + *errorString = QLatin1String("Invalid empty magic rule value"); + return; + } + if (d->type >= Host16 && d->type <= Byte) { bool ok; d->number = d->value.toUInt(&ok, 0); // autodetect - Q_ASSERT(ok); + if (!ok) { + d->type = Invalid; + if (errorString) + *errorString = QString::fromLatin1("Invalid magic rule value \"%1\"").arg( + QString::fromLatin1(d->value)); + return; + } d->numberMask = !d->mask.isEmpty() ? d->mask.toUInt(&ok, 0) : 0; // autodetect } @@ -259,9 +287,23 @@ QMimeMagicRule::QMimeMagicRule(QMimeMagicRule::Type theType, d->pattern = makePattern(d->value); d->pattern.squeeze(); if (!d->mask.isEmpty()) { - Q_ASSERT(d->mask.size() >= 4 && d->mask.startsWith("0x")); - d->mask = QByteArray::fromHex(QByteArray::fromRawData(d->mask.constData() + 2, d->mask.size() - 2)); - Q_ASSERT(d->mask.size() == d->pattern.size()); + if (d->mask.size() < 4 || !d->mask.startsWith("0x")) { + d->type = Invalid; + if (errorString) + *errorString = QString::fromLatin1("Invalid magic rule mask \"%1\"").arg( + QString::fromLatin1(d->mask)); + return; + } + const QByteArray &tempMask = QByteArray::fromHex(QByteArray::fromRawData( + d->mask.constData() + 2, d->mask.size() - 2)); + if (tempMask.size() != d->pattern.size()) { + d->type = Invalid; + if (errorString) + *errorString = QString::fromLatin1("Invalid magic rule mask size \"%1\"").arg( + QString::fromLatin1(d->mask)); + return; + } + d->mask = tempMask; } else { d->mask.fill(char(-1), d->pattern.size()); } diff --git a/src/corelib/mimetypes/qmimemagicrule_p.h b/src/corelib/mimetypes/qmimemagicrule_p.h index 03ac1d1de9..6b64bfcc10 100644 --- a/src/corelib/mimetypes/qmimemagicrule_p.h +++ b/src/corelib/mimetypes/qmimemagicrule_p.h @@ -61,7 +61,8 @@ class QMimeMagicRule public: enum Type { Invalid = 0, String, Host16, Host32, Big16, Big32, Little16, Little32, Byte }; - QMimeMagicRule(Type type, const QByteArray &value, int startPos, int endPos, const QByteArray &mask = QByteArray()); + QMimeMagicRule(const QString &typeStr, const QByteArray &value, const QString &offsets, + const QByteArray &mask, QString *errorString); QMimeMagicRule(const QMimeMagicRule &other); ~QMimeMagicRule(); diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp index 9610162c4f..8a8b97655a 100644 --- a/src/corelib/mimetypes/qmimetypeparser.cpp +++ b/src/corelib/mimetypes/qmimetypeparser.cpp @@ -153,8 +153,8 @@ QMimeTypeParserBase::ParseState QMimeTypeParserBase::nextState(ParseState curren return ParseError; } -// Parse int number from an (attribute) string) -static bool parseNumber(const QString &n, int *target, QString *errorMessage) +// Parse int number from an (attribute) string +bool QMimeTypeParserBase::parseNumber(const QString &n, int *target, QString *errorMessage) { bool ok; *target = n.toInt(&ok); @@ -165,37 +165,14 @@ static bool parseNumber(const QString &n, int *target, QString *errorMessage) return true; } -// Evaluate a magic match rule like -// -// #ifndef QT_NO_XMLSTREAMREADER -static bool createMagicMatchRule(const QXmlStreamAttributes &atts, - QString *errorMessage, QMimeMagicRule *&rule) +static QMimeMagicRule *createMagicMatchRule(const QXmlStreamAttributes &atts, QString *errorMessage) { const QString type = atts.value(QLatin1String(matchTypeAttributeC)).toString(); - QMimeMagicRule::Type magicType = QMimeMagicRule::type(type.toLatin1()); - if (magicType == QMimeMagicRule::Invalid) { - qWarning("%s: match type %s is not supported.", Q_FUNC_INFO, type.toUtf8().constData()); - return true; - } const QString value = atts.value(QLatin1String(matchValueAttributeC)).toString(); - if (value.isEmpty()) { - *errorMessage = QString::fromLatin1("Empty match value detected."); - return false; - } - // Parse for offset as "1" or "1:10" - int startPos, endPos; - const QString offsetS = atts.value(QLatin1String(matchOffsetAttributeC)).toString(); - const int colonIndex = offsetS.indexOf(QLatin1Char(':')); - const QString startPosS = colonIndex == -1 ? offsetS : offsetS.mid(0, colonIndex); - const QString endPosS = colonIndex == -1 ? offsetS : offsetS.mid(colonIndex + 1); - if (!parseNumber(startPosS, &startPos, errorMessage) || !parseNumber(endPosS, &endPos, errorMessage)) - return false; + const QString offsets = atts.value(QLatin1String(matchOffsetAttributeC)).toString(); const QString mask = atts.value(QLatin1String(matchMaskAttributeC)).toString(); - - rule = new QMimeMagicRule(magicType, value.toUtf8(), startPos, endPos, mask.toLatin1()); - - return true; + return new QMimeMagicRule(type, value.toUtf8(), offsets, mask.toLatin1(), errorMessage); } #endif @@ -283,9 +260,10 @@ bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString } break; case ParseMagicMatchRule: { - QMimeMagicRule *rule = 0; - if (!createMagicMatchRule(atts, errorMessage, rule)) - return false; + QString magicErrorMessage; + QMimeMagicRule *rule = createMagicMatchRule(atts, &magicErrorMessage); + if (!rule->isValid()) + qWarning("QMimeDatabase: Error parsing %s\n%s", qPrintable(fileName), qPrintable(magicErrorMessage)); QList *ruleList; if (currentRules.isEmpty()) ruleList = &rules; diff --git a/src/corelib/mimetypes/qmimetypeparser_p.h b/src/corelib/mimetypes/qmimetypeparser_p.h index 2be4380cee..3a2e6b8a14 100644 --- a/src/corelib/mimetypes/qmimetypeparser_p.h +++ b/src/corelib/mimetypes/qmimetypeparser_p.h @@ -66,6 +66,8 @@ public: bool parse(QIODevice *dev, const QString &fileName, QString *errorMessage); + static bool parseNumber(const QString &n, int *target, QString *errorMessage); + protected: virtual bool process(const QMimeType &t, QString *errorMessage) = 0; virtual bool process(const QMimeGlobPattern &t, QString *errorMessage) = 0; diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic1.xml b/tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic1.xml new file mode 100644 index 0000000000..04204d8763 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic1.xml @@ -0,0 +1,9 @@ + + + + wrong value for byte type + + + + + diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic2.xml b/tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic2.xml new file mode 100644 index 0000000000..f18075482e --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic2.xml @@ -0,0 +1,9 @@ + + + + mask doesn't start with 0x + + + + + diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic3.xml b/tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic3.xml new file mode 100644 index 0000000000..0e2508cc0f --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/invalid-magic3.xml @@ -0,0 +1,9 @@ + + + + mask has wrong size + + + + + diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc b/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc index 4654a61660..29666627a1 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc +++ b/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc @@ -4,5 +4,8 @@ qml-again.xml text-x-objcsrc.xml test.qml + invalid-magic1.xml + invalid-magic2.xml + invalid-magic3.xml diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index 8bc90d917e..763bb58602 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -45,9 +45,16 @@ #include -static const char yastFileName[] ="yast2-metapackage-handler-mimetypes.xml"; -static const char qmlAgainFileName[] ="qml-again.xml"; -static const char textXObjCSrcFileName[] ="text-x-objcsrc.xml"; +static const char *const additionalMimeFiles[] = { + "yast2-metapackage-handler-mimetypes.xml", + "qml-again.xml", + "text-x-objcsrc.xml", + "invalid-magic1.xml", + "invalid-magic2.xml", + "invalid-magic3.xml", + 0 +}; + #define RESOURCE_PREFIX ":/qt-project.org/qmime/" void initializeLang() @@ -149,12 +156,12 @@ void tst_QMimeDatabase::initTestCase() qWarning("%s", qPrintable(testSuiteWarning())); errorMessage = QString::fromLatin1("Cannot find '%1'"); - m_yastMimeTypes = QLatin1String(RESOURCE_PREFIX) + yastFileName; - QVERIFY2(QFile::exists(m_yastMimeTypes), qPrintable(errorMessage.arg(yastFileName))); - m_qmlAgainFileName = QLatin1String(RESOURCE_PREFIX) + qmlAgainFileName; - QVERIFY2(QFile::exists(m_qmlAgainFileName), qPrintable(errorMessage.arg(qmlAgainFileName))); - m_textXObjCSrcFileName = QLatin1String(RESOURCE_PREFIX) + textXObjCSrcFileName; - QVERIFY2(QFile::exists(m_textXObjCSrcFileName), qPrintable(errorMessage.arg(textXObjCSrcFileName))); + for (uint i = 0; i < sizeof additionalMimeFiles / sizeof additionalMimeFiles[0] - 1; i++) { + const QString resourceFilePath = QString::fromLatin1(RESOURCE_PREFIX) + QLatin1String(additionalMimeFiles[i]); + QVERIFY2(QFile::exists(resourceFilePath), qPrintable(errorMessage.arg(resourceFilePath))); + m_additionalMimeFileNames.append(QLatin1String(additionalMimeFiles[i])); + m_additionalMimeFilePaths.append(resourceFilePath); + } initTestCaseInternal(); m_isUsingCacheProvider = !qEnvironmentVariableIsSet("QT_NO_MIME_CACHE"); @@ -859,6 +866,14 @@ static void checkHasMimeType(const QString &mimeType) QVERIFY(found); } +static void ignoreInvalidMimetypeWarnings(const QString &mimeDir) +{ + const QByteArray basePath = QFile::encodeName(mimeDir) + "/packages/"; + QTest::ignoreMessage(QtWarningMsg, ("QMimeDatabase: Error parsing " + basePath + "invalid-magic1.xml\nInvalid magic rule value \"foo\"").constData()); + QTest::ignoreMessage(QtWarningMsg, ("QMimeDatabase: Error parsing " + basePath + "invalid-magic2.xml\nInvalid magic rule mask \"ffff\"").constData()); + QTest::ignoreMessage(QtWarningMsg, ("QMimeDatabase: Error parsing " + basePath + "invalid-magic3.xml\nInvalid magic rule mask size \"0xffff\"").constData()); +} + QT_BEGIN_NAMESPACE extern Q_CORE_EXPORT int qmime_secondsBetweenChecks; // see qmimeprovider.cpp QT_END_NAMESPACE @@ -879,23 +894,21 @@ void tst_QMimeDatabase::installNewGlobalMimeType() const QString mimeDir = m_globalXdgDir + QLatin1String("/mime"); const QString destDir = mimeDir + QLatin1String("/packages/"); - const QString destFile = destDir + QLatin1String(yastFileName); - QFile::remove(destFile); - const QString destQmlFile = destDir + QLatin1String(qmlAgainFileName); - QFile::remove(destQmlFile); - const QString destTextXObjCSrcFile = destDir + QLatin1String(textXObjCSrcFileName); - QFile::remove(destTextXObjCSrcFile); - //qDebug() << destFile; - if (!QFileInfo(destDir).isDir()) QVERIFY(QDir(m_globalXdgDir).mkpath(destDir)); + QString errorMessage; - QVERIFY2(copyResourceFile(m_yastMimeTypes, destFile, &errorMessage), qPrintable(errorMessage)); - QVERIFY2(copyResourceFile(m_qmlAgainFileName, destQmlFile, &errorMessage), qPrintable(errorMessage)); - QVERIFY2(copyResourceFile(m_textXObjCSrcFileName, destTextXObjCSrcFile, &errorMessage), qPrintable(errorMessage)); + for (int i = 0; i < m_additionalMimeFileNames.size(); ++i) { + const QString destFile = destDir + m_additionalMimeFileNames.at(i); + QFile::remove(destFile); + QVERIFY2(copyResourceFile(m_additionalMimeFilePaths.at(i), destFile, &errorMessage), qPrintable(errorMessage)); + } if (m_isUsingCacheProvider && !waitAndRunUpdateMimeDatabase(mimeDir)) QSKIP("shared-mime-info not found, skipping mime.cache test"); + if (!m_isUsingCacheProvider) + ignoreInvalidMimetypeWarnings(mimeDir); + QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), QString::fromLatin1("text/x-SuSE-ymu")); QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); @@ -916,10 +929,9 @@ void tst_QMimeDatabase::installNewGlobalMimeType() qDebug() << objcsrc.globPatterns(); } - // Now test removing it again - QVERIFY(QFile::remove(destFile)); - QVERIFY(QFile::remove(destQmlFile)); - QVERIFY(QFile::remove(destTextXObjCSrcFile)); + // Now test removing the mimetype definitions again + for (int i = 0; i < m_additionalMimeFileNames.size(); ++i) + QFile::remove(destDir + m_additionalMimeFileNames.at(i)); if (m_isUsingCacheProvider && !waitAndRunUpdateMimeDatabase(mimeDir)) QSKIP("shared-mime-info not found, skipping mime.cache test"); QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), @@ -936,23 +948,35 @@ void tst_QMimeDatabase::installNewLocalMimeType() qmime_secondsBetweenChecks = 0; QMimeDatabase db; + + // Check that we're starting clean QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); + QVERIFY(!db.mimeTypeForName(QLatin1String("text/invalid-magic1")).isValid()); const QString destDir = m_localMimeDir + QLatin1String("/packages/"); - QDir().mkpath(destDir); - const QString destFile = destDir + QLatin1String(yastFileName); - QFile::remove(destFile); - const QString destQmlFile = destDir + QLatin1String(qmlAgainFileName); - QFile::remove(destQmlFile); + QVERIFY(QDir().mkpath(destDir)); QString errorMessage; - QVERIFY2(copyResourceFile(m_yastMimeTypes, destFile, &errorMessage), qPrintable(errorMessage)); - QVERIFY2(copyResourceFile(m_qmlAgainFileName, destQmlFile, &errorMessage), qPrintable(errorMessage)); - if (m_isUsingCacheProvider && !runUpdateMimeDatabase(m_localMimeDir)) { + for (int i = 0; i < m_additionalMimeFileNames.size(); ++i) { + const QString destFile = destDir + m_additionalMimeFileNames.at(i); + QFile::remove(destFile); + QVERIFY2(copyResourceFile(m_additionalMimeFilePaths.at(i), destFile, &errorMessage), qPrintable(errorMessage)); + } + if (m_isUsingCacheProvider && !waitAndRunUpdateMimeDatabase(m_localMimeDir)) { const QString skipWarning = QStringLiteral("shared-mime-info not found, skipping mime.cache test (") + QDir::toNativeSeparators(m_localMimeDir) + QLatin1Char(')'); QSKIP(qPrintable(skipWarning)); } + if (!m_isUsingCacheProvider) + ignoreInvalidMimetypeWarnings(m_localMimeDir); + + QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); + + // These mimetypes have invalid magic, but still do exist. + QVERIFY(db.mimeTypeForName(QLatin1String("text/invalid-magic1")).isValid()); + QVERIFY(db.mimeTypeForName(QLatin1String("text/invalid-magic2")).isValid()); + QVERIFY(db.mimeTypeForName(QLatin1String("text/invalid-magic3")).isValid()); + QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), QString::fromLatin1("text/x-SuSE-ymu")); QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); @@ -968,8 +992,8 @@ void tst_QMimeDatabase::installNewLocalMimeType() QString::fromLatin1("text/x-qml")); // Now test removing the local mimetypes again (note, this leaves a mostly-empty mime.cache file) - QVERIFY(QFile::remove(destFile)); - QVERIFY(QFile::remove(destQmlFile)); + for (int i = 0; i < m_additionalMimeFileNames.size(); ++i) + QFile::remove(destDir + m_additionalMimeFileNames.at(i)); if (m_isUsingCacheProvider && !waitAndRunUpdateMimeDatabase(m_localMimeDir)) QSKIP("shared-mime-info not found, skipping mime.cache test"); QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(), diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h index f12beafe86..2827bd2dc4 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h @@ -36,6 +36,7 @@ #include #include +#include class tst_QMimeDatabase : public QObject { @@ -92,9 +93,8 @@ private: QString m_globalXdgDir; QString m_localMimeDir; - QString m_yastMimeTypes; - QString m_qmlAgainFileName; - QString m_textXObjCSrcFileName; + QStringList m_additionalMimeFileNames; + QStringList m_additionalMimeFilePaths; QTemporaryDir m_temporaryDir; QString m_testSuite; bool m_isUsingCacheProvider; -- cgit v1.2.3 From 750509c3d11324a8371aeefc389f8b6ba7ed8a2e Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 12 Aug 2015 15:25:17 +0200 Subject: Fix compilation with QNETWORKACCESSHTTPBACKEND_DEBUG enabled Change-Id: I868e8ecdff6a503ee891a257121bf14a7da77fec Reviewed-by: Markus Goetz (Woboq GmbH) Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/network/access/qnetworkreplyhttpimpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index c445677792..abc6603be2 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1152,7 +1152,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData if (statusCode == 304) { #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) - qDebug() << "Received a 304 from" << url(); + qDebug() << "Received a 304 from" << request.url(); #endif QAbstractNetworkCache *nc = managerPrivate->networkCache; if (nc) { @@ -1457,7 +1457,7 @@ QNetworkCacheMetaData QNetworkReplyHttpImplPrivate::fetchCacheMetaData(const QNe } #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) - QByteArray n = rawHeader(header); + QByteArray n = q->rawHeader(header); QByteArray o; if (it != cacheHeaders.rawHeaders.constEnd()) o = (*it).second; -- cgit v1.2.3 From cb12da0387458fb63a80a4f59d5ddb24d33ad59b Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 2 Sep 2015 18:30:29 +0300 Subject: Android: Don't use predictive text when selecting file names Using predictive text will not refresh the selected files until a word is completed or the keyboard is hidden. Task-number: QTBUG-44337 Change-Id: I9e9f1e760fe5d5a69abd6e112af55b217ae6a16d Reviewed-by: Shawn Rutledge --- src/widgets/dialogs/qfiledialog.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 64e3f5069e..c9e6a199c4 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -2851,6 +2851,9 @@ void QFileDialogPrivate::createWidgets() completer = new QFSCompleter(model, q); qFileDialogUi->fileNameEdit->setCompleter(completer); #endif // QT_NO_FSCOMPLETER + + qFileDialogUi->fileNameEdit->setInputMethodHints(Qt::ImhNoPredictiveText); + QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)), q, SLOT(_q_autoCompleteFileName(QString))); QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)), -- cgit v1.2.3 From 6413ceeccff9078bc8ec2dcb63b445c031c420dd Mon Sep 17 00:00:00 2001 From: Kari Pihkala Date: Sat, 2 Aug 2014 09:59:18 +0300 Subject: Fix default hotspot of a hidpi QCursor The hotspot is defined in device independent coordinates, so the default coordinates need to be divided by device pixel ratio. Also, modify the scaling of cursor's pixmap to use SmoothTransformation to generate cleaner looking lodpi cursors from hidpi cursors. Change-Id: Ia938fd1e476e19e796f30712e23b06a5efed9964 Task-number: QTBUG-34116 Reviewed-by: Jake Petroules --- src/gui/kernel/qcursor.cpp | 10 +++++----- src/gui/kernel/qcursor_p.h | 3 ++- src/plugins/platforms/cocoa/qcocoacursor.mm | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index 6ed750eda1..6b01952647 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -387,7 +387,7 @@ QCursor::QCursor(const QPixmap &pixmap, int hotX, int hotY) bmm.fill(Qt::color1); } - d = QCursorData::setBitmap(bm, bmm, hotX, hotY); + d = QCursorData::setBitmap(bm, bmm, hotX, hotY, pixmap.devicePixelRatio()); d->pixmap = pixmap; } @@ -430,7 +430,7 @@ QCursor::QCursor(const QPixmap &pixmap, int hotX, int hotY) QCursor::QCursor(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) : d(0) { - d = QCursorData::setBitmap(bitmap, mask, hotX, hotY); + d = QCursorData::setBitmap(bitmap, mask, hotX, hotY, 1.0); } /*! @@ -650,7 +650,7 @@ void QCursorData::initialize() QCursorData::initialized = true; } -QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) +QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY, qreal devicePixelRatio) { if (!QCursorData::initialized) QCursorData::initialize(); @@ -664,8 +664,8 @@ QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, d->bm = new QBitmap(bitmap); d->bmm = new QBitmap(mask); d->cshape = Qt::BitmapCursor; - d->hx = hotX >= 0 ? hotX : bitmap.width() / 2; - d->hy = hotY >= 0 ? hotY : bitmap.height() / 2; + d->hx = hotX >= 0 ? hotX : bitmap.width() / 2 / devicePixelRatio; + d->hy = hotY >= 0 ? hotY : bitmap.height() / 2 / devicePixelRatio; return d; } diff --git a/src/gui/kernel/qcursor_p.h b/src/gui/kernel/qcursor_p.h index 0aaa62b891..188ea387b3 100644 --- a/src/gui/kernel/qcursor_p.h +++ b/src/gui/kernel/qcursor_p.h @@ -70,7 +70,8 @@ public: short hx, hy; static bool initialized; void update(); - static QCursorData *setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY); + static QCursorData *setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY, + qreal devicePixelRatio); }; extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index 922809f90d..f08386d18e 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -304,7 +304,7 @@ NSCursor *QCocoaCursor::createCursorFromPixmap(const QPixmap pixmap, const QPoin NSImage *nsimage; if (pixmap.devicePixelRatio() > 1.0) { QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio(); - QPixmap scaledPixmap = pixmap.scaled(layoutSize); + QPixmap scaledPixmap = pixmap.scaled(layoutSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); nsimage = static_cast(qt_mac_create_nsimage(scaledPixmap)); CGImageRef cgImage = qt_mac_toCGImage(pixmap.toImage()); NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage]; -- cgit v1.2.3 From 1a5cc2a868969f1b1e9278c4145b7af2fc4b8f69 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Mon, 24 Aug 2015 12:22:52 +0200 Subject: Cocoa: correct QDesktopWidget::availableGeometry() Since 10.9, System Preferences->Mission Control->Displays have separate Spaces settings needs to be followed. Task-number: QTBUG-47030 Change-Id: I1c1cf326246bd5609090ce5ac3212d963d562593 Reviewed-by: Jake Petroules --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index c8f6dd05db..8f84539e04 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -86,9 +86,17 @@ void QCocoaScreen::updateGeometry() NSRect frameRect = [nsScreen frame]; - if (m_screenIndex == 0) { + // Since Mavericks, there is a setting, System Preferences->Mission Control-> + // Displays have separate Spaces. + BOOL spansDisplays = NO; +#if QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9) + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_9) + spansDisplays = [NSScreen screensHaveSeparateSpaces]; +#endif + if (spansDisplays || m_screenIndex == 0) { m_geometry = QRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height); - // This is the primary screen, the one that contains the menubar. Its origin should be + // Displays have separate Spaces setting is on or this is the primary screen, + // the one that contains the menubar. Its origin should be // (0, 0), and it's the only one whose available geometry differs from its full geometry. NSRect visibleRect = [nsScreen visibleFrame]; m_availableGeometry = QRect(visibleRect.origin.x, -- cgit v1.2.3 From 0e895c47b049fffd58abff3f61681e94ba5515ec Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 25 Aug 2015 13:55:12 +0200 Subject: Doc: Update links to Qt Creator Manual MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're now at 3.5 level: - Fixed changed filenames and topic titles - Removed links to obsolete pages - Added links to new pages Task-number: QTBUG-47901 Change-Id: I3393555c86bf3cf58770f230e7a9c7fd7e258476 Reviewed-by: Topi Reiniö --- doc/global/externalsites/qtcreator.qdoc | 44 +++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/doc/global/externalsites/qtcreator.qdoc b/doc/global/externalsites/qtcreator.qdoc index 200ef307ca..95200622f3 100644 --- a/doc/global/externalsites/qtcreator.qdoc +++ b/doc/global/externalsites/qtcreator.qdoc @@ -27,24 +27,16 @@ /*! \externalpage http://doc.qt.io/qtcreator/creator-deployment-qnx.html - \title Qt Creator: Deploying Applications to QNX Devices + \title Qt Creator: Deploying Applications to QNX Neutrino Devices */ /*! \externalpage http://doc.qt.io/qtcreator/creator-developing-baremetal.html \title Qt Creator: Connecting Bare Metal Devices */ -/*! - \externalpage http://doc.qt.io/qtcreator/creator-developing-bb10.html - \title Qt Creator: Connecting BlackBerry 10 Devices -*/ /*! \externalpage http://doc.qt.io/qtcreator/creator-developing-qnx.html \title Qt Creator: Connecting QNX Devices */ -/*! - \externalpage http://doc.qt.io/qtcreator/creator-deployment-bb10.html - \title Qt Creator: Deploying Applications to BlackBerry 10 Devices -*/ /*! \externalpage http://doc.qt.io/qtcreator/creator-developing-generic-linux.html \title Qt Creator: Connecting Embedded Linux Devices @@ -98,7 +90,19 @@ \title Qt Creator: Creating Screens */ /*! - \externalpage http://doc.qt.io/qtcreator/creator-qml-application.html + \externalpage http://doc.qt.io/qtcreator/creator-qtquick-designer-extensions.html + \title Qt Creator: Using Qt Quick Designer Extensions +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/qmldesigner-pathview-editor.html + \title Qt Creator: Editing PathView Properties +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/qmldesigner-connections.html + \title Qt Creator: Adding Connections +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/qtcreator-transitions-example.html \title Qt Creator: Creating a Qt Quick Application */ /*! @@ -279,7 +283,7 @@ */ /*! \externalpage http://doc.qt.io/qtcreator/creator-testing.html - \title Qt Creator: Debugging and Analyzing + \title Qt Creator: Testing */ /*! \externalpage http://doc.qt.io/qtcreator/creator-deployment.html @@ -297,10 +301,6 @@ \externalpage http://doc.qt.io/qtcreator/creator-design-mode.html \title Qt Creator: Designing User Interfaces */ -/*! - \externalpage http://doc.qt.io/qtcreator/creator-publish-ovi.html - \title Qt Creator: Publishing -*/ /*! \externalpage http://doc.qt.io/qtcreator/creator-glossary.html \title Qt Creator: Glossary @@ -476,7 +476,7 @@ \title Qt Creator: Adding Debuggers */ /*! - \externalpage http://doc.qt.io/qtcreator/creator-mobile-app-tutorial.html + \externalpage http://doc.qt.io/qtcreator/qtcreator-accelbubble-example.html \title Qt Creator: Creating a Mobile Application */ /*! @@ -499,7 +499,19 @@ \externalpage http://doc.qt.io/qtcreator/creator-quick-ui-forms.html \title Qt Creator: Qt Quick UI Forms */ +/*! + \externalpage http://doc.qt.io/qtcreator/qtcreator-uiforms-example.html + \title Qt Creator: Using Qt Quick UI Forms +*/ /*! \externalpage http://doc.qt.io/qtcreator/creator-clang-static-analyzer.html \title Qt Creator: Using Clang Static Analyzer */ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-cpu-usage-analyzer.html + \title Qt Creator: Analyzing CPU Usage +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-autotest.html + \title Qt Creator: Running Autotests +*/ -- cgit v1.2.3 From 0552331d0e42e7b73f36e31ffd3cc511b50d2ec0 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 3 Aug 2015 10:07:17 +0200 Subject: Do not install headers for private classes When merging the accessibility plugin into the widgets library, the headers were just moved. They should have gotten the _p at that time. Task-number: QTBUG-47569 Change-Id: I0a2290dae3a8187596e9d7541ccf69beeb603296 Reviewed-by: Dimitar Dobrev Reviewed-by: Thiago Macieira --- src/widgets/accessible/accessible.pri | 12 +- src/widgets/accessible/complexwidgets.cpp | 2 +- src/widgets/accessible/complexwidgets.h | 137 --------- src/widgets/accessible/complexwidgets_p.h | 148 ++++++++++ src/widgets/accessible/itemviews.cpp | 2 +- src/widgets/accessible/itemviews.h | 284 ------------------ src/widgets/accessible/itemviews_p.h | 295 +++++++++++++++++++ src/widgets/accessible/qaccessiblemenu.cpp | 2 +- src/widgets/accessible/qaccessiblemenu.h | 123 -------- src/widgets/accessible/qaccessiblemenu_p.h | 134 +++++++++ .../accessible/qaccessiblewidgetfactory.cpp | 12 +- .../accessible/qaccessiblewidgetfactory_p.h | 11 + src/widgets/accessible/qaccessiblewidgets.cpp | 2 +- src/widgets/accessible/qaccessiblewidgets.h | 306 -------------------- src/widgets/accessible/qaccessiblewidgets_p.h | 317 +++++++++++++++++++++ src/widgets/accessible/rangecontrols.cpp | 4 +- src/widgets/accessible/rangecontrols.h | 186 ------------ src/widgets/accessible/rangecontrols_p.h | 197 +++++++++++++ src/widgets/accessible/simplewidgets.cpp | 2 +- src/widgets/accessible/simplewidgets.h | 209 -------------- src/widgets/accessible/simplewidgets_p.h | 220 ++++++++++++++ 21 files changed, 1341 insertions(+), 1264 deletions(-) delete mode 100644 src/widgets/accessible/complexwidgets.h create mode 100644 src/widgets/accessible/complexwidgets_p.h delete mode 100644 src/widgets/accessible/itemviews.h create mode 100644 src/widgets/accessible/itemviews_p.h delete mode 100644 src/widgets/accessible/qaccessiblemenu.h create mode 100644 src/widgets/accessible/qaccessiblemenu_p.h delete mode 100644 src/widgets/accessible/qaccessiblewidgets.h create mode 100644 src/widgets/accessible/qaccessiblewidgets_p.h delete mode 100644 src/widgets/accessible/rangecontrols.h create mode 100644 src/widgets/accessible/rangecontrols_p.h delete mode 100644 src/widgets/accessible/simplewidgets.h create mode 100644 src/widgets/accessible/simplewidgets_p.h diff --git a/src/widgets/accessible/accessible.pri b/src/widgets/accessible/accessible.pri index bcdfbd639c..ac8205b1e3 100644 --- a/src/widgets/accessible/accessible.pri +++ b/src/widgets/accessible/accessible.pri @@ -4,12 +4,12 @@ contains(QT_CONFIG, accessibility) { HEADERS += \ accessible/qaccessiblewidget.h \ accessible/qaccessiblewidgetfactory_p.h \ - accessible/complexwidgets.h \ - accessible/itemviews.h \ - accessible/qaccessiblemenu.h \ - accessible/qaccessiblewidgets.h \ - accessible/rangecontrols.h \ - accessible/simplewidgets.h + accessible/complexwidgets_p.h \ + accessible/itemviews_p.h \ + accessible/qaccessiblemenu_p.h \ + accessible/qaccessiblewidgets_p.h \ + accessible/rangecontrols_p.h \ + accessible/simplewidgets_p.h SOURCES += \ accessible/qaccessiblewidget.cpp \ diff --git a/src/widgets/accessible/complexwidgets.cpp b/src/widgets/accessible/complexwidgets.cpp index 60a1329d5e..6e985c86e8 100644 --- a/src/widgets/accessible/complexwidgets.cpp +++ b/src/widgets/accessible/complexwidgets.cpp @@ -31,7 +31,7 @@ ** ****************************************************************************/ -#include "complexwidgets.h" +#include "complexwidgets_p.h" #include #include diff --git a/src/widgets/accessible/complexwidgets.h b/src/widgets/accessible/complexwidgets.h deleted file mode 100644 index bd063e7517..0000000000 --- a/src/widgets/accessible/complexwidgets.h +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef COMPLEXWIDGETS_H -#define COMPLEXWIDGETS_H - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ACCESSIBILITY - -class QAbstractButton; -class QHeaderView; -class QTabBar; -class QComboBox; -class QTitleBar; -class QAbstractScrollArea; -class QScrollArea; - -#ifndef QT_NO_SCROLLAREA -class QAccessibleAbstractScrollArea : public QAccessibleWidget -{ -public: - explicit QAccessibleAbstractScrollArea(QWidget *widget); - - enum AbstractScrollAreaElement { - Self = 0, - Viewport, - HorizontalContainer, - VerticalContainer, - CornerWidget, - Undefined - }; - - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - -//protected: - QAbstractScrollArea *abstractScrollArea() const; - -private: - QWidgetList accessibleChildren() const; - AbstractScrollAreaElement elementType(QWidget *widget) const; - bool isLeftToRight() const; -}; - -class QAccessibleScrollArea : public QAccessibleAbstractScrollArea -{ -public: - explicit QAccessibleScrollArea(QWidget *widget); -}; -#endif // QT_NO_SCROLLAREA - -#ifndef QT_NO_TABBAR -class QAccessibleTabBar : public QAccessibleWidget -{ -public: - explicit QAccessibleTabBar(QWidget *w); - ~QAccessibleTabBar(); - - int childCount() const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - -protected: - QTabBar *tabBar() const; - mutable QHash m_childInterfaces; -}; -#endif // QT_NO_TABBAR - -#ifndef QT_NO_COMBOBOX -class QAccessibleComboBox : public QAccessibleWidget -{ -public: - explicit QAccessibleComboBox(QWidget *w); - - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE; - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - // QAccessibleActionInterface - QStringList actionNames() const Q_DECL_OVERRIDE; - QString localizedActionDescription(const QString &actionName) const Q_DECL_OVERRIDE; - void doAction(const QString &actionName) Q_DECL_OVERRIDE; - QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; - -protected: - QComboBox *comboBox() const; -}; -#endif // QT_NO_COMBOBOX - -#endif // QT_NO_ACCESSIBILITY - -QT_END_NAMESPACE - -#endif // COMPLEXWIDGETS_H diff --git a/src/widgets/accessible/complexwidgets_p.h b/src/widgets/accessible/complexwidgets_p.h new file mode 100644 index 0000000000..8edf996818 --- /dev/null +++ b/src/widgets/accessible/complexwidgets_p.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef COMPLEXWIDGETS_H +#define COMPLEXWIDGETS_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY + +class QAbstractButton; +class QHeaderView; +class QTabBar; +class QComboBox; +class QTitleBar; +class QAbstractScrollArea; +class QScrollArea; + +#ifndef QT_NO_SCROLLAREA +class QAccessibleAbstractScrollArea : public QAccessibleWidget +{ +public: + explicit QAccessibleAbstractScrollArea(QWidget *widget); + + enum AbstractScrollAreaElement { + Self = 0, + Viewport, + HorizontalContainer, + VerticalContainer, + CornerWidget, + Undefined + }; + + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + bool isValid() const Q_DECL_OVERRIDE; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + +//protected: + QAbstractScrollArea *abstractScrollArea() const; + +private: + QWidgetList accessibleChildren() const; + AbstractScrollAreaElement elementType(QWidget *widget) const; + bool isLeftToRight() const; +}; + +class QAccessibleScrollArea : public QAccessibleAbstractScrollArea +{ +public: + explicit QAccessibleScrollArea(QWidget *widget); +}; +#endif // QT_NO_SCROLLAREA + +#ifndef QT_NO_TABBAR +class QAccessibleTabBar : public QAccessibleWidget +{ +public: + explicit QAccessibleTabBar(QWidget *w); + ~QAccessibleTabBar(); + + int childCount() const Q_DECL_OVERRIDE; + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + +protected: + QTabBar *tabBar() const; + mutable QHash m_childInterfaces; +}; +#endif // QT_NO_TABBAR + +#ifndef QT_NO_COMBOBOX +class QAccessibleComboBox : public QAccessibleWidget +{ +public: + explicit QAccessibleComboBox(QWidget *w); + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE; + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + // QAccessibleActionInterface + QStringList actionNames() const Q_DECL_OVERRIDE; + QString localizedActionDescription(const QString &actionName) const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; + +protected: + QComboBox *comboBox() const; +}; +#endif // QT_NO_COMBOBOX + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // COMPLEXWIDGETS_H diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp index 4f6cb56060..6534d51a45 100644 --- a/src/widgets/accessible/itemviews.cpp +++ b/src/widgets/accessible/itemviews.cpp @@ -31,7 +31,7 @@ ** ****************************************************************************/ -#include "itemviews.h" +#include "itemviews_p.h" #include #include diff --git a/src/widgets/accessible/itemviews.h b/src/widgets/accessible/itemviews.h deleted file mode 100644 index c1bd70a390..0000000000 --- a/src/widgets/accessible/itemviews.h +++ /dev/null @@ -1,284 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ACCESSIBLE_ITEMVIEWS_H -#define ACCESSIBLE_ITEMVIEWS_H - -#include "QtCore/qpointer.h" -#include -#include -#include -#include - - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ACCESSIBILITY - -#ifndef QT_NO_ITEMVIEWS - -class QAccessibleTableCell; -class QAccessibleTableHeaderCell; - -class QAccessibleTable :public QAccessibleTableInterface, public QAccessibleObject -{ -public: - explicit QAccessibleTable(QWidget *w); - bool isValid() const Q_DECL_OVERRIDE; - - QAccessible::Role role() const Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE; - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // table interface - virtual QAccessibleInterface *cellAt(int row, int column) const Q_DECL_OVERRIDE; - virtual QAccessibleInterface *caption() const Q_DECL_OVERRIDE; - virtual QAccessibleInterface *summary() const Q_DECL_OVERRIDE; - virtual QString columnDescription(int column) const Q_DECL_OVERRIDE; - virtual QString rowDescription(int row) const Q_DECL_OVERRIDE; - virtual int columnCount() const Q_DECL_OVERRIDE; - virtual int rowCount() const Q_DECL_OVERRIDE; - - // selection - virtual int selectedCellCount() const Q_DECL_OVERRIDE; - virtual int selectedColumnCount() const Q_DECL_OVERRIDE; - virtual int selectedRowCount() const Q_DECL_OVERRIDE; - virtual QList selectedCells() const Q_DECL_OVERRIDE; - virtual QList selectedColumns() const Q_DECL_OVERRIDE; - virtual QList selectedRows() const Q_DECL_OVERRIDE; - virtual bool isColumnSelected(int column) const Q_DECL_OVERRIDE; - virtual bool isRowSelected(int row) const Q_DECL_OVERRIDE; - virtual bool selectRow(int row) Q_DECL_OVERRIDE; - virtual bool selectColumn(int column) Q_DECL_OVERRIDE; - virtual bool unselectRow(int row) Q_DECL_OVERRIDE; - virtual bool unselectColumn(int column) Q_DECL_OVERRIDE; - - QAbstractItemView *view() const; - - void modelChange(QAccessibleTableModelChangeEvent *event) Q_DECL_OVERRIDE; - -protected: - inline QAccessible::Role cellRole() const { - switch (m_role) { - case QAccessible::List: - return QAccessible::ListItem; - case QAccessible::Table: - return QAccessible::Cell; - case QAccessible::Tree: - return QAccessible::TreeItem; - default: - Q_ASSERT(0); - } - return QAccessible::NoRole; - } - - QHeaderView *horizontalHeader() const; - QHeaderView *verticalHeader() const; - - // maybe vector - typedef QHash ChildCache; - mutable ChildCache childToId; - - virtual ~QAccessibleTable(); - -private: - // the child index for a model index - inline int logicalIndex(const QModelIndex &index) const; - QAccessible::Role m_role; -}; - -class QAccessibleTree :public QAccessibleTable -{ -public: - explicit QAccessibleTree(QWidget *w) - : QAccessibleTable(w) - {} - - - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - - int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE; - - int rowCount() const Q_DECL_OVERRIDE; - - // table interface - QAccessibleInterface *cellAt(int row, int column) const Q_DECL_OVERRIDE; - QString rowDescription(int row) const Q_DECL_OVERRIDE; - bool isRowSelected(int row) const Q_DECL_OVERRIDE; - bool selectRow(int row) Q_DECL_OVERRIDE; - -private: - QModelIndex indexFromLogical(int row, int column = 0) const; - - inline int logicalIndex(const QModelIndex &index) const; -}; - -class QAccessibleTableCell: public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface -{ -public: - QAccessibleTableCell(QAbstractItemView *view, const QModelIndex &m_index, QAccessible::Role role); - - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - QObject *object() const Q_DECL_OVERRIDE { return 0; } - QAccessible::Role role() const Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; - - QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } - int childCount() const Q_DECL_OVERRIDE { return 0; } - int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int) const Q_DECL_OVERRIDE; - - // cell interface - virtual int columnExtent() const Q_DECL_OVERRIDE; - virtual QList columnHeaderCells() const Q_DECL_OVERRIDE; - virtual int columnIndex() const Q_DECL_OVERRIDE; - virtual int rowExtent() const Q_DECL_OVERRIDE; - virtual QList rowHeaderCells() const Q_DECL_OVERRIDE; - virtual int rowIndex() const Q_DECL_OVERRIDE; - virtual bool isSelected() const Q_DECL_OVERRIDE; - virtual QAccessibleInterface* table() const Q_DECL_OVERRIDE; - - //action interface - virtual QStringList actionNames() const Q_DECL_OVERRIDE; - virtual void doAction(const QString &actionName) Q_DECL_OVERRIDE; - virtual QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; - -private: - QHeaderView *verticalHeader() const; - QHeaderView *horizontalHeader() const; - QPointer view; - QModelIndex m_index; - QAccessible::Role m_role; - - void selectCell(); - void unselectCell(); - -friend class QAccessibleTable; -friend class QAccessibleTree; -}; - - -class QAccessibleTableHeaderCell: public QAccessibleInterface -{ -public: - // For header cells, pass the header view in addition - QAccessibleTableHeaderCell(QAbstractItemView *view, int index, Qt::Orientation orientation); - - QObject *object() const Q_DECL_OVERRIDE { return 0; } - QAccessible::Role role() const Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; - - QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } - int childCount() const Q_DECL_OVERRIDE { return 0; } - int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - -private: - QHeaderView *headerView() const; - - QPointer view; - int index; - Qt::Orientation orientation; - -friend class QAccessibleTable; -friend class QAccessibleTree; -}; - -// This is the corner button on the top left of a table. -// It can be used to select all cells or it is not active at all. -// For now it is ignored. -class QAccessibleTableCornerButton: public QAccessibleInterface -{ -public: - QAccessibleTableCornerButton(QAbstractItemView *view_) - :view(view_) - {} - - QObject *object() const Q_DECL_OVERRIDE { return 0; } - QAccessible::Role role() const Q_DECL_OVERRIDE { return QAccessible::Pane; } - QAccessible::State state() const Q_DECL_OVERRIDE { return QAccessible::State(); } - QRect rect() const Q_DECL_OVERRIDE { return QRect(); } - bool isValid() const Q_DECL_OVERRIDE { return true; } - - QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } - int childCount() const Q_DECL_OVERRIDE { return 0; } - int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } - - QString text(QAccessible::Text) const Q_DECL_OVERRIDE { return QString(); } - void setText(QAccessible::Text, const QString &) Q_DECL_OVERRIDE {} - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE { - return QAccessible::queryAccessibleInterface(view); - } - QAccessibleInterface *child(int) const Q_DECL_OVERRIDE { - return 0; - } - -private: - QPointer view; -}; - - -#endif - -#endif // QT_NO_ACCESSIBILITY - -QT_END_NAMESPACE - -#endif // ACCESSIBLE_ITEMVIEWS_H diff --git a/src/widgets/accessible/itemviews_p.h b/src/widgets/accessible/itemviews_p.h new file mode 100644 index 0000000000..a1b6a6db9f --- /dev/null +++ b/src/widgets/accessible/itemviews_p.h @@ -0,0 +1,295 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ACCESSIBLE_ITEMVIEWS_H +#define ACCESSIBLE_ITEMVIEWS_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "QtCore/qpointer.h" +#include +#include +#include +#include + + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY + +#ifndef QT_NO_ITEMVIEWS + +class QAccessibleTableCell; +class QAccessibleTableHeaderCell; + +class QAccessibleTable :public QAccessibleTableInterface, public QAccessibleObject +{ +public: + explicit QAccessibleTable(QWidget *w); + bool isValid() const Q_DECL_OVERRIDE; + + QAccessible::Role role() const Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE; + + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // table interface + virtual QAccessibleInterface *cellAt(int row, int column) const Q_DECL_OVERRIDE; + virtual QAccessibleInterface *caption() const Q_DECL_OVERRIDE; + virtual QAccessibleInterface *summary() const Q_DECL_OVERRIDE; + virtual QString columnDescription(int column) const Q_DECL_OVERRIDE; + virtual QString rowDescription(int row) const Q_DECL_OVERRIDE; + virtual int columnCount() const Q_DECL_OVERRIDE; + virtual int rowCount() const Q_DECL_OVERRIDE; + + // selection + virtual int selectedCellCount() const Q_DECL_OVERRIDE; + virtual int selectedColumnCount() const Q_DECL_OVERRIDE; + virtual int selectedRowCount() const Q_DECL_OVERRIDE; + virtual QList selectedCells() const Q_DECL_OVERRIDE; + virtual QList selectedColumns() const Q_DECL_OVERRIDE; + virtual QList selectedRows() const Q_DECL_OVERRIDE; + virtual bool isColumnSelected(int column) const Q_DECL_OVERRIDE; + virtual bool isRowSelected(int row) const Q_DECL_OVERRIDE; + virtual bool selectRow(int row) Q_DECL_OVERRIDE; + virtual bool selectColumn(int column) Q_DECL_OVERRIDE; + virtual bool unselectRow(int row) Q_DECL_OVERRIDE; + virtual bool unselectColumn(int column) Q_DECL_OVERRIDE; + + QAbstractItemView *view() const; + + void modelChange(QAccessibleTableModelChangeEvent *event) Q_DECL_OVERRIDE; + +protected: + inline QAccessible::Role cellRole() const { + switch (m_role) { + case QAccessible::List: + return QAccessible::ListItem; + case QAccessible::Table: + return QAccessible::Cell; + case QAccessible::Tree: + return QAccessible::TreeItem; + default: + Q_ASSERT(0); + } + return QAccessible::NoRole; + } + + QHeaderView *horizontalHeader() const; + QHeaderView *verticalHeader() const; + + // maybe vector + typedef QHash ChildCache; + mutable ChildCache childToId; + + virtual ~QAccessibleTable(); + +private: + // the child index for a model index + inline int logicalIndex(const QModelIndex &index) const; + QAccessible::Role m_role; +}; + +class QAccessibleTree :public QAccessibleTable +{ +public: + explicit QAccessibleTree(QWidget *w) + : QAccessibleTable(w) + {} + + + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + + int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE; + + int rowCount() const Q_DECL_OVERRIDE; + + // table interface + QAccessibleInterface *cellAt(int row, int column) const Q_DECL_OVERRIDE; + QString rowDescription(int row) const Q_DECL_OVERRIDE; + bool isRowSelected(int row) const Q_DECL_OVERRIDE; + bool selectRow(int row) Q_DECL_OVERRIDE; + +private: + QModelIndex indexFromLogical(int row, int column = 0) const; + + inline int logicalIndex(const QModelIndex &index) const; +}; + +class QAccessibleTableCell: public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface +{ +public: + QAccessibleTableCell(QAbstractItemView *view, const QModelIndex &m_index, QAccessible::Role role); + + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + QObject *object() const Q_DECL_OVERRIDE { return 0; } + QAccessible::Role role() const Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + bool isValid() const Q_DECL_OVERRIDE; + + QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } + int childCount() const Q_DECL_OVERRIDE { return 0; } + int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; + + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int) const Q_DECL_OVERRIDE; + + // cell interface + virtual int columnExtent() const Q_DECL_OVERRIDE; + virtual QList columnHeaderCells() const Q_DECL_OVERRIDE; + virtual int columnIndex() const Q_DECL_OVERRIDE; + virtual int rowExtent() const Q_DECL_OVERRIDE; + virtual QList rowHeaderCells() const Q_DECL_OVERRIDE; + virtual int rowIndex() const Q_DECL_OVERRIDE; + virtual bool isSelected() const Q_DECL_OVERRIDE; + virtual QAccessibleInterface* table() const Q_DECL_OVERRIDE; + + //action interface + virtual QStringList actionNames() const Q_DECL_OVERRIDE; + virtual void doAction(const QString &actionName) Q_DECL_OVERRIDE; + virtual QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; + +private: + QHeaderView *verticalHeader() const; + QHeaderView *horizontalHeader() const; + QPointer view; + QModelIndex m_index; + QAccessible::Role m_role; + + void selectCell(); + void unselectCell(); + +friend class QAccessibleTable; +friend class QAccessibleTree; +}; + + +class QAccessibleTableHeaderCell: public QAccessibleInterface +{ +public: + // For header cells, pass the header view in addition + QAccessibleTableHeaderCell(QAbstractItemView *view, int index, Qt::Orientation orientation); + + QObject *object() const Q_DECL_OVERRIDE { return 0; } + QAccessible::Role role() const Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + bool isValid() const Q_DECL_OVERRIDE; + + QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } + int childCount() const Q_DECL_OVERRIDE { return 0; } + int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; + + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + +private: + QHeaderView *headerView() const; + + QPointer view; + int index; + Qt::Orientation orientation; + +friend class QAccessibleTable; +friend class QAccessibleTree; +}; + +// This is the corner button on the top left of a table. +// It can be used to select all cells or it is not active at all. +// For now it is ignored. +class QAccessibleTableCornerButton: public QAccessibleInterface +{ +public: + QAccessibleTableCornerButton(QAbstractItemView *view_) + :view(view_) + {} + + QObject *object() const Q_DECL_OVERRIDE { return 0; } + QAccessible::Role role() const Q_DECL_OVERRIDE { return QAccessible::Pane; } + QAccessible::State state() const Q_DECL_OVERRIDE { return QAccessible::State(); } + QRect rect() const Q_DECL_OVERRIDE { return QRect(); } + bool isValid() const Q_DECL_OVERRIDE { return true; } + + QAccessibleInterface *childAt(int, int) const Q_DECL_OVERRIDE { return 0; } + int childCount() const Q_DECL_OVERRIDE { return 0; } + int indexOfChild(const QAccessibleInterface *) const Q_DECL_OVERRIDE { return -1; } + + QString text(QAccessible::Text) const Q_DECL_OVERRIDE { return QString(); } + void setText(QAccessible::Text, const QString &) Q_DECL_OVERRIDE {} + + QAccessibleInterface *parent() const Q_DECL_OVERRIDE { + return QAccessible::queryAccessibleInterface(view); + } + QAccessibleInterface *child(int) const Q_DECL_OVERRIDE { + return 0; + } + +private: + QPointer view; +}; + + +#endif + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // ACCESSIBLE_ITEMVIEWS_H diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp index 72eb82b2b7..a0a7852851 100644 --- a/src/widgets/accessible/qaccessiblemenu.cpp +++ b/src/widgets/accessible/qaccessiblemenu.cpp @@ -31,7 +31,7 @@ ** ****************************************************************************/ -#include "qaccessiblemenu.h" +#include "qaccessiblemenu_p.h" #include #include diff --git a/src/widgets/accessible/qaccessiblemenu.h b/src/widgets/accessible/qaccessiblemenu.h deleted file mode 100644 index 9c7671072d..0000000000 --- a/src/widgets/accessible/qaccessiblemenu.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QACCESSIBLEMENU_H -#define QACCESSIBLEMENU_H - -#include -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ACCESSIBILITY - -#ifndef QT_NO_MENU -class QMenu; -class QMenuBar; -class QAction; - -class QAccessibleMenu : public QAccessibleWidget -{ -public: - explicit QAccessibleMenu(QWidget *w); - - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - int indexOfChild( const QAccessibleInterface *child ) const Q_DECL_OVERRIDE; - -protected: - QMenu *menu() const; -}; - -#ifndef QT_NO_MENUBAR -class QAccessibleMenuBar : public QAccessibleWidget -{ -public: - explicit QAccessibleMenuBar(QWidget *w); - - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - -protected: - QMenuBar *menuBar() const; -}; -#endif // QT_NO_MENUBAR - - -class QAccessibleMenuItem : public QAccessibleInterface, public QAccessibleActionInterface -{ -public: - explicit QAccessibleMenuItem(QWidget *owner, QAction *w); - - ~QAccessibleMenuItem(); - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface * child) const Q_DECL_OVERRIDE; - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - QObject * object() const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString & text) Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - // QAccessibleActionInterface - QStringList actionNames() const Q_DECL_OVERRIDE; - void doAction(const QString &actionName) Q_DECL_OVERRIDE; - QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; - - QWidget *owner() const; -protected: - QAction *action() const; -private: - QAction *m_action; - QPointer m_owner; // can hold either QMenu or the QMenuBar that contains the action -}; - -#endif // QT_NO_MENU - -QT_END_NAMESPACE -#endif // QT_NO_ACCESSIBILITY -#endif // QACCESSIBLEMENU_H diff --git a/src/widgets/accessible/qaccessiblemenu_p.h b/src/widgets/accessible/qaccessiblemenu_p.h new file mode 100644 index 0000000000..b42c852ff1 --- /dev/null +++ b/src/widgets/accessible/qaccessiblemenu_p.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QACCESSIBLEMENU_H +#define QACCESSIBLEMENU_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY + +#ifndef QT_NO_MENU +class QMenu; +class QMenuBar; +class QAction; + +class QAccessibleMenu : public QAccessibleWidget +{ +public: + explicit QAccessibleMenu(QWidget *w); + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + int indexOfChild( const QAccessibleInterface *child ) const Q_DECL_OVERRIDE; + +protected: + QMenu *menu() const; +}; + +#ifndef QT_NO_MENUBAR +class QAccessibleMenuBar : public QAccessibleWidget +{ +public: + explicit QAccessibleMenuBar(QWidget *w); + + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + +protected: + QMenuBar *menuBar() const; +}; +#endif // QT_NO_MENUBAR + + +class QAccessibleMenuItem : public QAccessibleInterface, public QAccessibleActionInterface +{ +public: + explicit QAccessibleMenuItem(QWidget *owner, QAction *w); + + ~QAccessibleMenuItem(); + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + bool isValid() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface * child) const Q_DECL_OVERRIDE; + + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + QObject * object() const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString & text) Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + // QAccessibleActionInterface + QStringList actionNames() const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; + + QWidget *owner() const; +protected: + QAction *action() const; +private: + QAction *m_action; + QPointer m_owner; // can hold either QMenu or the QMenuBar that contains the action +}; + +#endif // QT_NO_MENU + +QT_END_NAMESPACE +#endif // QT_NO_ACCESSIBILITY +#endif // QACCESSIBLEMENU_H diff --git a/src/widgets/accessible/qaccessiblewidgetfactory.cpp b/src/widgets/accessible/qaccessiblewidgetfactory.cpp index e8b325b93f..4fa7c89482 100644 --- a/src/widgets/accessible/qaccessiblewidgetfactory.cpp +++ b/src/widgets/accessible/qaccessiblewidgetfactory.cpp @@ -31,12 +31,12 @@ ** ****************************************************************************/ -#include "qaccessiblewidgets.h" -#include "qaccessiblemenu.h" -#include "simplewidgets.h" -#include "rangecontrols.h" -#include "complexwidgets.h" -#include "itemviews.h" +#include "qaccessiblewidgets_p.h" +#include "qaccessiblemenu_p.h" +#include "simplewidgets_p.h" +#include "rangecontrols_p.h" +#include "complexwidgets_p.h" +#include "itemviews_p.h" #include #include diff --git a/src/widgets/accessible/qaccessiblewidgetfactory_p.h b/src/widgets/accessible/qaccessiblewidgetfactory_p.h index b3f9d8a251..caa37dcf81 100644 --- a/src/widgets/accessible/qaccessiblewidgetfactory_p.h +++ b/src/widgets/accessible/qaccessiblewidgetfactory_p.h @@ -36,6 +36,17 @@ #ifndef QACCESSIBLEWIDGETFACTORY_H #define QACCESSIBLEWIDGETFACTORY_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + QT_BEGIN_NAMESPACE QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *object); diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp index a2bf14b25b..604c754ea1 100644 --- a/src/widgets/accessible/qaccessiblewidgets.cpp +++ b/src/widgets/accessible/qaccessiblewidgets.cpp @@ -31,7 +31,7 @@ ** ****************************************************************************/ -#include "qaccessiblewidgets.h" +#include "qaccessiblewidgets_p.h" #include "qabstracttextdocumentlayout.h" #include "qapplication.h" #include "qclipboard.h" diff --git a/src/widgets/accessible/qaccessiblewidgets.h b/src/widgets/accessible/qaccessiblewidgets.h deleted file mode 100644 index 53f8c2c603..0000000000 --- a/src/widgets/accessible/qaccessiblewidgets.h +++ /dev/null @@ -1,306 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QACCESSIBLEWIDGETS_H -#define QACCESSIBLEWIDGETS_H - -#include - -#ifndef QT_NO_ACCESSIBILITY - -#include -#include - -QT_BEGIN_NAMESPACE - -class QTextEdit; -class QStackedWidget; -class QToolBox; -class QMdiArea; -class QMdiSubWindow; -class QRubberBand; -class QTextBrowser; -class QCalendarWidget; -class QAbstractItemView; -class QDockWidget; -class QDockWidgetLayout; -class QMainWindow; -class QPlainTextEdit; -class QTextCursor; -class QTextDocument; - -#ifndef QT_NO_CURSOR -class QAccessibleTextWidget : public QAccessibleWidget, - public QAccessibleTextInterface, - public QAccessibleEditableTextInterface -{ -public: - QAccessibleTextWidget(QWidget *o, QAccessible::Role r = QAccessible::EditableText, const QString &name = QString()); - - QAccessible::State state() const Q_DECL_OVERRIDE; - - // QAccessibleTextInterface - // selection - void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - int selectionCount() const Q_DECL_OVERRIDE; - void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; - void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; - void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; - - // cursor - int cursorPosition() const Q_DECL_OVERRIDE; - void setCursorPosition(int position) Q_DECL_OVERRIDE; - - // text - QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; - QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - int characterCount() const Q_DECL_OVERRIDE; - - // character <-> geometry - QRect characterRect(int offset) const Q_DECL_OVERRIDE; - int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; - - QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - - // QAccessibleEditableTextInterface - void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; - void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; - void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; - - using QAccessibleWidget::text; - -protected: - QTextCursor textCursorForRange(int startOffset, int endOffset) const; - virtual QPoint scrollBarPosition() const; - // return the current text cursor at the caret position including a potential selection - virtual QTextCursor textCursor() const = 0; - virtual void setTextCursor(const QTextCursor &) = 0; - virtual QTextDocument *textDocument() const = 0; - virtual QWidget *viewport() const = 0; -}; - -#ifndef QT_NO_TEXTEDIT -class QAccessiblePlainTextEdit : public QAccessibleTextWidget -{ -public: - explicit QAccessiblePlainTextEdit(QWidget *o); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleTextInterface - void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; - - using QAccessibleTextWidget::text; - -protected: - QPlainTextEdit *plainTextEdit() const; - - QPoint scrollBarPosition() const Q_DECL_OVERRIDE; - QTextCursor textCursor() const Q_DECL_OVERRIDE; - void setTextCursor(const QTextCursor &textCursor) Q_DECL_OVERRIDE; - QTextDocument *textDocument() const Q_DECL_OVERRIDE; - QWidget *viewport() const Q_DECL_OVERRIDE; -}; - -class QAccessibleTextEdit : public QAccessibleTextWidget -{ -public: - explicit QAccessibleTextEdit(QWidget *o); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleTextInterface - void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; - - using QAccessibleTextWidget::text; - -protected: - QTextEdit *textEdit() const; - - QPoint scrollBarPosition() const Q_DECL_OVERRIDE; - QTextCursor textCursor() const Q_DECL_OVERRIDE; - void setTextCursor(const QTextCursor &textCursor) Q_DECL_OVERRIDE; - QTextDocument *textDocument() const Q_DECL_OVERRIDE; - QWidget *viewport() const Q_DECL_OVERRIDE; -}; -#endif // QT_NO_TEXTEDIT -#endif //QT_NO_CURSOR - -class QAccessibleStackedWidget : public QAccessibleWidget -{ -public: - explicit QAccessibleStackedWidget(QWidget *widget); - - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - -protected: - QStackedWidget *stackedWidget() const; -}; - -class QAccessibleToolBox : public QAccessibleWidget -{ -public: - explicit QAccessibleToolBox(QWidget *widget); - -// FIXME we currently expose the toolbox but it is not keyboard navigatable -// and the accessible hierarchy is not exactly beautiful. -// int childCount() const; -// QAccessibleInterface *child(int index) const; -// int indexOfChild(const QAccessibleInterface *child) const; - -protected: - QToolBox *toolBox() const; -}; - -#ifndef QT_NO_MDIAREA -class QAccessibleMdiArea : public QAccessibleWidget -{ -public: - explicit QAccessibleMdiArea(QWidget *widget); - - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - -protected: - QMdiArea *mdiArea() const; -}; - -class QAccessibleMdiSubWindow : public QAccessibleWidget -{ -public: - explicit QAccessibleMdiSubWindow(QWidget *widget); - - QString text(QAccessible::Text textType) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text textType, const QString &text) Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - -protected: - QMdiSubWindow *mdiSubWindow() const; -}; -#endif // QT_NO_MDIAREA - -class QAccessibleDialogButtonBox : public QAccessibleWidget -{ -public: - explicit QAccessibleDialogButtonBox(QWidget *widget); -}; - -#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) -class QAccessibleTextBrowser : public QAccessibleTextEdit -{ -public: - explicit QAccessibleTextBrowser(QWidget *widget); - - QAccessible::Role role() const Q_DECL_OVERRIDE; -}; -#endif // QT_NO_TEXTBROWSER && QT_NO_CURSOR - -#ifndef QT_NO_CALENDARWIDGET -class QAccessibleCalendarWidget : public QAccessibleWidget -{ -public: - explicit QAccessibleCalendarWidget(QWidget *widget); - - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - -protected: - QCalendarWidget *calendarWidget() const; - -private: - QAbstractItemView *calendarView() const; - QWidget *navigationBar() const; -}; -#endif // QT_NO_CALENDARWIDGET - -#ifndef QT_NO_DOCKWIDGET -class QAccessibleDockWidget: public QAccessibleWidget -{ -public: - explicit QAccessibleDockWidget(QWidget *widget); - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - QRect rect () const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - QDockWidget *dockWidget() const; -protected: - QDockWidgetLayout *dockWidgetLayout() const; -}; - -#endif // QT_NO_DOCKWIDGET - -#ifndef QT_NO_MAINWINDOW -class QAccessibleMainWindow : public QAccessibleWidget -{ -public: - explicit QAccessibleMainWindow(QWidget *widget); - - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *iface) const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - QMainWindow *mainWindow() const; - -}; -#endif //QT_NO_MAINWINDOW - -#endif // QT_NO_ACCESSIBILITY - -QT_END_NAMESPACE - -#endif // QACESSIBLEWIDGETS_H diff --git a/src/widgets/accessible/qaccessiblewidgets_p.h b/src/widgets/accessible/qaccessiblewidgets_p.h new file mode 100644 index 0000000000..4bdc229578 --- /dev/null +++ b/src/widgets/accessible/qaccessiblewidgets_p.h @@ -0,0 +1,317 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QACCESSIBLEWIDGETS_H +#define QACCESSIBLEWIDGETS_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#ifndef QT_NO_ACCESSIBILITY + +#include +#include + +QT_BEGIN_NAMESPACE + +class QTextEdit; +class QStackedWidget; +class QToolBox; +class QMdiArea; +class QMdiSubWindow; +class QRubberBand; +class QTextBrowser; +class QCalendarWidget; +class QAbstractItemView; +class QDockWidget; +class QDockWidgetLayout; +class QMainWindow; +class QPlainTextEdit; +class QTextCursor; +class QTextDocument; + +#ifndef QT_NO_CURSOR +class QAccessibleTextWidget : public QAccessibleWidget, + public QAccessibleTextInterface, + public QAccessibleEditableTextInterface +{ +public: + QAccessibleTextWidget(QWidget *o, QAccessible::Role r = QAccessible::EditableText, const QString &name = QString()); + + QAccessible::State state() const Q_DECL_OVERRIDE; + + // QAccessibleTextInterface + // selection + void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + int selectionCount() const Q_DECL_OVERRIDE; + void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; + void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; + void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; + + // cursor + int cursorPosition() const Q_DECL_OVERRIDE; + void setCursorPosition(int position) Q_DECL_OVERRIDE; + + // text + QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; + QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + int characterCount() const Q_DECL_OVERRIDE; + + // character <-> geometry + QRect characterRect(int offset) const Q_DECL_OVERRIDE; + int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; + + QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + + // QAccessibleEditableTextInterface + void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; + void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; + void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; + + using QAccessibleWidget::text; + +protected: + QTextCursor textCursorForRange(int startOffset, int endOffset) const; + virtual QPoint scrollBarPosition() const; + // return the current text cursor at the caret position including a potential selection + virtual QTextCursor textCursor() const = 0; + virtual void setTextCursor(const QTextCursor &) = 0; + virtual QTextDocument *textDocument() const = 0; + virtual QWidget *viewport() const = 0; +}; + +#ifndef QT_NO_TEXTEDIT +class QAccessiblePlainTextEdit : public QAccessibleTextWidget +{ +public: + explicit QAccessiblePlainTextEdit(QWidget *o); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleTextInterface + void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; + + using QAccessibleTextWidget::text; + +protected: + QPlainTextEdit *plainTextEdit() const; + + QPoint scrollBarPosition() const Q_DECL_OVERRIDE; + QTextCursor textCursor() const Q_DECL_OVERRIDE; + void setTextCursor(const QTextCursor &textCursor) Q_DECL_OVERRIDE; + QTextDocument *textDocument() const Q_DECL_OVERRIDE; + QWidget *viewport() const Q_DECL_OVERRIDE; +}; + +class QAccessibleTextEdit : public QAccessibleTextWidget +{ +public: + explicit QAccessibleTextEdit(QWidget *o); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleTextInterface + void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; + + using QAccessibleTextWidget::text; + +protected: + QTextEdit *textEdit() const; + + QPoint scrollBarPosition() const Q_DECL_OVERRIDE; + QTextCursor textCursor() const Q_DECL_OVERRIDE; + void setTextCursor(const QTextCursor &textCursor) Q_DECL_OVERRIDE; + QTextDocument *textDocument() const Q_DECL_OVERRIDE; + QWidget *viewport() const Q_DECL_OVERRIDE; +}; +#endif // QT_NO_TEXTEDIT +#endif //QT_NO_CURSOR + +class QAccessibleStackedWidget : public QAccessibleWidget +{ +public: + explicit QAccessibleStackedWidget(QWidget *widget); + + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + +protected: + QStackedWidget *stackedWidget() const; +}; + +class QAccessibleToolBox : public QAccessibleWidget +{ +public: + explicit QAccessibleToolBox(QWidget *widget); + +// FIXME we currently expose the toolbox but it is not keyboard navigatable +// and the accessible hierarchy is not exactly beautiful. +// int childCount() const; +// QAccessibleInterface *child(int index) const; +// int indexOfChild(const QAccessibleInterface *child) const; + +protected: + QToolBox *toolBox() const; +}; + +#ifndef QT_NO_MDIAREA +class QAccessibleMdiArea : public QAccessibleWidget +{ +public: + explicit QAccessibleMdiArea(QWidget *widget); + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + +protected: + QMdiArea *mdiArea() const; +}; + +class QAccessibleMdiSubWindow : public QAccessibleWidget +{ +public: + explicit QAccessibleMdiSubWindow(QWidget *widget); + + QString text(QAccessible::Text textType) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text textType, const QString &text) Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + +protected: + QMdiSubWindow *mdiSubWindow() const; +}; +#endif // QT_NO_MDIAREA + +class QAccessibleDialogButtonBox : public QAccessibleWidget +{ +public: + explicit QAccessibleDialogButtonBox(QWidget *widget); +}; + +#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) +class QAccessibleTextBrowser : public QAccessibleTextEdit +{ +public: + explicit QAccessibleTextBrowser(QWidget *widget); + + QAccessible::Role role() const Q_DECL_OVERRIDE; +}; +#endif // QT_NO_TEXTBROWSER && QT_NO_CURSOR + +#ifndef QT_NO_CALENDARWIDGET +class QAccessibleCalendarWidget : public QAccessibleWidget +{ +public: + explicit QAccessibleCalendarWidget(QWidget *widget); + + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + +protected: + QCalendarWidget *calendarWidget() const; + +private: + QAbstractItemView *calendarView() const; + QWidget *navigationBar() const; +}; +#endif // QT_NO_CALENDARWIDGET + +#ifndef QT_NO_DOCKWIDGET +class QAccessibleDockWidget: public QAccessibleWidget +{ +public: + explicit QAccessibleDockWidget(QWidget *widget); + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + QRect rect () const Q_DECL_OVERRIDE; + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + QDockWidget *dockWidget() const; +protected: + QDockWidgetLayout *dockWidgetLayout() const; +}; + +#endif // QT_NO_DOCKWIDGET + +#ifndef QT_NO_MAINWINDOW +class QAccessibleMainWindow : public QAccessibleWidget +{ +public: + explicit QAccessibleMainWindow(QWidget *widget); + + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *iface) const Q_DECL_OVERRIDE; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; + QMainWindow *mainWindow() const; + +}; +#endif //QT_NO_MAINWINDOW + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // QACESSIBLEWIDGETS_H diff --git a/src/widgets/accessible/rangecontrols.cpp b/src/widgets/accessible/rangecontrols.cpp index 002d4a9ef4..0607a35269 100644 --- a/src/widgets/accessible/rangecontrols.cpp +++ b/src/widgets/accessible/rangecontrols.cpp @@ -31,7 +31,7 @@ ** ****************************************************************************/ -#include "rangecontrols.h" +#include "rangecontrols_p.h" #include #include @@ -47,7 +47,7 @@ #include #include -#include "simplewidgets.h" // let spinbox use line edit's interface +#include "simplewidgets_p.h" // let spinbox use line edit's interface QT_BEGIN_NAMESPACE diff --git a/src/widgets/accessible/rangecontrols.h b/src/widgets/accessible/rangecontrols.h deleted file mode 100644 index 11d4435e9d..0000000000 --- a/src/widgets/accessible/rangecontrols.h +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef RANGECONTROLS_H -#define RANGECONTROLS_H - -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ACCESSIBILITY - -class QAbstractSpinBox; -class QAbstractSlider; -class QScrollBar; -class QSlider; -class QSpinBox; -class QDoubleSpinBox; -class QDial; -class QAccessibleLineEdit; - -#ifndef QT_NO_SPINBOX -class QAccessibleAbstractSpinBox: - public QAccessibleWidget, - public QAccessibleValueInterface, - public QAccessibleTextInterface, - public QAccessibleEditableTextInterface -{ -public: - explicit QAccessibleAbstractSpinBox(QWidget *w); - virtual ~QAccessibleAbstractSpinBox(); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleValueInterface - QVariant currentValue() const Q_DECL_OVERRIDE; - void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE; - QVariant maximumValue() const Q_DECL_OVERRIDE; - QVariant minimumValue() const Q_DECL_OVERRIDE; - QVariant minimumStepSize() const Q_DECL_OVERRIDE; - - // QAccessibleTextInterface - void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; - QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - int cursorPosition() const Q_DECL_OVERRIDE; - QRect characterRect(int offset) const Q_DECL_OVERRIDE; - int selectionCount() const Q_DECL_OVERRIDE; - int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; - void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; - QString textBeforeOffset (int offset, QAccessible::TextBoundaryType boundaryType, - int *endOffset, int *startOffset) const Q_DECL_OVERRIDE; - QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; - void setCursorPosition(int position) Q_DECL_OVERRIDE; - void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; - int characterCount() const Q_DECL_OVERRIDE; - void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; - - // QAccessibleEditableTextInterface - void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; - void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; - void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; - -protected: - QAbstractSpinBox *abstractSpinBox() const; - QAccessibleInterface *lineEditIface() const; -private: - mutable QAccessibleLineEdit *lineEdit; -}; - -class QAccessibleSpinBox : public QAccessibleAbstractSpinBox -{ -public: - explicit QAccessibleSpinBox(QWidget *w); - -protected: - QSpinBox *spinBox() const; -}; - -class QAccessibleDoubleSpinBox : public QAccessibleAbstractSpinBox -{ -public: - explicit QAccessibleDoubleSpinBox(QWidget *widget); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - using QAccessibleAbstractSpinBox::text; -protected: - QDoubleSpinBox *doubleSpinBox() const; -}; -#endif // QT_NO_SPINBOX - -class QAccessibleAbstractSlider: public QAccessibleWidget, public QAccessibleValueInterface -{ -public: - explicit QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r = QAccessible::Slider); - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleValueInterface - QVariant currentValue() const Q_DECL_OVERRIDE; - void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE; - QVariant maximumValue() const Q_DECL_OVERRIDE; - QVariant minimumValue() const Q_DECL_OVERRIDE; - QVariant minimumStepSize() const Q_DECL_OVERRIDE; - -protected: - QAbstractSlider *abstractSlider() const; -}; - -#ifndef QT_NO_SCROLLBAR -class QAccessibleScrollBar : public QAccessibleAbstractSlider -{ -public: - explicit QAccessibleScrollBar(QWidget *w); - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - -protected: - QScrollBar *scrollBar() const; -}; -#endif // QT_NO_SCROLLBAR - -#ifndef QT_NO_SLIDER -class QAccessibleSlider : public QAccessibleAbstractSlider -{ -public: - explicit QAccessibleSlider(QWidget *w); - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - -protected: - QSlider *slider() const; -}; -#endif // QT_NO_SLIDER - -#ifndef QT_NO_DIAL -class QAccessibleDial : public QAccessibleAbstractSlider -{ -public: - explicit QAccessibleDial(QWidget *w); - - QString text(QAccessible::Text textType) const Q_DECL_OVERRIDE; - -protected: - QDial *dial() const; -}; -#endif // QT_NO_DIAL - -#endif // QT_NO_ACCESSIBILITY - -QT_END_NAMESPACE - -#endif // RANGECONTROLS_H diff --git a/src/widgets/accessible/rangecontrols_p.h b/src/widgets/accessible/rangecontrols_p.h new file mode 100644 index 0000000000..32c6d6985f --- /dev/null +++ b/src/widgets/accessible/rangecontrols_p.h @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RANGECONTROLS_H +#define RANGECONTROLS_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY + +class QAbstractSpinBox; +class QAbstractSlider; +class QScrollBar; +class QSlider; +class QSpinBox; +class QDoubleSpinBox; +class QDial; +class QAccessibleLineEdit; + +#ifndef QT_NO_SPINBOX +class QAccessibleAbstractSpinBox: + public QAccessibleWidget, + public QAccessibleValueInterface, + public QAccessibleTextInterface, + public QAccessibleEditableTextInterface +{ +public: + explicit QAccessibleAbstractSpinBox(QWidget *w); + virtual ~QAccessibleAbstractSpinBox(); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleValueInterface + QVariant currentValue() const Q_DECL_OVERRIDE; + void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE; + QVariant maximumValue() const Q_DECL_OVERRIDE; + QVariant minimumValue() const Q_DECL_OVERRIDE; + QVariant minimumStepSize() const Q_DECL_OVERRIDE; + + // QAccessibleTextInterface + void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; + QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + int cursorPosition() const Q_DECL_OVERRIDE; + QRect characterRect(int offset) const Q_DECL_OVERRIDE; + int selectionCount() const Q_DECL_OVERRIDE; + int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; + void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; + QString textBeforeOffset (int offset, QAccessible::TextBoundaryType boundaryType, + int *endOffset, int *startOffset) const Q_DECL_OVERRIDE; + QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; + void setCursorPosition(int position) Q_DECL_OVERRIDE; + void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; + int characterCount() const Q_DECL_OVERRIDE; + void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; + + // QAccessibleEditableTextInterface + void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; + void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; + void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; + +protected: + QAbstractSpinBox *abstractSpinBox() const; + QAccessibleInterface *lineEditIface() const; +private: + mutable QAccessibleLineEdit *lineEdit; +}; + +class QAccessibleSpinBox : public QAccessibleAbstractSpinBox +{ +public: + explicit QAccessibleSpinBox(QWidget *w); + +protected: + QSpinBox *spinBox() const; +}; + +class QAccessibleDoubleSpinBox : public QAccessibleAbstractSpinBox +{ +public: + explicit QAccessibleDoubleSpinBox(QWidget *widget); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + using QAccessibleAbstractSpinBox::text; +protected: + QDoubleSpinBox *doubleSpinBox() const; +}; +#endif // QT_NO_SPINBOX + +class QAccessibleAbstractSlider: public QAccessibleWidget, public QAccessibleValueInterface +{ +public: + explicit QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r = QAccessible::Slider); + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleValueInterface + QVariant currentValue() const Q_DECL_OVERRIDE; + void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE; + QVariant maximumValue() const Q_DECL_OVERRIDE; + QVariant minimumValue() const Q_DECL_OVERRIDE; + QVariant minimumStepSize() const Q_DECL_OVERRIDE; + +protected: + QAbstractSlider *abstractSlider() const; +}; + +#ifndef QT_NO_SCROLLBAR +class QAccessibleScrollBar : public QAccessibleAbstractSlider +{ +public: + explicit QAccessibleScrollBar(QWidget *w); + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + +protected: + QScrollBar *scrollBar() const; +}; +#endif // QT_NO_SCROLLBAR + +#ifndef QT_NO_SLIDER +class QAccessibleSlider : public QAccessibleAbstractSlider +{ +public: + explicit QAccessibleSlider(QWidget *w); + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + +protected: + QSlider *slider() const; +}; +#endif // QT_NO_SLIDER + +#ifndef QT_NO_DIAL +class QAccessibleDial : public QAccessibleAbstractSlider +{ +public: + explicit QAccessibleDial(QWidget *w); + + QString text(QAccessible::Text textType) const Q_DECL_OVERRIDE; + +protected: + QDial *dial() const; +}; +#endif // QT_NO_DIAL + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // RANGECONTROLS_H diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp index b08c21939a..065c618cf7 100644 --- a/src/widgets/accessible/simplewidgets.cpp +++ b/src/widgets/accessible/simplewidgets.cpp @@ -31,7 +31,7 @@ ** ****************************************************************************/ -#include "simplewidgets.h" +#include "simplewidgets_p.h" #include #include diff --git a/src/widgets/accessible/simplewidgets.h b/src/widgets/accessible/simplewidgets.h deleted file mode 100644 index 0dfd9f79c8..0000000000 --- a/src/widgets/accessible/simplewidgets.h +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SIMPLEWIDGETS_H -#define SIMPLEWIDGETS_H - -#include -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ACCESSIBILITY - -class QAbstractButton; -class QLineEdit; -class QToolButton; -class QGroupBox; -class QProgressBar; - -class QAccessibleButton : public QAccessibleWidget -{ - Q_DECLARE_TR_FUNCTIONS(QAccessibleButton) -public: - QAccessibleButton(QWidget *w); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QRect rect() const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - - QStringList actionNames() const Q_DECL_OVERRIDE; - void doAction(const QString &actionName) Q_DECL_OVERRIDE; - QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; - -protected: - QAbstractButton *button() const; -}; - -#ifndef QT_NO_TOOLBUTTON -class QAccessibleToolButton : public QAccessibleButton -{ -public: - QAccessibleToolButton(QWidget *w); - - QAccessible::State state() const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - - // QAccessibleActionInterface - QStringList actionNames() const Q_DECL_OVERRIDE; - void doAction(const QString &actionName) Q_DECL_OVERRIDE; - -protected: - QToolButton *toolButton() const; - - bool isSplitButton() const; -}; -#endif // QT_NO_TOOLBUTTON - -class QAccessibleDisplay : public QAccessibleWidget, public QAccessibleImageInterface -{ -public: - explicit QAccessibleDisplay(QWidget *w, QAccessible::Role role = QAccessible::StaticText); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - - QVector >relations(QAccessible::Relation match = QAccessible::AllRelations) const Q_DECL_OVERRIDE; - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleImageInterface - QString imageDescription() const Q_DECL_OVERRIDE; - QSize imageSize() const Q_DECL_OVERRIDE; - QPoint imagePosition() const Q_DECL_OVERRIDE; -}; - -#ifndef QT_NO_GROUPBOX -class QAccessibleGroupBox : public QAccessibleWidget -{ -public: - explicit QAccessibleGroupBox(QWidget *w); - - QAccessible::State state() const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - - QVector >relations(QAccessible::Relation match = QAccessible::AllRelations) const Q_DECL_OVERRIDE; - - //QAccessibleActionInterface - QStringList actionNames() const Q_DECL_OVERRIDE; - void doAction(const QString &actionName) Q_DECL_OVERRIDE; - QStringList keyBindingsForAction(const QString &) const Q_DECL_OVERRIDE; - -private: - QGroupBox *groupBox() const; -}; -#endif - -#ifndef QT_NO_LINEEDIT -class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface, public QAccessibleEditableTextInterface -{ -public: - explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString()); - - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleTextInterface - void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; - QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - int cursorPosition() const Q_DECL_OVERRIDE; - QRect characterRect(int offset) const Q_DECL_OVERRIDE; - int selectionCount() const Q_DECL_OVERRIDE; - int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; - void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; - QString textBeforeOffset (int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; - void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; - void setCursorPosition(int position) Q_DECL_OVERRIDE; - void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; - int characterCount() const Q_DECL_OVERRIDE; - void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; - - // QAccessibleEditableTextInterface - void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; - void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; - void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; -protected: - QLineEdit *lineEdit() const; - friend class QAccessibleAbstractSpinBox; -}; -#endif // QT_NO_LINEEDIT - -#ifndef QT_NO_PROGRESSBAR -class QAccessibleProgressBar : public QAccessibleDisplay, public QAccessibleValueInterface -{ -public: - explicit QAccessibleProgressBar(QWidget *o); - void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; - - // QAccessibleValueInterface - QVariant currentValue() const Q_DECL_OVERRIDE; - QVariant maximumValue() const Q_DECL_OVERRIDE; - QVariant minimumValue() const Q_DECL_OVERRIDE; - QVariant minimumStepSize() const Q_DECL_OVERRIDE; - void setCurrentValue(const QVariant &) Q_DECL_OVERRIDE {} - -protected: - QProgressBar *progressBar() const; -}; -#endif - -class QWindowContainer; -class QAccessibleWindowContainer : public QAccessibleWidget -{ -public: - QAccessibleWindowContainer(QWidget *w); - int childCount() const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int i) const Q_DECL_OVERRIDE; - -private: - QWindowContainer *container() const; -}; - -#endif // QT_NO_ACCESSIBILITY - -QT_END_NAMESPACE - -#endif // SIMPLEWIDGETS_H diff --git a/src/widgets/accessible/simplewidgets_p.h b/src/widgets/accessible/simplewidgets_p.h new file mode 100644 index 0000000000..c2e904273f --- /dev/null +++ b/src/widgets/accessible/simplewidgets_p.h @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SIMPLEWIDGETS_H +#define SIMPLEWIDGETS_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY + +class QAbstractButton; +class QLineEdit; +class QToolButton; +class QGroupBox; +class QProgressBar; + +class QAccessibleButton : public QAccessibleWidget +{ + Q_DECLARE_TR_FUNCTIONS(QAccessibleButton) +public: + QAccessibleButton(QWidget *w); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + + QStringList actionNames() const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; + +protected: + QAbstractButton *button() const; +}; + +#ifndef QT_NO_TOOLBUTTON +class QAccessibleToolButton : public QAccessibleButton +{ +public: + QAccessibleToolButton(QWidget *w); + + QAccessible::State state() const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + + // QAccessibleActionInterface + QStringList actionNames() const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + +protected: + QToolButton *toolButton() const; + + bool isSplitButton() const; +}; +#endif // QT_NO_TOOLBUTTON + +class QAccessibleDisplay : public QAccessibleWidget, public QAccessibleImageInterface +{ +public: + explicit QAccessibleDisplay(QWidget *w, QAccessible::Role role = QAccessible::StaticText); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + + QVector >relations(QAccessible::Relation match = QAccessible::AllRelations) const Q_DECL_OVERRIDE; + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleImageInterface + QString imageDescription() const Q_DECL_OVERRIDE; + QSize imageSize() const Q_DECL_OVERRIDE; + QPoint imagePosition() const Q_DECL_OVERRIDE; +}; + +#ifndef QT_NO_GROUPBOX +class QAccessibleGroupBox : public QAccessibleWidget +{ +public: + explicit QAccessibleGroupBox(QWidget *w); + + QAccessible::State state() const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + + QVector >relations(QAccessible::Relation match = QAccessible::AllRelations) const Q_DECL_OVERRIDE; + + //QAccessibleActionInterface + QStringList actionNames() const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + QStringList keyBindingsForAction(const QString &) const Q_DECL_OVERRIDE; + +private: + QGroupBox *groupBox() const; +}; +#endif + +#ifndef QT_NO_LINEEDIT +class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface, public QAccessibleEditableTextInterface +{ +public: + explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString()); + + QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; + QAccessible::State state() const Q_DECL_OVERRIDE; + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleTextInterface + void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; + QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + int cursorPosition() const Q_DECL_OVERRIDE; + QRect characterRect(int offset) const Q_DECL_OVERRIDE; + int selectionCount() const Q_DECL_OVERRIDE; + int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; + void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; + QString textBeforeOffset (int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; + void setCursorPosition(int position) Q_DECL_OVERRIDE; + void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; + int characterCount() const Q_DECL_OVERRIDE; + void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; + + // QAccessibleEditableTextInterface + void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; + void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; + void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; +protected: + QLineEdit *lineEdit() const; + friend class QAccessibleAbstractSpinBox; +}; +#endif // QT_NO_LINEEDIT + +#ifndef QT_NO_PROGRESSBAR +class QAccessibleProgressBar : public QAccessibleDisplay, public QAccessibleValueInterface +{ +public: + explicit QAccessibleProgressBar(QWidget *o); + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; + + // QAccessibleValueInterface + QVariant currentValue() const Q_DECL_OVERRIDE; + QVariant maximumValue() const Q_DECL_OVERRIDE; + QVariant minimumValue() const Q_DECL_OVERRIDE; + QVariant minimumStepSize() const Q_DECL_OVERRIDE; + void setCurrentValue(const QVariant &) Q_DECL_OVERRIDE {} + +protected: + QProgressBar *progressBar() const; +}; +#endif + +class QWindowContainer; +class QAccessibleWindowContainer : public QAccessibleWidget +{ +public: + QAccessibleWindowContainer(QWidget *w); + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int i) const Q_DECL_OVERRIDE; + +private: + QWindowContainer *container() const; +}; + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // SIMPLEWIDGETS_H -- cgit v1.2.3 From d05bb9ffb05be57b9ef8e961cc17111b1bdaffc8 Mon Sep 17 00:00:00 2001 From: Jonathan Meier Date: Sat, 5 Sep 2015 11:38:56 +0200 Subject: Fix qmake messing up headers of generated Visual Studio solution files While generating Visual Studio 2015 solution files for a project using the subdirs template qmake writes out both the header for version 2015 and version 2013. The problem is a case fall-through. Task-number: QTBUG-48110 Change-Id: Ib6ddc1ceb306be9b3098d7b7c66a8ffabbd86481 Reviewed-by: J-P Nurmi Reviewed-by: Andrew Knight Reviewed-by: Joerg Bornemann --- qmake/generators/win32/msvc_vcproj.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 8e08ab248e..9acfa6588b 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -655,6 +655,7 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { case NET2015: t << _slnHeader140; + break; case NET2013: t << _slnHeader120; break; -- cgit v1.2.3 From 1b29ef627ce8e69dbe2daae73bc6a9f57b631b3d Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Wed, 29 Jul 2015 13:33:51 +1000 Subject: Fix hang in qnam when disconnecting Generate error for network requests when connection gets disconnected. Documentation states that QNAM requests will fail if network is not accessible, so we need to track session state. Task-number: QTBUG-47482 Change-Id: I2c2d348637f72b2a908b438a66aa543a878de1e5 Reviewed-by: Timo Jyrinki Reviewed-by: Richard J. Moore --- src/network/access/qnetworkreplyhttpimpl.cpp | 15 +++++++++++++++ src/network/access/qnetworkreplyhttpimpl_p.h | 2 ++ src/network/access/qnetworkreplyimpl.cpp | 15 +++++++++++++++ src/network/access/qnetworkreplyimpl_p.h | 2 ++ 4 files changed, 34 insertions(+) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index abc6603be2..c1956ae99f 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1676,6 +1676,11 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "backend start error."))); QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); return; +#endif + } else { +#ifndef QT_NO_BEARERMANAGEMENT + QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), + q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); #endif } @@ -1844,6 +1849,16 @@ void QNetworkReplyHttpImplPrivate::_q_networkSessionConnected() } } +void QNetworkReplyHttpImplPrivate::_q_networkSessionStateChanged(QNetworkSession::State sessionState) +{ + if (sessionState == QNetworkSession::Disconnected + && (state != Idle || state != Reconnecting)) { + error(QNetworkReplyImpl::NetworkSessionFailedError, + QCoreApplication::translate("QNetworkReply", "Network session error.")); + finished(); + } +} + void QNetworkReplyHttpImplPrivate::_q_networkSessionFailed() { // Abort waiting and working replies. diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h index b009092196..cfc05edbd8 100644 --- a/src/network/access/qnetworkreplyhttpimpl_p.h +++ b/src/network/access/qnetworkreplyhttpimpl_p.h @@ -95,6 +95,7 @@ public: #ifndef QT_NO_BEARERMANAGEMENT Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed()) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies)) #endif Q_PRIVATE_SLOT(d_func(), void _q_finished()) @@ -170,6 +171,7 @@ public: #ifndef QT_NO_BEARERMANAGEMENT void _q_networkSessionConnected(); void _q_networkSessionFailed(); + void _q_networkSessionStateChanged(QNetworkSession::State); void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies); #endif void _q_finished(); diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index f235adaee8..18f322f45d 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -126,6 +126,11 @@ void QNetworkReplyImplPrivate::_q_startOperation() finished(); #endif return; + } else { +#ifndef QT_NO_BEARERMANAGEMENT + QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), + q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); +#endif } #ifndef QT_NO_BEARERMANAGEMENT @@ -310,6 +315,16 @@ void QNetworkReplyImplPrivate::_q_networkSessionConnected() } } +void QNetworkReplyImplPrivate::_q_networkSessionStateChanged(QNetworkSession::State sessionState) +{ + if (sessionState == QNetworkSession::Disconnected + && (state != Idle || state != Reconnecting)) { + error(QNetworkReplyImpl::NetworkSessionFailedError, + QCoreApplication::translate("QNetworkReply", "Network session error.")); + finished(); + } +} + void QNetworkReplyImplPrivate::_q_networkSessionFailed() { // Abort waiting and working replies. diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index d2e7d02408..5883c9d1c3 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -89,6 +89,7 @@ public: #ifndef QT_NO_BEARERMANAGEMENT Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed()) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies)) #endif @@ -124,6 +125,7 @@ public: #ifndef QT_NO_BEARERMANAGEMENT void _q_networkSessionConnected(); void _q_networkSessionFailed(); + void _q_networkSessionStateChanged(QNetworkSession::State); void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies); #endif -- cgit v1.2.3 From c258422cf9962b994505030b7cc9bb00d22b7bf8 Mon Sep 17 00:00:00 2001 From: Tuomas Heimonen Date: Tue, 8 Sep 2015 14:52:21 +0300 Subject: tst_QProcess_and_GuiEventLoop: Added flag QT_NO_PROCESS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I895b9c12de8734c20ec87ac30a9a9cca8f4242d7 Reviewed-by: Pasi Petäjäjärvi Reviewed-by: Thiago Macieira --- .../qprocess_and_guieventloop/tst_qprocess_and_guieventloop.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/other/qprocess_and_guieventloop/tst_qprocess_and_guieventloop.cpp b/tests/auto/other/qprocess_and_guieventloop/tst_qprocess_and_guieventloop.cpp index 53459b13f6..b79b3aba28 100644 --- a/tests/auto/other/qprocess_and_guieventloop/tst_qprocess_and_guieventloop.cpp +++ b/tests/auto/other/qprocess_and_guieventloop/tst_qprocess_and_guieventloop.cpp @@ -45,9 +45,11 @@ private slots: void tst_QProcess_and_GuiEventLoop::waitForAndEventLoop() { -#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) +#if defined(QT_NO_PROCESS) + QSKIP("QProcess not supported"); +#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) QSKIP("Not supported on Android"); -#endif +#else // based on testcase provided in QTBUG-39488 QByteArray msg = "Hello World"; @@ -78,6 +80,7 @@ void tst_QProcess_and_GuiEventLoop::waitForAndEventLoop() QCOMPARE(process.exitCode(), 0); QCOMPARE(spy.count(), 1); QCOMPARE(process.readAll().trimmed(), msg); +#endif } QTEST_MAIN(tst_QProcess_and_GuiEventLoop) -- cgit v1.2.3 From 4b2db07b42dc0be28beafbd20d005cc0b7b11fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Pet=C3=A4j=C3=A4j=C3=A4rvi?= Date: Wed, 9 Sep 2015 15:45:18 +0300 Subject: Fix tst_QGuiApplication for embedded platforms using eglfs QPA Disable input and cursor for QGuiApplication instances used in autotest to initialize it properly. Change-Id: I78dc9b776269c082c20f244a51f858289129275d Reviewed-by: Laszlo Agocs --- .../kernel/qcoreapplication/tst_qcoreapplication.cpp | 5 ----- .../gui/kernel/qguiapplication/tst_qguiapplication.cpp | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index efecf31d66..60e358232e 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -41,12 +41,7 @@ #include #include -#ifdef QT_GUI_LIB -#include -typedef QGuiApplication TestApplication; -#else typedef QCoreApplication TestApplication; -#endif class EventSpy : public QObject { diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index 19365bffdd..d573d97495 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -60,6 +60,7 @@ class tst_QGuiApplication: public tst_QCoreApplication Q_OBJECT private slots: + void initTestCase(); void cleanup(); void displayName(); void firstWindowTitle(); @@ -84,6 +85,21 @@ private slots: void settableStyleHints(); // Needs to run last as it changes style hints. }; +void tst_QGuiApplication::initTestCase() +{ +#ifdef QT_QPA_DEFAULT_PLATFORM_NAME + if ((QString::compare(QStringLiteral(QT_QPA_DEFAULT_PLATFORM_NAME), + QStringLiteral("eglfs"), Qt::CaseInsensitive) == 0) || + (QString::compare(QString::fromLatin1(qgetenv("QT_QPA_PLATFORM")), + QStringLiteral("eglfs"), Qt::CaseInsensitive) == 0)) { + // Set env variables to disable input and cursor because eglfs is single fullscreen window + // and trying to initialize input and cursor will crash test. + qputenv("QT_QPA_EGLFS_DISABLE_INPUT", "1"); + qputenv("QT_QPA_EGLFS_HIDECURSOR", "1"); + } +#endif +} + void tst_QGuiApplication::cleanup() { QVERIFY(QGuiApplication::allWindows().isEmpty()); -- cgit v1.2.3 From d75505faccc9a86d9e76932ae022b660e01ad1a5 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 8 Sep 2015 13:38:41 +0200 Subject: iOS: silence compiler warning about unimplemented 'selectionRectsForRange' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement a dummy method to silence the compiler. After testing, this method seems to never be called. Which is good, since the current IM API in Qt have little to offer to resolve what is being asked. Until a need arise, we just return an empty array. Change-Id: I573eb8205a7e635a46d487ae175fb46e3a602001 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiostextresponder.mm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 4e109f6921..c9120e848c 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -738,6 +738,15 @@ return toCGRect(startRect.united(endRect)); } +- (NSArray *)selectionRectsForRange:(UITextRange *)range +{ + Q_UNUSED(range); + // This method is supposed to return a rectangle for each line with selection. Since we don't + // expose an API in Qt/IM for getting this information, and since we never seems to be getting + // a call from UIKit for this, we return an empty array until a need arise. + return [[NSArray new] autorelease]; +} + - (CGRect)caretRectForPosition:(UITextPosition *)position { Q_UNUSED(position); -- cgit v1.2.3 From 378e26dd14df808a55471330400984841ef414d4 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Wed, 11 Feb 2015 20:02:07 +0200 Subject: QUdpSocket: avoid infinite read notifier blocking There was a small amount of time between the last readDatagram() call and disabling a read notifier in case the socket had a pending datagram. If a new datagram arrived in this period, this qualified as absence of a datagram reader. Do not change the read notifier state because it is disabled on canReadNotification() entry and always enabled by the datagram reader. Thanks to Peter Seiderer, who investigated the same: "Querying hasPendingDatagrams() for enabling/disabling setReadNotificationEnabled() is racy (a new datagram could arrive after readDatagam() is called and before hasPendingDatagrams() is checked). But for unbuffered sockets the ReadNotification is already disabled before the readReady signal is emitted and should be re-enabled when calling read() or readDatagram() from the user." However, this patch does not completely solve the problem under Windows, as the socket notifier may emit spurious notifications. Task-number: QTBUG-46552 Change-Id: If7295d53ae2c788c39e86303502f38135c4d6180 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/network/socket/qabstractsocket.cpp | 12 ++--- .../network/socket/qudpsocket/tst_qudpsocket.cpp | 54 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index c42b4f520c..d93150799c 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -739,15 +739,9 @@ bool QAbstractSocketPrivate::canReadNotification() return true; } - if (socketEngine) { - // turn the socket engine off if we've either: - // - got pending datagrams - // - reached the buffer size limit - if (isBuffered) - socketEngine->setReadNotificationEnabled(readBufferMaxSize == 0 || readBufferMaxSize > q->bytesAvailable()); - else if (socketType != QAbstractSocket::TcpSocket) - socketEngine->setReadNotificationEnabled(!socketEngine->hasPendingDatagrams()); - } + // turn the socket engine off if we've reached the buffer size limit + if (socketEngine && isBuffered) + socketEngine->setReadNotificationEnabled(readBufferMaxSize == 0 || readBufferMaxSize > q->bytesAvailable()); // reset the read socket notifier state if we reentered inside the // readyRead() connected slot. diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index b6129bec08..a4695955af 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -116,10 +116,12 @@ private slots: void linkLocalIPv4(); void readyRead(); void readyReadForEmptyDatagram(); + void asyncReadDatagram(); protected slots: void empty_readyReadSlot(); void empty_connectedSlot(); + void async_readDatagramSlot(); private: #ifndef QT_NO_BEARERMANAGEMENT @@ -127,6 +129,8 @@ private: QNetworkConfiguration networkConfiguration; QSharedPointer networkSession; #endif + QUdpSocket *m_asyncSender; + QUdpSocket *m_asyncReceiver; }; static QHostAddress makeNonAny(const QHostAddress &address, QHostAddress::SpecialAddress preferForAny = QHostAddress::LocalHost) @@ -1671,5 +1675,55 @@ void tst_QUdpSocket::readyReadForEmptyDatagram() QCOMPARE(receiver.readDatagram(buf, sizeof buf), qint64(0)); } +void tst_QUdpSocket::async_readDatagramSlot() +{ + char buf[1]; + QVERIFY(m_asyncReceiver->hasPendingDatagrams()); + QCOMPARE(m_asyncReceiver->pendingDatagramSize(), qint64(1)); + QCOMPARE(m_asyncReceiver->bytesAvailable(), qint64(1)); + QCOMPARE(m_asyncReceiver->readDatagram(buf, sizeof(buf)), qint64(1)); + + if (buf[0] == '2') { + QTestEventLoop::instance().exitLoop(); + return; + } + + m_asyncSender->writeDatagram("2", makeNonAny(m_asyncReceiver->localAddress()), m_asyncReceiver->localPort()); + // wait a little to ensure that the datagram we've just sent + // will be delivered on receiver side. + QTest::qSleep(100); +} + +void tst_QUdpSocket::asyncReadDatagram() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + m_asyncSender = new QUdpSocket; + m_asyncReceiver = new QUdpSocket; +#ifdef FORCE_SESSION + m_asyncSender->setProperty("_q_networksession", QVariant::fromValue(networkSession)); + m_asyncReceiver->setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif + + QVERIFY(m_asyncReceiver->bind(QHostAddress(QHostAddress::AnyIPv4), 0)); + quint16 port = m_asyncReceiver->localPort(); + QVERIFY(port != 0); + + QSignalSpy spy(m_asyncReceiver, SIGNAL(readyRead())); + connect(m_asyncReceiver, SIGNAL(readyRead()), SLOT(async_readDatagramSlot())); + + m_asyncSender->writeDatagram("1", makeNonAny(m_asyncReceiver->localAddress()), port); + + QTestEventLoop::instance().enterLoop(1); + + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(spy.count(), 2); + + delete m_asyncSender; + delete m_asyncReceiver; +} + QTEST_MAIN(tst_QUdpSocket) #include "tst_qudpsocket.moc" -- cgit v1.2.3 From a6ec869211d67fed94e3513dc453a96717155121 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Tue, 11 Aug 2015 13:23:32 +0300 Subject: Fix the spurious socket notifications under Windows To handle network events, QEventDispatcherWin32 uses I/O model based on notifications through the window message queue. Having successfully posted notification of a particular event to an application window, no further messages for that network event will be posted to the application window until the application makes the function call that implicitly re-enables notification of that network event. With these semantics, an application need not read all available data in response to an FD_READ message: a single recv in response to each FD_READ message is appropriate. If an application issues multiple recv calls in response to a single FD_READ, it can receive multiple FD_READ messages (including spurious). To solve this issue, this patch always disables the notifier after getting a notification, and re-enables it only when the message queue is empty. Task-number: QTBUG-46552 Change-Id: I05df67032911cd1f5927fa7912f7864bfbf8711e Reviewed-by: Joerg Bornemann --- src/corelib/kernel/qeventdispatcher_win.cpp | 112 +++++++++++++-------- src/corelib/kernel/qeventdispatcher_win_p.h | 11 +- src/corelib/kernel/qsocketnotifier.cpp | 36 ------- .../kernel/qsocketnotifier/tst_qsocketnotifier.cpp | 73 ++++++++++++++ 4 files changed, 153 insertions(+), 79 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 6da70cf0bd..695eb3d5d0 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -391,6 +391,8 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA QSockNot *sn = dict ? dict->value(wp) : 0; if (sn) { + d->doWsaAsyncSelect(sn->fd, 0); + d->active_fd[sn->fd].selected = false; if (type < 3) { QEvent event(QEvent::SockAct); QCoreApplication::sendEvent(sn->obj, &event); @@ -633,19 +635,12 @@ void QEventDispatcherWin32Private::sendTimerEvent(int timerId) } } -void QEventDispatcherWin32Private::doWsaAsyncSelect(int socket) +void QEventDispatcherWin32Private::doWsaAsyncSelect(int socket, long event) { Q_ASSERT(internalHwnd); - int sn_event = 0; - if (sn_read.contains(socket)) - sn_event |= FD_READ | FD_CLOSE | FD_ACCEPT; - if (sn_write.contains(socket)) - sn_event |= FD_WRITE | FD_CONNECT; - if (sn_except.contains(socket)) - sn_event |= FD_OOB; - // BoundsChecker may emit a warning for WSAAsyncSelect when sn_event == 0 + // BoundsChecker may emit a warning for WSAAsyncSelect when event == 0 // This is a BoundsChecker bug and not a Qt bug - WSAAsyncSelect(socket, internalHwnd, sn_event ? int(WM_QT_SOCKETNOTIFIER) : 0, sn_event); + WSAAsyncSelect(socket, internalHwnd, event ? int(WM_QT_SOCKETNOTIFIER) : 0, event); } void QEventDispatcherWin32::createInternalHwnd() @@ -658,13 +653,6 @@ void QEventDispatcherWin32::createInternalHwnd() installMessageHook(); - // register all socket notifiers - QList sockets = (d->sn_read.keys().toSet() - + d->sn_write.keys().toSet() - + d->sn_except.keys().toSet()).toList(); - for (int i = 0; i < sockets.count(); ++i) - d->doWsaAsyncSelect(sockets.at(i)); - // start all normal timers for (int i = 0; i < d->timerVec.count(); ++i) d->registerTimer(d->timerVec.at(i)); @@ -749,28 +737,40 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) msg = d->queuedSocketEvents.takeFirst(); } else { haveMessage = PeekMessage(&msg, 0, 0, 0, PM_REMOVE); - if (haveMessage && (flags & QEventLoop::ExcludeUserInputEvents) - && ((msg.message >= WM_KEYFIRST - && msg.message <= WM_KEYLAST) - || (msg.message >= WM_MOUSEFIRST - && msg.message <= WM_MOUSELAST) - || msg.message == WM_MOUSEWHEEL - || msg.message == WM_MOUSEHWHEEL - || msg.message == WM_TOUCH + if (haveMessage) { + if ((flags & QEventLoop::ExcludeUserInputEvents) + && ((msg.message >= WM_KEYFIRST + && msg.message <= WM_KEYLAST) + || (msg.message >= WM_MOUSEFIRST + && msg.message <= WM_MOUSELAST) + || msg.message == WM_MOUSEWHEEL + || msg.message == WM_MOUSEHWHEEL + || msg.message == WM_TOUCH #ifndef QT_NO_GESTURES - || msg.message == WM_GESTURE - || msg.message == WM_GESTURENOTIFY + || msg.message == WM_GESTURE + || msg.message == WM_GESTURENOTIFY #endif - || msg.message == WM_CLOSE)) { - // queue user input events for later processing - haveMessage = false; - d->queuedUserInputEvents.append(msg); - } - if (haveMessage && (flags & QEventLoop::ExcludeSocketNotifiers) - && (msg.message == WM_QT_SOCKETNOTIFIER && msg.hwnd == d->internalHwnd)) { - // queue socket events for later processing - haveMessage = false; - d->queuedSocketEvents.append(msg); + || msg.message == WM_CLOSE)) { + // queue user input events for later processing + d->queuedUserInputEvents.append(msg); + continue; + } + if ((flags & QEventLoop::ExcludeSocketNotifiers) + && (msg.message == WM_QT_SOCKETNOTIFIER && msg.hwnd == d->internalHwnd)) { + // queue socket events for later processing + d->queuedSocketEvents.append(msg); + continue; + } + } else if (!(flags & QEventLoop::ExcludeSocketNotifiers)) { + // register all socket notifiers + for (QSFDict::iterator it = d->active_fd.begin(), end = d->active_fd.end(); + it != end; ++it) { + QSockFd &sd = it.value(); + if (!sd.selected) { + d->doWsaAsyncSelect(it.key(), sd.event); + sd.selected = true; + } + } } } if (!haveMessage) { @@ -896,8 +896,25 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier) sn->fd = sockfd; dict->insert(sn->fd, sn); - if (d->internalHwnd) - d->doWsaAsyncSelect(sockfd); + long event = 0; + if (d->sn_read.contains(sockfd)) + event |= FD_READ | FD_CLOSE | FD_ACCEPT; + if (d->sn_write.contains(sockfd)) + event |= FD_WRITE | FD_CONNECT; + if (d->sn_except.contains(sockfd)) + event |= FD_OOB; + + QSFDict::iterator it = d->active_fd.find(sockfd); + if (it != d->active_fd.end()) { + QSockFd &sd = it.value(); + if (sd.selected) { + d->doWsaAsyncSelect(sockfd, 0); + sd.selected = false; + } + sd.event |= event; + } else { + d->active_fd.insert(sockfd, QSockFd(event)); + } } void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) @@ -916,6 +933,19 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) #endif Q_D(QEventDispatcherWin32); + QSFDict::iterator it = d->active_fd.find(sockfd); + if (it != d->active_fd.end()) { + QSockFd &sd = it.value(); + if (sd.selected) + d->doWsaAsyncSelect(sockfd, 0); + const long event[3] = { FD_READ | FD_CLOSE | FD_ACCEPT, FD_WRITE | FD_CONNECT, FD_OOB }; + sd.event ^= event[type]; + if (sd.event == 0) + d->active_fd.erase(it); + else + sd.selected = false; + } + QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except }; QSNDict *dict = sn_vec[type]; QSockNot *sn = dict->value(sockfd); @@ -924,9 +954,6 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) dict->remove(sockfd); delete sn; - - if (d->internalHwnd) - d->doWsaAsyncSelect(sockfd); } void QEventDispatcherWin32::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) @@ -1165,6 +1192,7 @@ void QEventDispatcherWin32::closingDown() unregisterSocketNotifier((*(d->sn_write.begin()))->obj); while (!d->sn_except.isEmpty()) unregisterSocketNotifier((*(d->sn_except.begin()))->obj); + Q_ASSERT(d->active_fd.isEmpty()); // clean up any timers for (int i = 0; i < d->timerVec.count(); ++i) diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index e59e29f1ff..8578110ee4 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -115,6 +115,14 @@ struct QSockNot { }; typedef QHash QSNDict; +struct QSockFd { + long event; + bool selected; + + explicit inline QSockFd(long ev = 0) : event(ev), selected(false) { } +}; +typedef QHash QSFDict; + struct WinTimerInfo { // internal timer info QObject *dispatcher; int timerId; @@ -169,7 +177,8 @@ public: QSNDict sn_read; QSNDict sn_write; QSNDict sn_except; - void doWsaAsyncSelect(int socket); + QSFDict active_fd; + void doWsaAsyncSelect(int socket, long event); QList winEventNotifierList; void activateEventNotifier(QWinEventNotifier * wen); diff --git a/src/corelib/kernel/qsocketnotifier.cpp b/src/corelib/kernel/qsocketnotifier.cpp index d789af2fd9..3a5eff0c19 100644 --- a/src/corelib/kernel/qsocketnotifier.cpp +++ b/src/corelib/kernel/qsocketnotifier.cpp @@ -98,42 +98,6 @@ public: QTcpSocket and QUdpSocket provide notification through signals, so there is normally no need to use a QSocketNotifier on them. - \section1 Notes for Windows Users - - The socket passed to QSocketNotifier will become non-blocking, even if - it was created as a blocking socket. - The activated() signal is sometimes triggered by high general activity - on the host, even if there is nothing to read. A subsequent read from - the socket can then fail, the error indicating that there is no data - available (e.g., \c{WSAEWOULDBLOCK}). This is an operating system - limitation, and not a bug in QSocketNotifier. - - To ensure that the socket notifier handles read notifications correctly, - follow these steps when you receive a notification: - - \list 1 - \li Disable the notifier. - \li Read data from the socket. - \li Re-enable the notifier if you are interested in more data (such as after - having written a new command to a remote server). - \endlist - - To ensure that the socket notifier handles write notifications correctly, - follow these steps when you receive a notification: - - \list 1 - \li Disable the notifier. - \li Write as much data as you can (before \c EWOULDBLOCK is returned). - \li Re-enable notifier if you have more data to write. - \endlist - - \b{Further information:} - On Windows, Qt always disables the notifier after getting a notification, - and only re-enables it if more data is expected. For example, if data is - read from the socket and it can be used to read more, or if reading or - writing is not possible because the socket would block, in which case - it is necessary to wait before attempting to read or write again. - \sa QFile, QProcess, QTcpSocket, QUdpSocket */ diff --git a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp index 930a17c3a9..f49da1f5a8 100644 --- a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #ifndef Q_OS_WINRT #include #else @@ -66,8 +67,29 @@ private slots: #ifdef Q_OS_UNIX void posixSockets(); #endif + void asyncMultipleDatagram(); + +protected slots: + void async_readDatagramSlot(); + void async_writeDatagramSlot(); + +private: + QUdpSocket *m_asyncSender; + QUdpSocket *m_asyncReceiver; }; +static QHostAddress makeNonAny(const QHostAddress &address, + QHostAddress::SpecialAddress preferForAny = QHostAddress::LocalHost) +{ + if (address == QHostAddress::Any) + return preferForAny; + if (address == QHostAddress::AnyIPv4) + return QHostAddress::LocalHost; + if (address == QHostAddress::AnyIPv6) + return QHostAddress::LocalHostIPv6; + return address; +} + class UnexpectedDisconnectTester : public QObject { Q_OBJECT @@ -299,5 +321,56 @@ void tst_QSocketNotifier::posixSockets() } #endif +void tst_QSocketNotifier::async_readDatagramSlot() +{ + char buf[1]; + QVERIFY(m_asyncReceiver->hasPendingDatagrams()); + do { + QCOMPARE(m_asyncReceiver->pendingDatagramSize(), qint64(1)); + QCOMPARE(m_asyncReceiver->readDatagram(buf, sizeof(buf)), qint64(1)); + if (buf[0] == '1') { + // wait for the second datagram message. + QTest::qSleep(100); + } + } while (m_asyncReceiver->hasPendingDatagrams()); + + if (buf[0] == '3') + QTestEventLoop::instance().exitLoop(); +} + +void tst_QSocketNotifier::async_writeDatagramSlot() +{ + m_asyncSender->writeDatagram("3", makeNonAny(m_asyncReceiver->localAddress()), + m_asyncReceiver->localPort()); +} + +void tst_QSocketNotifier::asyncMultipleDatagram() +{ + m_asyncSender = new QUdpSocket; + m_asyncReceiver = new QUdpSocket; + + QVERIFY(m_asyncReceiver->bind(QHostAddress(QHostAddress::AnyIPv4), 0)); + quint16 port = m_asyncReceiver->localPort(); + QVERIFY(port != 0); + + QSignalSpy spy(m_asyncReceiver, &QIODevice::readyRead); + connect(m_asyncReceiver, &QIODevice::readyRead, this, + &tst_QSocketNotifier::async_readDatagramSlot); + m_asyncSender->writeDatagram("1", makeNonAny(m_asyncReceiver->localAddress()), port); + m_asyncSender->writeDatagram("2", makeNonAny(m_asyncReceiver->localAddress()), port); + // wait a little to ensure that the datagrams we've just sent + // will be delivered on receiver side. + QTest::qSleep(100); + + QTimer::singleShot(500, this, &tst_QSocketNotifier::async_writeDatagramSlot); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(spy.count(), 2); + + delete m_asyncSender; + delete m_asyncReceiver; +} + QTEST_MAIN(tst_QSocketNotifier) #include -- cgit v1.2.3 From c86ca601edfde6e7b6a0769903d86bd48e26d70d Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 21 Aug 2015 13:00:55 +0300 Subject: Windows socket engine: do not discard datagram on critical failure On some network conditions, WSARecvFrom() may return WSAECONNRESET or WSAENETRESET error code to indicate that the connection has been broken and should be reset. According to MSDN documentation, WSAECONNRESET mean that the virtual circuit was reset by the remote side executing a hard or abortive close. Also, it would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message. For a datagram socket, WSAENETRESET indicates that the time to live has expired. Previously, hasPendingDatagram() discarded datagrams with these errors and reported no data available. This behavior is incorrect and can lead to infinite "freezing" of the socket. This patch allows to handle these notifications as a result of the readDatagram() call. Task-number: QTBUG-46552 Change-Id: I7d84babe22d36736b928b4dd4841e30be53d16bd Reviewed-by: Kai Koehne Reviewed-by: Joerg Bornemann --- src/network/socket/qnativesocketengine_win.cpp | 37 +++++++++++++++----------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 72f85c831f..708be2dea7 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1090,8 +1090,11 @@ qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const buf.buf = &c; buf.len = sizeof(c); DWORD flags = MSG_PEEK; - if (::WSARecvFrom(socketDescriptor, &buf, 1, 0, &flags, 0,0,0,0) == SOCKET_ERROR) - return 0; + if (::WSARecvFrom(socketDescriptor, &buf, 1, 0, &flags, 0,0,0,0) == SOCKET_ERROR) { + int err = WSAGetLastError(); + if (err != WSAECONNRESET && err != WSAENETRESET) + return 0; + } } return nbytes; } @@ -1119,14 +1122,7 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const int err = WSAGetLastError(); if (ret == SOCKET_ERROR && err != WSAEMSGSIZE) { WS_ERROR_DEBUG(err); - if (err == WSAECONNRESET || err == WSAENETRESET) { - // Discard error message to prevent QAbstractSocket from - // getting this message repeatedly after reenabling the - // notifiers. - flags = 0; - ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, - &storage.a, &storageSize, 0, 0); - } + result = (err == WSAECONNRESET || err == WSAENETRESET); } else { // If there's no error, or if our buffer was too small, there must be // a pending datagram. @@ -1179,12 +1175,21 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const if (recvResult != SOCKET_ERROR) { ret = qint64(bytesRead); break; - } else if (recvResult == SOCKET_ERROR && err == WSAEMSGSIZE) { - bufferCount += 5; - delete[] buf; - } else if (recvResult == SOCKET_ERROR) { - WS_ERROR_DEBUG(err); - ret = -1; + } else { + switch (err) { + case WSAEMSGSIZE: + bufferCount += 5; + delete[] buf; + continue; + case WSAECONNRESET: + case WSAENETRESET: + ret = 0; + break; + default: + WS_ERROR_DEBUG(err); + ret = -1; + break; + } break; } } -- cgit v1.2.3 From 3f531512e859f78e22a775193f0832f4709c84ec Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 29 Jun 2015 14:26:07 +0200 Subject: Force GLES 2.0 on Android 4.2 devices reporting 3.0 Android does not support GLES 3.0 before 4.3 (API level 18). However some 4.2.2 devices are reported to return 3.0 in the version string and therefore choose the GLES 3+ code paths in Qt. This blows up sooner or later because the 3.0 specific functions are apparently not present at all. Task-number: QTBUG-46831 Change-Id: Ic3eeb7c55829cf36c6d142c01ff8a1e18e9ecc1a Reviewed-by: Kati Kankaanpaa Reviewed-by: Christian Stromme --- src/platformsupport/eglconvenience/qeglplatformcontext.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp index 5bee29afef..bffb0eb4e8 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -39,6 +39,10 @@ #include #include +#ifdef Q_OS_ANDROID +#include +#endif + QT_BEGIN_NAMESPACE /*! @@ -294,6 +298,14 @@ void QEGLPlatformContext::updateFormatFromGL() QByteArray version = QByteArray(reinterpret_cast(s)); int major, minor; if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) { +#ifdef Q_OS_ANDROID + // Some Android 4.2.2 devices report OpenGL ES 3.0 without the functions being available. + static int apiLevel = QtAndroidPrivate::androidSdkVersion(); + if (apiLevel <= 17 && major >= 3) { + major = 2; + minor = 0; + } +#endif m_format.setMajorVersion(major); m_format.setMinorVersion(minor); } -- cgit v1.2.3 From c12b5e07274acde364be98cd0de620d3a44c97b7 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 2 Sep 2015 17:35:53 +0200 Subject: QCocoaMenu: Manually reposition popups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the popup will show too close to the screen bottom, we need to help Cocoa a bit. The horizontal positioning hasn't shown any problems. Change-Id: I5f298529fbf4a902e39f686f368046a8d1c11760 Task-number: QTBUG-45063 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenu.mm | 41 +++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 6668080725..a6157bdc3a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -464,6 +464,13 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, NSView *view = cocoaWindow ? cocoaWindow->contentView() : nil; NSMenuItem *nsItem = item ? ((QCocoaMenuItem *)item)->nsItem() : nil; + QScreen *screen = 0; + if (parentWindow) + screen = parentWindow->screen(); + if (!screen && !QGuiApplication::screens().isEmpty()) + screen = QGuiApplication::screens().at(0); + Q_ASSERT(screen); + // Ideally, we would call -popUpMenuPositioningItem:atLocation:inView:. // However, this showed not to work with modal windows where the menu items // would appear disabled. So, we resort to a more artisanal solution. Note @@ -480,6 +487,21 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, [popupCell setTransparent:YES]; [popupCell setMenu:m_nativeMenu]; [popupCell selectItem:nsItem]; + + int availableHeight = screen->availableSize().height(); + const QPoint &globalPos = parentWindow->mapToGlobal(pos); + int menuHeight = m_nativeMenu.size.height; + if (globalPos.y() + menuHeight > availableHeight) { + // Maybe we need to fix the vertical popup position but we don't know the + // exact popup height at the moment (and Cocoa is just guessing) nor its + // position. So, instead of translating by the popup's full height, we need + // to estimate where the menu will show up and translate by the remaining height. + float idx = ([m_nativeMenu indexOfItem:nsItem] + 1.0f) / m_nativeMenu.numberOfItems; + float heightBelowPos = (1.0 - idx) * menuHeight; + if (globalPos.y() + heightBelowPos > availableHeight) + pos.setY(pos.y() - globalPos.y() + availableHeight - heightBelowPos); + } + NSRect cellFrame = NSMakeRect(pos.x(), pos.y(), m_nativeMenu.minimumWidth, 10); [popupCell performClickWithFrame:cellFrame inView:view]; } else { @@ -488,22 +510,21 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, if (view) { // convert coordinates from view to the view's window nsPos = [view convertPoint:nsPos toView:nil]; - } else if (!QGuiApplication::screens().isEmpty()) { - QScreen *screen = QGuiApplication::screens().at(0); + } else { nsPos.y = screen->availableVirtualSize().height() - nsPos.y; } if (view) { // Finally, we need to synthesize an event. NSEvent *menuEvent = [NSEvent mouseEventWithType:NSRightMouseDown - location:nsPos - modifierFlags:0 - timestamp:0 - windowNumber:view ? view.window.windowNumber : 0 - context:nil - eventNumber:0 - clickCount:1 - pressure:1.0]; + location:nsPos + modifierFlags:0 + timestamp:0 + windowNumber:view ? view.window.windowNumber : 0 + context:nil + eventNumber:0 + clickCount:1 + pressure:1.0]; [NSMenu popUpContextMenu:m_nativeMenu withEvent:menuEvent forView:view]; } else { [m_nativeMenu popUpMenuPositioningItem:nsItem atLocation:nsPos inView:0]; -- cgit v1.2.3 From deb6b5032c8eed35021b3c697a770645d90b11ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89meric=20MASCHINO?= Date: Wed, 9 Sep 2015 22:56:32 +0200 Subject: Fixed compilation errors in qatomic_ia64.h QBasicAtomicOps::testAndSetRelaxed(T &, T, T) and QBasicAtomicOps::testAndSetOrdered(T &, T, T) bodies don't match any prototypes in qatomic_ia64.h: the optional parameter T *currentValue is missing. Task-number: QTBUG-48197 Change-Id: I0112c429b161b4a0ddb6e8a0400a436282ffb1c7 Reviewed-by: Thiago Macieira --- src/corelib/arch/qatomic_ia64.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/arch/qatomic_ia64.h b/src/corelib/arch/qatomic_ia64.h index c880e85209..2ba6d127d9 100644 --- a/src/corelib/arch/qatomic_ia64.h +++ b/src/corelib/arch/qatomic_ia64.h @@ -1035,16 +1035,16 @@ bool QBasicAtomicOps::deref(T &_q_value) Q_DECL_NOTHROW } template template inline -bool QBasicAtomicOps::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { - return testAndSetAcquire(_q_value, expectedValue, newValue); + return testAndSetAcquire(_q_value, expectedValue, newValue, currentValue); } template template inline -bool QBasicAtomicOps::testAndSetOrdered(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps::testAndSetOrdered(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { orderedMemoryFence(_q_value); - return testAndSetAcquire(_q_value, expectedValue, newValue); + return testAndSetAcquire(_q_value, expectedValue, newValue, currentValue); } template template inline -- cgit v1.2.3 From 9f452719f368816787e3640b84cb25f53149f15d Mon Sep 17 00:00:00 2001 From: Tuomas Heimonen Date: Wed, 20 May 2015 14:03:17 +0300 Subject: tst_QUndoGroup, tst_QUndoStack Fixed flag QT_NO_PROCESS Change-Id: I6c36475e343de72c954fcc917132977eb1f8d61a Reviewed-by: Tuomas Heimonen Reviewed-by: Marko Kangas Reviewed-by: Friedemann Kleint --- tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp | 8 ++++---- tests/auto/widgets/util/qundostack/tst_qundostack.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp index f19ef391ff..781adeedad 100644 --- a/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp +++ b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp @@ -193,9 +193,7 @@ private slots: void deleteStack(); void checkSignals(); void addStackAndDie(); -#ifndef QT_NO_PROCESS void commandTextFormat(); -#endif }; tst_QUndoGroup::tst_QUndoGroup() @@ -599,9 +597,11 @@ void tst_QUndoGroup::addStackAndDie() delete stack; } -#ifndef QT_NO_PROCESS void tst_QUndoGroup::commandTextFormat() { +#ifdef QT_NO_PROCESS + QSKIP("No QProcess available"); +#else QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); if (QProcess::execute(binDir + "/lrelease -version") != 0) @@ -643,8 +643,8 @@ void tst_QUndoGroup::commandTextFormat() QCOMPARE(redo_action->text(), QString("redo-prefix append redo-suffix")); qApp->removeTranslator(&translator); -} #endif +} #else class tst_QUndoGroup : public QObject diff --git a/tests/auto/widgets/util/qundostack/tst_qundostack.cpp b/tests/auto/widgets/util/qundostack/tst_qundostack.cpp index 29bc14f372..2c8a9a3ee5 100644 --- a/tests/auto/widgets/util/qundostack/tst_qundostack.cpp +++ b/tests/auto/widgets/util/qundostack/tst_qundostack.cpp @@ -239,9 +239,7 @@ private slots: void macroBeginEnd(); void compression(); void undoLimit(); -#ifndef QT_NO_PROCESS void commandTextFormat(); -#endif void separateUndoText(); }; @@ -2958,9 +2956,11 @@ void tst_QUndoStack::undoLimit() true); // redoChanged } -#ifndef QT_NO_PROCESS void tst_QUndoStack::commandTextFormat() { +#ifdef QT_NO_PROCESS + QSKIP("No QProcess available"); +#else QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); if (QProcess::execute(binDir + "/lrelease -version") != 0) @@ -2999,8 +2999,8 @@ void tst_QUndoStack::commandTextFormat() QCOMPARE(redo_action->text(), QString("redo-prefix append redo-suffix")); qApp->removeTranslator(&translator); -} #endif +} void tst_QUndoStack::separateUndoText() { -- cgit v1.2.3 From e3fa2cb660b70d3b45a047bdb055959e36e8445f Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Fri, 22 May 2015 13:09:57 +0300 Subject: Fix regression with QStandardPaths::standardLocations on Windows Commit f3bc9f5c5cee9dac8a7815c2861a9945b5341390 broke standardLocations by replacing them with same paths as writeable locations would return. Task-number: QTBUG-46279 Change-Id: I43150e3af13320a707c7882dd0f0cdcb2c6e8a70 Reviewed-by: Friedemann Kleint Reviewed-by: David Faure --- src/corelib/io/qstandardpaths_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index b1d5821a97..615f85a279 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -200,7 +200,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type) case AppDataLocation: case AppLocalDataLocation: case GenericDataLocation: - if (SHGetSpecialFolderPath(0, path, clsidForAppDataLocation(type), FALSE)) { + if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) { QString result = convertCharArray(path); if (type != GenericDataLocation && type != GenericConfigLocation) { #ifndef QT_BOOTSTRAPPED -- cgit v1.2.3 From d4ebbac1b3c6abbdbf5a67c75460c33998847233 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 17 Sep 2015 18:06:57 +0200 Subject: fix parsing of WinRT compiler options Set defaults before parsing compiler options. UsePrecompiledHeader, CompileAsWinRT and GenerateWindowsMetadata options were overwritten after parsing the options. Task-number: QTBUG-46978 Change-Id: I8c4e423cd13f575fa679b114108b693937908549 Reviewed-by: Oswald Buddenhagen Reviewed-by: Andrew Knight --- qmake/generators/win32/msvc_vcproj.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 9acfa6588b..895bfbaf0d 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1037,6 +1037,17 @@ void VcprojGenerator::initConfiguration() conf.suppressUnknownOptionWarnings = project->isActiveConfig("suppress_vcproj_warnings"); conf.CompilerVersion = which_dotnet_version(project->first("MSVC_VER").toLatin1()); + if (conf.CompilerVersion >= NET2012) { + conf.WinRT = project->isActiveConfig("winrt"); + if (conf.WinRT) { + conf.WinPhone = project->isActiveConfig("winphone"); + // Saner defaults + conf.compiler.UsePrecompiledHeader = pchNone; + conf.compiler.CompileAsWinRT = _False; + conf.linker.GenerateWindowsMetadata = _False; + } + } + initCompilerTool(); // Only on configuration per build @@ -1083,17 +1094,6 @@ void VcprojGenerator::initConfiguration() conf.PrimaryOutputExtension = '.' + targetSuffix; } - if (conf.CompilerVersion >= NET2012) { - conf.WinRT = project->isActiveConfig("winrt"); - if (conf.WinRT) { - conf.WinPhone = project->isActiveConfig("winphone"); - // Saner defaults - conf.compiler.UsePrecompiledHeader = pchNone; - conf.compiler.CompileAsWinRT = _False; - conf.linker.GenerateWindowsMetadata = _False; - } - } - conf.Name = project->values("BUILD_NAME").join(' '); if (conf.Name.isEmpty()) conf.Name = isDebug ? "Debug" : "Release"; -- cgit v1.2.3 From 0e647aeb6a49a0fc9b5605031f246bb79dd6a6fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Tue, 15 Sep 2015 18:17:06 +0200 Subject: Blacklist PowerVR Rogue G6200 (v1.3) from supporting BGRA. The drivers for PowerVR Rogue G6200 reports BGRA support, but reading from the FBO does not produce the correct result. Initially reported here: http://launchpad.net/bugs/1436074 Change-Id: Ia173817d557446818d08609d943eb3573b900cc3 Reviewed-by: Gunnar Sletta --- src/gui/opengl/qopenglframebufferobject.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 8d298496df..1cf748d15f 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -43,6 +43,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -1141,9 +1142,19 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN // Without GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA only makes sense on little endian. - const bool supports_bgra = context->isOpenGLES() - ? context->hasExtension(QByteArrayLiteral("GL_EXT_read_format_bgra")) - : context->hasExtension(QByteArrayLiteral("GL_EXT_bgra")); + const bool has_bgra_ext = context->isOpenGLES() + ? context->hasExtension(QByteArrayLiteral("GL_EXT_read_format_bgra")) + : context->hasExtension(QByteArrayLiteral("GL_EXT_bgra")); + + const char *renderer = reinterpret_cast(funcs->glGetString(GL_RENDERER)); + const char *ver = reinterpret_cast(funcs->glGetString(GL_VERSION)); + + // Blacklist PowerVR Rogue G6200 as it has problems with its BGRA support. + const bool blackListed = (qstrcmp(renderer, "PowerVR Rogue G6200") == 0 + && ::strstr(ver, "1.3") != 0); + + const bool supports_bgra = has_bgra_ext && !blackListed; + if (supports_bgra) { QImage img(size, include_alpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); funcs->glReadPixels(0, 0, w, h, GL_BGRA, GL_UNSIGNED_BYTE, img.bits()); -- cgit v1.2.3 From 9b9f86985ff711838d9d1b486ed10823ba02a681 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 18 Sep 2015 15:05:37 +0200 Subject: Fix compilation with QT_NO_[DEBUG|WARNING]_OUTPUT Change-Id: I4b92ac6b917c9979449b4834764497003d6de087 Reviewed-by: Friedemann Kleint --- src/corelib/io/qiodevice.cpp | 6 ++++++ src/plugins/platforms/windows/qwindowsopengltester.cpp | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index b908ae3145..cd448ad9cf 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -82,6 +82,7 @@ void debugBinaryString(const char *data, qint64 maxlen) static void checkWarnMessage(const QIODevice *device, const char *function, const char *what) { +#ifndef QT_NO_WARNING_OUTPUT QDebug d = qWarning(); d.noquote(); d.nospace(); @@ -97,6 +98,11 @@ static void checkWarnMessage(const QIODevice *device, const char *function, cons Q_UNUSED(device) #endif // !QT_NO_QOBJECT d << ": " << what; +#else + Q_UNUSED(device); + Q_UNUSED(function); + Q_UNUSED(what); +#endif // QT_NO_WARNING_OUTPUT } #define CHECK_MAXLEN(function, returnType) \ diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index 810fddbca7..9ebd946ce4 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -276,7 +276,7 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::supportedGlesRenderers() { const GpuDescription gpu = GpuDescription::detect(); const QWindowsOpenGLTester::Renderers result = detectSupportedRenderers(gpu, true); - qDebug(lcQpaGl) << __FUNCTION__ << gpu << "renderer: " << result; + qCDebug(lcQpaGl) << __FUNCTION__ << gpu << "renderer: " << result; return result; } @@ -284,7 +284,7 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::supportedRenderers() { const GpuDescription gpu = GpuDescription::detect(); const QWindowsOpenGLTester::Renderers result = detectSupportedRenderers(gpu, false); - qDebug(lcQpaGl) << __FUNCTION__ << gpu << "renderer: " << result; + qCDebug(lcQpaGl) << __FUNCTION__ << gpu << "renderer: " << result; return result; } -- cgit v1.2.3 From d37643c4336ac87903647ed3cdad65a9e0357f82 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 17 Sep 2015 11:29:46 +0200 Subject: Cocoa integration - make tool window resizable again Tool window always had NSResizableWindowMask before dd02c1eb38c6dfc8367f2c692e11897b6c00b097, and this is broken, the new logic depends on WindowMaximizeButtonHint which is not set on, for example, un-docked widget. Bring the old behavior back, while not cancelling dd02c1e - make it resizable unconditionally, as it always was. Task-number: QTBUG-46882 Change-Id: Ib739a701d85aaadab83230deee808757de6b5e21 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoawindow.mm | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 3188463dbe..84667350d7 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -800,13 +800,10 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) return styleMask; if ((type & Qt::Popup) == Qt::Popup) { if (!windowIsPopupType(type)) { - styleMask = NSUtilityWindowMask; + styleMask = NSUtilityWindowMask | NSResizableWindowMask; if (!(flags & Qt::CustomizeWindowHint)) { - styleMask |= NSResizableWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSTitledWindowMask; + styleMask |= NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask; } else { - if (flags & Qt::WindowMaximizeButtonHint) - styleMask |= NSResizableWindowMask; if (flags & Qt::WindowTitleHint) styleMask |= NSTitledWindowMask; if (flags & Qt::WindowCloseButtonHint) -- cgit v1.2.3 From ff1275a3bed82ddec0904e07675794a7c242c935 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 19 Sep 2015 10:09:10 -0700 Subject: Fix detection of uClibc version numbers Major << 16 is 0x90000. Reported in QTBUG-45139 Change-Id: I42e7ef1a481840699a8dffff14057022bc4df8e9 Reviewed-by: Oswald Buddenhagen Reviewed-by: Rafael Roquetto --- src/3rdparty/forkfd/forkfd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index 55dc92fe45..ec24ba7b16 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -45,12 +45,12 @@ #ifdef __linux__ # if defined(__BIONIC__) || (defined(__GLIBC__) && (__GLIBC__ << 8) + __GLIBC_MINOR__ >= 0x207 && \ - (!defined(__UCLIBC__) || ((__UCLIBC_MAJOR__ << 16) + (__UCLIBC_MINOR__ << 8) + __UCLIBC_SUBLEVEL__ > 0x921))) + (!defined(__UCLIBC__) || ((__UCLIBC_MAJOR__ << 16) + (__UCLIBC_MINOR__ << 8) + __UCLIBC_SUBLEVEL__ > 0x90201))) # include # define HAVE_EVENTFD 1 # endif # if defined(__BIONIC__) || (defined(__GLIBC__) && (__GLIBC__ << 8) + __GLIBC_MINOR__ >= 0x209 && \ - (!defined(__UCLIBC__) || ((__UCLIBC_MAJOR__ << 16) + (__UCLIBC_MINOR__ << 8) + __UCLIBC_SUBLEVEL__ > 0x921))) + (!defined(__UCLIBC__) || ((__UCLIBC_MAJOR__ << 16) + (__UCLIBC_MINOR__ << 8) + __UCLIBC_SUBLEVEL__ > 0x90201))) # define HAVE_PIPE2 1 # endif #endif -- cgit v1.2.3 From bb6d57479c508e45ad781f07206d448cfcca8669 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Fri, 14 Aug 2015 16:41:19 +0300 Subject: Remove confusing license information from torrent.qdoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The torrent example does not have its own code to work with SHA-1, it uses QCryptographicHash instead. Change-Id: Ided0e3dcded1096feb3366682c97530c4cec0a14 Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Sami Makkonen Reviewed-by: Topi Reiniö --- examples/network/doc/src/torrent.qdoc | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/examples/network/doc/src/torrent.qdoc b/examples/network/doc/src/torrent.qdoc index 08857f02d3..9576e08cfa 100644 --- a/examples/network/doc/src/torrent.qdoc +++ b/examples/network/doc/src/torrent.qdoc @@ -35,37 +35,4 @@ supported by the Qt Network APIs. \image torrent-example.png - - \section1 License Information - - The implementation of the US Secure Hash Algorithm 1 (SHA1) in this example is - derived from the original description in \l{http://www.rfc-editor.org/rfc/rfc3174.txt}{RFC 3174}. - - \legalese - Copyright (C) The Internet Society (2001). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - \endlegalese */ -- cgit v1.2.3 From 363e6e3d52ff7a048f0db9166f6e43137c92669c Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 21 Sep 2015 11:25:54 +0200 Subject: fix error message The error message mentioned a wrong function name. Change-Id: Ia2258744fd9268af6b00f54e74d40476ded3b0d2 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index 14aad0e193..c1f5d2aace 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -187,7 +187,7 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode, pipeBroken = true; break; default: - emit winError(errorCode, QLatin1String("QWindowsPipeReader::completeAsyncRead")); + emit winError(errorCode, QLatin1String("QWindowsPipeReader::notified")); pipeBroken = true; break; } -- cgit v1.2.3 From c7fa644c3880fada2e7047bcb46ec5e2c8d1b239 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 16 Sep 2015 15:18:24 +0200 Subject: QFileDialog: preserve window state after delayed widget dialog creation The widget UI for a QFileDialog is sometimes created lazily as a fallback when the dialog is about to show (the reson being that the platform reports that is has native dialogs, but fails showing it, perhaps because of unsupported configuration). In that case, the widget setup code will resize the dialog to default sizes, and as such, wipe out any explicitly set geometry or window states. This is especially visible on iOS, since there we show all windows maximized by default. If the fallback triggers, the dialog will loose the maximized state and be shown partially outside the screen without a way to close it. This patch will make sure that even if the widgets are created late, we still respect any geometry or window states set by the application. Note: The bug became visible after: 6468cf4e Change-Id: Ib2b87cd24e959c547208aa1cf76d683b9cbc283a Reviewed-by: Gabriel de Dietrich --- src/widgets/dialogs/qfiledialog.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index c9e6a199c4..2d4ba1aeb9 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -2806,6 +2806,13 @@ void QFileDialogPrivate::createWidgets() if (qFileDialogUi) return; Q_Q(QFileDialog); + + // This function is sometimes called late (e.g as a fallback from setVisible). In that case we + // need to ensure that the following UI code (setupUI in particular) doesn't reset any explicitly + // set window state or geometry. + QSize preSize = q->testAttribute(Qt::WA_Resized) ? q->size() : QSize(); + Qt::WindowStates preState = q->windowState(); + model = new QFileSystemModel(q); model->setFilter(options->filter()); model->setObjectName(QLatin1String("qt_filesystem_model")); @@ -2967,7 +2974,8 @@ void QFileDialogPrivate::createWidgets() lineEdit()->selectAll(); _q_updateOkButton(); retranslateStrings(); - q->resize(q->sizeHint()); + q->resize(preSize.isValid() ? preSize : q->sizeHint()); + q->setWindowState(preState); } void QFileDialogPrivate::_q_showHeader(QAction *action) -- cgit v1.2.3 From a6161563e65b398b0e16ed35e97c8828a0ec0526 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 22 Sep 2015 14:39:52 +0200 Subject: Fixed pageLayout, pageSize, pageOrientation, pageMargins for QPdfWriter Task-number: QTBUG-46887 Change-Id: I8f1497a8b7ff13213879de01fcdfcabfdd471874 Reviewed-by: Gunnar Sletta Reviewed-by: Friedemann Kleint --- src/gui/painting/qpdfwriter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp index ca411ebe08..a8c1d8297c 100644 --- a/src/gui/painting/qpdfwriter.cpp +++ b/src/gui/painting/qpdfwriter.cpp @@ -151,7 +151,8 @@ QPdfWriter::QPdfWriter(const QString &filename) Constructs a PDF writer that will write the pdf to \a device. */ QPdfWriter::QPdfWriter(QIODevice *device) - : QObject(*new QPdfWriterPrivate) + : QObject(*new QPdfWriterPrivate), + QPagedPaintDevice(new QPdfPagedPaintDevicePrivate(d_func())) { Q_D(QPdfWriter); -- cgit v1.2.3 From 71df75966db5f51c66bff1c436dd1cb5a895b51b Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Fri, 21 Aug 2015 18:03:46 +0100 Subject: Set positionAutomatic when using setX setY QWindow keeps track of whether a position has been explicitly set by use of a flag positionAutomatic which gets set in setGeometry. This is used to determine if position is passed to the window manager. However calls to setX, setY via properties did not update this flag if the caller is setting it to the default position 0,0. This patch fixes that by making sure the flag is always updated. Change-Id: I2c0c002fe57efa101b3ca79e6e8b3f36cc465761 Reviewed-by: Kai Uwe Broulik Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/kernel/qwindow.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index b54e85a1d3..871437efb1 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1270,8 +1270,11 @@ void QWindow::setMinimumSize(const QSize &size) */ void QWindow::setX(int arg) { + Q_D(QWindow); if (x() != arg) setGeometry(QRect(arg, y(), width(), height())); + else + d->positionAutomatic = false; } /*! @@ -1280,8 +1283,11 @@ void QWindow::setX(int arg) */ void QWindow::setY(int arg) { + Q_D(QWindow); if (y() != arg) setGeometry(QRect(x(), arg, width(), height())); + else + d->positionAutomatic = false; } /*! -- cgit v1.2.3 From ec6556a2b99df373eb43ca009340a7f0f19bacbd Mon Sep 17 00:00:00 2001 From: David Faure Date: Sat, 1 Aug 2015 15:50:00 +0200 Subject: Fix two data races in QThread/QThreadData * theMainThread is written by the main thread and read by QThreadData::~QThreadData() (any managed thread) * QThreadData::thread is written by QThread::~QThread (in the parent thread) and read+written by QThreadData::~QThreadData (in the managed thread). This can happen because QThreadData is refcounted so the managed thread (which derefs it) races with the parent thread (which sets it to 0). Change-Id: I72de793716391a0937254cda6b4328fcad5060c7 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qcoreapplication.cpp | 12 ++++++------ src/corelib/kernel/qcoreapplication_p.h | 2 +- src/corelib/kernel/qobject.cpp | 2 +- src/corelib/thread/qthread_p.h | 2 +- src/corelib/thread/qthread_unix.cpp | 2 +- src/corelib/thread/qthread_win.cpp | 2 +- src/corelib/thread/qthreadstorage.cpp | 6 +++--- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 37a26cf556..24427bd1af 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -460,8 +460,8 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint qt_application_thread_id = QThread::currentThreadId(); # endif - // note: this call to QThread::currentThread() may end up setting theMainThread! - if (QThread::currentThread() != theMainThread) + QThread *cur = QThread::currentThread(); // note: this may end up setting theMainThread! + if (cur != theMainThread) qWarning("WARNING: QApplication was not created in the main() thread."); #endif } @@ -531,11 +531,11 @@ void QCoreApplicationPrivate::eventDispatcherReady() { } -QThread *QCoreApplicationPrivate::theMainThread = 0; +QBasicAtomicPointer QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(0); QThread *QCoreApplicationPrivate::mainThread() { - Q_ASSERT(theMainThread != 0); - return theMainThread; + Q_ASSERT(theMainThread.load() != 0); + return theMainThread.load(); } void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver) @@ -2671,7 +2671,7 @@ bool QCoreApplication::hasPendingEvents() QAbstractEventDispatcher *QCoreApplication::eventDispatcher() { if (QCoreApplicationPrivate::theMainThread) - return QCoreApplicationPrivate::theMainThread->eventDispatcher(); + return QCoreApplicationPrivate::theMainThread.load()->eventDispatcher(); return 0; } diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 2646a28d71..e985f8d052 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -105,7 +105,7 @@ public: } void maybeQuit(); - static QThread *theMainThread; + static QBasicAtomicPointer theMainThread; static QThread *mainThread(); static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data); diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index bcc4e7f8e6..f2c67fb3a0 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1468,7 +1468,7 @@ void QObject::moveToThread(QThread *targetThread) } else if (d->threadData != currentData) { qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n" "Cannot move to target thread (%p)\n", - currentData->thread, d->threadData->thread, targetData ? targetData->thread : Q_NULLPTR); + currentData->thread.load(), d->threadData->thread.load(), targetData ? targetData->thread.load() : Q_NULLPTR); #ifdef Q_OS_MAC qWarning("You might be loading two sets of Qt binaries into the same process. " diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 1ecd682ad1..8331816729 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -269,7 +269,7 @@ public: QStack eventLoops; QPostEventList postEventList; - QThread *thread; + QAtomicPointer thread; Qt::HANDLE threadId; QAtomicPointer eventDispatcher; QVector tls; diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 77093c9cf1..5698a61326 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -225,7 +225,7 @@ QThreadData *QThreadData::current(bool createIfNecessary) data->isAdopted = true; data->threadId = (Qt::HANDLE)pthread_self(); if (!QCoreApplicationPrivate::theMainThread) - QCoreApplicationPrivate::theMainThread = data->thread; + QCoreApplicationPrivate::theMainThread = data->thread.load(); } return data; } diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index c16a2e958c..a4b853d62e 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -121,7 +121,7 @@ QThreadData *QThreadData::current(bool createIfNecessary) threadData->threadId = reinterpret_cast(GetCurrentThreadId()); if (!QCoreApplicationPrivate::theMainThread) { - QCoreApplicationPrivate::theMainThread = threadData->thread; + QCoreApplicationPrivate::theMainThread = threadData->thread.load(); // TODO: is there a way to reflect the branch's behavior using // WinRT API? } else { diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp index 05ab01cc54..37892233f3 100644 --- a/src/corelib/thread/qthreadstorage.cpp +++ b/src/corelib/thread/qthreadstorage.cpp @@ -121,7 +121,7 @@ void **QThreadStorageData::get() const DEBUG_MSG("QThreadStorageData: Returning storage %d, data %p, for thread %p", id, *v, - data->thread); + data->thread.load()); return *v ? v : 0; } @@ -143,7 +143,7 @@ void **QThreadStorageData::set(void *p) DEBUG_MSG("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p", id, value, - data->thread); + data->thread.load()); QMutexLocker locker(&destructorsMutex); DestructorMap *destr = destructors(); @@ -159,7 +159,7 @@ void **QThreadStorageData::set(void *p) // store new data value = p; - DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread, p); + DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread.load(), p); return &value; } -- cgit v1.2.3 From c28bc5f11361960da1bc94a5ea6566ee0fc8397c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20R=C3=B6ssler?= Date: Mon, 6 Jul 2015 17:51:15 +0200 Subject: QNativeSocketEngine: fix SO_REUSEPORT problems on Linux Commit d1cd75e81af809a46fcf40cd2b39858e238a4d97 introduced the usage of the SO_REUSEPORT socket flag on Unix systems if available. However, on Linux systems this socket option behaves differently from the previously used SO_REUSEADDR socket option. This patch disables the use of the SO_REUSEPORT option to fix rebinding problems on Linux. The option was introduced to improve support on OS X and other BSDs. It is not necessary on Linux. [ChangeLog][QtNetwork][QUdpSocket] Fixed a bug that caused the QAbstractSocket::ShareAddress option not to work on Linux. Change-Id: Ice04b8b9e78400dce193e2c1d73b67e33edf8840 Reviewed-by: Richard J. Moore --- src/network/socket/qnativesocketengine_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 4648a3cb5a..8869d75c8b 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -337,7 +337,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt int n, level; convertToLevelAndOption(opt, socketProtocol, level, n); -#if defined(SO_REUSEPORT) +#if defined(SO_REUSEPORT) && !defined(Q_OS_LINUX) if (opt == QNativeSocketEngine::AddressReusable) { // on OS X, SO_REUSEADDR isn't sufficient to allow multiple binds to the // same port (which is useful for multicast UDP). SO_REUSEPORT is, but -- cgit v1.2.3 From 63cf5d3d26a6f65938c3cdec1734eac9faaaf8cb Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 22 Sep 2015 14:26:24 -0400 Subject: QNAM: Assign proper channel before sslErrors() emission There can be a race condition where another channel connects and gets the sslErrors() from the socket first. Then the QSslConfiguration from the wrong socket (the default channel 0's socket) was used. Task-number: QTBUG-18722 Change-Id: Ibbfa48c27f181563745daf540fa792a57cc09682 Reviewed-by: Richard J. Moore --- src/network/access/qhttpnetworkconnectionchannel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 257aa13718..477cba267b 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -1066,6 +1066,8 @@ void QHttpNetworkConnectionChannel::_q_sslErrors(const QList &errors) connection->d_func()->pauseConnection(); if (pendingEncrypt && !reply) connection->d_func()->dequeueRequest(socket); + if (reply) // a reply was actually dequeued. + reply->d_func()->connectionChannel = this; // set correct channel like in sendRequest() and queueRequest(); if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP) { if (reply) emit reply->sslErrors(errors); -- cgit v1.2.3 From 8a0be4007d9c333a93dad04a3809166269cc78d8 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Fri, 21 Aug 2015 01:10:53 +0200 Subject: Doc: update QFileDialog::setSideBarUrls code snippet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The example code uses QDesktopServices::storageLocation which has been replaced by QStandardPaths. This patch fixes this. Change-Id: Ifff25fcb9d85b37ef8247cb4cd9c4c1c8d368780 Reviewed-by: Topi Reiniö --- src/widgets/doc/images/filedialogurls.png | Bin 29132 -> 26724 bytes src/widgets/doc/snippets/filedialogurls.cpp | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/doc/images/filedialogurls.png b/src/widgets/doc/images/filedialogurls.png index 7d22ef33ae..4e26bbfb6d 100644 Binary files a/src/widgets/doc/images/filedialogurls.png and b/src/widgets/doc/images/filedialogurls.png differ diff --git a/src/widgets/doc/snippets/filedialogurls.cpp b/src/widgets/doc/snippets/filedialogurls.cpp index 9e2862b56f..ea771c2050 100644 --- a/src/widgets/doc/snippets/filedialogurls.cpp +++ b/src/widgets/doc/snippets/filedialogurls.cpp @@ -46,8 +46,8 @@ int main(int argv, char **args) //![0] QList urls; - urls << QUrl::fromLocalFile("/home/gvatteka/dev/qt-45") - << QUrl::fromLocalFile(QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); + urls << QUrl::fromLocalFile("/Users/foo/Code/qt5") + << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::MusicLocation).first()); QFileDialog dialog; dialog.setSidebarUrls(urls); -- cgit v1.2.3 From 843199f303652fa2208e50e03987436ca312b791 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Tue, 18 Aug 2015 00:02:24 +0200 Subject: Add shader files to examples documentation file list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the shader code is not accessible from the examples documentation page. This patch fixes this by adding .glsl to the file extensions list for examples Change-Id: Iafe327d1bd99b78641a89863f9dbaf8112651c45 Reviewed-by: Topi Reiniö --- doc/global/fileextensions.qdocconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/global/fileextensions.qdocconf b/doc/global/fileextensions.qdocconf index 88e51595f1..ca036619f1 100644 --- a/doc/global/fileextensions.qdocconf +++ b/doc/global/fileextensions.qdocconf @@ -2,7 +2,7 @@ naturallanguage = en outputencoding = UTF-8 sourceencoding = UTF-8 -examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml *.css" +examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml *.css *.glsl" examples.imageextensions = "*.png *.jpg *.gif" headers.fileextensions = "*.ch *.h *.h++ *.hh *.hpp *.hxx" -- cgit v1.2.3 From be2e0f75ae2e55f235b34b402b70628a839b7782 Mon Sep 17 00:00:00 2001 From: jian liang Date: Sun, 20 Sep 2015 23:08:59 +0800 Subject: Free the QFreeList object allocated memory on exit This memory allocation was introduced in 314c83c0c2f91532654f869b7dc6af1b7e8538da. With a compiler without thread safe statics support mutex.cpp use a function named freelist() to create the global QFreeList object. it will be created when the first time it was accessed, but will never be released. This patch use Q_DESTRUCTOR_FUNCTION to delete this object. Task-number: QTBUG-48359 Change-Id: I4e4716930930aa98630101a1f96de6a7672af9cb Reviewed-by: Thiago Macieira --- src/corelib/thread/qmutex.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 3269ee3ae8..742a572bef 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -571,19 +571,26 @@ FreeList *freelist() return &list; } #else +static QBasicAtomicPointer freeListPtr; + FreeList *freelist() { - static QAtomicPointer list; - FreeList *local = list.loadAcquire(); + FreeList *local = freeListPtr.loadAcquire(); if (!local) { local = new FreeList; - if (!list.testAndSetRelease(0, local)) { + if (!freeListPtr.testAndSetRelease(0, local)) { delete local; - local = list.loadAcquire(); + local = freeListPtr.loadAcquire(); } } return local; } + +static void qFreeListDeleter() +{ + delete freeListPtr.load(); +} +Q_DESTRUCTOR_FUNCTION(qFreeListDeleter) #endif } -- cgit v1.2.3 From c619d2daac9b1f61e8ad2320b59c648b6af6af90 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 22 Sep 2015 13:17:50 +0200 Subject: QDateTime: Ensure a valid timezone when using the "offset constructor". The timeZone() function used to assert when called on such an object (or, for a release build, return an invalid time zone). Change-Id: I6ae8316b2ad76f1f868e2498f7ce8aa3fcabf4a6 Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 1 + tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index eb4eff32b4..d6428920e5 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -3123,6 +3123,7 @@ QTimeZone QDateTime::timeZone() const case Qt::UTC: return QTimeZone::utc(); case Qt::OffsetFromUTC: + return QTimeZone(d->m_offsetFromUtc); case Qt::TimeZone: Q_ASSERT(d->m_timeZone.isValid()); return d->m_timeZone; diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 4ab79909e3..df9089057d 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -2170,6 +2170,7 @@ void tst_QDateTime::offsetFromUtc() // Offset constructor QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, 60 * 60); QCOMPARE(dt1.offsetFromUtc(), 60 * 60); + QVERIFY(dt1.timeZone().isValid()); dt1 = QDateTime(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, -60 * 60); QCOMPARE(dt1.offsetFromUtc(), -60 * 60); -- cgit v1.2.3 From 3ea04c7d388a1790ff3eda9c67f1e224df48e5aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 21 Sep 2015 13:29:17 +0200 Subject: Cocoa: Support Qt::WindowTransparentForInput Map this to ignoresMouseEvents on NSWindow. Task-number: QTBUG-45498 Change-Id: I86e518bbf805647d9f12b1af1747355ef55cc167 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoawindow.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 84667350d7..809acdd87e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1344,6 +1344,9 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) [m_contentView setHidden: YES]; } + m_nsWindow.ignoresMouseEvents = + (window()->flags() & Qt::WindowTransparentForInput) == Qt::WindowTransparentForInput; + const qreal opacity = qt_window_private(window())->opacity; if (!qFuzzyCompare(opacity, qreal(1.0))) setOpacity(opacity); -- cgit v1.2.3 From f0f9f309e03accf17ffcf0a7c8df8f458a73f9f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 23 Sep 2015 14:25:38 +0200 Subject: Support non-latin1 platform plugin paths Replace two instances of QLatin1String() conversion with QString::fromLocal8Bit() Change-Id: I04336c47b0c030c69e38db9aa4dcd208d7200b63 Task-number: QTBUG-48399 Reviewed-by: Liang Qi Reviewed-by: Thiago Macieira --- src/gui/kernel/qguiapplication.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 7dc8444163..64be8ee3d9 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1116,7 +1116,7 @@ void QGuiApplicationPrivate::createPlatformIntegration() QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true); // Load the platform integration - QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH")); + QString platformPluginPath = QString::fromLocal8Bit(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH")); QByteArray platformName; @@ -1146,7 +1146,7 @@ void QGuiApplicationPrivate::createPlatformIntegration() arg.remove(0, 1); if (arg == "-platformpluginpath") { if (++i < argc) - platformPluginPath = QLatin1String(argv[i]); + platformPluginPath = QString::fromLocal8Bit(argv[i]); } else if (arg == "-platform") { if (++i < argc) platformName = argv[i]; -- cgit v1.2.3 From f98c2ef27a4f6fa3b7e9c35cf7896abc4b22816b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20L=C3=B6sch?= Date: Mon, 10 Aug 2015 12:47:04 +0200 Subject: Abort underlying socket when aborting QNetworkReply If we abort a connection in QNetworkReply::encrypted the underlying socket gets flushed. This patch fixes that no data will be transmitted after someone called abort(). Change-Id: I59306e69cb9f2e1421b324e11947375130e52135 Task-number: QTBUG-47471 Reviewed-by: Markus Goetz (Woboq GmbH) Reviewed-by: Thiago Macieira --- src/network/access/qhttpnetworkconnection.cpp | 9 +++++++-- src/network/access/qhttpnetworkconnectionchannel.cpp | 20 ++++++++++++++++++++ src/network/access/qhttpnetworkconnectionchannel_p.h | 1 + src/network/access/qhttpnetworkreply.cpp | 11 +++++++++++ src/network/access/qhttpnetworkreply_p.h | 6 +++++- src/network/access/qhttpthreaddelegate.cpp | 1 + 6 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index b7d17be955..f810df5711 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -835,8 +835,13 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) // if HTTP mandates we should close // or the reply is not finished yet, e.g. it was aborted // we have to close that connection - if (reply->d_func()->isConnectionCloseEnabled() || !reply->isFinished()) - channels[i].close(); + if (reply->d_func()->isConnectionCloseEnabled() || !reply->isFinished()) { + if (reply->isAborted()) { + channels[i].abort(); + } else { + channels[i].close(); + } + } QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); return; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 477cba267b..0820a8d63e 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -205,6 +205,26 @@ void QHttpNetworkConnectionChannel::close() } +void QHttpNetworkConnectionChannel::abort() +{ + if (!socket) + state = QHttpNetworkConnectionChannel::IdleState; + else if (socket->state() == QAbstractSocket::UnconnectedState) + state = QHttpNetworkConnectionChannel::IdleState; + else + state = QHttpNetworkConnectionChannel::ClosingState; + + // pendingEncrypt must only be true in between connected and encrypted states + pendingEncrypt = false; + + if (socket) { + // socket can be 0 since the host lookup is done from qhttpnetworkconnection.cpp while + // there is no socket yet. + socket->abort(); + } +} + + bool QHttpNetworkConnectionChannel::sendRequest() { Q_ASSERT(!protocolHandler.isNull()); diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 37ad6c9b0a..87329b7397 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -157,6 +157,7 @@ public: void init(); void close(); + void abort(); bool sendRequest(); diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 80f3670660..b744a99f0f 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -247,6 +247,17 @@ char* QHttpNetworkReply::userProvidedDownloadBuffer() return d->userProvidedDownloadBuffer; } +void QHttpNetworkReply::abort() +{ + Q_D(QHttpNetworkReply); + d->state = QHttpNetworkReplyPrivate::Aborted; +} + +bool QHttpNetworkReply::isAborted() const +{ + return d_func()->state == QHttpNetworkReplyPrivate::Aborted; +} + bool QHttpNetworkReply::isFinished() const { return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState; diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 0fe298da27..46b6541dfa 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -121,6 +121,9 @@ public: void setUserProvidedDownloadBuffer(char*); char* userProvidedDownloadBuffer(); + void abort(); + + bool isAborted() const; bool isFinished() const; bool isPipeliningUsed() const; @@ -205,7 +208,8 @@ public: SPDYSYNSent, SPDYUploading, SPDYHalfClosed, - SPDYClosed + SPDYClosed, + Aborted } state; QHttpNetworkRequest request; diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index be6fa01098..e4931db304 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -396,6 +396,7 @@ void QHttpThreadDelegate::abortRequest() qDebug() << "QHttpThreadDelegate::abortRequest() thread=" << QThread::currentThreadId() << "sync=" << synchronous; #endif if (httpReply) { + httpReply->abort(); delete httpReply; httpReply = 0; } -- cgit v1.2.3 From bb281eea179d50a413f4ec1ff172d27ee48d3a41 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Fri, 17 Jul 2015 15:32:23 +1000 Subject: Make sure networkAccessibilityChanged is emitted Task-number: QTBUG-46323 Change-Id: I8297072b62763136f457ca6ae15282d1c22244f4 Reviewed-by: Timo Jyrinki Reviewed-by: Alex Blasche --- src/network/access/qnetworkaccessmanager.cpp | 70 +++++++++++++++------- src/network/access/qnetworkaccessmanager_p.h | 14 ++++- .../tst_qnetworkaccessmanager.cpp | 31 +++++----- 3 files changed, 77 insertions(+), 38 deletions(-) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 84931cbb40..f9e9513c55 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -278,7 +278,8 @@ static void ensureInitialized() \snippet code/src_network_access_qnetworkaccessmanager.cpp 4 - Network requests can be reenabled again by calling + Network requests can be re-enabled again, and this property will resume to + reflect the actual device state by calling \snippet code/src_network_access_qnetworkaccessmanager.cpp 5 @@ -467,16 +468,12 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) qRegisterMetaType >(); #ifndef QT_NO_BEARERMANAGEMENT - if (!d->networkSessionRequired) { - // if a session is required, we track online state through - // the QNetworkSession's signals - connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), - SLOT(_q_onlineStateChanged(bool))); - } - // we would need all active configurations to check for - // d->networkConfigurationManager.isOnline(), which is asynchronous - // and potentially expensive. We can just check the configuration here - d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active); + // if a session is required, we track online state through + // the QNetworkSession's signals if a request is already made. + // we need to track current accessibility state by default + // + connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), + SLOT(_q_onlineStateChanged(bool))); #endif } @@ -946,7 +943,8 @@ QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkAccessibility accessible) { Q_D(QNetworkAccessManager); - d->defaultAccessControl = false; + + d->defaultAccessControl = accessible == NotAccessible ? false : true; if (d->networkAccessible != accessible) { NetworkAccessibility previous = networkAccessible(); @@ -965,6 +963,10 @@ void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkA QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccessible() const { Q_D(const QNetworkAccessManager); + + if (d->networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) + return UnknownAccessibility; + if (d->networkSessionRequired) { QSharedPointer networkSession(d->getNetworkSession()); if (networkSession) { @@ -1622,32 +1624,56 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession if (online) { if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { online = false; - networkAccessible = QNetworkAccessManager::NotAccessible; - emit q->networkAccessibleChanged(networkAccessible); + if (networkAccessible != QNetworkAccessManager::NotAccessible) { + networkAccessible = QNetworkAccessManager::NotAccessible; + emit q->networkAccessibleChanged(networkAccessible); + } } } else { if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { online = true; if (defaultAccessControl) - networkAccessible = QNetworkAccessManager::Accessible; - emit q->networkAccessibleChanged(networkAccessible); + if (networkAccessible != QNetworkAccessManager::Accessible) { + networkAccessible = QNetworkAccessManager::Accessible; + emit q->networkAccessibleChanged(networkAccessible); + } } } } void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) { - // if the user set a config, we only care whether this one is active. + Q_Q(QNetworkAccessManager); + // if the user set a config, we only care whether this one is active. // Otherwise, this QNAM is online if there is an online config. if (customNetworkConfiguration) { online = (networkConfiguration.state() & QNetworkConfiguration::Active); } else { - if (isOnline && online != isOnline) { - networkSessionStrongRef.clear(); - networkSessionWeakRef.clear(); + if (online != isOnline) { + if (isOnline) { + networkSessionStrongRef.clear(); + networkSessionWeakRef.clear(); + } + online = isOnline; + } + } + if (online) { + if (defaultAccessControl) { + if (networkAccessible != QNetworkAccessManager::Accessible) { + networkAccessible = QNetworkAccessManager::Accessible; + emit q->networkAccessibleChanged(networkAccessible); + } + } + } else if (networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) { + if (networkAccessible != QNetworkAccessManager::UnknownAccessibility) { + networkAccessible = QNetworkAccessManager::UnknownAccessibility; + emit q->networkAccessibleChanged(networkAccessible); + } + } else { + if (networkAccessible != QNetworkAccessManager::NotAccessible) { + networkAccessible = QNetworkAccessManager::NotAccessible; + emit q->networkAccessibleChanged(networkAccessible); } - - online = isOnline; } } diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index c715da00c1..54ae114581 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -78,7 +78,6 @@ public: customNetworkConfiguration(false), networkSessionRequired(networkConfigurationManager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired), - networkAccessible(QNetworkAccessManager::Accessible), activeReplyCount(0), online(false), initializeSession(true), @@ -86,7 +85,18 @@ public: cookieJarCreated(false), defaultAccessControl(true), authenticationManager(QSharedPointer::create()) - { } + { +#ifndef QT_NO_BEARERMANAGEMENT + // we would need all active configurations to check for + // d->networkConfigurationManager.isOnline(), which is asynchronous + // and potentially expensive. We can just check the configuration here + online = (networkConfiguration.state().testFlag(QNetworkConfiguration::Active)); + if (online) + networkAccessible = QNetworkAccessManager::Accessible; + else + networkAccessible = QNetworkAccessManager::NotAccessible; +#endif + } ~QNetworkAccessManagerPrivate(); void _q_replyFinished(); diff --git a/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp b/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp index b4e4b9ce0a..8ecb57dd33 100644 --- a/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp +++ b/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp @@ -74,6 +74,10 @@ void tst_QNetworkAccessManager::networkAccessible() // if there is no session, we cannot know in which state we are in QNetworkAccessManager::NetworkAccessibility initialAccessibility = manager.networkAccessible(); + + if (initialAccessibility == QNetworkAccessManager::UnknownAccessibility) + QSKIP("Unknown accessibility", SkipAll); + QCOMPARE(manager.networkAccessible(), initialAccessibility); manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible); @@ -94,29 +98,28 @@ void tst_QNetworkAccessManager::networkAccessible() QCOMPARE(manager.networkAccessible(), initialAccessibility); QNetworkConfigurationManager configManager; - bool sessionRequired = (configManager.capabilities() - & QNetworkConfigurationManager::NetworkSessionRequired); QNetworkConfiguration defaultConfig = configManager.defaultConfiguration(); if (defaultConfig.isValid()) { manager.setConfiguration(defaultConfig); - // the accessibility has not changed if no session is required - if (sessionRequired) { + QCOMPARE(spy.count(), 0); + + if (defaultConfig.state().testFlag(QNetworkConfiguration::Active)) + QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::Accessible); + else + QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::NotAccessible); + + manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible); + + if (defaultConfig.state().testFlag(QNetworkConfiguration::Active)) { QCOMPARE(spy.count(), 1); - QCOMPARE(spy.takeFirst().at(0).value(), - QNetworkAccessManager::Accessible); + QCOMPARE(QNetworkAccessManager::NetworkAccessibility(spy.takeFirst().at(0).toInt()), + QNetworkAccessManager::NotAccessible); } else { QCOMPARE(spy.count(), 0); } - QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::Accessible); - - manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible); - - QCOMPARE(spy.count(), 1); - QCOMPARE(QNetworkAccessManager::NetworkAccessibility(spy.takeFirst().at(0).toInt()), - QNetworkAccessManager::NotAccessible); - QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::NotAccessible); } + QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::NotAccessible); #endif } -- cgit v1.2.3 From e18554d4f7722b7fc5b576efb7ca429112789a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C4=81vis=20Mos=C4=81ns?= Date: Thu, 27 Aug 2015 00:50:11 +0300 Subject: Network: Use QFile::encodeName for POSIX paths instead of toLatin1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit POSIX API doesn't really have defined encoding and kernel works with null-terminated byte strings (char *) without any knowledge about encodings. But usually applications use LANG (and LC_*) as encoding making it possible to use any encoding user wishes, including full Unicode support when UTF-8 is used. This allows to create and listen to sockets with paths containing non-latin characters. eg. listen(QString("/run/υποδοχή")); Change-Id: I022ac6a8a4575103125c48768a66bef88a232a2a Reviewed-by: Thiago Macieira Reviewed-by: Dāvis Mosāns --- src/network/socket/qlocalserver_unix.cpp | 22 +++++++++++----------- src/network/socket/qlocalsocket_unix.cpp | 7 ++++--- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp index ef10b1e68d..634074d91f 100644 --- a/src/network/socket/qlocalserver_unix.cpp +++ b/src/network/socket/qlocalserver_unix.cpp @@ -85,7 +85,8 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) } serverName = requestedServerName; - QString tempPath; + QByteArray encodedTempPath; + const QByteArray encodedFullServerName = QFile::encodeName(fullServerName); QScopedPointer tempDir; // Check any of the flags @@ -96,8 +97,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) setError(QLatin1String("QLocalServer::listen")); return false; } - tempPath = tempDir->path(); - tempPath += QLatin1String("/s"); + encodedTempPath = QFile::encodeName(tempDir->path() + QLatin1String("/s")); } // create the unix socket @@ -111,23 +111,23 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) // Construct the unix address struct ::sockaddr_un addr; addr.sun_family = PF_UNIX; - if (sizeof(addr.sun_path) < (uint)fullServerName.toLatin1().size() + 1) { + if (sizeof(addr.sun_path) < (uint)encodedFullServerName.size() + 1) { setError(QLatin1String("QLocalServer::listen")); closeServer(); return false; } if (socketOptions & QLocalServer::WorldAccessOption) { - if (sizeof(addr.sun_path) < (uint)tempPath.toLatin1().size() + 1) { + if (sizeof(addr.sun_path) < (uint)encodedTempPath.size() + 1) { setError(QLatin1String("QLocalServer::listen")); closeServer(); return false; } - ::memcpy(addr.sun_path, tempPath.toLatin1().data(), - tempPath.toLatin1().size() + 1); + ::memcpy(addr.sun_path, encodedTempPath.constData(), + encodedTempPath.size() + 1); } else { - ::memcpy(addr.sun_path, fullServerName.toLatin1().data(), - fullServerName.toLatin1().size() + 1); + ::memcpy(addr.sun_path, encodedFullServerName.constData(), + encodedFullServerName.size() + 1); } // bind @@ -165,13 +165,13 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) if (socketOptions & QLocalServer::OtherAccessOption) mode |= S_IRWXO; - if (::chmod(tempPath.toLatin1(), mode) == -1) { + if (::chmod(encodedTempPath.constData(), mode) == -1) { setError(QLatin1String("QLocalServer::listen")); closeServer(); return false; } - if (::rename(tempPath.toLatin1(), fullServerName.toLatin1()) == -1) { + if (::rename(encodedTempPath.constData(), encodedFullServerName.constData()) == -1) { setError(QLatin1String("QLocalServer::listen")); closeServer(); return false; diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index 77c5028fb3..bb0f11f038 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -268,15 +268,16 @@ void QLocalSocketPrivate::_q_connectToSocket() connectingPathName += QLatin1Char('/') + connectingName; } + const QByteArray encodedConnectingPathName = QFile::encodeName(connectingPathName); struct sockaddr_un name; name.sun_family = PF_UNIX; - if (sizeof(name.sun_path) < (uint)connectingPathName.toLatin1().size() + 1) { + if (sizeof(name.sun_path) < (uint)encodedConnectingPathName.size() + 1) { QString function = QLatin1String("QLocalSocket::connectToServer"); errorOccurred(QLocalSocket::ServerNotFoundError, function); return; } - ::memcpy(name.sun_path, connectingPathName.toLatin1().data(), - connectingPathName.toLatin1().size() + 1); + ::memcpy(name.sun_path, encodedConnectingPathName.constData(), + encodedConnectingPathName.size() + 1); if (-1 == qt_safe_connect(connectingSocket, (struct sockaddr *)&name, sizeof(name))) { QString function = QLatin1String("QLocalSocket::connectToServer"); switch (errno) -- cgit v1.2.3 From 1a6ac8319313b6e024305397512513387afcafb8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 27 Sep 2015 11:43:47 -0700 Subject: Ensure there's no sign-extension here. Both e_shentsize and e_shtrndx are ELF half-words, which means C integers of rank less than int (they're quint16). That means this multiplcation was done actually as int, due to integer promotion from unsigned short. So preempt the integer promotion and force them to full- word integers (unsigned int). While the bit-pattern result of the multiplication is the same, the addition with e_shoff (a qelfoff_t = quintptr) wouldn't: the promotion from 32-bit int to 64-bit would first execute a sign-extension. Now, this shouldn't happen on regular ELF files, but it cause QLibrary to crash if a specially-crafted (or simply corrupt) plugin is found. Found by Coverity, CID 22642 Change-Id: I42e7ef1a481840699a8dffff1407e9f1282eeecf Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/plugin/qelfparser_p.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp index d93be439e0..3798231383 100644 --- a/src/corelib/plugin/qelfparser_p.cpp +++ b/src/corelib/plugin/qelfparser_p.cpp @@ -148,7 +148,7 @@ int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library #endif ElfSectionHeader strtab; - qulonglong soff = e_shoff + e_shentsize * (e_shtrndx); + qulonglong soff = e_shoff + qelfword_t(e_shentsize) * qelfword_t(e_shtrndx); if ((soff + e_shentsize) > fdlen || soff % 4 || soff == 0) { if (lib) -- cgit v1.2.3 From d24366a63281543e6c1a8e6b615ce882ea6259ab Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 25 Sep 2015 10:45:20 +0200 Subject: Fix comparisons between QByteArray and QString. QByteArray::operator< and friends had their logic reversed. Task-number: QTBUG-48350 Change-Id: I625209cc922b47e78dfb8de9fe100411f285a628 Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.h | 8 ++++---- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 63107ff688..d44a5baf2a 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1228,13 +1228,13 @@ inline bool QByteArray::operator==(const QString &s) const inline bool QByteArray::operator!=(const QString &s) const { return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) != 0; } inline bool QByteArray::operator<(const QString &s) const -{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) < 0; } -inline bool QByteArray::operator>(const QString &s) const { return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) > 0; } +inline bool QByteArray::operator>(const QString &s) const +{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) < 0; } inline bool QByteArray::operator<=(const QString &s) const -{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) <= 0; } -inline bool QByteArray::operator>=(const QString &s) const { return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) >= 0; } +inline bool QByteArray::operator>=(const QString &s) const +{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) <= 0; } #endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII) #ifndef QT_NO_CAST_TO_ASCII diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 6d4dbab1fd..0d10a9c5bd 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -4584,6 +4584,22 @@ void tst_QString::operator_smaller() QVERIFY(QString("b") >= "a"); QVERIFY(QString("b") > "a"); + QVERIFY(QString("a") < QByteArray("b")); + QVERIFY(QString("a") <= QByteArray("b")); + QVERIFY(QString("a") <= QByteArray("a")); + QVERIFY(QString("a") == QByteArray("a")); + QVERIFY(QString("a") >= QByteArray("a")); + QVERIFY(QString("b") >= QByteArray("a")); + QVERIFY(QString("b") > QByteArray("a")); + + QVERIFY(QByteArray("a") < QString("b")); + QVERIFY(QByteArray("a") <= QString("b")); + QVERIFY(QByteArray("a") <= QString("a")); + QVERIFY(QByteArray("a") == QString("a")); + QVERIFY(QByteArray("a") >= QString("a")); + QVERIFY(QByteArray("b") >= QString("a")); + QVERIFY(QByteArray("b") > QString("a")); + QVERIFY(QLatin1String("a") < QString("b")); QVERIFY(QLatin1String("a") <= QString("b")); QVERIFY(QLatin1String("a") <= QString("a")); -- cgit v1.2.3 From 3964b683f849baade1576ea2f50aab631970df58 Mon Sep 17 00:00:00 2001 From: Martin Afanasjew Date: Sun, 27 Sep 2015 14:39:06 +0200 Subject: qmake: Fix 'Libs:' line in .pc files on OS X On OS X with a framework-based build of Qt, the 'Libs:' line of the .pc files generated by `qmake` references the framework. This requires two separate arguments to the linker: The fixed string '-framework' and the name of the framework (e.g. 'QtCore'). Only the latter might need quoting. Prior to this fix, they were treated as a single argument (e.g. '-framework QtCore'), thus always quoted because of the contained space, and later lead to errors when trying to link a Qt framework discovered via `pkg-config`. Change-Id: I5c11ee651048832007e2ee4ebcbcf2e3212c8f48 Task-number: QTBUG-47162 Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 4a03fafd77..7d4026c292 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -3253,7 +3253,8 @@ MakefileGenerator::writePkgConfigFile() int suffix = bundle.lastIndexOf(".framework"); if (suffix != -1) bundle = bundle.left(suffix); - pkgConfiglibName = "-framework " + bundle + " "; + t << "-framework "; + pkgConfiglibName = bundle.toQString(); } else { if (!project->values("QMAKE_DEFAULT_LIBDIRS").contains(libDir)) t << "-L${libdir} "; -- cgit v1.2.3 From 9ef87603553c59f8666e868a69b75bf240b9cc12 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 28 Sep 2015 16:25:02 +0200 Subject: QWindowsPipeWriter: clean up OVERLAPPED resource handling Use RAII to ensure that every code path cleans up the event handle, and re-initialize the whole OVERLAPPED object, not just the two offset members. Change-Id: If7e68ec6e61b7bb04df0d06734c04589f6822c4a Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipewriter.cpp | 39 ++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 57053f129a..e75712ba80 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -90,11 +90,38 @@ qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen) return maxlen; } +class QPipeWriterOverlapped +{ +public: + QPipeWriterOverlapped() + { + overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + } + + ~QPipeWriterOverlapped() + { + CloseHandle(overlapped.hEvent); + } + + void prepare() + { + const HANDLE hEvent = overlapped.hEvent; + ZeroMemory(&overlapped, sizeof overlapped); + overlapped.hEvent = hEvent; + } + + OVERLAPPED *operator&() + { + return &overlapped; + } + +private: + OVERLAPPED overlapped; +}; + void QWindowsPipeWriter::run() { - OVERLAPPED overl; - memset(&overl, 0, sizeof overl); - overl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + QPipeWriterOverlapped overl; forever { lock.lock(); while(data.isEmpty() && (!quitNow)) { @@ -115,8 +142,7 @@ void QWindowsPipeWriter::run() const char *ptrData = copy.data(); qint64 maxlen = copy.size(); qint64 totalWritten = 0; - overl.Offset = 0; - overl.OffsetHigh = 0; + overl.prepare(); while ((!quitNow) && totalWritten < maxlen) { DWORD written = 0; if (!WriteFile(writePipe, ptrData + totalWritten, @@ -130,11 +156,9 @@ void QWindowsPipeWriter::run() #ifndef Q_OS_WINCE if (GetLastError() == ERROR_IO_PENDING) { if (!GetOverlappedResult(writePipe, &overl, &written, TRUE)) { - CloseHandle(overl.hEvent); return; } } else { - CloseHandle(overl.hEvent); return; } #else @@ -154,7 +178,6 @@ void QWindowsPipeWriter::run() emit bytesWritten(totalWritten); emit canWrite(); } - CloseHandle(overl.hEvent); } #endif //QT_NO_THREAD -- cgit v1.2.3 From 7fe5f82e48c023edff7c1c60a14f3958ffda8ad2 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 28 Sep 2015 16:27:51 +0200 Subject: clean up QWindowsPipeWriter I/O error handling Exit early, and add warning messages for (unlikely) error cases. Change-Id: I7130b2e298f3a644a9d0e96a3a1860350e11adff Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipewriter.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index e75712ba80..fd14523d45 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -147,18 +147,19 @@ void QWindowsPipeWriter::run() DWORD written = 0; if (!WriteFile(writePipe, ptrData + totalWritten, maxlen - totalWritten, &written, &overl)) { - - if (GetLastError() == 0xE8/*NT_STATUS_INVALID_USER_BUFFER*/) { + const DWORD writeError = GetLastError(); + if (writeError == 0xE8/*NT_STATUS_INVALID_USER_BUFFER*/) { // give the os a rest msleep(100); continue; } #ifndef Q_OS_WINCE - if (GetLastError() == ERROR_IO_PENDING) { - if (!GetOverlappedResult(writePipe, &overl, &written, TRUE)) { - return; - } - } else { + if (writeError != ERROR_IO_PENDING) { + qErrnoWarning(writeError, "QWindowsPipeWriter: async WriteFile failed."); + return; + } + if (!GetOverlappedResult(writePipe, &overl, &written, TRUE)) { + qErrnoWarning(GetLastError(), "QWindowsPipeWriter: GetOverlappedResult failed."); return; } #else -- cgit v1.2.3 From b7f4346c4ff2b2bc579818d33854fad9941510de Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 29 Sep 2015 07:20:45 +0000 Subject: Windows: Change the mocinclude extension to .opt When cleaning in Visual Studio then it will remove all instances of tmp files which meant it would remove the mocinclude.tmp as well incorrectly. Therefore the extension of the mocinclude file needs to be changed to .opt so that it is left untouched by Visual Studio. Change-Id: Iebc055f33f9dc87a4fa42ae87b253f6739903e8f Reviewed-by: Oswald Buddenhagen --- mkspecs/features/moc.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index c0b5682446..8e8deec63c 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -16,7 +16,7 @@ MOC_INCLUDEPATH = $$QMAKESPEC $$_PRO_FILE_PWD_ $$MOC_INCLUDEPATH $$QMAKE_DEFAULT # has too many includes. We do this to overcome a command-line limit on Win < XP WIN_INCLUDETEMP= win32:count(MOC_INCLUDEPATH, 40, >) { - WIN_INCLUDETEMP = $$MOC_DIR/mocinclude.tmp + WIN_INCLUDETEMP = $$MOC_DIR/mocinclude.opt WIN_INCLUDETEMP_CONT = for (inc, MOC_INCLUDEPATH): \ -- cgit v1.2.3 From a5f470240f31d35e694a40fe837fc4f49bc32072 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 28 Sep 2015 16:41:34 +0200 Subject: qprintengine_win.cpp: Check access to members of DOCINFO in warning. DOCINFO::lpszOutput can be 0. Task-number: QTBUG-48203 Change-Id: Ia3940b5b3200143d8d50caa8f4f44c4b22bfff75 Reviewed-by: Andy Shaw --- src/printsupport/kernel/qprintengine_win.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index b377401ed9..a4209d833a 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -93,9 +93,10 @@ static QByteArray msgBeginFailed(const char *function, const DOCINFO &d) { QString result; QTextStream str(&result); - str << "QWin32PrintEngine::begin: " << function << " failed, document \"" - << QString::fromWCharArray(d.lpszDocName) << '"'; - if (d.lpszOutput[0]) + str << "QWin32PrintEngine::begin: " << function << " failed"; + if (d.lpszDocName && d.lpszDocName[0]) + str << ", document \"" << QString::fromWCharArray(d.lpszDocName) << '"'; + if (d.lpszOutput && d.lpszOutput[0]) str << ", file \"" << QString::fromWCharArray(d.lpszOutput) << '"'; return result.toLocal8Bit(); } -- cgit v1.2.3